Adding new components with portal-FE-common
[portal.git] / portal-FE-common / src / app / pages / functional-menu / functional-menu-dialog / functional-menu-dialog.component.ts
1 /*-
2  * ============LICENSE_START==========================================
3  * ONAP Portal
4  * ===================================================================
5  * Copyright (C) 2019 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  * 
37  */
38  
39 import { Component, OnInit, Input, Output, EventEmitter  } from '@angular/core';
40 import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
41 import { FunctionalMenuService } from 'src/app/shared/services';
42 import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
43 import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
44
45 @Component({
46   selector: 'app-functional-menu-dialog',
47   templateUrl: './functional-menu-dialog.component.html',
48   styleUrls: ['./functional-menu-dialog.component.scss']
49 })
50 export class FunctionalMenuDialogComponent implements OnInit {
51
52   @Input() nodedata: any;
53   @Input() operationName: string;
54   @Output() passEntry: EventEmitter<any> = new EventEmitter();
55   isEditMode: boolean = false;
56   isViewMode: boolean = false;
57   isAddItemMode: boolean = false;
58   selectedItem: any;
59   result: any;
60   availableRoles: any;
61   preSelectedRoles: any;
62   isAllApplications: boolean  = false;
63   availableApps: any
64   selectedRole: any = [];
65   selectedApp={
66     index:null,
67     isDisabled: null
68   };
69   selectedAppIndex: any;
70   menutitle:string;
71   menuLocation:string;
72   nodedetails: any;
73   isParentDisable:boolean =true;
74   hideRoleField:boolean = true;
75   conflictMessages = {};
76   functionalMenuForm = {};
77   
78   constructor(public functionalMenuService : FunctionalMenuService, public ngbModal: NgbModal, public activeModal: NgbActiveModal) { }
79
80   ngOnInit() {
81     //console.log("nodedata in dialog ",this.nodedata);
82     this.nodedetails = Object.assign({}, this.nodedata);
83     this.isViewMode = true;
84     this.selectedItem = this.nodedata;
85     this.selectedRole = [];
86     this.availableRoles = [];
87     if(this.nodedata && (this.isViewMode || this.isEditMode) && this.isLeafMenuItem(this.nodedetails)){
88         this.selectedApp.index = this.nodedetails.appid;
89         this.selectedAppIndex=this.nodedetails.appid;
90         this.getAvailableRoles(this.selectedAppIndex);
91     }
92     
93     if(this.isViewMode || this.isEditMode){
94          this.nodedetails.menutitle = this.nodedetails.name;
95          this.nodedetails.menuLocation = this.isParentMenuItem(this.nodedata) ? this.nodedata.name : this.nodedata.parent.name;
96     }else{
97         this.nodedetails.menutitle = '';
98         this.nodedetails.menuLocation = this.nodedata.name;
99     }
100     this.nodedetails.selectedAppIndex = (this.selectedItem.appid) ? this.selectedItem.appid : 0;
101     this.getAvailableApps();
102     if(this.selectedItem.appid && this.selectedItem.appid >0){
103       this.getAvailableRoles(this.selectedItem.appid);
104     }
105   }
106
107   switchToEditMode(){
108     //console.log("switchToEditMode :: ",this.nodedata);
109     this.isViewMode = false;
110     this.isEditMode = true;
111     this.isParentDisable =true;
112     this.nodedetails.name = this.selectedItem.name;
113     this.nodedetails.url = this.selectedItem.url;
114     this.nodedetails.selectedAppIndex = (this.selectedItem.appid) ? this.selectedItem.appid : 0;
115     this.nodedetails.selectedRole = (this.selectedItem.roles) ? this.selectedItem.roles : 0;
116   }
117
118   switchToAddMode(){
119     //console.log("switchToAddMode :: ",this.nodedata);
120     if(this.selectedItem != null && this.selectedItem.getLevel() >= 4){
121       this.openConfirmationModal("","You are not allowed to have a menu item at a level greater than 4.");
122       return ;
123     }
124     //this.isViewMode = false;
125     this.isViewMode = false;
126     this.isEditMode = true;
127     this.isAddItemMode = true;
128     this.nodedetails.name = "";
129     this.nodedetails.url = "";
130     this.nodedetails.selectedAppIndex = 0;
131     this.nodedetails.selectedRole = 0;
132   }
133
134   /**
135    * deleteMenuItem
136    * @param selectedItem 
137    */
138   deleteMenuItem(){
139     if(this.selectedItem.children!=null && this.selectedItem.children.length>0){
140       const modalRef = this.ngbModal.open(ConfirmationModalComponent);
141       modalRef.componentInstance.title = "";
142       modalRef.componentInstance.message = 'You are not allowed to delete a menu item that has children. You can only delete leaf menu items.';
143       modalRef.result.then((result) => { }, (resut) => {return;});
144     }else{
145       const modalRef = this.ngbModal.open(InformationModalComponent);
146       modalRef.componentInstance.title = "Confirmation";
147       modalRef.componentInstance.message = 'Are you sure you want to delete '+ this.selectedItem.name+' ?';
148       modalRef.result.then((result) => {
149         if (result === 'Ok') {
150           this.functionalMenuService.deleteMenuItem(this.selectedItem.menuId)
151           .subscribe(_data => {
152               this.result = _data
153               this.passEntry.emit(this.result);
154               let successMsg = "Item Deleted Successfully";
155               this.openConfirmationModal("Success",successMsg);
156               this.ngbModal.dismissAll();
157           }, error =>{
158             console.log(error);
159             let deleteErrorMsg  = 'There was an error while deleting the item.'+error.message;
160             this.openConfirmationModal("Error",deleteErrorMsg);
161             return;
162           });
163         }
164       }, (resut) => {
165         
166       })
167     }
168   }
169
170   updateSelectedApp(appid){
171     //console.log("updateSelectedApp called with appId :: ",appid);
172     if (!appid) {
173       return;
174     }
175     this.getAvailableRoles(appid);
176   }
177
178   getAvailableRoles(appid){
179     //console.log("getAvailableRoles called with appId :: ",appid);
180     if (appid != null && appid >0) {
181       this.functionalMenuService.getManagedRolesMenu(appid)
182       .subscribe(rolesObj => {
183         this.availableRoles = rolesObj;
184         if(this.availableRoles && this.availableRoles.length >0){
185           this.hideRoleField = false;
186         }
187         this.preSelectedRoles = {roles:[]};
188         this.preSelectedRoles = {roles:[]};
189
190         if((this.isEditMode) && this.isMidLevelMenuItem(this.nodedata)){
191             // in Edit flow , for Midlevel menu item no need to preSelect.
192             this.preSelectedRoles = {roles:[]};
193         }else if(this.nodedata && this.isEditMode && this.isLeafMenuItem(this.nodedata) && this.nodedata.appid!=appid) {
194             // in Edit flow , for LeafMenuItem, if appid changed then no need to preSelect.
195             this.preSelectedRoles = {roles:[]};
196         }else{
197             if(this.nodedata && this.nodedata.roles){
198                 for(var i=0; i< this.nodedata.roles.length; i++){
199                     var role = {"roleId": this.nodedata.roles[i]};
200                     this.preSelectedRoles.roles.push(role);
201                 }
202             }
203         }
204         
205         if(this.nodedata.rolesObj){
206           for(var i=0; i< this.nodedata.rolesObj.length;i++){
207             //this.availableRoles[i].isApplied = false;
208             for(var j=0;j<this.preSelectedRoles.roles.length;j++){
209               if(this.preSelectedRoles.roles[j].roleId==this.availableRoles[i].roleId){
210                 this.availableRoles[i].isApplied=true;
211                 this.nodedetails.selectedRole = (this.preSelectedRoles.roles[j]) ? this.preSelectedRoles.roles[j] : 0;
212                 break;
213               }
214           }
215           }
216         }
217       }, error =>{
218         console.log(error);
219         let errorMsg = 'There was an error while gettting available roles. ' + error.message;
220         this.openConfirmationModal("",errorMsg);
221         return;
222       });
223       //console.log("this.availableRoles >>>>>",this.availableRoles);
224     }else{
225       console.log("FunctionalMenuDialogComponent::getAvailableRoles: appid was null or -1");
226     }
227   }
228
229   getAvailableApps(){
230     this.isAllApplications = true;
231     this.functionalMenuService.getAvailableApplications()
232       .subscribe(apps => {
233         this.availableApps = apps;
234         if (this.nodedetails && this.nodedetails.index) {
235           for (var i = 0; i < this.availableApps.length; i++) {
236               if (apps[i].index === this.nodedetails.index) {
237                   //console.log("MenuDetailsModalCtrl::getAvailableApps: found app with index: " + this.nodedetails.index);
238                   //console.log("MenuDetailsModalCtrl::getAvailableApps: setting isDisabled to: " + !apps[i].enabled);
239                   this.nodedetails.isDisabled = !apps[i].enabled;
240                   break;
241               }
242           }
243           //console.log("didn't find index: " + this.nodedetails.index);
244         }
245       }, error =>{
246         console.log(error);
247         this.isAllApplications = false;
248         let errorMsg = 'There was a problem retrieving the Applications. '+error.message;
249         this.openConfirmationModal("Error",errorMsg);
250       });
251   }
252
253   isLeafMenuItem(menu: any){
254       return menu.children.length>0 ? false : true;
255   }
256
257   isMidLevelMenuItem(menu: any){
258       return menu.parentMenuId!=null && menu.children.length>0 ? true : false;
259   }
260
261   isParentMenuItem(menu: any){
262       return menu.parentMenuId!=null ? false : true;
263   };
264
265  isRoleSelected(){
266    var selectedRoleIds=[];
267    for(var i=0;i<this.availableRoles.length;i++){
268        if(this.availableRoles[i].isApplied){
269           selectedRoleIds.push(this.availableRoles[i].roleId);
270           return true;
271        }
272      }
273    return false;
274   }  
275
276   getDialogTitle = (source) => {
277     switch (source) {
278       case 'edit':
279           return "Functional Menu - Edit";
280       case 'view':
281           return "Functional Menu - View";
282       case 'add':
283           return "Functional Menu - Add";
284       default:
285           return "Functional Menu";
286     };
287   }
288
289   saveChanges(){
290     if(!this.nodedetails.menuLocation || !this.nodedetails.name 
291         || !this.nodedetails.url || !this.nodedetails.selectedAppIndex 
292         || !this.nodedetails.selectedAppIndex || !this.nodedetails.selectedRole){
293       this.openConfirmationModal("","All fields are mandatory, please provide inputs for all the fields.");
294       return;
295     }
296     /*
297     if(!!this.nodedetails.url && (!this.selectedApp || this.selectedAppIndex <=0)) {
298       this.openConfirmationModal("","Please select the appropriate app, or remove the url");
299       return;
300     }else if(!this.nodedetails.url && (this.selectedApp) && this.selectedApp.index>0){
301         this.openConfirmationModal("","Please enter url, or select No Application");
302         return;
303     }else if(!this.nodedetails.menutitle){
304         this.openConfirmationModal("","Please enter the Menu title");
305         return;
306     }
307     */
308     
309     if(this.isAddItemMode){
310       if(this.selectedItem != null && this.selectedItem.getLevel() >= 4){
311         this.openConfirmationModal("","You are not allowed to have a menu item at a level greater than 4.");
312         return ;
313       }else{
314         let data = null;
315         let selectedMenuDetails = null;
316         this.functionalMenuService.getFunctionalMenu(this.selectedItem.menuId)
317           .subscribe(_data => {
318               selectedMenuDetails = _data
319               if((this.selectedItem.children===null || this.selectedItem.children.length == 0) && (!!selectedMenuDetails.url
320                  || !!selectedMenuDetails.appid || !!selectedMenuDetails.roles)){
321                 let warning_message = 'Warning: the child menu item "' + 
322                               this.selectedItem.name + '" is already configured with an application. You can create a new mid-level menu item.';
323                 this.openConfirmationModal("",warning_message);
324                 return;
325               }else{
326                 if(this.selectedItem){
327                     var selectedRoleIds=[];
328                     //console.log("Selected Role ID ; ",this.nodedetails.selectedRole);
329                     if(this.nodedetails.selectedRole){
330                       selectedRoleIds.push(this.nodedetails.selectedRole);
331                     }
332                     
333                     let applicationid: any = null;
334                     if(!this.nodedata){
335                       applicationid = null;
336                     }else{
337                       applicationid = this.nodedata.appid;
338                     }
339                     var newMenuItem = {
340                         menuId:null, // this is a new menu item
341                         column:this.nodedata.column,
342                         text:this.nodedetails.name,
343                         // We are creating this new menu item under the menu item that was clicked on.
344                         parentMenuId:this.nodedata.menuId,
345                         url:(this.nodedetails.url) ? this.nodedetails.url : null,
346                         appid:(this.nodedetails.selectedAppIndex) ? this.nodedetails.selectedAppIndex: null,
347                         roles:selectedRoleIds
348                     };
349                     //console.log("Add menu Item newMenuItem :: ",newMenuItem)
350                     this.functionalMenuService.saveMenuItem(newMenuItem)
351                     .subscribe(_data => {
352                         this.result = _data
353                         //console.log("add menu item response :: ",_data);
354                         this.passEntry.emit(this.result);
355                         let successMsg = "Item added successfully";
356                         this.openConfirmationModal("Success",successMsg);
357                     }, error =>{
358                       console.log(error);
359                       if(error.status === 409){//Conflict
360                         this.handleConflictErrors(error);
361                       } else {
362                         let errorMsg = "There was a problem saving your menu. Please try again later. Error Status: "+error.status
363                         this.openConfirmationModal("",errorMsg);
364                         return;
365                       }
366                    });
367                 }
368               }
369           }, error =>{
370             //console.log(error);
371             let errorMsg = "There was a problem saving your menu. Please try again later. Error Status: "+error.status
372             this.openConfirmationModal("",errorMsg );
373             return;
374         });
375       }
376     }else{
377       //edit mode..
378       //console.log('MenuDetailsModalCtrl::saveChanges: Will be saving an edit menu item');
379       var selectedRoleIds=[];
380       //console.log("Selected Role ID ---->>>> ",this.nodedetails.selectedRole);
381       if(this.nodedetails.selectedRole){
382         selectedRoleIds.push(this.nodedetails.selectedRole);
383       }
384       let activeMenuItem = {
385           menuId:this.nodedata.menuId,
386           column:this.nodedata.column,
387           text:this.nodedetails.name,
388           parentMenuId:this.nodedata.parentMenuId,
389           url:(this.nodedetails.url) ? this.nodedetails.url : null,
390           appid: (this.nodedetails.selectedAppIndex) ? this.nodedetails.selectedAppIndex: null,          
391           roles:selectedRoleIds
392       };
393       if ((activeMenuItem.appid==null && activeMenuItem.url=="") || (activeMenuItem.appid==null && activeMenuItem.url=="undefined")) {
394         activeMenuItem.roles = null;
395       }
396       //console.log("Update menu Item activeMenuItem :: ",activeMenuItem);
397       this.functionalMenuService.saveEditedMenuItem(activeMenuItem)
398       .subscribe(_data => {
399           this.result = _data
400           //console.log("Edit menu item response :: ",_data);
401           this.passEntry.emit(this.result);
402           let successMsg = "Item updated successfully";
403           this.openConfirmationModal("Success",successMsg);
404           //this.ngbModal.dismissAll();
405       }, error =>{
406         //console.log(error);
407         let errorMsg = "There was a problem updating your menu. Please try again later. Error Status: "+error.status;
408         this.openConfirmationModal("",errorMsg);
409         return;
410       });
411     } 
412   }
413
414   //This part handles conflict errors (409)
415   handleConflictErrors(error){
416     if(!error.data){
417       return;
418     }
419     if(!error.data.length){ //support objects
420       error.data = [error.data]
421     }
422     //console.log('MenuDetailsModalCtrl::handleConflictErrors: err.data = ' + JSON.stringify(error.data));
423     if(error.data){
424       error.data.forEach(item => {
425          //set conflict message
426          this.conflictMessages[item.field.name] = item.errorCode;
427          //set field as invalid
428          //console.log('MenuDetailsModalCtrl::handleConflictErrors: fieldName = ' + item.field.name);
429          this.functionalMenuForm[item.field.name].$setValidity('conflict', false);
430       });
431     }
432   }
433
434   openConfirmationModal(_title: string, _message: string) {
435     const modalInfoRef = this.ngbModal.open(ConfirmationModalComponent);
436     modalInfoRef.componentInstance.title = _title;
437     modalInfoRef.componentInstance.message = _message;
438   }
439
440   openInformationModal(_title: string, _message: string){
441     const modalInfoRef = this.ngbModal.open(InformationModalComponent);
442     modalInfoRef.componentInstance.title = _title;
443     modalInfoRef.componentInstance.message = _message;
444     return modalInfoRef;
445   }
446 }