@bennerinformatics/ember-fw-gc
Version:
A set of components, controllers, routes, and helpers used in all Group-Control managed FW App System applications
188 lines (164 loc) • 6.21 kB
JavaScript
import {inject as injectService} from '@ember/service';
import {scheduleOnce, throttle} from '@ember/runloop';
import {htmlSafe} from '@ember/string';
import {isEmpty, isNone} from '@ember/utils';
import FWHeader from '@bennerinformatics/ember-fw/components/fw-header';
import {sortBy} from '@bennerinformatics/ember-fw/utils/computed';
import layout from '@bennerinformatics/ember-fw-gc/templates/components/fw-header';
/**
* Page Header Component. This extends [Ember FW's FwHeader](https://linformatics.bitbucket.io/docs/addons/client-api/ember-fw/classes/FwHeader.html).
* In addition to the logo and App Name rendered by Ember FW's FwHeader, Ember FW GC also adds information about the user, such as the app switcher,
* current department and dropdown on the right side of the header. It also is responsible for calling the following modals: about, app-switch, and change-password.
*
* It is called in an identical way as Ember FW's `FwHeader`:
* ```handlebars
* <FwHeader />
* ```
*
* There is no configuration for this component, so everything is documented as private.
*
* @public
* @class FwHeaderGc
* @extends FwHeader
* @module Components
*/
export default FWHeader.extend({
layout,
// deprecated by currentUser service
user: null,
currentDepartment: null,
app: null,
// department switcher
departments: null,
sortedDepartments: sortBy('departments', 'name'),
// label for the switch department dropdown
switchDepartmentLabel: htmlSafe('<i class="fa-solid fa-arrow-right-arrow-left" style="margin-right: 2px;"></i> Switch Departments'),
/**
* Deprecated. This property actually does nothing and should be deleted from your FwHeader
*
* @public
* @property showAboutLink
* @type {Boolean}
* @deprecated
*/
showAboutLink: false,
/**
* Flags for whether modals are shown or not. Contains: about, apps, and change booleans within it.
* @property modals
* @type {Object}
* @private
*/
modals: {
about: false,
apps: false,
change: false
},
/**
* Whether or not the dropdown is currently shown. Internal.
* @property showDropdown
* @type {Boolean}
* @private
*/
showDropdown: false,
/**
* Whether or not the logged in user needs a password change
*
* @private
* @property needSecureChangePassword
* @type {Boolean}
*/
needSecureChangePassword: false,
// Services
currentUser: injectService(),
notifications: injectService(),
session: injectService(),
config: injectService(),
ajax: injectService(),
// Hooks to the currentUser service to open the change password modal when needed
init() {
this._super(...arguments);
this.get('currentUser').on('change-password', this, function (needSecure) {
this.send('toggleChangeModal', needSecure);
});
},
didReceiveAttrs() {
this._super(...arguments);
if (this.get('session.isAuthenticated')) {
this._loadDepartment();
} else {
this.get('currentUser').on('login', this, this._loadDepartment);
}
},
/** Called on load to load the current visible department */
_loadDepartment() {
let currentDept = this.get('currentUser.currentDept');
// department may be empty if the user has no roles
if (isEmpty(currentDept)) {
return;
}
let departmentUrl = this.get('config').formGCUrl('departments', currentDept);
this.get('ajax').request(departmentUrl).then(({department}) => {
scheduleOnce('afterRender', () => {
this.set('currentDepartment', department.name);
});
});
},
/** Called when the menu is clicked to load all available departments */
_loadDepartments() {
if (isNone(this.get('departments'))) {
this.get('ajax').request(this.get('config').formGCUrl('departments', {limit: 'current'})).then(({departments}) => {
this.set('departments', departments);
});
}
},
/** Toggles the dropdown value */
toggleDropdown(value) {
throttle(this, 'set', 'showDropdown', !!value, 100);
},
actions: {
/** Logs the user out of FW */
logout() {
this.get('session').invalidate();
},
/** Reloads the user's permissions */
reload() {
this.get('currentUser').reload().catch(() => {
this.get('notifications').showError('Reload failed!', 'global');
});
},
/** Sets the dropdown to open or closed */
toggleDropdown(value) {
this.toggleDropdown(value);
if (value) {
this._loadDepartments();
}
},
/** Shows the given modal */
showModal(name) {
this.set(`modals.${name}`, true);
this.toggleDropdown(false);
},
/** Shows the apps modal */
toggleAppsModal() {
if (this.get('session.isAuthenticated')) {
this.toggleProperty('modals.apps');
}
this.toggleDropdown(false);
},
/** Shows the change password modall */
toggleChangeModal(needSecure = false) {
this.toggleProperty('modals.change');
this.set('needSecureChangePassword', needSecure);
},
/** Switches the user's current department */
changeDepartment(department) {
if (!this.get('currentUser').checkDepartment(department.id)) {
this.get('currentUser').changeDepartment(department.id).then(() => {
window.location.replace(this.get('config.url'));
}).catch(() => {
this.get('notifications').showError('Failed to switch departments!', 'global');
});
}
}
}
});