Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Added ability to save roles #404

Merged
merged 5 commits into from
Apr 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions app/admin/roles/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import AbstractEditController from 'hospitalrun/controllers/abstract-edit-controller';
import Ember from 'ember';
import UserRoles from 'hospitalrun/mixins/user-roles';
import UserSession from 'hospitalrun/mixins/user-session';

export default AbstractEditController.extend(UserRoles, UserSession, {
currentRole: '',
disabledAction: false,
hideCancelButton: true,
updateCapability: 'user_roles',
filteredRoles: Ember.computed.filter('userRoles', function(userRole) {
return (userRole.name !== 'System Administrator');
}),

availableCapabilities: [{
name: 'admin',
capabilities: [
'admin',
'load_db',
'update_config',
'user_roles'
]
}, {
name: 'appointments',
capabilities: [
'appointments',
'add_appointment'
]
}, {
name: 'billing',
capabilities: [
'billing',
'add_charge',
'add_pricing',
'add_pricing_profile',
'add_invoice',
'add_payment',
'delete_invoice',
'delete_pricing',
'delete_pricing_profile',
'edit_invoice',
'invoices',
'override_invoice',
'pricing'
]
}, {
name: 'patients',
capabilities: [
'patients',
'add_diagnosis',
'add_photo',
'add_patient',
'add_visit',
'add_vitals',
'admit_patient',
'delete_photo',
'delete_patient',
'delete_appointment',
'delete_diagnosis',
'delete_procedure',
'delete_socialwork',
'delete_vitals',
'delete_visit',
'discharge_patient',
'patient_reports',
'visits'
]
}, {
name: 'medication',
capabilities: [
'medication',
'add_medication',
'delete_medication',
'fulfill_medication'
]
}, {
name: 'labs',
capabilities: [
'labs',
'add_lab',
'complete_lab',
'delete_lab'
]
}, {
name: 'imaging',
capabilities: [
'imaging',
'add_imaging',
'complete_imaging',
'delete_imaging'
]
}, {
name: 'inventory',
capabilities: [
'inventory',
'add_inventory_request',
'add_inventory_item',
'add_inventory_purchase',
'adjust_inventory_location',
'delete_inventory_item',
'delete_inventory_purchase',
'fulfill_inventory'
]
}],

capabilitySections: Ember.computed.map('availableCapabilities', function(section) {
var mappedCapabilities = [];
section.capabilities.forEach((key) => {
mappedCapabilities.push({
key: key,
name: this.get('i18n').t('admin.roles.capability.' + key)
});
});
return {
name: this.get('i18n').t('admin.roles.capability.' + section.name),
capabilities: mappedCapabilities
};
}),

actions: {
selectRole(role) {
var roleToUpdate = this.get('model').findBy('id', role.dasherize());
this.set('currentRole', role);
this.set('roleToUpdate', roleToUpdate);
if (roleToUpdate) {
var capabilities = roleToUpdate.get('capabilities');
this.get('availableCapabilities').forEach((section) => {
section.capabilities.forEach((capability) => {
if (capabilities.contains(capability)) {
this.set(capability, true);
} else {
this.set(capability, false);
}
});
});
} else {
var defaultCapabilities = this.get('defaultCapabilities');
Object.keys(defaultCapabilities).forEach((capability) => {
var capabilityRoles = defaultCapabilities[capability];
if (capabilityRoles.contains(role)) {
this.set(capability, true);
} else {
this.set(capability, false);
}
});
}
},

update() {
var currentRole = this.get('currentRole');
var roleToUpdate = this.get('roleToUpdate');
if (Ember.isEmpty(roleToUpdate)) {
roleToUpdate = this.get('store').createRecord('user-role', {
id: currentRole.dasherize(),
name: currentRole
});
}
var capabilitiesToSave = [];
this.get('availableCapabilities').forEach((section) => {
section.capabilities.forEach((capability) => {
if (this.get(capability) === true) {
capabilitiesToSave.push(capability);
}
});
});
roleToUpdate.set('capabilities', capabilitiesToSave);
roleToUpdate.save().then(() => {
this.displayAlert(this.get('i18n').t('admin.roles.titles.role_saved'),
this.get('i18n').t('admin.roles.messages.role_saved', { roleName: currentRole }));
});
}
}

});
10 changes: 10 additions & 0 deletions app/admin/roles/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import AbstractEditRoute from 'hospitalrun/routes/abstract-edit-route';
import { translationMacro as t } from 'ember-i18n';
export default AbstractEditRoute.extend({
hideNewButton: true,
newTitle: t('admin.user_roles'),
editTitle: t('admin.user_roles'),
model: function() {
return this.get('store').findAll('user-role');
}
});
35 changes: 35 additions & 0 deletions app/admin/roles/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{#edit-panel editPanelProps=editPanelProps}}
<div class="panel panel-primary">
<div class="panel-body">
{{#em-form model=this submitButton=false }}
<div class="form-group has-success">
<label class="control-label">{{t 'labels.role'}}</label>
<select onchange={{action "selectRole" value="target.value"}} class="form-control role-select">
<option disabled selected={{is-not selectedRole}}>
</option>
{{#each filteredRoles as |userRole|}}
<option value="{{userRole.name}}"
selected={{eq selectedRole userRole.name}}>
{{userRole.name}}
</option>
{{/each}}
</select>
</div>
{{#each capabilitySections as |capabilitySection|}}
<div class="detail-section">
<div class="panel-heading">
<h3 class="panel-title">
{{capabilitySection.name}}
</h3>
</div>
<div class="detail-section-content">
{{#each capabilitySection.capabilities as |capability|}}
{{em-checkbox label=capability.name property=capability.key class=(concat 'checkbox' ' checkbox-' capability.key)}}
{{/each}}
</div>
</div>
{{/each}}
{{/em-form}}
</div>
</div>
{{/edit-panel}}
2 changes: 1 addition & 1 deletion app/components/nav-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default Ember.Component.extend(UserSession, {

show: function() {
return this.currentUserCan(this.get('nav').capability);
}.property('nav'),
}.property('nav', 'session.data.authenticated.userCaps'),

isShowing: false,

Expand Down
71 changes: 70 additions & 1 deletion app/locales/en/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export default {
address_fields: 'Address Fields',
load_db: 'Load DB',
users: 'Users',
new_user: 'New User'
new_user: 'New User',
user_roles: 'User Roles'
},
actions: {
logout: 'Logout',
Expand All @@ -50,6 +51,7 @@ export default {
address_options: 'Address Options',
lookup_lists: 'Lookup Lists',
load_db: 'Load DB',
user_roles: 'User Roles',
users: 'Users',
address: {
address1_label: 'Address 1 Label',
Expand Down Expand Up @@ -135,6 +137,73 @@ export default {
visit_location_list: 'Visit Locations',
visit_types: 'Visit Types',
ward_pricing_types: 'Ward Pricing Types'
},
roles: {
capability: {
admin: 'Administration',
load_db: 'Load Database',
update_config: 'Update Configurations',
appointments: 'Appointments',
add_appointment: 'Add Appointment',
billing: 'Billing',
add_charge: 'Add Charge',
add_pricing: 'Add Pricing',
add_pricing_profile: 'Add Pricing Profile',
add_invoice: 'Add Invoice',
add_payment: 'Add Payment',
delete_invoice: 'Delete Invoice',
delete_pricing: 'Delete Pricing',
delete_pricing_profile: 'Delete Pricing Profile',
edit_invoice: 'Edit Invoice',
invoices: 'Invoices',
override_invoice: 'Override Invoice',
pricing: 'Pricing',
patients: 'Patients',
add_diagnosis: 'Add Diagnosis',
add_photo: 'Add Photo',
add_patient: 'Add Patient',
add_visit: 'Add Visit',
add_vitals: 'Add Vitals',
admit_patient: 'Admit Patient',
delete_photo: 'Delete Photo',
delete_patient: 'Delete Patient',
delete_appointment: 'Delete Appointment',
delete_diagnosis: 'Delete Diagnosis',
delete_procedure: 'Delete Procedure',
delete_socialwork: 'Delete Social Work',
delete_vitals: 'Delete Vitals',
delete_visit: 'Delete Visit',
discharge_patient: 'Discharge Patient',
patient_reports: 'Patient Reports',
visits: 'Visits',
medication: 'Medication',
add_medication: 'Add Medication',
delete_medication: 'Delete Medication',
fulfill_medication: 'Fulfill Medication',
labs: 'Labs',
add_lab: 'Add Lab',
complete_lab: 'Complete Lab',
delete_lab: 'Delete Lab',
imaging: 'Imaging',
add_imaging: 'Add Imaging',
complete_imaging: 'Complete Imaging',
delete_imaging: 'Delete Imaging',
inventory: 'Inventory',
add_inventory_request: 'Add Inventory Request',
add_inventory_item: 'Add Inventory Item',
add_inventory_purchase: 'Add Inventory Purchase',
adjust_inventory_location: 'Adjust Inventory Location',
delete_inventory_item: 'Delete Inventory Item',
delete_inventory_purchase: 'Delete Inventory Purchase',
fulfill_inventory: 'Fulfill Inventory',
user_roles: 'User Roles'
},
messages: {
role_saved: 'The {{roleName}} role has been saved.'
},
titles: {
role_saved: 'Role Saved'
}
}
},
labels: {
Expand Down
6 changes: 6 additions & 0 deletions app/mixins/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ export default Ember.Mixin.create({
route: 'users.edit',
subroute: 'new',
capability: 'add_user'
},
{
title: 'User Roles',
iconClass: 'octicon-chevron-right',
route: 'admin.roles',
capability: 'user_roles'
}
]
}
Expand Down
17 changes: 12 additions & 5 deletions app/mixins/user-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,10 @@ export default Ember.Mixin.create({
'Nurse Manager',
'Patient Administration',
'System Administrator'
],
'user_roles': [
'System Administrator'
]

},

_getUserSessionVars: function() {
Expand All @@ -465,10 +467,15 @@ export default Ember.Mixin.create({
currentUserCan: function(capability) {
var sessionVars = this._getUserSessionVars();
if (!Ember.isEmpty(sessionVars) && !Ember.isEmpty(sessionVars.role)) {
var capabilities = this.get('defaultCapabilities'),
supportedRoles = capabilities[capability];
if (!Ember.isEmpty(supportedRoles)) {
return supportedRoles.contains(sessionVars.role);
var userCaps = this.get('session').get('data.authenticated.userCaps');
if (Ember.isEmpty(userCaps)) {
var capabilities = this.get('defaultCapabilities');
var supportedRoles = capabilities[capability];
if (!Ember.isEmpty(supportedRoles)) {
return supportedRoles.contains(sessionVars.role);
}
} else {
return userCaps.contains(capability);
}
}
return false;
Expand Down
6 changes: 6 additions & 0 deletions app/models/user-role.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AbstractModel from 'hospitalrun/models/abstract';
import DS from 'ember-data';
export default AbstractModel.extend({
name: DS.attr('string'),
capabilities: DS.attr()
});
1 change: 1 addition & 0 deletions app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Router.map(function() {
}, function() {
this.route('edit', { path: '/edit/:user_id' });
});
this.route('roles');
this.route('query');
});

Expand Down
9 changes: 9 additions & 0 deletions app/routes/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ var ApplicationRoute = Route.extend(ApplicationRouteMixin, {
into: 'application',
outlet: 'modal'
});
},

sessionAuthenticated() {
const session = this.get('session');
const userRole = session.get('data.authenticated.role');
this.get('store').find('user-role', userRole.dasherize()).then((userCaps) => {
session.set('data.authenticated.userCaps', userCaps.get('capabilities'));
}).catch(Ember.K);
this._super();
}

});
Expand Down
Loading