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