From dee96e48ce6467871e1e2ef7e8d3dbb568e87474 Mon Sep 17 00:00:00 2001 From: Qun Huang Date: Mon, 15 May 2017 23:06:19 +0800 Subject: [PATCH] roles management --- bower.json | 4 +- src/app/app.js | 7 + src/app/less/custom.less | 9 +- src/app/less/navigation.less | 12 ++ .../permission_management.controller.js | 178 ++++++++++++++++ .../permission_management.html | 191 ++++++++++++++++++ .../permission_management.service.js | 66 ++++++ src/components/common/navigation.html | 10 + 8 files changed, 474 insertions(+), 3 deletions(-) create mode 100644 src/app/permission_management/permission_management.controller.js create mode 100644 src/app/permission_management/permission_management.html create mode 100644 src/app/permission_management/permission_management.service.js diff --git a/bower.json b/bower.json index 5b9a7a6..9f2351f 100755 --- a/bower.json +++ b/bower.json @@ -10,7 +10,6 @@ "angular-resource": "~1.4.4", "angular-ui-router": "~0.2.13", "bootstrap": "~3.3.5", - "angular-bootstrap": "0.12.x", "angular": "~1.4.4", "PACE": "https://github.com/HubSpot/pace.git#~1.0.2", "metisMenu": "~2.0.2", @@ -33,7 +32,8 @@ "moment-timezone": "~0.5.0", "ng-file-model": "https://github.com/mistralworks/ng-file-model.git#fd1889b28e279944012919574bbcaaf45c1540d6", "angular-bootstrap-multiselect": "*", - "bootstrap-ui-datetime-picker": "^2.4.0" + "bootstrap-ui-datetime-picker": "^2.4.0", + "angular-bootstrap": "^2.5.0" }, "overrides": { "bootstrap": { diff --git a/src/app/app.js b/src/app/app.js index 831dd10..d0b8817 100755 --- a/src/app/app.js +++ b/src/app/app.js @@ -75,6 +75,13 @@ angular.module('supportAdminApp', [ templateUrl: 'app/addmembers/add.html', data: { pageTitle: 'User Management' } }) + .state('index.permission_management', { + url: '/permission_management', + templateUrl: 'app/permission_management/permission_management.html', + data: { pageTitle: 'Permission Management' }, + controller: 'PermissionManagementCtrl', + controllerAs: 'ctrl', + }) .state('index.submissions', { abstract: true, url: '/submissions', diff --git a/src/app/less/custom.less b/src/app/less/custom.less index 89f8f14..ffddbda 100755 --- a/src/app/less/custom.less +++ b/src/app/less/custom.less @@ -3,4 +3,11 @@ .welcome-message { display: none; } -} \ No newline at end of file +} + +/* Permission Management - Roles */ + +.user-in-role { + display: inline-block; + margin-right: 12px; +} diff --git a/src/app/less/navigation.less b/src/app/less/navigation.less index 3e4e56f..95ce0ee 100755 --- a/src/app/less/navigation.less +++ b/src/app/less/navigation.less @@ -476,6 +476,18 @@ body.canvas-menu.mini-navbar .navbar-default .nav li a span { display: inline; } +#side-menu { + li { + span { + vertical-align: top; + } + } + .nav-label { + display: inline-block; + width: 120px; + } +} + body.canvas-menu.mini-navbar .navbar-default .nav li .profile-element a span { display: block; } diff --git a/src/app/permission_management/permission_management.controller.js b/src/app/permission_management/permission_management.controller.js new file mode 100644 index 0000000..92dcb5b --- /dev/null +++ b/src/app/permission_management/permission_management.controller.js @@ -0,0 +1,178 @@ +angular.module('supportAdminApp') +.controller('PermissionManagementCtrl', [ + '$scope', '$timeout', 'PermissionManagementService', 'UserService', + function ($scope, $timeout, PMService, UserService) { + + var vm = this; + + /* Table initialization. */ + + angular.element(document).ready(function() { + $('.footable').footable({ + addRowToggle: true + }); + }); + + $scope.$on('permissionManagement.DataUpdated', function(event) { + $timeout(function () { + $('.footable').trigger('footable_redraw'); + }, 100); + }); + + /* Role search by name. */ + + vm.searchCreateRoleText = ''; + + vm.clearRoleSearch = function() { + vm.searchCreateRoleText = ''; + vm.searchRole(); + } + + vm.searchRole = function() { + $('.footable').trigger('footable_filter', { + filter: vm.searchCreateRoleText, + }); + } + + /* Role creation. */ + + vm.creatingNewRole = false; + vm.createNewRoleError = ''; + + vm.createNewRole = function() { + vm.creatingNewRole = true; + vm.createNewRoleError = ''; + PMService.createRole(vm.searchCreateRoleText) + .then(function(res) { + vm.roles.push(res); + loadUser(res.createdBy); + loadUser(res.modifiedBy); + vm.assignment[res.id] = {}; + vm.roles = vm.roles.sort(function(a, b) { + return a.roleName.localeCompare(b.roleName); + }); + }, function(error) { + vm.createNewRoleError = + 'Error: ' + (error.message || 'Failed to create role!'); + }).then(function() { + vm.creatingNewRole = false; + $scope.$broadcast('permissionManagement.DataUpdated'); + }); + } + + /* Role assignments. */ + + vm.assignment = {}; + + /** + * Assigns role to the user. + * @param {String} roleId + * @param {String} userHandle + */ + vm.assignRole = function(roleId, userHandle) { + vm.assignment[roleId].inProgress = true; + vm.assignment[roleId].error = ''; + vm.assignment[roleId].info = ''; + var userId; + UserService.find({ + filter: 'handle=' + userHandle, + }).then(function(res) { + if (!res.length) throw new Error('No user found!'); + userId = res[0].id; + vm.users[userId] = userHandle; + return PMService.assignRole(roleId, userId); + }).then(function() { + var role = vm.roles.find(function (r) { return r.id === roleId; }); + vm.assignment[roleId].info = + 'Success: Role ' + role.roleName + + ' assigned to the user ' + userHandle; + }, function(error) { + vm.assignment[roleId].error = + 'Error: ' + (error.message || 'Failed to assign role!'); + }).then(function() { + vm.assignment[roleId].inProgress = false; + }); + } + + /** + * Unassign role from the user. + * @param {String} roleId + * @param {String} userId + */ + vm.unassignRole = function(roleId, userHandle) { + vm.assignment[roleId].error = ''; + var role = vm.roles.find(function(r) { + return r.id === roleId; + }); + vm.assignment[roleId].error = ''; + vm.assignment[roleId].info = ''; + var userId; + UserService.find({ + filter: 'handle=' + userHandle, + }).then(function (res) { + if (!res.length) throw new Error('No user found!'); + userId = res[0].id; + vm.users[userId] = userHandle; + if (confirm('Unassign role ' + role.roleName + ' from user ' + vm.users[userId] + '?')) { + return PMService.unassignRole(roleId, userId).then(function() { + var role = vm.roles.find(function (r) { return r.id === roleId; }); + vm.assignment[roleId].info = + 'Success: Role ' + role.roleName + + ' unassigned from the user ' + userHandle; + }); + } + }).catch(function(error) { + vm.assignment[roleId].error = + 'Error: ' + (error.message || 'Failed to unassign role!'); + }); + }; + + /* Loading roles. */ + + vm.loadingRoles = true; + vm.loadingRolesError = null; + PMService.getRoles().then(function(roles) { + vm.roles = roles; + roles.forEach(function(role) { + vm.assignment[role.id] = {}; + loadUser(role.createdBy); + loadUser(role.modifiedBy); + }); + }, function(error) { + vm.loadingRolesError = + 'Error: ' + (error.message || 'Failed to load roles!'); + }).then(function() { + vm.loadingRoles = false; + $scope.$broadcast('permissionManagement.DataUpdated'); + }); + + /* Maps user ids, present in the page, into user handles. */ + vm.users = {}; + + /** + * Loads handle of the user specified by id into $scope.users. Does nothing, + * if the handle is already in there. To avoid overflooding API with + * requests, this function handles the calls sequentially. + * @param {String} id User ID. + */ + var loadingUser = false; + var userLoadQueue = []; + function loadUser(id) { + if (id && !vm.users[id]) { + if (loadingUser) userLoadQueue.push(id); + else { + loadingUser = true; + UserService.findById(id).then(function(res) { + vm.users[id] = res.handle; + loadingUser = false; + while (userLoadQueue.length) { + var next = userLoadQueue[0]; + userLoadQueue = userLoadQueue.slice(1); + if (!vm.users[next]) return loadUser(next); + } + }); + } + } + } + } +]); \ No newline at end of file diff --git a/src/app/permission_management/permission_management.html b/src/app/permission_management/permission_management.html new file mode 100644 index 0000000..9bb00bf --- /dev/null +++ b/src/app/permission_management/permission_management.html @@ -0,0 +1,191 @@ +
+
+

Roles

+
+
+
+
+ +
+
+
+
+
+
+
{{ctrl.loadingRolesError}}
+
+
+
+ +
+
+
+
+ +
+
+ + +
+
+
+
{{ctrl.createNewRoleError}}
+
+
+
+
+

Press on a role row to assign/unassign users.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Role IDRole NameCreated byCreated atModified byModified atUser handle
{{role.id}}{{role.roleName}} + + {{ctrl.users[role.createdBy]}} + + loading... + {{role.createdAt | date : 'MM dd yyyy HH:mm' : 'EDT'}} EDT + + {{ctrl.users[role.modifiedBy]}} + + loading... + {{role.modifiedAt | date : 'MM dd yyyy HH:mm' : 'EDT'}} EDT +
+
+ +
+
+ +
+
+ +
+
+
+
{{ctrl.assignment[role.id].error}}
+
+
+
{{ctrl.assignment[role.id].info}}
+
+
+
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/permission_management/permission_management.service.js b/src/app/permission_management/permission_management.service.js new file mode 100644 index 0000000..bfd35af --- /dev/null +++ b/src/app/permission_management/permission_management.service.js @@ -0,0 +1,66 @@ +angular.module('supportAdminApp') +.factory('PermissionManagementService', [ + '$http', 'API_URL', + function($http, API_URL) { + var Service = {}; + + /** + * Assigns role to the user. + * @param {String} roleId + * @param {String} userId + * @return {Promise} Resolves to the roleId, if success. + */ + Service.assignRole = function(roleId, userId) { + return $http.post(API_URL + '/v3/roles/' + roleId + + '/assign?action=true&filter=subjectID%3D' + userId) + .then(function(res) { + return res.data.result.content; + }); + }; + + /** + * Creates a new role. + * @param {String} roleName + * @return {Promise} Resolves to the created role object. + */ + Service.createRole = function(roleName) { + return $http.post(API_URL + '/v3/roles', { + param: { + roleName: roleName + } + }).then(function(res) { + return res.data.result.content; + }); + }; + + /** + * Gets roles. + * @return {Promise} Resolves to the array of role objects, sorted + * by names. + */ + Service.getRoles = function() { + return $http.get(API_URL + '/v3/roles') + .then(function(res) { + return res.data.result.content.sort(function(a, b) { + return a.roleName.localeCompare(b.roleName); + }); + }); + }; + + /** + * Unassigns the role from the user. + * @param {String} roleId + * @param {String} userId + * @return {Promise} Resolves to the roleId, if success. + */ + Service.unassignRole = function(roleId, userId) { + return $http.delete(API_URL + '/v3/roles/' + roleId + + '/deassign?action=true&filter=subjectID%3D' + userId) + .then(function(res) { + return res.data.result.content; + }); + }; + + return Service; + } +]); diff --git a/src/components/common/navigation.html b/src/components/common/navigation.html index 949ac59..7d429d1 100755 --- a/src/components/common/navigation.html +++ b/src/components/common/navigation.html @@ -17,6 +17,16 @@
  • Import SSO Users
  • +
  • + + + Permission Management + + + +
  • Billing Account