Adding unlimited max value to VNF, NETWORK
[vid.git] / vid-webpack-master / src / app / drawingBoard / service-planning / objectsToTree / shared.tree.service.ts
1 import {Injectable} from "@angular/core";
2 import {NgRedux} from "@angular-redux/store";
3 import {AppState} from "../../../shared/store/reducers";
4 import {ServiceInstanceActions} from "../../../shared/models/serviceInstanceActions";
5 import {MessageBoxData} from "../../../shared/components/messageBox/messageBox.data";
6 import {MessageBoxService} from "../../../shared/components/messageBox/messageBox.service";
7 import * as _ from "lodash";
8 import {DrawingBoardModes} from "../drawing-board.modes";
9 import {AuditInfoModalComponent} from "../../../shared/components/auditInfoModal/auditInfoModal.component";
10 import {ILevelNodeInfo} from "./models/basic.model.info";
11 import {ComponentInfoModel, ComponentInfoType} from "../component-info/component-info-model";
12 import {ModelInformationItem} from "../../../shared/components/model-information/model-information.component";
13 import {undoUpgradeService, upgradeService} from "../../../shared/storeUtil/utils/service/service.actions";
14 import {VNFMethods} from "../../../shared/storeUtil/utils/vnf/vnf.actions";
15 import {FeatureFlagsService, Features} from "../../../shared/services/featureFlag/feature-flags.service";
16 import {Utils} from "../../../shared/utils/utils";
17
18 @Injectable()
19 export class SharedTreeService {
20   private _sharedTreeService: SharedTreeService;
21   constructor(private _store: NgRedux<AppState>) {
22   }
23
24   /***********************************************************
25    * return if instance has missing data
26    * @param instance - vnf instance
27    * @param dynamicInputs - from the instance
28    * @param isEcompGeneratedNaming
29    ************************************************************/
30   selectedVNF: string = null;
31
32
33   getSelectedVNF(): string {
34     return this.selectedVNF;
35   }
36
37   setSelectedVNF(node): void {
38     if (_.isNil(node) || node.data.type !== 'VF') {
39       this.selectedVNF = null;
40     } else {
41       this.selectedVNF = node.data.vnfStoreKey;
42     }
43   }
44
45   hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean, requiredFields: string[]): boolean {
46     if (!isEcompGeneratedNaming && _.isEmpty(instance.instanceName)) {
47       return true;
48     }
49
50     for (let field of requiredFields) {
51       if (_.isEmpty(instance[field])) {
52         return true;
53       }
54     }
55
56     for (let field of dynamicInputs) {
57       if (field.isRequired && !_.isNil(instance.instanceParams) && _.isEmpty(instance.instanceParams[0][field.id])) {
58         return true;
59       }
60     }
61     return false;
62   }
63
64
65   addingStatusProperty(node) {
66     node['statusProperties'] = [];
67     node['statusProperties'].push({key: 'Prov Status:', value: node.provStatus, testId: 'provStatus'});
68     node['statusProperties'].push({key: 'Orch Status:', value: node.orchStatus, testId: 'orchStatus'});
69     if (node.inMaint) {
70       node['statusProperties'].push({key: 'In-maintenance', value: '', testId: 'inMaint'});
71     }
72     return node;
73   }
74
75   /**********************************************
76    * should delete or remove child instance's
77    "new" -> should remove
78    !new" -> should change action status
79    **********************************************/
80   removeDeleteAllChild(node, serviceModelId: string, callback): void {
81     for (let nodeChild of node.children) {
82       if (nodeChild.data.action === ServiceInstanceActions.Create) {
83         if (!_.isNil(nodeChild.data) && !_.isNil(nodeChild.data.menuActions) && !_.isNil(nodeChild.data.menuActions['remove'])) {
84           nodeChild.data.menuActions['remove']['method'](nodeChild, serviceModelId);
85         }
86       } else {
87         if (!_.isNil(nodeChild.data) && !_.isNil(nodeChild.data.menuActions) && !_.isNil(nodeChild.data.menuActions['delete'])) {
88           nodeChild.data.menuActions['delete']['method'](nodeChild, serviceModelId);
89         }
90       }
91     }
92     callback(node, serviceModelId);
93   }
94
95
96   /**********************************************
97    * should undo delete child instance's
98    **********************************************/
99   undoDeleteAllChild(node, serviceModelId: string, callback): void {
100     for (let nodeChild of node.children) {
101       if (!_.isNil(nodeChild.data) && !_.isNil(nodeChild.data.menuActions) && !_.isNil(nodeChild.data.menuActions['undoDelete'])) {
102         nodeChild.data.menuActions['undoDelete']['method'](nodeChild, serviceModelId);
103       }
104     }
105     callback(node, serviceModelId);
106   }
107
108   /**********************************************
109    * should return true if can delete
110    **********************************************/
111   shouldShowDelete(node): boolean {
112     return this.shouldShowButtonGeneric(node, "delete")
113   }
114
115   /**********************************************
116    * should return true if can undo delete
117    **********************************************/
118   shouldShowUndoDelete(node): boolean {
119     const mode = this._store.getState().global.drawingBoardStatus;
120     if (mode === DrawingBoardModes.EDIT && !_.isNil(node.data.action) && !_.isNil(node.data.menuActions['undoDelete'])) {
121       if (node.data.action === ServiceInstanceActions.Create || node.data.action === ServiceInstanceActions.Delete) {
122         return false;
123       } else if (node.data.action.split('_').pop() === 'Delete') {
124         return true
125       }
126       return false;
127     }
128     return false;
129   }
130   /**********************************************
131    * should return true if can remove or edit
132    * enabled only on edit/design mode and for new instances
133    **********************************************/
134   shouldShowRemoveAndEdit(node): boolean {
135     const mode = this._store.getState().global.drawingBoardStatus;
136     if (!_.isNil(node) && !_.isNil(node.data) && !_.isNil(node.data.action) && node.data.action === ServiceInstanceActions.Create &&
137       mode !== DrawingBoardModes.VIEW && mode !== DrawingBoardModes.RETRY) {
138       return true;
139     }
140     return false;
141   }
142   /**********************************************
143    * enabled only on edit/design
144    * enabled only if there's a newer version for VNF-M
145    **********************************************/
146   upgradeBottomUp(node,serviceModelId: string): void {
147     this.iterateOverTreeBranchAndRunAction(node, serviceModelId, VNFMethods.UPGRADE);
148     this._store.dispatch(upgradeService(serviceModelId));
149   }
150
151   private iterateOverTreeBranchAndRunAction(node, serviceModelId: string, actionMethod) {
152     while (_.has(node.parent, 'data') && _.has(node.parent.data, 'menuActions')
153     && !_.isNil(node.parent.data.menuActions[actionMethod])) {
154       node = node.parent;
155       node.data.menuActions[actionMethod]['method'](node, serviceModelId);
156     }
157   }
158
159   /****************************************************
160    * should return true if customer can upgrade a VFM *
161    ****************************************************/
162   shouldShowUpgrade(node, serviceModelId): boolean {
163     if (FeatureFlagsService.getFlagState(Features.FLAG_FLASH_REPLACE_VF_MODULE, this._store) &&
164       this.isThereAnUpdatedLatestVersion(serviceModelId)) {
165       return this.shouldShowButtonGeneric(node, VNFMethods.UPGRADE);
166     }
167     else {
168       return false
169     }
170   }
171
172   private isThereAnUpdatedLatestVersion(serviceModelId) : boolean{
173     let serviceInstance = this._store.getState().service.serviceInstance[serviceModelId];
174     return !_.isNil(serviceInstance.latestAvailableVersion) && (Number(serviceInstance.modelInfo.modelVersion) < serviceInstance.latestAvailableVersion);
175   }
176
177   private shouldShowButtonGeneric(node, method) {
178     const mode = this._store.getState().global.drawingBoardStatus;
179     if (!_.isNil(node) && !_.isNil(node.data) && !_.isNil(node.data.action) && !_.isNil(node.data.menuActions[method])) {
180       if (mode !== DrawingBoardModes.EDIT || node.data.action === ServiceInstanceActions.Create) {
181         return false;
182       }
183       else if (node.data.action === ServiceInstanceActions.None) {
184         return true
185       }
186     }
187     return false;
188   }
189
190   /**********************************************
191    * return boolean according to
192    * current defined action of VFModule node
193    **********************************************/
194   shouldShowUndoUpgrade(node): boolean {
195     const mode = this._store.getState().global.drawingBoardStatus;
196     if (mode === DrawingBoardModes.EDIT && !_.isNil(node.data.action) && !_.isNil(node.data.menuActions[VNFMethods.UNDO_UPGRADE])) {
197       if (node.data.action === ServiceInstanceActions.Upgrade) {
198         return false;
199       } else if (node.data.action.split('_').pop() === ServiceInstanceActions.Upgrade) {
200         return true
201       }
202       return false;
203     }
204     return false;
205   }
206   /**********************************************
207    * enabled only on edit/design
208    * enabled only if there's a newer version for VNF-M
209    **********************************************/
210   undoUpgradeBottomUp(node,serviceModelId: string): void {
211     this.iterateOverTreeBranchAndRunAction(node, serviceModelId, VNFMethods.UNDO_UPGRADE);
212     this._store.dispatch(undoUpgradeService(serviceModelId));
213   }
214   /**********************************************
215    * should return true if can duplicate by mode
216    **********************************************/
217   shouldShowDuplicate(node): boolean {
218     const mode = this._store.getState().global.drawingBoardStatus;
219     return !mode.includes('RETRY');
220   }
221
222   /**********************************************
223    * should return true if can audit info
224    **********************************************/
225   shouldShowAuditInfo(node): boolean {
226     return this.isRetryMode() || (!_.isNil(node.data) && !_.isNil(node.data.action) && node.data.action !== ServiceInstanceActions.Create);
227   }
228
229
230   isRetryMode(): boolean {
231     const mode = this._store.getState().global.drawingBoardStatus;
232     return mode.includes('RETRY');
233   }
234
235
236   /**********************************************
237    * should return true if can add node instances
238    **********************************************/
239   shouldShowAddIcon(): boolean{
240     const mode = this._store.getState().global.drawingBoardStatus;
241     return mode === DrawingBoardModes.EDIT || mode=== DrawingBoardModes.CREATE;
242   }
243
244
245   isReachedToMaxInstances(properties, counter, flags): boolean{
246     let maxInstances  = Utils.getMaxFirstLevel(properties, flags);
247     if(_.isNil(maxInstances)){
248       return false;
249     }else {
250       return !(maxInstances > counter);
251     }
252   }
253   /************************************************
254    return number of instances with action Delete
255    @type: vnfs networks, vngGroups (not vfModule)
256    @node : node model from the left tree
257    ************************************************/
258   getExistingInstancesWithDeleteMode(node, serviceModelId: string, type: string): number {
259     let counter = 0;
260     const existingInstances = this._store.getState().service.serviceInstance[serviceModelId][type];
261     const modelUniqueId = node.data.modelUniqueId;
262     if (!_.isNil(existingInstances)) {
263       for (let instanceKey in existingInstances) {
264         if (!_.isNil(existingInstances[instanceKey].action)) {
265           if (existingInstances[instanceKey].modelInfo.modelUniqueId === modelUniqueId && existingInstances[instanceKey].action.split('_').pop() === 'Delete') {
266             counter++;
267           }
268         }
269       }
270     }
271     return counter;
272   }
273
274
275   isServiceOnDeleteMode(serviceId: string): boolean {
276     return this._store.getState().service.serviceInstance[serviceId].action === ServiceInstanceActions.Delete;
277   }
278
279
280   openModal(node : any | any[] , serviceModelId : string, cb : Function) : void {
281     let type: string = _.isArray(node) ? 'Service' : node.data.typeName;
282     let messageBoxData: MessageBoxData = new MessageBoxData(
283       "Mark for Delete",
284       `You are about to mark for delete this ${type} this will also mark all its children and remove all new instances just added`,
285       <any>"warning",
286       <any>"md",
287       [
288         {
289           text: "Mark and remove",
290           size: "large",
291           callback: cb.bind(this, node, serviceModelId),
292           closeModal: true
293         },
294         {text: "Don’t Remove", size: "medium", closeModal: true}
295       ]);
296
297     MessageBoxService.openModal.next(messageBoxData);
298   }
299
300   someChildHasCreateAction(nodes: any | any[]) : boolean {
301     let nodesArr = _.isArray(nodes) ? nodes : [nodes];
302     for(const node of nodesArr){
303       if(node.action === ServiceInstanceActions.Create) {return true;}
304       if(node.children){
305         for (let nodeChild of node.children) {
306           if (nodeChild.action === ServiceInstanceActions.Create) {
307             return true;
308           }
309           if(nodeChild.children && nodeChild.children.length > 0){
310             for(let child of nodeChild.children){
311               let hasCreateAction = this.someChildHasCreateAction(child);
312               if(hasCreateAction) {
313                 return true;
314               }
315             }
316           }
317         }
318       }
319     }
320     return false;
321   }
322
323   shouldShowDeleteInstanceWithChildrenModal(node : any | any[] , serviceModelId : string, cb : Function) : void {
324     if(this.someChildHasCreateAction(node)){
325       this.openModal(node , serviceModelId, cb);
326     }else {
327       cb(node, serviceModelId)
328     }
329   }
330
331
332   isFailed(node): boolean {
333     return !_.isNil(node.data) ? node.data.isFailed : false;
334   }
335
336   /************************************************
337    in a case the node is failed e.g. not instantiated correctly
338    the function will call to openRetryInstanceAuditInfoModal
339    @node : node model from the left tree
340    @serviceModelId : serviceModelId
341    @instance : instance
342    @instanceType: instanceType
343    @modelInfoService : the model (vnf, vfmodule, network, vnfgroup)object that call to the function (this)
344    ************************************************/
345   openAuditInfoModal(node, serviceModelId, instance, instanceType, modelInfoService : ILevelNodeInfo){
346     AuditInfoModalComponent.openInstanceAuditInfoModal.next({
347       instanceId: serviceModelId,
348       type: instanceType,
349       model: modelInfoService.getModel(node.data.modelName, instance, this._store.getState().service.serviceHierarchy[serviceModelId]),
350       instance
351     });
352   }
353
354
355   addGeneralInfoItems(modelInfoSpecificItems: ModelInformationItem[], type: ComponentInfoType, model, instance):ComponentInfoModel {
356     let modelInfoItems: ModelInformationItem[] = [
357       ModelInformationItem.createInstance("Model version", model ? model.version : null),
358       ModelInformationItem.createInstance("Model customization ID", model ? model.customizationUuid : null),
359       ModelInformationItem.createInstance("Instance ID", instance ? instance.instanceId : null),
360       ModelInformationItem.createInstance("Instance type", instance ? instance.instanceType : null),
361       ModelInformationItem.createInstance("In maintenance", instance? instance.inMaint : null),
362     ];
363     modelInfoItems = modelInfoItems.concat(modelInfoSpecificItems);
364     return this.getComponentInfoModelByModelInformationItems(modelInfoItems, type, instance);
365   }
366
367   getComponentInfoModelByModelInformationItems(modelInfoItems: ModelInformationItem[], type: ComponentInfoType, instance){
368     const modelInfoItemsWithoutEmpty = _.filter(modelInfoItems, function(item){ return !item.values.every(_.isNil)});
369     return new ComponentInfoModel(type, modelInfoItemsWithoutEmpty, [], instance != null);
370   }
371 }