0ff46e4de660a150898a247b6c39d612063a598c
[portal.git] / ecomp-portal-FE-os / client / src / views / functionalMenu / functionalMenu.controller.js
1 /*-
2  * ================================================================================
3  * ECOMP Portal
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ================================================================================
19  */
20 'use strict';
21 (function () {
22     class FunctionalMenuCtrl {
23         constructor($log, functionalMenuService, $scope,ngDialog, confirmBoxService,$modal) {
24             $log.info('FunctionalMenuCtrl init');
25
26             $scope.invokeDialog = () => {
27                 // alert("click dialog");
28             };
29
30             this.regenerateFunctionalMenuAncestors = () => {
31                 functionalMenuService.regenerateFunctionalMenuAncestors().then(res => {
32                     $log.debug("FunctionalMenuCtrl:regenerateFunctionalMenuAncestors::returned from regenerateFunctionalMenuAncestors API call");
33                     confirmBoxService.showInformation('You have successfully regenerated the menu.').then(isConfirmed => {
34                     });
35                 })['catch'](function (err) {
36                     $log.error("FunctionalMenuCtrl:regenerateFunctionalMenuAncestors:: error: " + err);
37                     confirmBoxService.showInformation('There was an error while regenerating the menu.').then(isConfirmed => {
38                     });
39                 });
40             };
41
42             let getFunctionalMenu = () => {
43                 this.isLoadingTable = true;
44                 functionalMenuService.getManagedFunctionalMenu().then(res => {
45
46                     let actualData=[];
47
48                     //Adding children and label attribute to all objects in res
49                     for(let i = 0; i < res.length; i++){
50                         res[i].children=[];
51                         res[i].label=res[i].text;
52                         res[i].id=res[i].text;
53
54                     }
55                     //Adding actual child items to children array in res objects
56                     for(let i = 0; i < res.length; i++){
57
58                         let parentId=res[i].menuId;
59                         for(let j = 0; j < res.length; j++){
60                             let childId=res[j].parentMenuId;
61                             if(parentId===childId){
62                                 res[i].children.push(res[j]);
63
64                             }
65                         }
66                     }
67
68                     // Sort the top-level menu items in order based on the column
69                     res.sort(function(a, b) {
70                         return a.column-b.column;
71                     });
72
73                     // Sort all the children in order based on the column
74                     for(let i = 0; i < res.length; i++){
75                         res[i].children.sort(function(a, b){
76                             return a.column-b.column;
77                         });
78                     }
79
80                     //Forming actual parent items
81                     for(let i = 0; i < res.length; i++){
82                         let parentId=res[i].parentMenuId;
83                         if(parentId===null){
84                             actualData.push(res[i]);
85                         }
86                     }
87
88                     $scope.treedata = actualData;
89
90                 }).catch(err => {
91                     $log.error('FunctionalMenuCtrl:getFunctionalMenu:: error ',err);
92                 }).finally(()=> {
93                     this.isLoadingTable = false;
94                 });
95
96             };
97
98
99             let init = () => {
100                 this.isLoadingTable = false;
101                 this.functionalMenu = [];
102                 getFunctionalMenu();
103                 this.searchString = '';
104
105
106             };
107
108             this.filterByDropdownValue = item => {
109                 if(this.filterByApp.value === ''){
110                     return true;
111                 }
112                 return item.appName === this.filterByApp.value;
113             };
114
115             let getDialogTitle = (source) => {
116                 switch (source) {
117                     case 'edit':
118                         return "Functional Menu - Edit";
119                     case 'view':
120                         return "Functional Menu - View";
121                     case 'add':
122                         return "Functional Menu - Add";
123                     default:
124                         return "Functional Menu";
125                 };
126             };
127
128             $scope.reloadTreeStructure = (selectedItem,source) => {
129                 getFunctionalMenu();
130             };
131             $scope.openMenuDetailsModal = (selectedItem,source) => {
132                 let data = null;
133                 let selectedMenuDetails = null;
134                 console.log('selectedItem: ', selectedItem);
135
136                 functionalMenuService.getMenuDetails(selectedItem.menuId)
137                     .then(function( resp ){
138                         selectedMenuDetails = resp;
139                         $log.info('FunctionalMenuCtrl::openMenuDetailsModal: getMenuDetails: ', resp );
140
141                         if(selectedItem){
142                             data = {
143                                 menuItem: {menu: _.clone(selectedItem),menuDetails:_.clone(selectedMenuDetails)},
144                                 source: source,
145                                 title: getDialogTitle(source)
146                             };
147                         }
148                           var modalInstance = $modal.open({
149                             templateUrl: 'app/views/functionalMenu/functionalMenu-dialog/menu-details.modal.html',
150                             controller: 'MenuDetailsModalCtrl as functionalMenuDetails',
151                             sizeClass: 'modal-large', 
152                             resolve: {
153                                                 items: function () {
154                                           return data;
155                                                 }
156                                 }
157                         })
158                         
159                         modalInstance.result.finally(function (needUpdate){
160                                 if(needUpdate.value === true){
161                                         $log.debug('FunctionalMenuCtrl::openMenuDetailsModal: updating table data...');
162                                 if(source==="edit") {
163                                     init();
164                                 }
165
166                           }
167                         });
168                     });
169             };
170
171
172             $scope.createNewMenuItem = (selectedItem,source) => {
173
174                 if(selectedItem != null && selectedItem.getLevel() >= 4){
175                     confirmBoxService.showInformation('You are not allowed to have a menu item at a level greater than 4.').then(isConfirmed => {
176
177                     });
178                     return ;
179                 }
180
181                 let data = null;
182                 let selectedMenuDetails = null;
183                 functionalMenuService.getMenuDetails(selectedItem.menuId)
184                     .then(function( resp ){
185                         selectedMenuDetails = resp;
186
187                         if((selectedItem.children===null || !selectedItem.children.length>0) &&
188                             (!!selectedMenuDetails.url || !!selectedMenuDetails.appid || !!selectedMenuDetails.roles)){
189                             confirmBoxService.showInformation('Warning: the child menu item "' + selectedItem.name + '" is already configured with an application. You can create a new mid-level menu item, and move this item under it.').then(isConfirmed => {
190                                 return;
191                             });
192                         }else{
193                             if(selectedItem){
194                                 data = {
195                                     menuItem: {menu: _.clone(selectedItem)},
196                                     source:source,
197                                     title: getDialogTitle(source)
198                                 };
199                             }
200
201                                 var modalInstance = $modal.open({
202                                 templateUrl: 'app/views/functionalMenu/functionalMenu-dialog/menu-details.modal.html',
203                                 controller: 'MenuDetailsModalCtrl as functionalMenuDetails',
204                                 sizeClass: 'modal-large', 
205                                 resolve: {
206                                                         items: function () {
207                                           return data;
208                                                         }
209                                         }
210                             })
211                             
212                             modalInstance.result.finally(function (needUpdate){
213                                 if(needUpdate.value === true){
214                                     $log.debug('FunctionalMenuCtrl::getMenuDetails: updating table data...');
215                                     init();
216                                     //getOnboardingWidgets();
217
218                               }
219                                 });
220                         }
221                     });
222             };
223
224             $scope.deleteMenuItem = (selectedItem,source) => {
225                 $log.info('FunctionalMenuCtrl:deleteMenuItem:: delete selectedItem: ', selectedItem);
226
227                 if(selectedItem.children!=null && selectedItem.children.length>0){
228                     confirmBoxService.showInformation('You are not allowed to delete a menu item that has children. You can only delete leaf menu items.').then(isConfirmed => {
229
230                     });
231                 }else{
232                     confirmBoxService.deleteItem(selectedItem.name).then(isConfirmed => {
233                         if(isConfirmed){
234                             $log.info('FunctionalMenuCtrl:deleteMenuItem:: Deleting Menu Item :: name: '+selectedItem.name+'; menuId: '+selectedItem.menuId);
235                             $log.info('FunctionalMenuCtrl:deleteMenuItem:: selectedItem: ', selectedItem);
236
237                             functionalMenuService.deleteMenuItem(selectedItem.menuId).then(() => {
238                                 //TODO:Have to splice menu item
239                                 //this.widgetsList.splice(this.widgetsList.indexOf(widget), 1);
240                                 $log.info('FunctionalMenuCtrl:deleteMenuItem:: Removed Menu Item :: '+selectedItem.name);
241                                 init();
242                             }).catch(err => {
243                                 $log.error(err);
244                             });
245                         }
246                     }).catch(err => {
247                         $log.error(err);
248                     });
249                 }
250             };
251
252             init();
253         }
254     }
255     FunctionalMenuCtrl.$inject = ['$log', 'functionalMenuService','$scope', 'ngDialog', 'confirmBoxService','$modal'];
256     angular.module('ecompApp').controller('FunctionalMenuCtrl', FunctionalMenuCtrl);
257
258     angular.module('ecompApp').directive('jqTree', ['functionalMenuService','$log','confirmBoxService',function(functionalMenuService,$log,confirmBoxService){
259         return {
260             templateUrl: 'jqtree-tmpl.html',
261             link: function(scope, el, attrs){
262
263                 var $jqTree =  el.find('#jqTree').tree({
264                     data: scope.treedata,
265                     autoOpen: false,
266                     dragAndDrop: true,
267                     onCreateLi: function(node, $li) {
268                         $li.attr('id', node.id.replace(/\s+/g,'_'));
269                     }
270                 });
271
272                 el.find('#jqTree').bind('tree.move',  function(event){
273                     event.preventDefault();
274                     console.log('moved_node', event.move_info.moved_node);
275                     console.log('target_node', event.move_info.target_node);
276                     console.log('position', event.move_info.position);
277                     console.log('previous_parent', event.move_info.previous_parent);
278
279
280
281                     if(event.move_info.target_node != null &&
282                         ((event.move_info.position === 'after' && event.move_info.target_node.getLevel() > 4) ||
283                         (event.move_info.position === 'inside' && event.move_info.target_node.getLevel() > 3))){
284                         confirmBoxService.showInformation('You are not allowed to have a menu item at a level greater than 4.').then(isConfirmed => {
285
286                         });
287                         return ;
288                     }
289
290                     var confMsg = 'Are you sure you want to move "'+event.move_info.moved_node.name+'" ?';
291                     if ((event.move_info.position === "inside") && (event.move_info.target_node.url != "")) {
292                         // If we are moving UNDER a node that has a url associated with it, warn the user
293                         // that all the app information will be removed if they do this.
294                         confMsg = 'Warning: You are moving "'+event.move_info.moved_node.name+'" under "'+event.move_info.target_node.name+'", which has application information associated with it. This will cause all the application information from "'+event.move_info.target_node.name+'" to be deleted.';
295                     }
296                     confirmBoxService.moveMenuItem(confMsg).then(isConfirmed => {
297                         if(isConfirmed){
298                             /*
299                              {
300                              "menuId": 129,
301                              "column": 3,
302                              "text": "",
303                              "parentMenuId": 37,
304                              "url": "",
305                              "appid": null,
306                              "roles": null
307                              }
308
309                              The menuId for the menu item being moved
310                              The column it is being moved to
311                              The parentMenuId for the parent it is being moved under
312                              */
313
314                             // The target_node is the node before the position we are
315                             // moving to. If we are moving to a lower column number, or
316                             // to a new parent, we must adjust the column to be after
317                             // the target_node.
318                             var new_column = event.move_info.target_node.column;
319                             var old_column = event.move_info.moved_node.column;
320                             if ((event.move_info.moved_node.parentMenuId !=
321                                 event.move_info.target_node.parentMenuId) ||
322                                 (new_column < old_column)
323                             ) {
324                                 new_column += 1;
325                             }
326                             var activeMenuItem = {
327                                 menuId:event.move_info.moved_node.menuId,
328                                 column:new_column,
329                                 text:"",
330                                 parentMenuId:event.move_info.target_node.parentMenuId,
331                                 url:"",
332                                 appid: null,
333                                 roles:null
334                             };
335                             // When position is "inside", this is a special case,
336                             // where you are moving to the first column under
337                             // a parent. The target_node is the parent node.
338                             // So we need to set the column to 1, and the parentMenuId to the menuId of
339                             // the target move.
340                             if (event.move_info.position === "inside") {
341                                 console.log("special case: target_node is parent");
342                                 activeMenuItem.column = 1;
343                                 activeMenuItem.parentMenuId = event.move_info.target_node.menuId;
344                             }
345
346
347                             functionalMenuService.saveEditedMenuItem(activeMenuItem)
348                                 .then(() => {
349                                     $log.debug(' Menu Item moved');
350                                     scope.reloadTreeStructure();
351                                 }).catch(err => {
352                                 $log.error(err);
353                             }).finally(()=>{
354                             });
355                         }
356                     }).catch(err => {
357                         $log.error(err);
358                     });
359
360                     //event.move_info.do_move();
361                 });
362
363
364                 $jqTree.jqTreeContextMenu(el.find('ul.dropdown-menu'), {
365                     "view": function (node) {scope.openMenuDetailsModal(node,'view'); },
366                     "edit": function (node) {scope.openMenuDetailsModal(node,'edit'); },
367                     "delete": function (node) { scope.deleteMenuItem(node,'delete') },
368                     "add": function (node) {  scope.createNewMenuItem(node,'add') }
369                 });
370
371                 scope.$watch('treedata', function(oldValue, newValue){
372                     if(oldValue !== newValue){
373                         console.log('FunctionalMenuCtrl:: Tree value has changed in some way');
374                         $jqTree.tree('loadData',  scope.treedata);
375                         $jqTree.tree('reload', function() {
376                             console.log('FunctionalMenuCtrl:: Tree is reloaded');
377                         });
378                     }
379                 });
380             }
381         };
382     }]);
383
384 })();
385
386