@bennerinformatics/ember-fw-gc
Version:
A set of components, controllers, routes, and helpers used in all Group-Control managed FW App System applications
255 lines (233 loc) • 7.33 kB
JavaScript
import Service from '@ember/service';
import {inject as injectService} from '@ember/service';
import {computed} from '@ember/object';
import {notEmpty} from '@ember/object/computed';
import Evented from '@ember/object/evented';
import {A as emberA} from '@ember/array';
import {isEmpty} from '@ember/utils';
import match from '@bennerinformatics/ember-fw-gc/utils/match';
import RSVP from 'rsvp';
/**
* This service handles various functionality that deals with logged in
* user management. This is one of the most used services in Ember FW GC,
* and once injected has various properties and methods which can be called upon it
* which are invaluable to various aspects of the department.
*
* **Note**: This is different from the user model in that this deals with the currently logged
* in user, rather than an array of user models from Group Control. Because this is a service
* and not a user model, it should not be used as such. For example, a property expecting a user
* model, should not be set in the following way:
* ```javascript
* this.set('user', this.get('currentUser'));
* ```
*
* But rather using the id to find the actual user model from a user array:
*
* ```javascript
* this.set('user', this.get('users').findBy('id', this.get('currentUser.userId')));
* ```
*
* That being said the CurrentUser service is indispensable to a proper integration of Group Control with
* the apps. For a list of all available properties and methods, see below.
*
* @public
* @class CurrentUserService
* @extends Ember.Service
* @uses Ember.Evented
* @module Services
*/
export default Service.extend(Evented, {
/**
* Username of the logged in user.
*
* @public
* @property userId
* @type {String}
*/
userId: '',
/**
* Array of apps the user has access to
*
* @public
* @property apps
* @type {Array}
*/
apps: emberA(),
/**
* Array of roles the user has for the current app and department
*
* @public
* @property roles
* @type {Array}
*/
roles: emberA(),
/**
* If true, the user has roles in this app
*
* @public
* @property hasRoles
* @type {boolean}
*/
hasRoles: notEmpty('roles').readOnly(),
/**
* Array of departments the user has access to for the current app
*
* @public
* @property departments
* @type {Array}
*/
departments: emberA(),
/**
* If true, the user has at least one department
*
* @public
* @property hasRoles
* @type {boolean}
*/
hasDepartments: notEmpty('departments').readOnly(),
/**
* Current department the user is viewing the application as
*
* @public
* @property currentDept
* @type {String}
*/
currentDept: '',
/**
* First name of the user
*
* @public
* @property nameFirst
* @type {String}
*/
nameFirst: '',
/**
* Last name of the user
*
* @public
* @property nameLast
* @type {String}
*/
nameLast: '',
/**
* Preferred first name (nickname) of the user
*
* @public
* @property namePref
* @type {String}
*/
namePref: '',
/**
* Email of the user
*
* @public
* @property email
* @type {String}
*/
email: '',
config: injectService(),
ajax: injectService(),
/**
* Full name of the user, using the user's first, last, and
* preferred name (if available)
*
* @public
* @property nameFull
* @type {String}
*/
nameFull: computed('nameFirst', 'nameLast', 'namePref', function () {
if (isEmpty(this.get('nameFirst')) || isEmpty(this.get('nameLast'))) {
return '';
}
return `${(this.get('namePref') ? this.get('namePref') : this.get('nameFirst'))} ${this.get('nameLast')}`;
}),
/**
* Checks if the user is currently viewing the application as
* a particular department
*
* @public
* @method checkDepartment
* @param {String} department department to check
* @return {Boolean} whether or not the current department matches the provided one
*/
checkDepartment(department) {
return this.get('currentDept') === department;
},
/**
* Changes the department the user is currently viewing the department as.
*
* @public
* @method changeDepartment
* @param {String} newDept new department to view
* @return {Promise} Promise that resolves when the request has been made successfully
*/
changeDepartment(department) {
if (isEmpty(department)) {
return RSVP.resolve();
}
let config = this.get('config');
let app = config.get('appId');
return this.get('ajax').request(config.formGCUrl('session', 'change', {app, department})).then((data) => {
this.setProperties(data);
});
},
/**
* Checks if the user is still logged in.
*
* @public
* @method check
* @return {Promise} Promise that resolves with the current user's status
*/
check() {
let url = this.get('config').formGCUrl('session', 'check');
return this.get('ajax').request(url).catch((error) => {
// if we 500, retry once in case the server was randomly down
if (error.status == 500) {
return this.get('ajax').request(url);
}
// return false for active otherwise
return {isActive: false};
}).then(({isActive}) => {
return isActive;
}).catch(() => {
return false;
});
},
/**
* Reloads the user's roles
*
* @public
* @method reload
* @return {Promise} Promise that resolves when the request has completed.
*/
reload() {
let config = this.get('config');
let app = config.get('appId');
return this.get('ajax').request(config.formGCUrl('session', 'reload', {app})).then(() => {
window.location.replace(this.get('config.url'));
});
},
/**
* Checks if the user's roles match the provided list of roles.
* Uses the [match](../classes/MatchUtil.html) utility to match users
* current roles. Note the use of arrays to match with AND/OR
* (a single array is OR, a double array is AND).
*
* @public
* @param {Array|String} roles Roles to check in either and/or array or string.
* @return {Boolean} Whether or not the given roles match the user's roles
*/
match(roles) {
return match(this.get('roles'), roles);
},
/**
* Shortcut to trigger the change-password trigger
*
* @private
* @method changePassword
* @param {Boolean} needSecure Whether or the user needs to change this password for security reasons.
*/
changePassword(needSecure = false) {
this.trigger('change-password', needSecure);
}
});