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