Skip to content

Commit

Permalink
Merge pull request #3 from fleetbase/dev-v0.0.3
Browse files Browse the repository at this point in the history
v0.0.3
  • Loading branch information
roncodes authored May 8, 2024
2 parents 27bd16a + 0bf8aef commit 0ca4592
Show file tree
Hide file tree
Showing 91 changed files with 2,142 additions and 118 deletions.
6 changes: 5 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ module.exports = {
env: {
browser: true,
},
globals: {
socketClusterClient: 'readonly',
L: 'readonly',
},
rules: {
'ember/no-array-prototype-extensions': 'off',
'ember/no-computed-properties-in-native-classes': 'off',
Expand All @@ -27,7 +31,7 @@ module.exports = {
'n/no-unpublished-require': [
'error',
{
allowModules: ['resolve', 'broccoli-funnel'],
allowModules: ['resolve'],
},
],
},
Expand Down
4 changes: 4 additions & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@

# addons
/.node_modules.ember-try/

# server
/server/
/server_vendor/
5 changes: 5 additions & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

module.exports = {
extends: ['stylelint-config-standard', 'stylelint-prettier/recommended'],
rules: {
'selector-class-pattern': null,
'no-descending-specificity': null,
'color-function-notation': null,
},
};
18 changes: 18 additions & 0 deletions addon/components/explorer-header.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div id="next-view-section-subheader" class="next-view-section-subheader {{if @hideActions 'actions-hidden'}}" ...attributes>
<div id="next-view-section-subheader-left" class="next-view-section-subheader-left {{@leftSubheaderClass}}">
<div class="flex flex-row items-center">
<FaIcon @icon="folder-tree" @size="sm" class="{{@iconClass}} text-gray-200 dark:text-gray-600 mr-2" />
<div class="pod-explorer-breadcrumb-container">
{{#each this.state as |content|}}
<a href="#" class="pod-explorer-breadcrumb {{if (eq @current content.id) "active-breadcrumb"}} {{@breadcrumbClass}}" {{on "click" (fn this.onStateClicked content)}}>{{content.name}}</a>
{{/each}}
</div>
</div>
</div>
<div id="next-view-section-subheader-actions" class="next-view-section-subheader-actions {{@actionsWrapperClass}}">
{{#if @onSearch}}
<Input @type="text" @value={{@searchQuery}} aria-label={{t "common.search-input"}} placeholder={{or @searchPlaceholder (concat (t "common.search") " " (pluralize @title))}} class="w-64 mr-2 form-input form-input-sm {{@searchInputClass}}" {{on "keyup" @onSearch}} />
{{/if}}
{{yield}}
</div>
</div>
25 changes: 25 additions & 0 deletions addon/components/explorer-header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class ExplorerHeaderComponent extends Component {
@service explorerState;
@tracked state = [];

constructor(owner, { pod }) {
super(...arguments);
this.state = this.explorerState.get(pod);
this.explorerState.on('change', (id, state) => {
if (id === pod) {
this.state = state;
}
});
}

@action onStateClicked(content) {
if (typeof this.args.onStateClicked === 'function') {
this.args.onStateClicked(content);
}
}
}
3 changes: 3 additions & 0 deletions addon/components/modals/backup-pod.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
<div class="modal-body-container"></div>
</Modal::Default>
5 changes: 5 additions & 0 deletions addon/components/modals/create-pod.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
<div class="modal-body-container">
<InputGroup @name="Pod Name" @value={{@options.pod.name}} @helpText="Input a name for your new Pod" />
</div>
</Modal::Default>
3 changes: 3 additions & 0 deletions addon/components/modals/resync-pod.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
<div class="modal-body-container"></div>
</Modal::Default>
32 changes: 32 additions & 0 deletions addon/components/table/cell/pod-content-actions.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div class="cell-dropdown-button overflow-visible {{@column.wrapperClass}}" {{did-insert this.setupComponent}} ...attributes>
<DropdownButton @icon={{@column.ddButtonIcon}} @iconPrefix={{@column.ddButtonIconPrefix}} @text={{this.buttonText}} @size="xs" @horizontalPosition="left" @calculatePosition={{this.calculatePosition}} @renderInPlace={{true}} as |dd|>
<div class="next-dd-menu mt-0i" role="menu" aria-orientation="vertical" aria-labelledby="user-menu">
{{#if @column.ddMenuLabel}}
<div class="px-1">
<div class="text-sm flex flex-row items-center px-3 py-1 rounded-md my-1 text-gray-800 dark:text-gray-300">
{{@column.ddMenuLabel}}
</div>
</div>
<div class="next-dd-menu-seperator"></div>
{{/if}}
{{#each this.actions as |action|}}
{{#if action.separator}}
<div class="next-dd-menu-seperator"></div>
{{else}}
{{#if (is-dd-item-visible @row action.isVisible)}}
<div role="group" class="px-1">
<a href="javascript:;" role="menuitem" class="next-dd-item {{action.class}}" {{on "click" (fn this.onDropdownItemClick action @row dd)}}>
{{#if action.icon}}
<span class="mr-1">
<FaIcon class={{action.iconClass}} @icon={{action.icon}} @prefix={{action.iconPrefix}} />
</span>
{{/if}}
{{action.label}}
</a>
</div>
{{/if}}
{{/if}}
{{/each}}
</div>
</DropdownButton>
</div>
73 changes: 73 additions & 0 deletions addon/components/table/cell/pod-content-actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action, computed } from '@ember/object';
import { isArray } from '@ember/array';

export default class TableCellPodContentActionsComponent extends Component {
constructor(owner, { column, row }) {
super(...arguments);
if (isArray(column.actions)) {
this.actions = column.actions;
}

if (typeof column.actions === 'function') {
this.actions = column.actions(row);
}
}

@tracked actions = [];
@tracked defaultButtonText = 'Actions';

@computed('args.column.ddButtonText', 'defaultButtonText') get buttonText() {
const { ddButtonText } = this.args.column;

if (ddButtonText === undefined) {
return this.defaultButtonText;
}

if (ddButtonText === false) {
return null;
}

return ddButtonText;
}

@action setupComponent(dropdownWrapperNode) {
const tableCellNode = this.getOwnerTableCell(dropdownWrapperNode);
tableCellNode.style.overflow = 'visible';
}

@action getOwnerTableCell(dropdownWrapperNode) {
while (dropdownWrapperNode) {
dropdownWrapperNode = dropdownWrapperNode.parentNode;

if (dropdownWrapperNode.tagName.toLowerCase() === 'td') {
return dropdownWrapperNode;
}
}

return undefined;
}

@action onDropdownItemClick(columnAction, row, dd) {
if (typeof dd?.actions?.close === 'function') {
dd.actions.close();
}

if (typeof columnAction?.fn === 'function') {
columnAction.fn(row);
}
}

@action calculatePosition(trigger) {
let { width } = trigger.getBoundingClientRect();

let style = {
marginTop: '0px',
right: width + 3,
top: 0,
};

return { style };
}
}
8 changes: 8 additions & 0 deletions addon/components/table/cell/pod-content-name.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<a href="#" {{on "click" this.onClick}} class={{@column.anchorClass}} disabled={{not @value}} ...attributes>
{{#if (has-block)}}
{{yield}}
{{else}}
<FaIcon @icon={{@row.type}} @size="xs" class="mr-1" />
<span class={{@column.anchorSpanClass}}>{{or @value @column.anchorText "-"}}</span>
{{/if}}
</a>
16 changes: 16 additions & 0 deletions addon/components/table/cell/pod-content-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';

export default class TableCellPodContentNameComponent extends Component {
@action onClick() {
const { column, row } = this.args;

if (typeof column?.action === 'function') {
column.action(row);
}

if (typeof column?.onClick === 'function') {
column.onClick(row, ...arguments);
}
}
}
130 changes: 130 additions & 0 deletions addon/controllers/account.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { alias } from '@ember/object/computed';
import { task } from 'ember-concurrency';

export default class AccountController extends Controller {
/**
* Inject the `currentUser` service.
*
* @memberof ConsoleAccountIndexController
*/
@service currentUser;

/**
* Inject the `fetch` service.
*
* @memberof ConsoleAccountIndexController
*/
@service fetch;

/**
* Inject the `notifications` service.
*
* @memberof ConsoleAccountIndexController
*/
@service notifications;

/**
* Inject the `modalsManager` service.
*
* @memberof ConsoleAccountIndexController
*/
@service modalsManager;

/**
* Alias to the currentUser service user record.
*
* @memberof ConsoleAccountIndexController
*/
@alias('currentUser.user') user;

/**
* Handle upload of new photo
*
* @param {UploadFile} file
* @memberof ConsoleAccountIndexController
*/
@action uploadNewPhoto(file) {
return this.fetch.uploadFile.perform(
file,
{
path: `uploads/${this.user.company_uuid}/users/${this.user.slug}`,
subject_uuid: this.user.id,
subject_type: 'user',
type: 'user_avatar',
},
(uploadedFile) => {
this.user.setProperties({
avatar_uuid: uploadedFile.id,
avatar_url: uploadedFile.url,
});

return this.user.save();
}
);
}

/**
* Starts the task to change password
*
* @param {Event} event
* @memberof ConsoleAccountIndexController
*/
@task *saveProfile(event) {
// If from event fired
if (event instanceof Event) {
event.preventDefault();
}

let canUpdateProfile = true;
// If email has been changed prompt for password validation
if (this.changedUserAttribute('email')) {
canUpdateProfile = yield this.validatePassword.perform();
}

if (canUpdateProfile === true) {
try {
const user = yield this.user.save();
this.notifications.success('Profile changes saved.');
this.currentUser.set('user', user);
} catch (error) {
this.notifications.serverError(error);
}
} else {
this.user.rollbackAttributes();
}
}

/**
* Task to validate current password
*
* @return {boolean}
* @memberof ConsoleAccountIndexController
*/
@task *validatePassword() {
let isPasswordValid = false;

yield this.modalsManager.show('modals/validate-password', {
body: 'You must validate your password to update the account email address.',
onValidated: (isValid) => {
isPasswordValid = isValid;
},
});

return isPasswordValid;
}

/**
* Checks if any user attribute has been changed
*
* @param {string} attributeKey
* @return {boolean}
* @memberof ConsoleAccountIndexController
*/
changedUserAttribute(attributeKey) {
const changedAttributes = this.user.changedAttributes();
return changedAttributes[attributeKey] !== undefined;
}
}
Loading

0 comments on commit 0ca4592

Please sign in to comment.