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