diff options
author | talasila <talasila@research.att.com> | 2017-02-07 15:03:57 -0500 |
---|---|---|
committer | talasila <talasila@research.att.com> | 2017-02-07 15:05:15 -0500 |
commit | 4ad39a5c96dd99acf819ce189b13fec946d7506b (patch) | |
tree | a1449286441947cc3d07a45227fa0d6f978e1a7d /ecomp-portal-FE/client/app/views/users/new-user-dialogs | |
parent | 5500448cbd1f374d0ac743ee2fd636fe2d3c0027 (diff) |
Initial OpenECOMP Portal commit
Change-Id: I804b80e0830c092e307da1599bd9fbb5c3e2da77
Signed-off-by: talasila <talasila@research.att.com>
Diffstat (limited to 'ecomp-portal-FE/client/app/views/users/new-user-dialogs')
4 files changed, 629 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; + + } + + } + } + + } +} |