diff options
Diffstat (limited to 'ecomp-portal-FE/client/app/views/users')
8 files changed, 999 insertions, 0 deletions
diff --git a/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.controller.js b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.controller.js new file mode 100644 index 00000000..182ffe8f --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.controller.js @@ -0,0 +1,211 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ + +'use strict'; +(function () { + class NewUserModalCtrl { + constructor($scope, $log, usersService, applicationsService, confirmBoxService) { + let init = () => { + $log.info('NewUserModalCtrl::init'); + this.isSaving = false; + this.anyChanges = false; + this.isGettingAdminApps = false; + if($scope.ngDialogData && $scope.ngDialogData.selectedUser && $scope.ngDialogData.dialogState){ + this.selectedUser = $scope.ngDialogData.selectedUser; + this.dialogState = $scope.ngDialogData.dialogState; + this.isShowBack = false; + if(this.dialogState === 3){ + this.getUserAppsRoles(); + } + }else{ + this.isShowBack = true; + this.selectedUser = null; + this.dialogState = 1; + } + }; + + this.appChanged = (index) => { + let myApp = this.adminApps[index]; + $log.debug('NewUserModalCtrl::appChanged: index: ', index, '; app id: ', myApp.id, 'app name: ',myApp.name); + myApp.isChanged = true; + this.anyChanges = true; + } + + this.deleteApp = (app) => { + let appMessage = this.selectedUser.firstName + ' ' + this.selectedUser.lastName; + confirmBoxService.deleteItem(appMessage).then(isConfirmed => { + if(isConfirmed){ + app.isChanged = true; + this.anyChanges = true; + app.isDeleted = true; + app.appRoles.forEach(function(role){ + role.isApplied = false; + }); + } + }).catch(err => { + $log.error('NewUserModalCtrl::deleteApp error: ',err); + }); + }; + + this.getUserAppsRoles = () => { + if (!this.selectedUser || !this.selectedUser.orgUserId) { + $log.error('NewUserModalCtrl::getUserAppsRoles error: No user is selected'); + this.dialogState = 1; + return; + } + $log.debug('NewUserModalCtrl::getUserAppsRoles: about to call getAdminAppsSimpler'); + this.isGettingAdminApps = true; + applicationsService.getAdminAppsSimpler().then((apps) => { + $log.debug('NewUserModalCtrl::getUserAppsRoles: beginning of then for getAdminAppsSimpler'); + this.isGettingAdminApps = false; + if (!apps || !apps.length) { + $log.error('NewUserModalCtrl::getUserAppsRoles error: no apps found'); + return null; + } + $log.debug('NewUserModalCtrl::getUserAppsRoles: then for getAdminAppsSimpler: step 2'); + $log.debug('NewUserModalCtrl::getUserAppsRoles: admin apps: ', apps); + this.adminApps = apps; + this.dialogState = 3; + this.userAppRoles = {}; + this.numberAppsProcessed = 0; + this.isLoading = true; + apps.forEach(app => { + $log.debug('NewUserModalCtrl::getUserAppsRoles: app: id: ', app.id, 'name: ',app.name); + app.isChanged = false; + app.isLoading = true; + app.isError = false; + app.isDeleted = false; + app.printNoChanges = false; + app.isUpdating = false; + app.isErrorUpdating = false; + app.isDoneUpdating = false; + app.errorMessage = ""; + usersService.getUserAppRoles(app.id, this.selectedUser.orgUserId).then((userAppRolesResult) => { + $log.debug('NewUserModalCtrl::getUserAppsRoles: got a result for app: ',app.id,': ',app.name,': ',userAppRolesResult); + app.appRoles = userAppRolesResult; + app.isLoading = false; + + }).catch(err => { + $log.error(err); + app.isError = true; + app.isLoading = false; + app.errorMessage = err.headers('FEErrorString'); + $log.debug('NewUserModalCtrl::getUserAppsRoles: in new-user.controller: response header: '+err.headers('FEErrorString')); + }).finally(()=>{ + this.numberAppsProcessed++; + if (this.numberAppsProcessed == this.adminApps.length) { + this.isLoading = false; + } + }); + }) + return; + }).catch(err => { + $log.error(err); + }) + + } + + this.getAdminApps = () => { + if (!this.selectedUser || !this.selectedUserorgUserId) { + $log.error('NewUserModalCtrl::getAdminApps: No user is selected'); + this.dialogState = 1; + return; + } + applicationsService.getAdminApps().promise().then(apps => { + if (!apps || !apps.length) { + $log.error('NewUserModalCtrl::getAdminApps: no apps found'); + return null; + } + $log.debug('NewUserModalCtrl::getAdminApps: admin apps: ', apps); + this.adminApps = apps; + this.dialogState = 3; + return; + }).catch(err => { + $log.error('NewUserModalCtrl::getAdminApps: ', err); + }) + + } + + this.updateUserAppsRoles = () => { + $log.debug('NewUserModalCtrl::updateUserAppsRoles: entering updateUserAppsRoles'); + if(!this.selectedUser || !this.selectedUser.orgUserId || !this.adminApps){ + $log.debug('NewUserModalCtrl::updateUserAppsRoles: returning early'); + return; + } + this.isSaving = true; + $log.debug('NewUserModalCtrl::updateUserAppsRoles: going to update user: ' + this.selectedUser.orgUserId); + this.numberAppsProcessed = 0; + this.numberAppsSucceeded = 0; + this.adminApps.forEach(app => { + if (app.isChanged) { + $log.debug('NewUserModalCtrl::updateUserAppsRoles: app roles have changed; going to update: id: ', app.id, '; name: ', app.name); + app.isUpdating = true; + usersService.updateUserAppRoles({orgUserId: this.selectedUser.orgUserId, appId: app.id, appRoles: app.appRoles}) + .then(res => { + $log.debug('NewUserModalCtrl::updateUserAppsRoles: User app roles updated successfully on app: ',app.id); + app.isUpdating = false; + app.isDoneUpdating = true; + this.numberAppsSucceeded++; + }).catch(err => { + $log.error(err); + app.isErrorUpdating = true; + }).finally(()=>{ + this.numberAppsProcessed++; + if (this.numberAppsProcessed == this.adminApps.length) { + this.isSaving = false; + } + if (this.numberAppsSucceeded == this.adminApps.length) { + $scope.closeThisDialog(true); + } + }) + } else { + $log.debug('NewUserModalCtrl::updateUserAppsRoles: app roles have NOT changed; NOT going to update: id: ', app.id, '; name: ', app.name); + app.noChanges = true; + app.isError = false; + this.numberAppsProcessed++; + this.numberAppsSucceeded++; + if (this.numberAppsProcessed == this.adminApps.length) { + this.isSaving = false; + } + if (this.numberAppsSucceeded == this.adminApps.length) { + $scope.closeThisDialog(true); + } + } + }); + }; + + this.navigateBack = () => { + if (this.dialogState === 1) { + } + if (this.dialogState === 3) { + this.dialogState = 1; + } + }; + + init(); + + $scope.$on('$stateChangeStart', e => { + e.preventDefault(); + }); + } + } + NewUserModalCtrl.$inject = ['$scope', '$log', 'usersService', 'applicationsService', 'confirmBoxService']; + angular.module('ecompApp').controller('NewUserModalCtrl', NewUserModalCtrl); +})(); diff --git a/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.controller.spec.js b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.controller.spec.js new file mode 100644 index 00000000..54c564b7 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.controller.spec.js @@ -0,0 +1,222 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ + +'use strict'; + +describe('Controller: NewUserModalCtrl ', () => { + beforeEach(module('testUtils')); + beforeEach(module('ecompApp')); + + let promisesTestUtils; + beforeEach(inject((_CacheFactory_, _promisesTestUtils_)=> { + _CacheFactory_.destroyAll(); + promisesTestUtils = _promisesTestUtils_; + })); + + let newUser, $controller, $q, $rootScope, $log, $scope; + + let applicationsServiceMock, usersServiceMock, confirmBoxServiceMock; + let deferredAdminApps, deferredUsersAccounts, deferredUsersAppRoles, deferredUsersAppRoleUpdate; + + beforeEach(inject((_$controller_, _$q_, _$rootScope_, _$log_)=> { + $rootScope = _$rootScope_; + $q = _$q_; + $controller = _$controller_; + $log = _$log_; + })); + + beforeEach(()=> { + [deferredAdminApps, deferredUsersAccounts, deferredUsersAppRoles, deferredUsersAppRoleUpdate] = [$q.defer(),$q.defer(), $q.defer(), $q.defer()]; + + /*applicationsServiceMock = { + getAdminApps: () => { + var promise = () => {return deferredAdminApps.promise}; + var cancel = jasmine.createSpy(); + return { + promise: promise, + cancel: cancel + } + } + };*/ + + confirmBoxServiceMock = { + deleteItem: () => { + var promise = () => {return deferredAdminApps.promise}; + var cancel = jasmine.createSpy(); + return { + promise: promise, + cancel: cancel + } + } + }; + + applicationsServiceMock = jasmine.createSpyObj('applicationsServiceMock', ['getAdminAppsSimpler']); + applicationsServiceMock.getAdminAppsSimpler.and.returnValue(deferredAdminApps.promise); + + usersServiceMock = jasmine.createSpyObj('usersServiceMock', ['getAccountUsers','getUserAppRoles','updateUserAppsRoles']); + + usersServiceMock.getAccountUsers.and.returnValue(deferredUsersAccounts.promise); + usersServiceMock.getUserAppRoles.and.returnValue(deferredUsersAppRoles.promise); + usersServiceMock.updateUserAppsRoles.and.returnValue(deferredUsersAppRoleUpdate.promise); + + $scope = $rootScope.$new(); + newUser = $controller('NewUserModalCtrl', { + $scope: $scope, + $log: $log, + usersService: usersServiceMock, + applicationsService: applicationsServiceMock, + confirmBoxService: confirmBoxServiceMock + }); + }); + + it('should open modal window without user when no user is selected', ()=> { + expect(newUser.selectedUser).toBe(null); + }); + + it('should open modal window with selectedUser apps roles when user is selected', ()=> { + let roles = {apps: [{id: 1, appRoles: [{id: 3, isApplied: true}]}]}; + let someUser = {userId: 'asdfjl'}; + + deferredUsersAppRoles.resolve(roles); + deferredAdminApps.resolve(roles.apps); + + $scope.ngDialogData = { + selectedUser: someUser, + dialogState: 2 + }; + + newUser = $controller('NewUserModalCtrl', { + $scope: $scope, + $log: $log, + usersService: usersServiceMock, + applicationsService: applicationsServiceMock, + confirmBoxService: confirmBoxServiceMock + }); + + newUser.getUserAppsRoles(); + $scope.$apply(); + + expect(newUser.selectedUser).toBe(someUser); + expect(newUser.adminApps).toEqual(roles.apps); + }); + + it('should push to apps order list only apps that has applied roles when initializing', () => { + let roles = {apps: [{appId: 13, appRoles: [{id: 3, isApplied: true}]},{appId: 20, appRoles: [{id: 3, isApplied: false}]}]}; + let someUser = {userId: 'asdfjl'}; + + deferredUsersAppRoles.resolve(roles); + + $scope.ngDialogData = { + selectedUser: someUser, + dialogState: 2 + }; + + newUser = $controller('NewUserModalCtrl', { + $scope: $scope, + $log: $log, + usersService: usersServiceMock, + applicationsService: applicationsServiceMock, + confirmBoxService: confirmBoxServiceMock + }); + + $scope.$apply(); + + }); + + it('should push app to apps order list when applying at least one role to user from app', () => { + let roles = {apps: [{appId: 13, appRoles: [{id: 3, isApplied: true}]},{appId: 20, appRoles: [{id: 3, isApplied: false}]}]}; + let someUser = {userId: 'asdfjl'}; + + deferredUsersAppRoles.resolve(roles); + + $scope.ngDialogData = { + selectedUser: someUser, + dialogState: 2 + }; + + newUser = $controller('NewUserModalCtrl', { + $scope: $scope, + $log: $log, + usersService: usersServiceMock, + applicationsService: applicationsServiceMock, + confirmBoxService: confirmBoxServiceMock + }); + + $scope.$apply(); + + }); + + + it('should remove app from list when removing all user roles in it', () => { + let roles = {apps: [{appName: 'aaa', appId: 13, appRoles: [{id: 3, isApplied: true}]},{appName: 'vvv', appId: 20, appRoles: [{id: 3, isApplied: true}]}]}; + let someUser = {userId: 'asdfjl'}; + + promisesTestUtils.resolvePromise(confirmBoxServiceMock, 'deleteItem', true); + + deferredUsersAppRoles.resolve(roles); + + $scope.ngDialogData = { + selectedUser: someUser, + dialogState: 2 + }; + + newUser = $controller('NewUserModalCtrl', { + $scope: $scope, + $log: $log, + usersService: usersServiceMock, + applicationsService: applicationsServiceMock, + confirmBoxService: confirmBoxServiceMock + }); + + $scope.$apply(); + newUser.deleteApp(roles.apps[0]); + $scope.$apply(); + + }); + + it('should close the modal when update changes succeeded', () => { + let roles = {apps: [{appName: 'aaa', appId: 13, appRoles: [{id: 3, isApplied: true}]},{appName: 'vvv', appId: 20, appRoles: [{id: 3, isApplied: true}]}]}; + let someUser = {userId: 'asdfjl'}; + deferredUsersAppRoles.resolve(roles); + deferredUsersAppRoleUpdate.resolve(); + deferredAdminApps.resolve(roles.apps); + + $scope.ngDialogData = { + selectedUser: someUser, + dialogState: 2 + }; + + newUser = $controller('NewUserModalCtrl', { + $scope: $scope, + $log: $log, + usersService: usersServiceMock, + applicationsService: applicationsServiceMock, + confirmBoxService: confirmBoxServiceMock + }); + $scope.closeThisDialog = function(){}; + spyOn($scope, 'closeThisDialog'); + + newUser.getUserAppsRoles(); + $scope.$apply(); + newUser.updateUserAppsRoles(); + $scope.$apply(); + expect($scope.closeThisDialog).toHaveBeenCalledWith(true); + }); + }); diff --git a/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.modal.html b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.modal.html new file mode 100644 index 00000000..e50c9d4a --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.modal.html @@ -0,0 +1,70 @@ +<!-- + ================================================================================ + eCOMP Portal + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ================================================================================ + --> +<div class="new-user-modal"> + <div class="search-users" ng-show="newUser.dialogState===1"> + <search-users search-title="New User" + selected-user="newUser.selectedUser"></search-users> + <div class="dialog-control"> + <div id="search-user-next-button" class="next-button" ng-click="newUser.selectedUser && newUser.getUserAppsRoles()" + ng-class="{disabled: !newUser.selectedUser}">Next + </div> + <div id="search-user-cancel-button" class="cancel-button" ng-click="closeThisDialog()">Cancel</div> + </div> + </div> + <div class="user-apps-roles" ng-show="newUser.dialogState===3"> + <div class="title" + ng-bind="newUser.selectedUser.firstName + ' ' + newUser.selectedUser.lastName + ' (' + newUser.selectedUser.orgUserId + ')'"></div> + <div class="app-roles-main"> + <div class="app-roles-main-title"> + <span class="left">Access and roles:</span> + </div> + <div class="app-roles-list"> + <div class="app-item" ng-repeat="app in (newUser.adminApps) track by app.id" ng-show="!app.isDeleted"> + <div class="app-item-left" id="div-app-name-{{app.name.split(' ').join('-')}}">{{app.name | elipsis: 27}}</div> + <div class="app-item-right" ng-show="!app.isError && !app.isLoading && !app.noChanges && !app.isUpdating && !app.isDoneUpdating && !app.isErrorUpdating"> + <multiple-select id="app-roles" + unique-data="{{$index}}" + placeholder="Select roles" + ng-model="app.appRoles" + on-change="newUser.appChanged($index)" + name-attr="roleName" + value-attr="isApplied"></multiple-select> + </div> + <div id="app-item-no-contact" class="app-item-right-error" ng-show="app.isError">{{app.errorMessage}}</div> + <div id="app-item-contacting" class="app-item-right-contacting" ng-show="app.isLoading">Contacting application...</div> + <div id="app-item-no-changes" class="app-item-right-contacting" ng-show="app.noChanges">No changes</div> + <div id="app-item-no-updating" class="app-item-right-contacting" ng-show="app.isUpdating">Updating application...</div> + <div id="app-item-done-updating" class="app-item-right-contacting" ng-show="app.isDoneUpdating">Finished updating application</div> + <div id="app-item-cannot-update" class="app-item-right-error" ng-show="app.isErrorUpdating">Could not update application...</div> + <i id="app-item-delete" class="ion-trash-b" ng-click="newUser.deleteApp(app)" ng-show="!app.isLoading && !app.isError"></i> + <div id='ecomp-small-spinner' class="ecomp-small-spinner" ng-show="app.isLoading"></div> + </div> + </div> + <div class="dialog-control"> + <span id="ecomp-save-spinner" class="ecomp-save-spinner" ng-show="newUser.isSaving || newUser.isGettingAdminApps"></span> + <div id="new-user-back-button" ng-show="newUser.isShowBack" class="back-button" ng-click="newUser.navigateBack()">Back</div> + <div id="new-user-next-button" class="next-button" ng-click="newUser.updateUserAppsRoles()" + ng-class="{disabled: !newUser.anyChanges}">Save + </div> + <div id="new-user-cancel-button" class="cancel-button" ng-click="closeThisDialog()">Cancel</div> + </div> + </div> + </div> +</div> diff --git a/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.modal.less b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.modal.less new file mode 100644 index 00000000..9f86b022 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/new-user-dialogs/new-user.modal.less @@ -0,0 +1,126 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ + .new-user-modal { + display:block; + overflow:auto; + min-height: 450px; + + .user-apps-roles{ + .title{ + .n18r; + border-bottom: @a 3px solid; + } + + .app-roles-list{ + height: 286px; + overflow-y: auto; + + .app-item{ + border: 1px solid #d8d8d8; + border-radius: 2px; + background-color: #f8f8f8; + + padding: 10px; + margin-top: 8px; + + .app-item-left{ + padding-top: 0; + line-height: 30px; + height: 30px; + vertical-align: middle; + display:inline-block; + width: 45%; + border-radius: 2px; + border: 1px solid #d8d8d8; + margin-right: 10px; + padding-left: 4px; + background: #fff; + white-space: nowrap; + + } + .app-item-right{ + display:inline-block; + width: 45%; + border-radius: 2px; + border: 1px solid #d8d8d8; + background: #fff; + vertical-align: middle; + } + + .app-item-right-error{ + .k; + padding: 7px 7px 7px 7px; + display:inline-block; + width: 45%; + border-radius: 2px; + border: 1px solid #d8d8d8; + background: #fff; + vertical-align: middle; + } + + .app-item-right-contacting{ + .e; + padding: 7px 7px 7px 7px; + display:inline-block; + width: 45%; + border-radius: 2px; + border: 1px solid #d8d8d8; + background: #fff; + vertical-align: middle; + } + + .app-select-left{ + width: 45%; + margin-right: 10px; + vertical-align: middle; + + + .select-field{ + padding-top: 0; + line-height: 30px; + height: 30px; + vertical-align: middle; + border-radius: 2px; + border: 1px solid #d8d8d8; + margin-right: 10px; + padding-left: 4px; + background: #fff; + display:inline-block; + } + } + + + .app-item-delete{ + .ico_trash_default; + display: inline-block; + vertical-align: 2px; + cursor: pointer; + position: relative; + top: 6px; + color: transparent; + margin-left: 8px; + + } + + } + } + + } +} diff --git a/ecomp-portal-FE/client/app/views/users/users.controller.js b/ecomp-portal-FE/client/app/views/users/users.controller.js new file mode 100644 index 00000000..433b24e4 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/users.controller.js @@ -0,0 +1,187 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +'use strict'; +(function () { + class UsersCtrl { + constructor($log, applicationsService, usersService, $scope, ngDialog,$timeout) { + this.$log = $log; + $scope.adminAppsIsNull = false; + $scope.appsIsDown = false; + + $log.info('UsersCtrl:: initializing...'); + let activeRequests = []; + let clearReq = (req) => { + activeRequests.splice(activeRequests.indexOf(req), 1); + }; + + let getAdminApps = () => { + $log.debug('UsersCtrl::getAdminApps: - Starting getAdminApps'); + try { + this.isLoadingTable = true; + var adminAppsReq = applicationsService.getAdminApps(); + + activeRequests.push(adminAppsReq); + adminAppsReq.promise().then(apps => { + $log.debug('UsersCtrl::getAdminApps: Apps for this user are: ' + JSON.stringify(apps)); + $log.debug('UsersCtrl::getAdminApps: Apps length: ' + apps.length); + var res1 = apps.sort(getSortOrder("name")); + if (!res1 || !res1.length) { + $log.error('UsersCtrl::getAdminApps: - no apps found'); + return null; + } + for (let i = 0; i < apps.length; i++) { + res1[i].index = i; + res1[i].value = apps[i].name; + res1[i].title = apps[i].name; + } + + this.adminApps = apps; + this.selectedApp = apps[0]; + clearReq(adminAppsReq); + $scope.adminAppsIsNull = false; + }).catch(e => { + $scope.adminAppsIsNull = true; + $log.error('UsersCtrl::getAdminApps: - getAdminApps() failed = '+ e.message); + clearReq(adminAppsReq); + }).finally(() => { + this.isLoadingTable = false; + }); + } catch (e) { + $scope.adminAppsIsNull = true; + $log.error('UsersCtrl::getAdminApps: - getAdminApps() failed!'); + this.isLoadingTable = false; + } + }; + + let getSortOrder = (prop) => { + return function(a, b) { + if (a[prop] > b[prop]) { + return 1; + } else if (a[prop] < b[prop]) { + return -1; + } + return 0; + } + } + + this.updateUsersList = () => { + $scope.appsIsDown = false; + $log.debug('UsersCtrl::updateUsersList: Starting updateUsersList'); + this.searchString = ''; + this.isAppSelectDisabled = true; + this.isLoadingTable = true; + usersService.getAccountUsers(this.selectedApp.id) + .then(accountUsers => { + $log.debug('UsersCtrl::updateUsersList length: '+ Object.keys(accountUsers).length); + this.isAppSelectDisabled = false; + this.accountUsers = accountUsers; + }).catch(err => { + this.isAppSelectDisabled = false; + $log.error('UsersCtrl::updateUsersList: ' + err); + $scope.appsIsDown = true; + }).finally(() => { + this.isLoadingTable = false; + }); + }; + + + let init = () => { + this.isLoadingTable = false; + this.selectedApp = null; + this.isAppSelectDisabled = false; + getAdminApps(); + + this.searchString = ''; + this.usersTableHeaders = ['First Name', 'Last Name', 'User ID', 'Roles']; + this.accountUsers = []; + }; + + this.openAddNewUserModal = (user) => { + let data = null; + if (user) { + data = { + dialogState: 3, + selectedUser: { + orgUserId: user.orgUserId, + firstName: user.firstName, + lastName: user.lastName + } + } + } + ngDialog.open({ + templateUrl: 'app/views/users/new-user-dialogs/new-user.modal.html', + controller: 'NewUserModalCtrl', + controllerAs: 'newUser', + data: data + }).closePromise.then(needUpdate => { + if (needUpdate.value === true) { + $log.debug('UsersCtrl::openAddNewUserModal updating table data...'); + this.updateUsersList(); + } + }); + }; + + this.openEditUserModal = (loginId) => { + var data = { + loginId : loginId, + updateRemoteApp : true, + appId : this.selectedApp!=null?this.selectedApp.id:'' + } + var modalInstance = ngDialog.open({ + templateUrl: 'app/views/header/user-edit/edit-user.tpl.html', + controller: 'editUserController', + data: data, + resolve: { + message: function message() { + var message = { + type: 'Contact', + }; + return message; + } + } + }).closePromise.then(needUpdate => { + //update selected app's database for this user. + console.log("'''''''''''''''''' now updating user list after update remote server"); + $timeout(this.updateUsersList, 1500); + }); + } + + + $scope.$watch('users.selectedApp', (newVal, oldVal) => { + if (!newVal || _.isEqual(newVal, oldVal)) { + return; + } + $log.debug('UsersCtrl::openAddNewUserModal:$watch selectedApp -> Fire with: ', newVal); + this.accountUsers = []; + this.updateUsersList(); + }); + + $scope.$on('$destroy', () => { + activeRequests.forEach(req => { + req.cancel(); + }); + }); + + init(); + } + } + UsersCtrl.$inject = ['$log', 'applicationsService', 'usersService', '$scope', 'ngDialog','$timeout']; + angular.module('ecompApp').controller('UsersCtrl', UsersCtrl); +})(); diff --git a/ecomp-portal-FE/client/app/views/users/users.controller.spec.js b/ecomp-portal-FE/client/app/views/users/users.controller.spec.js new file mode 100644 index 00000000..34042c14 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/users.controller.spec.js @@ -0,0 +1,19 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ diff --git a/ecomp-portal-FE/client/app/views/users/users.less b/ecomp-portal-FE/client/app/views/users/users.less new file mode 100644 index 00000000..ff2d815f --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/users.less @@ -0,0 +1,59 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ + .users-page-main{ + .bg_w; + position: @page-main-position; + top: @page-main-top; + left: @page-main-left; + right: @page-main-right; + bottom: @page-main-bottom; + padding-top: @padding-top; + overflow-y: @page-main-overflow-y; + padding-left: @padding-left-side; + + .users-table { + width: @table-width; + margin: @table-margin; + + } + + .error-text { + width: 1170px; + margin: auto; + padding: 20px; + left: 20px; + font-weight: bold; + font-size: 16px; + text-align: left; + color: @err; + background-color: @u; + + .error-help { + color: @o; + font-weight: normal; + } + + .error-help-bold { + color: @o; + font-weight: bold; + } + + } +} diff --git a/ecomp-portal-FE/client/app/views/users/users.tpl.html b/ecomp-portal-FE/client/app/views/users/users.tpl.html new file mode 100644 index 00000000..88a3b62d --- /dev/null +++ b/ecomp-portal-FE/client/app/views/users/users.tpl.html @@ -0,0 +1,105 @@ +<!-- + ================================================================================ + eCOMP Portal + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ================================================================================ + --> +<div class="w-ecomp-main"> + <div class="w-ecomp-main-container"> + <div class="users-page-main" id="contentId"> + <div id="users-page-title" class="w-ecomp-main-view-title">Users</div> + <div class="users-table"> + + + <div class="table-control"> + <div class="c-ecomp-att-abs-select default"> + <div class="form-field" id="form-field" + att-select="users.adminApps" + ng-model="users.selectedApp" + ng-disabled="users.isAppSelectDisabled" + ng-class="{disabled: users.isAppSelectDisabled}"></div> + </div> + <input class="table-search" type="text" id="input-search" + placeholder="Search in entire table" + ng-model="users.searchString"/> + + <div id="users-page-button-add" class="add-button" ng-click="users.openAddNewUserModal()">Add User</div> + </div> + <div ng-hide="users.isLoadingTable"> + <div class="error-text" + id="div-error-app-down" + ng-show="appsIsDown===true"> + <h1 class="error-help-bold">Attention:</h1> + <p> </p> + <p class="error-help">Select "Add User" in order to add User and Roles to the '{{users.selectedApp.name}}' Application.</p> + </div> + </div> + <span class="ecomp-spinner" ng-show="users.isLoadingTable"></span> + <div class="c-ecomp-att-abs-table default" ng-hide="users.isLoadingTable"> + <table att-table id="table-main" + table-data="users.accountUsers" + search-string="users.searchString" + view-per-page="users.viewPerPageIgnored" + current-page="users.currentPageIgnored" + total-page="users.totalPageIgnored"> + <thead att-table-row type="header"> + <tr> + <th id="th-users-0" att-table-header key="firstName" default-sort="a">{{users.usersTableHeaders[0]}}</th> + <th id="th-users-1" att-table-header key="lastName" sortable="true">{{users.usersTableHeaders[1]}}</th> + <th id="th-users-2" att-table-header key="userId" sortable="true">{{users.usersTableHeaders[2]}}</th> + <th id="th-users-3" att-table-header key="roles" sortable="false">{{users.usersTableHeaders[3]}}</th> + </tr> + </thead> + <tbody att-table-row type="body" + class="table-body" + track-by="$index" + row-repeat="rowData in users.accountUsers"> + <tr id="tr-rowData" ng-click="users.openAddNewUserModal(rowData)"> + <td class="td-first" att-table-body> + <div id="users-page-td-firstName-{{rowData.userId}}" ng-bind="rowData.firstName"></div> + </td> + <td att-table-body> + <div id="users-page-td-lastName-{{rowData.userId}}" ng-bind="rowData.lastName"></div> + </td> + <td att-table-body> + <div id="users-page-td-userId-{{rowData.userId}}" style="float: left;" ng-bind="rowData.orgUserId"></div> + <div> + <span style="float: left; margin-left:15px" class="ion-person" ng-click="users.openEditUserModal(rowData.orgUserId);$event.stopPropagation()"></span> + </div> + </td> + <td> + <div id="users-page-td-role-name-{{rowData.userId}}" ng-repeat="role in rowData.roles" ng-bind="role.name"></div> + </td> + </tr> + </tbody> + </table> + </div> + + </div> + <div class="error-text" + id="div-error-403" + ng-show="adminAppsIsNull==true"> + <h1>Attention:</h1> + <p> </p> + <p class="error-help">It appears that you have not been added as an admin yet to an application.</p> + <p> </p> + <p class="error-help">Click on the Admins link to the left and check and see if you are listed as an admin for an application. + If not, you can add yourself to the appropriate application.</p> + </div> + </div> + </div> + +</div> |