Sync Integ to Master
[sdc.git] / catalog-ui / src / app / view-models / dashboard / dashboard-view-model.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
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  * ============LICENSE_END=========================================================
19  */
20
21 'use strict';
22 import {IConfigRoles, IAppConfigurtaion, IAppMenu, IUserProperties, Component} from "app/models";
23 import {EntityService, SharingService, CacheService} from "app/services";
24 import {ComponentType, ResourceType, MenuHandler, ModalsHandler, ChangeLifecycleStateHandler, SEVERITY, ComponentFactory} from "app/utils";
25 import {IClientMessageModalModel} from "../modals/message-modal/message-client-modal/client-message-modal-view-model";
26 import {UserService} from "../../ng2/services/user.service";
27
28 export interface IDashboardViewModelScope extends ng.IScope {
29
30     isLoading:boolean;
31     components:Array<Component>;
32     folders:FoldersMenu;
33     roles:IConfigRoles;
34     user:IUserProperties;
35     sdcConfig:IAppConfigurtaion;
36     sdcMenu:IAppMenu;
37     sharingService:SharingService;
38     showTutorial:boolean;
39     isFirstTime:boolean;
40     version:string;
41     checkboxesFilter:CheckboxesFilter;
42     vfcmtType:string;
43
44
45     onImportVfc(file:any):void;
46     onImportVf(file:any):void;
47     openCreateModal(componentType:ComponentType, importedFile:any):void;
48     openWhatsNewModal(version:string):void;
49     openDesignerModal(isResource:boolean, uniqueId:string):void;
50     setSelectedFolder(folderItem:FoldersItemsMenu):void;
51     entitiesCount(folderItem:FoldersItemsMenu):number;
52     getCurrentFolderDistributed():Array<Component>;
53     changeLifecycleState(entity:any, data:any):void;
54     goToComponent(component:Component):void;
55     wizardDebugEdit:Function;
56     notificationIconCallback:Function;
57 }
58
59 interface CheckboxesFilter {
60     // Statuses
61     selectedStatuses:Array<string>;
62     // distributed
63     distributed:Array<string>;
64 }
65
66 export interface IItemMenu {
67
68 }
69
70 export interface IMenuItemProperties {
71     text:string;
72     group:string;
73     state:string;
74     dist:string;
75     groupname:string;
76     states:Array<any>;
77 }
78
79 export class FoldersMenu {
80
81     private _folders:Array<FoldersItemsMenu> = [];
82
83     constructor(folders:Array<IMenuItemProperties>) {
84         let self = this;
85         folders.forEach(function (folder:IMenuItemProperties) {
86             if (folder.groupname) {
87                 self._folders.push(new FoldersItemsMenuGroup(folder));
88             } else {
89                 self._folders.push(new FoldersItemsMenu(folder));
90             }
91         });
92         self._folders[0].setSelected(true);
93     }
94
95     public getFolders = ():Array<FoldersItemsMenu> => {
96         return this._folders;
97     };
98
99     public getCurrentFolder = ():FoldersItemsMenu => {
100         let menuItem:FoldersItemsMenu = undefined;
101         this.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) {
102             if (tmpFolder.isSelected()) {
103                 menuItem = tmpFolder;
104             }
105         });
106         return menuItem;
107     };
108
109     public setSelected = (folder:FoldersItemsMenu):void => {
110         this.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) {
111             tmpFolder.setSelected(false);
112         });
113         folder.setSelected(true);
114     }
115
116 }
117
118 export class FoldersItemsMenu implements IItemMenu {
119
120     public text:string;
121     public group:string;
122     public state:string;
123     public dist:string;
124     public states:Array<any>;
125
126     private selected:boolean = false;
127
128     constructor(menuProperties:IMenuItemProperties) {
129         this.text = menuProperties.text;
130         this.group = menuProperties.group;
131         this.state = menuProperties.state;
132         this.states = menuProperties.states;
133         this.dist = menuProperties.dist;
134     }
135
136     public isSelected = ():boolean => {
137         return this.selected;
138     };
139
140     public setSelected = (value:boolean):void => {
141         this.selected = value;
142     };
143
144     public isGroup = ():boolean => {
145         return false;
146     }
147
148 }
149
150 export class FoldersItemsMenuGroup extends FoldersItemsMenu {
151
152     public groupname:string;
153
154     constructor(menuProperties:IMenuItemProperties) {
155         super(menuProperties);
156         this.groupname = menuProperties.groupname;
157     }
158
159     public isGroup = ():boolean => {
160         return true;
161     }
162
163 }
164
165 export class DashboardViewModel {
166     static '$inject' = [
167         '$scope',
168         '$filter',
169         'Sdc.Services.EntityService',
170         '$http',
171         'sdcConfig',
172         'sdcMenu',
173         '$state',
174         '$stateParams',
175         'UserServiceNg2',
176         'Sdc.Services.SharingService',
177         'Sdc.Services.CacheService',
178         '$q',
179         'ComponentFactory',
180         'ChangeLifecycleStateHandler',
181         'ModalsHandler',
182         'MenuHandler'
183     ];
184
185     private components:Array<Component>;
186
187     constructor(private $scope:IDashboardViewModelScope,
188                 private $filter:ng.IFilterService,
189                 private entityService:EntityService,
190                 private $http:ng.IHttpService,
191                 private sdcConfig:IAppConfigurtaion,
192                 private sdcMenu:IAppMenu,
193                 private $state:any,
194                 private $stateParams:any,
195                 private userService:UserService,
196                 private sharingService:SharingService,
197                 private cacheService:CacheService,
198                 private $q:ng.IQService,
199                 private ComponentFactory:ComponentFactory,
200                 private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler,
201                 private ModalsHandler:ModalsHandler,
202                 private MenuHandler:MenuHandler) {
203         this.initScope();
204         this.initFolders();
205         this.initEntities(true);
206
207         if (this.$stateParams) {
208
209             if (this.$state.params.folder) {
210                 let self = this;
211                 let folderName = this.$state.params.folder.replaceAll("_", " ");
212
213                 this.$scope.folders.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) {
214                     if (tmpFolder.text === folderName) {
215                         self.$scope.setSelectedFolder(tmpFolder);
216                     }
217                 });
218             }
219
220             // Show the tutorial if needed when the dashboard page is opened.<script src="bower_components/angular-filter/dist/angular-filter.min.js"></script>
221             // This is called from the welcome page.
222             else if (this.$stateParams.show === 'tutorial') {
223                 this.$scope.showTutorial = true;
224                 this.$scope.isFirstTime = true;
225             }
226         }
227     }
228
229     private initFolders = ():void => {
230         if (this.$scope.user) {
231             this.$scope.folders = new FoldersMenu(this.$scope.roles[this.$scope.user.role].folder);
232         }
233     };
234
235     private initScope = ():void => {
236         let self = this;
237
238         this.$scope.version = this.cacheService.get('version');
239         this.$scope.sharingService = this.sharingService;
240         this.$scope.isLoading = false;
241         this.$scope.sdcConfig = this.sdcConfig;
242         this.$scope.sdcMenu = this.sdcMenu;
243         this.$scope.user = this.userService.getLoggedinUser();
244         this.$scope.roles = this.sdcMenu.roles;
245         this.$scope.showTutorial = false;
246         this.$scope.isFirstTime = false;
247         this.$scope.vfcmtType = ResourceType.VFCMT;
248
249         // Open onboarding modal
250         this.$scope.notificationIconCallback = ():void => {
251             this.ModalsHandler.openOnboadrdingModal('Import').then(()=> {
252                 // OK
253             }, ()=> {
254                 // ERROR
255             });
256         };
257
258         // Checkboxes filter init
259         this.$scope.checkboxesFilter = <CheckboxesFilter>{};
260         this.$scope.checkboxesFilter.selectedStatuses = [];
261         this.$scope.checkboxesFilter.distributed = [];
262
263         this.$scope.onImportVf = (file:any):void => {
264             if (file && file.filename) {
265                 // Check that the file has valid extension.
266                 let fileExtension:string = file.filename.split(".").pop();
267                 if (this.sdcConfig.csarFileExtension.indexOf(fileExtension.toLowerCase()) !== -1) {
268                     this.$state.go('workspace.general', {
269                         type: ComponentType.RESOURCE.toLowerCase(),
270                         importedFile: file,
271                         resourceType: ResourceType.VF
272                     });
273                 } else {
274                     let data:IClientMessageModalModel = {
275                         title: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS_TITLE"),
276                         message: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS", "{'extensions': '" + this.sdcConfig.csarFileExtension + "'}"),
277                         severity: SEVERITY.ERROR
278                     };
279                     this.ModalsHandler.openClientMessageModal(data);
280                 }
281             }
282         };
283
284         this.$scope.onImportVfc = (file:any):void => {
285             if (file && file.filename) {
286                 // Check that the file has valid extension.
287                 let fileExtension:string = file.filename.split(".").pop();
288                 if (this.sdcConfig.toscaFileExtension.indexOf(fileExtension.toLowerCase()) !== -1) {
289                     this.$state.go('workspace.general', {
290                         type: ComponentType.RESOURCE.toLowerCase(),
291                         importedFile: file,
292                         resourceType: ResourceType.VFC
293                     });
294                 } else {
295                     let data:IClientMessageModalModel = {
296                         title: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS_TITLE"),
297                         message: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS", "{'extensions': '" + this.sdcConfig.toscaFileExtension + "'}"),
298                         severity: SEVERITY.ERROR
299                     };
300                     this.ModalsHandler.openClientMessageModal(data);
301                 }
302             }
303         };
304
305         this.$scope.openCreateModal = (componentType:string, importedFile:any):void => {
306             if (importedFile) {
307                 this.initEntities(true); // Return from import
308             } else {
309                 this.$state.go('workspace.general', {type: componentType.toLowerCase()});
310             }
311
312         };
313
314         this.$scope.createPNF = ():void => {
315             this.$state.go('workspace.general', {
316                 type: ComponentType.RESOURCE.toLowerCase(),
317                 resourceType: ResourceType.PNF
318             });
319         };
320
321         this.$scope.createCR = ():void => {
322             this.$state.go('workspace.general', {
323                 type: ComponentType.RESOURCE.toLowerCase(),
324                 resourceType: ResourceType.CR
325             });
326         };
327
328         this.$scope.entitiesCount = (folderItem:FoldersItemsMenu):any => {
329             let self = this;
330             let total:number = 0;
331             if (folderItem.isGroup()) {
332                 this.$scope.folders.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) {
333                     if (tmpFolder.group && tmpFolder.group === (<FoldersItemsMenuGroup>folderItem).groupname) {
334                         total = total + self._getTotalCounts(tmpFolder, self);
335                     }
336                 });
337             } else {
338                 total = total + self._getTotalCounts(folderItem, self);
339             }
340             return total;
341         };
342
343         this.$scope.getCurrentFolderDistributed = ():Array<any> => {
344             let self = this;
345             let states = [];
346             if (this.$scope.folders) {
347                 let folderItem:FoldersItemsMenu = this.$scope.folders.getCurrentFolder();
348                 if (folderItem.isGroup()) {
349                     this.$scope.folders.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) {
350                         if (tmpFolder.group && tmpFolder.group === (<FoldersItemsMenuGroup>folderItem).groupname) {
351                             self._setStates(tmpFolder, states);
352                         }
353                     });
354                 } else {
355                     self._setStates(folderItem, states);
356                 }
357             }
358             return states;
359         };
360
361         this.$scope.setSelectedFolder = (folderItem:FoldersItemsMenu):void => {
362             this.$scope.folders.setSelected(folderItem);
363         };
364
365         this.$scope.goToComponent = (component:Component):void => {
366             this.$scope.isLoading = true;
367             this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()});
368         };
369
370     };
371
372     private _getTotalCounts(tmpFolder, self):number {
373         let total:number = 0;
374         if (tmpFolder.dist !== undefined) {
375             let distributions = tmpFolder.dist.split(',');
376             distributions.forEach((item:any) => {
377                 total = total + self.getEntitiesByStateDist(tmpFolder.state, item).length;
378             });
379         }
380         else {
381             total = total + self.getEntitiesByStateDist(tmpFolder.state, tmpFolder.dist).length;
382         }
383         return total;
384     }
385
386     private _setStates(tmpFolder, states) {
387         if (tmpFolder.states !== undefined) {
388             tmpFolder.states.forEach(function (item:any) {
389                 states.push({"state": item.state, "dist": item.dist});
390             });
391         } else {
392             states.push({"state": tmpFolder.state, "dist": tmpFolder.dist});
393         }
394     }
395
396     private initEntities = (reload:boolean):void => {
397         this.$scope.isLoading = reload;
398         this.entityService.getAllComponents().then(
399             (components:Array<Component>) => {
400                 this.components = components;
401                 this.$scope.components = components;
402                 this.$scope.isLoading = false;
403             });
404     };
405
406     private getEntitiesByStateDist = (state:string, dist:string):Array<Component> => {
407         let gObj:Array<Component>;
408         if (this.components && (state || dist)) {
409             gObj = this.components.filter(function (obj:Component) {
410                 if (dist !== undefined && obj.distributionStatus === dist && obj.lifecycleState === state) {
411                     return true;
412                 } else if (dist === undefined && obj.lifecycleState === state) {
413                     return true;
414                 }
415                 return false;
416             });
417         } else {
418             gObj = [];
419         }
420         return gObj;
421     }
422 }