Deliver centralized role management feature
[portal.git] / ecomp-portal-FE-common / client / app / views / functionalMenu / functionalMenu-dialog / menu-details.controller.js
1 /**
2  * Created by nnaffar on 12/20/15.
3  */
4 'use strict';
5 (function () {
6     class MenuDetailsModalCtrl {
7         constructor($scope, $log, functionalMenuService, errorMessageByCode, ECOMP_URL_REGEX,$rootScope,confirmBoxService,items) {
8                 $scope.ngDialogData=items;
9                 $scope.isAllApplications = false;
10             let newMenuModel = {
11                 name: null,
12                 menuId: null,
13                 parentMenuId: null,
14                 url: null
15             };
16
17             let getAvailableRoles = (appid) => {
18                 this.isSaving = true;
19                 if (appid != null) {
20                     $log.debug("MenuDetailsModalCtrl::getAvailableRoles: About to call getManagedRolesMenu");
21                     functionalMenuService.getManagedRolesMenu(appid).then(rolesObj => {
22                         $log.debug("MenuDetailsModalCtrl::getAvailableRoles: Roles returned = " + JSON.stringify(rolesObj))
23                         this.availableRoles = rolesObj;
24                        
25                    
26                         this.preSelectedRoles = {roles:[]};
27
28                         if(($scope.ngDialogData.source==='edit') && this.isMidLevelMenuItem()){
29                             // in Edit flow , for Midlevel menu item no need to preSelect.
30                             this.preSelectedRoles = {roles:[]};
31                         }else if(!angular.isUndefined(this.menuItem.menuDetails) &&
32                             $scope.ngDialogData.source==='edit' && this.isLeafMenuItem() &&
33                             this.menuItem.menuDetails.appid!=appid) {
34                             // in Edit flow , for LeafMenuItem, if appid changed then no need to preSelect.
35                             this.preSelectedRoles = {roles:[]};
36                         }else{
37                             if((!angular.isUndefined(this.menuItem.menuDetails)) &&
38                                 (!angular.isUndefined(this.menuItem.menuDetails.roles))){
39                                     $log.debug('menuDetails.roles: ' + this.menuItem.menuDetails.roles);
40                                     for(var i=0; i<this.menuItem.menuDetails.roles.length; i++){
41                                         var role = {"roleId":this.menuItem.menuDetails.roles[i]};
42                                         $log.debug('MenuDetailsModalCtrl::getAvailableRoles: adding role to preselected: ' + i + ': ' + JSON.stringify(role));
43                                         this.preSelectedRoles.roles.push(role);
44                                     }
45                             }
46                         }
47                         
48                         $rootScope.$broadcast('availableRolesReady');
49                         this.isSaving = false;
50                         for(var i=0; i<rolesObj.length;i++){
51                                 this.availableRoles[i].isApplied = false;
52                                 for(var j=0;j<this.preSelectedRoles.roles.length;j++){
53                                         if(this.preSelectedRoles.roles[j].roleId==this.availableRoles[i].roleId){
54                                                 this.availableRoles[i].isApplied=true;
55                                                 break;
56                                         }
57                                 }
58                                 
59
60                                 }
61                     }).catch(err => {
62                         $log.error("MenuDetailsModalCtrl::getAvailableRoles: error: " + err);
63                     });
64                 } else {
65                     $log.debug("MenuDetailsModalCtrl::getAvailableRoles: appid was null");
66                 }
67             };
68
69             let getAvailableApps = () => {
70                 $scope.isAllApplications = true;
71                 functionalMenuService.getAvailableApplications().then(apps => {
72                     $log.debug("MenuDetailsModalCtrl::getAvailableApps: Apps returned = " + JSON.stringify(apps))
73                     this.availableApps = apps;
74                     // Keep track of whether or not the selected app is disabled
75                     if (angular.isDefined(this.selectedApp) && angular.isDefined(this.selectedApp.index)) {
76                         for (var i = 0; i < apps.length; i++) {
77                             if (apps[i].index === this.selectedApp.index) {
78                                 $log.debug("MenuDetailsModalCtrl::getAvailableApps: found app with index: " + this.selectedApp.index);
79                                 $log.debug("MenuDetailsModalCtrl::getAvailableApps: setting isDisabled to: " + !apps[i].enabled);
80                                 this.selectedApp.isDisabled = !apps[i].enabled;
81                                 break;
82                             }
83                         }
84                         $log.debug("didn't find index: " + this.selectedApp.index);
85                     }
86                 })['catch'](function (err) {
87                     confirmBoxService.showInformation('There was a problem retrieving the Applications. ' +
88                         'Please try again later. Error Status: '+ err.status).then(isConfirmed => {});
89                     $log.error("MenuDetailsModalCtrl::getAvailableApps: getAvailableApps error: " + err);
90                     $scope.isAllApplications = false;
91                 }).finally(()=>{
92                     this.isSaving = false;
93                     $scope.isAllApplications = false;
94                 });
95             };
96
97             let init = () => {
98                 $scope.isAllApplications = false;
99                 $log.info('MenuDetailsModalCtrl::init');
100                 this.saveOrContinueBtnText = "Save";
101                 this.isSaving = false;
102                 this.displayRoles = $scope.ngDialogData.source==='view' ? true : false;
103                 this.formEditable = $scope.ngDialogData.source==='view' ? false : true;
104                 this.selectedRole = [];
105                 this.availableRoles = [];
106                 this.selectedApp={};
107                 this.menuItem = _.clone($scope.ngDialogData.menuItem);
108                 $log.info('MenuDetailsModalCtrl::getAvailableApps: Within init, about to check menuDetails for defined');
109                 if(!angular.isUndefined(this.menuItem.menuDetails) &&
110                     ($scope.ngDialogData.source==='view' ||
111                     ($scope.ngDialogData.source==='edit') && this.isLeafMenuItem() )){
112
113                     $log.debug("MenuDetailsModalCtrl::init: menuItem: ");
114                     $log.debug('MenuDetailsModalCtrl::init: ',this.menuItem);
115                     this.menuItem.menu.url = this.menuItem.menuDetails.url;
116                     this.selectedAppIndex=this.menuItem.menuDetails.appid;
117                     this.selectedApp.index = this.menuItem.menuDetails.appid;
118                     getAvailableRoles(this.selectedApp.index);
119
120                 }
121
122                 if($scope.ngDialogData.source==='view' || $scope.ngDialogData.source==='edit'){
123                     this.menutitle = this.menuItem.menu.name;
124                     this.menuLocation = this.isParentMenuItem() ? this.menuItem.menu.name : this.menuItem.menu.parent.name;
125                 }else{
126                     this.menutitle = '';
127                     this.menuLocation = this.menuItem.menu.name;
128                 }
129                 // Temporarily passing 0 as dummy for getAvailableRoles incase of this.selectedApp is not there i.e., in Add flow
130                 //  getAvailableRoles(angular.isUndefined(this.selectedApp) ? 0: this.selectedApp.index );
131                 getAvailableApps();
132                 $log.debug("MenuDetailsModalCtrl::init: Menu details: " +  JSON.stringify(this.menuItem.menuDetails));
133             };
134
135
136             this.ECOMP_URL_REGEX = ECOMP_URL_REGEX;
137
138             //This part handles conflict errors (409)
139             this.conflictMessages = {};
140             this.scrollApi = {};
141             let handleConflictErrors = err => {
142                 if(!err.data){
143                     return;
144                 }
145                 if(!err.data.length){ //support objects
146                     err.data = [err.data]
147                 }
148                 $log.debug('MenuDetailsModalCtrl::handleConflictErrors: err.data = ' + JSON.stringify(err.data));
149                 _.forEach(err.data, item => {
150                     _.forEach(item.fields, field => {
151                         //set conflict message
152                         this.conflictMessages[field.name] = errorMessageByCode[item.errorCode];
153                         //set field as invalid
154                         $log.debug('MenuDetailsModalCtrl::handleConflictErrors: fieldName = ' + field.name);
155                         $scope.functionalMenuForm[field.name].$setValidity('conflict', false);
156                         //set watch once to clear error after user correction
157                         watchOnce[field.name]();
158                     });
159                 });
160                 this.scrollApi.scrollTop();
161             };
162
163             let resetConflict = fieldName => {
164                 delete this.conflictMessages[fieldName];
165                 $log.debug('MenuDetailsModalCtrl::resetConflict: $setValidity(true) = ' + fieldName);
166                 if($scope.functionalMenuForm[fieldName]){
167                     $scope.functionalMenuForm[fieldName].$setValidity('conflict', true);
168                 }
169             };
170
171             let watchOnce = {
172                 text: () => {
173                     let unregisterName = $scope.$watch('functionalMenuDetails.menutitle', (newVal, oldVal) => {
174                         // $log.debug('title:: newVal, oldVal = ' + newVal.toLowerCase() + " | " + oldVal.toLowerCase());
175                         if(newVal.toLowerCase() !== oldVal.toLowerCase()){
176                             resetConflict('text');
177                             unregisterName();
178                         }
179                     });
180                 },
181                 url: () => {
182                     let unregisterUrl = $scope.$watch('functionalMenuDetails.menuItem.menu.url', (newVal, oldVal) => {
183                         if(newVal.toLowerCase() !== oldVal.toLowerCase()){
184                             resetConflict('url');
185                             unregisterUrl();
186                         }
187                     });
188                 }
189             };
190
191             //***************************
192
193             this.isLeafMenuItem = () => {
194                 return this.menuItem.menu.children.length>0 ? false : true;
195             };
196
197             this.isMidLevelMenuItem = () => {
198                 return this.menuItem.menu.parentMenuId!=null && this.menuItem.menu.children.length>0 ? true : false;
199             };
200
201             this.isParentMenuItem = () => {
202                 return this.menuItem.menu.parentMenuId!=null ? false : true;
203             };
204             
205             this.isRoleSelected=()=>{
206                 var selectedRoleIds=[];
207                  for(var i=0;i<this.availableRoles.length;i++){
208                         if(this.availableRoles[i].isApplied){
209                         selectedRoleIds.push(this.availableRoles[i].roleId);
210                         return true;
211                         }
212                  }
213                  return false;
214                 
215             };
216
217             this.updateSelectedApp = (appItem) => {
218                 /*var appItemobj= JSON.parse(appItem);
219                 this.selectedApp=JSON.parse(this.selectedApp);*/
220                 if (!appItem) {
221                     return;
222                 }
223                 var appobj={};
224                 for(var i=0;i<this.availableApps.length;i++ ){
225                         if(this.availableApps[i].index==appItem){
226                                 appobj=this.availableApps[i];
227                                 break;
228                         }
229                 }
230                 debugger;
231                 $log.debug('MenuDetailsModalCtrl::updateSelectedApp: drop down app item = ' + JSON.stringify(appItem.index));
232                 $log.debug("MenuDetailsModalCtrl::updateSelectedApp: appItem in updateSelectedApp: ");
233                 $log.debug('MenuDetailsModalCtrl::updateSelectedApp: ',appItem);
234                 this.selectedApp.isDisabled = ! appobj.enabled;
235                 this.selectedApp.index=appobj.index;
236                  $log.debug("MenuDetailsModalCtrl::updateSelectedApp: isDisabled: "+this.selectedApp.isDisabled);
237                 getAvailableRoles(appobj.index);
238             };
239
240             this.continue = () => {
241                 this.displayRoles = true;
242                 this.formEditable = false;
243             };
244
245             this.saveChanges = () => {
246
247                 //todo : form validation was commented as dialog message is kept for error validations
248                 /*if($scope.functionalMenuForm.$invalid){
249                  return;
250                  }*/
251                 if(!!this.menuItem.menu.url && (angular.isUndefined(this.selectedApp) || !this.selectedApp.index>0)) {
252                     confirmBoxService.showInformation('Please select the appropriate app, or remove the url').then(isConfirmed => {});
253                     return;
254                 }else if(!this.menuItem.menu.url && !angular.isUndefined(this.selectedApp) && this.selectedApp.index>0){
255                     confirmBoxService.showInformation('Please enter url, or select "No Application"').then(isConfirmed => {});
256                     return;
257                 }else if(!this.menutitle){
258                     confirmBoxService.showInformation('Please enter the Menu title').then(isConfirmed => {});
259                     return;
260                 }
261
262                 this.isSaving = true;
263                 var activeMenuItem = {};
264
265                 if ($scope.ngDialogData.source === 'edit') {     // Edit Menu Item
266                     $log.debug('MenuDetailsModalCtrl::saveChanges: Will be saving an edit menu item');
267                     var selectedRoleIds=[];
268                     for(var i=0;i<this.availableRoles.length;i++){
269                         if(this.availableRoles[i].isApplied){
270                         selectedRoleIds.push(this.availableRoles[i].roleId);
271                         }
272                     }
273                     activeMenuItem = {
274                         menuId:this.menuItem.menu.menuId,
275                         column:this.menuItem.menu.column,
276                         text:this.menutitle,
277                         parentMenuId:this.menuItem.menu.parentMenuId,
278                         url:this.menuItem.menu.url,
279                         
280                         appid: angular.isUndefined(this.selectedApp) ? null:this.selectedApp.index,
281                         
282                         roles:selectedRoleIds
283                     };
284                     
285                    // alert(activeMenuItem);
286                     // If we have removed the url and appid, we must remove the roles
287                     if (!activeMenuItem.appid && !activeMenuItem.url) {
288                         activeMenuItem.roles = null;
289                     }
290                     functionalMenuService.saveEditedMenuItem(activeMenuItem)
291                         .then(() => {
292                             $log.debug('MenuDetailsModalCtrl::saveChanges:  Menu Item saved');
293                            // $scope.closeThisDialog(true);
294                             $scope.$dismiss('cancel');
295
296                         }).catch(err => {
297                         if(err.status === 409){//Conflict
298                             handleConflictErrors(err);
299                         } else {
300                             confirmBoxService.showInformation('There was a problem saving your change. ' +
301                                 'Please try again later. Error Status: '+ err.status).then(isConfirmed => {});
302                         }
303                         $log.error('MenuDetailsModalCtrl::saveChanges: error - ',err);
304                     }).finally(()=>{
305                         this.isSaving = false;
306                     });
307
308                     $log.debug("MenuDetailsModalCtrl::saveChanges: Edit Menu output will be: " + JSON.stringify(activeMenuItem));
309                 } else {   // New Menu Item
310                     $log.debug('MenuDetailsModalCtrl::saveChanges: Will be saving a New menu item');
311                     var selectedRoleIds=[];
312                     for(var i=0;i<this.availableRoles.length;i++){
313                         if(this.availableRoles[i].isApplied){
314                         selectedRoleIds.push(this.availableRoles[i].roleId);
315                         }
316                     }
317                     var newMenuItem = {
318                         menuId:null, // this is a new menu item
319                         column:this.menuItem.menu.column,
320                         text:this.menutitle,
321                         // We are creating this new menu item under the menu item that was clicked on.
322                         parentMenuId:this.menuItem.menu.menuId,
323                         url:this.menuItem.menu.url,
324                         appid: angular.isUndefined(this.selectedApp) ? null:this.selectedApp.index,
325                         roles:selectedRoleIds
326                     };
327
328                     $log.debug("MenuDetailsModalCtrl::saveChanges:  New Menu output will be: " + JSON.stringify(newMenuItem));
329                     functionalMenuService.saveMenuItem(newMenuItem)
330                         .then(() => {
331                             $log.debug('MenuDetailsModalCtrl::saveChanges:  Menu Item saved');
332                            // $scope.closeThisDialog(true);
333                             $scope.$dismiss('cancel');
334                         }).catch(err => {
335                         if(err.status === 409){//Conflict
336                             handleConflictErrors(err);
337                         } else {
338                             confirmBoxService.showInformation('There was a problem saving your menu. ' +
339                                 'Please try again later. Error Status: '+ err.status).then(isConfirmed => {});
340                         }
341                         $log.error('MenuDetailsModalCtrl::saveChanges error: ', err);
342                     }).finally(()=>{
343                         this.isSaving = false;
344                     });
345
346                 }
347             };
348
349             init();
350
351             $scope.$on('$stateChangeStart', e => {
352                 //Disable navigation when modal is opened
353                 e.preventDefault();
354             });
355         }
356     }
357     MenuDetailsModalCtrl.$inject = ['$scope', '$log', 'functionalMenuService', 'errorMessageByCode', 'ECOMP_URL_REGEX','$rootScope','confirmBoxService','items'];
358     angular.module('ecompApp').controller('MenuDetailsModalCtrl', MenuDetailsModalCtrl);
359
360   })();