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