merge from ecomp a88f0072 - Modern UI
[vid.git] / vid-webpack-master / src / app / drawingBoard / service-planning / objectsToTree / models / vfModule / vfModule.model.info.ts
1 import {DynamicInputsService} from "../../dynamicInputs.service";
2 import {ILevelNodeInfo} from "../basic.model.info";
3 import * as _ from "lodash";
4 import {VNFModel} from "../../../../../shared/models/vnfModel";
5 import {SharedTreeService} from "../../shared.tree.service";
6 import {VfModuleTreeNode} from "../../../../../shared/models/vfModuleTreeNode";
7 import {VfModuleInstance} from "../../../../../shared/models/vfModuleInstance";
8 import {VfModule} from "../../../../../shared/models/vfModule";
9 import {NgRedux} from "@angular-redux/store";
10 import {ITreeNode} from "angular-tree-component/dist/defs/api";
11 import {
12   GenericFormPopupComponent,
13   PopupType
14 } from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
15 import {DialogService} from "ng2-bootstrap-modal";
16 import {VfModulePopuopService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModule/vfModule.popuop.service";
17 import {AppState} from "../../../../../shared/store/reducers";
18 import {MessageBoxData} from "../../../../../shared/components/messageBox/messageBox.data";
19 import {MessageBoxService} from "../../../../../shared/components/messageBox/messageBox.service";
20 import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service";
21 import {IframeService} from "../../../../../shared/utils/iframe.service";
22 import {
23   deleteActionVfModuleInstance,
24   removeVfModuleInstance,
25   undoDeleteVfModuleInstance,
26   updateVFModulePosition
27 } from "../../../../../shared/storeUtil/utils/vfModule/vfModule.actions";
28 import {ComponentInfoService} from "../../../component-info/component-info.service";
29 import {ComponentInfoModel, ComponentInfoType} from "../../../component-info/component-info-model";
30 import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
31
32 export class VFModuleModelInfo implements ILevelNodeInfo {
33   constructor(private _dynamicInputsService: DynamicInputsService,
34               private _sharedTreeService: SharedTreeService,
35               private _dialogService: DialogService,
36               private _vfModulePopupService: VfModulePopuopService,
37               private _iframeService: IframeService,
38               private _store: NgRedux<AppState>,
39               private _componentInfoService: ComponentInfoService) {
40   }
41
42   name: string = 'vfModules';
43   type: string = 'Module';
44   typeName: string = 'M';
45
46   /***********************************************************
47    * return if user should provide instance name or not.
48    *        get info from parent (VNF)
49    * @param currentModel - current Model object
50    * @param parentModel - current parent Model object
51    ************************************************************/
52   isEcompGeneratedNaming(currentModel, parentModel): boolean {
53     const ecompGeneratedNaming = !_.isNil(parentModel.properties) ? parentModel.properties.ecomp_generated_naming : undefined;
54     return ecompGeneratedNaming === "true";
55   }
56
57   /***********************************************************
58    * return model dynamic inputs
59    * @param currentModel - current Model object
60    ************************************************************/
61   updateDynamicInputsDataFromModel = (currentModel): any => {
62     let displayInputs = _.isNil(currentModel) ? [] : currentModel.inputs;
63     return _.isEmpty(displayInputs) ? [] : this._dynamicInputsService.getArbitraryInputs(displayInputs);
64   };
65
66   /***********************************************************
67    * return vfModule model
68    * @param vfModuleModelId - current Model id
69    * @param instance
70    * @param serviceHierarchy - serviceHierarchy
71    ************************************************************/
72   getModel = (vfModuleModelId: string, instance, serviceHierarchy): any => {
73     if (!_.isNil(serviceHierarchy)) {
74       if (!_.isNil(serviceHierarchy[this.name]) && !_.isNil(serviceHierarchy[this.name][vfModuleModelId])) {
75         return serviceHierarchy[this.name][vfModuleModelId];
76       }
77     }
78     return {};
79   };
80
81   createNode(instance: VfModuleInstance, currentModel: VfModule, parentModel: VNFModel, modelName: string, index: number): VfModuleTreeNode {
82     let dynamicModelName = Object.keys(instance)[index];
83     instance = instance[Object.keys(instance)[index]];
84     const isEcompGeneratedNaming: boolean = this.isEcompGeneratedNaming(currentModel, parentModel);
85
86     const dynamicInputs = this.updateDynamicInputsDataFromModel(currentModel);
87     let newVfModule: VfModuleTreeNode = new VfModuleTreeNode(instance, currentModel, modelName, dynamicInputs, isEcompGeneratedNaming, dynamicModelName);
88
89     newVfModule.missingData = this._sharedTreeService.hasMissingData(instance, newVfModule.dynamicInputs, isEcompGeneratedNaming, []);
90     newVfModule.typeName = this.typeName;
91     newVfModule.menuActions = this.getMenuAction(<any>newVfModule, currentModel.uuid);
92     newVfModule.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
93     newVfModule.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage: "";
94
95     newVfModule = this._sharedTreeService.addingStatusProperty(newVfModule);
96     return newVfModule;
97   }
98
99   createInstanceTreeNode(instance: VfModuleInstance, currentModel: VfModule, parentModel: VNFModel, modelName: string): VfModuleTreeNode | VfModuleTreeNode[] {
100     let numberOfChilds = Object.keys(instance).length;
101     if (numberOfChilds > 1) {
102       let result: VfModuleTreeNode[] = [];
103       for (let i = 0; i < numberOfChilds; i++) {
104         result.push(this.createNode(instance, currentModel, parentModel, modelName, i));
105       }
106       return result;
107     } else {
108       return this.createNode(instance, currentModel, parentModel, modelName, 0);
109     }
110   }
111
112   /***********************************************************
113    * return next level object (null because is last level)
114    ************************************************************/
115   getNextLevelObject(): any {
116     return null;
117   }
118
119   getTooltip = (): string => 'VFmodule';
120
121   getType = (): string => 'VFmodule';
122
123   /***********************************************************
124    * return if instance has missing data
125    * @param instance - vnf instance
126    * @param dynamicInputs
127    * @param isEcompGeneratedNaming
128    ************************************************************/
129   hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean): boolean {
130     return this._sharedTreeService.hasMissingData(instance, dynamicInputs, isEcompGeneratedNaming, []);
131   }
132
133
134   /***********************************************************
135    * return if instance has missing data
136    * @param node - VFModule node
137    * @param serviceModelId - current service id
138    ************************************************************/
139   onClickAdd(node: ITreeNode, serviceModelId: string): void {
140     const vnfStoreKey = this._sharedTreeService.getSelectedVNF() || this.getDefaultVNF(node.parent, serviceModelId);
141     if (vnfStoreKey) {
142       this._dialogService.addDialog(GenericFormPopupComponent, {
143         type: PopupType.VF_MODULE,
144         uuidData: <any>{
145           serviceId: serviceModelId,
146           modelName: node.data.name,
147           vFModuleStoreKey: null,
148           vnfStoreKey: vnfStoreKey,
149           modelId: node.data.modelId,
150           type: node.data.type,
151           popupService: this._vfModulePopupService
152         },
153         node: node,
154         isUpdateMode: false
155       });
156     } else {
157       let messageBoxData: MessageBoxData = new MessageBoxData(
158         "Select a parent",  // modal title
159         "There are multiple instances on the right side that can contain this vf-module Please select the VNF instance, to add this vf-module to, on the right side and then click the + sign",
160         <any>"warning",
161         <any>"md",
162         [
163           {text: "Close", size: "medium", closeModal: true}
164         ]);
165       MessageBoxService.openModal.next(messageBoxData);
166     }
167   }
168
169   getDefaultVNF(node: ITreeNode, serviceModelId: string): string {
170     let keys = _.keys(_.pickBy(this._store.getState().service.serviceInstance[serviceModelId].vnfs, vnf => {
171       return (vnf.originalName == node.data.name);
172     }));
173     return keys.length === 1 ? this._store.getState().service.serviceInstance[serviceModelId].vnfs[keys[0]].vnfStoreKey : null;
174   }
175
176   /***********************************************************
177    * return number of existing instances (in all VNF's)
178    * @param node - VfModule node
179    * @param serviceModelId - current service id
180    ************************************************************/
181   getNodeCount(node: ITreeNode, serviceModelId: string): number {
182     let count: number = 0;
183     if (!_.isNil(this._store.getState().service.serviceInstance) && !_.isNil(this._store.getState().service.serviceInstance[serviceModelId])) {
184       const vnfs = this._store.getState().service.serviceInstance[serviceModelId].vnfs;
185
186       for (let vnfKey in vnfs) {
187         count += this.countNumberOfVFModule(vnfs[vnfKey], node);
188       }
189       return count;
190     }
191     return count;
192   }
193
194
195   countNumberOfVFModule(vnf, node): number {
196     let count = 0;
197     for (let vfModuleKey in vnf['vfModules']) {
198       for (let vfModule in vnf['vfModules'][vfModuleKey]) {
199         if (vnf['vfModules'][vfModuleKey][vfModule]['modelInfo'].modelCustomizationId === node.data.modelUniqueId) {
200           const vfModuleObj = vnf['vfModules'][vfModuleKey][vfModule];
201           if (!(!_.isNil(vfModuleObj) && !_.isNil(vfModuleObj.action) && vfModuleObj.action.split('_').pop() === 'Delete')) count++;
202         }
203       }
204     }
205     return count;
206   }
207
208   getCountVFModuleOfSelectedVNF(node: ITreeNode, vnfStoreKey: string, serviceModelId: string): number {
209     let count: number = 0;
210     if (!_.isNil(this._store.getState().service.serviceInstance) && !_.isNil(this._store.getState().service.serviceInstance[serviceModelId])) {
211       const vnfs = this._store.getState().service.serviceInstance[serviceModelId].vnfs;
212
213       for (let vnfKey in vnfs) {
214         count += this.countNumberOfVFModule(vnfs[vnfKey], node);
215       }
216       return count;
217     }
218     return count;
219   }
220
221
222   /***********************************************************
223    * should show node icon
224    * @param node - current ITrees node
225    * @param serviceModelId - service id
226    ************************************************************/
227   showNodeIcons(node: ITreeNode, serviceModelId: string): AvailableNodeIcons {
228     const selectedVNF: string = this._sharedTreeService.getSelectedVNF();
229     if (selectedVNF) {
230       return this.showVFModuleOnSelectedVNF(node, selectedVNF, serviceModelId);
231     } else {
232       const optionalSelected = this.getOptionalVNFs(serviceModelId, node.parent.data.name);
233       if (optionalSelected.length === 1) {
234         return this.showVFModuleOnSelectedVNF(node, optionalSelected[0].vnfStoreKey, serviceModelId);
235       } else {
236         return new AvailableNodeIcons(false, false);
237       }
238     }
239   }
240
241
242   showVFModuleOnSelectedVNF(node: ITreeNode, selectedVNF: string, serviceModelId: string): AvailableNodeIcons {
243
244     if (!_.isNil(this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF]) && node.parent.data.name === this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF].originalName) {
245       const existingVFModules = this.getCountVFModuleOfSelectedVNF(node, selectedVNF, serviceModelId);
246       const reachedLimit = this.isVFModuleReachedLimit(node, this._store.getState().service.serviceHierarchy, serviceModelId, existingVFModules);
247       const showAddIcon = this._sharedTreeService.shouldShowAddIcon()&& !reachedLimit;
248       return new AvailableNodeIcons(showAddIcon, reachedLimit);
249     }
250     return new AvailableNodeIcons(false, false);
251
252   }
253
254   getOptionalVNFs(serviceUUID: string, vnfOriginalModelName: string): any[] {
255     let result = [];
256     if (!_.isNil(this._store.getState().service.serviceInstance) && !_.isNil(this._store.getState().service.serviceInstance[serviceUUID])) {
257       const serviceVNFsInstances = this._store.getState().service.serviceInstance[serviceUUID].vnfs;
258       for (let vnfKey in serviceVNFsInstances) {
259         if (serviceVNFsInstances[vnfKey].originalName === vnfOriginalModelName) {
260           serviceVNFsInstances[vnfKey].vnfStoreKey = vnfKey;
261           result.push(serviceVNFsInstances[vnfKey]);
262         }
263       }
264     }
265     return result;
266   }
267
268
269   /************************************************
270    return number of instances with action Delete
271    @type: vnfs networks, vngGroups (only vfModule)
272    @node : node model from the left tree
273    ************************************************/
274   getExistingInstancesWithDeleteMode(node, serviceModelId: string, selectedVNF: string): number {
275     const existingInstances = this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF].vfModules;
276     let counter = 0;
277     const modelUuid = node.data.uuid;
278
279     if (!_.isNil(existingInstances)) {
280       for (let instanceKey in existingInstances) {
281         let size = Object.keys(existingInstances[instanceKey]).length;
282         for (let i = 0; i < size; i++) {
283           let vfModuleDynamicKey = Object.keys(existingInstances[instanceKey])[i];
284           if (!_.isNil(existingInstances[instanceKey][vfModuleDynamicKey].action)) {
285             if (existingInstances[instanceKey][vfModuleDynamicKey]['uuid'] === modelUuid && existingInstances[instanceKey][vfModuleDynamicKey].action.split('_').pop() === 'Delete') {
286               counter++;
287             }
288           }
289         }
290
291       }
292     }
293     return counter;
294   }
295
296   isVFModuleReachedLimit(node: any, serviceHierarchy: any, serviceModelId: string, currentNodeCount: number): boolean {
297     let maxNodes: number = 1;
298     let vnfModules = serviceHierarchy[serviceModelId].vfModules;
299     if (vnfModules[node.data.name]) {
300       maxNodes = vnfModules[node.data.name].properties.maxCountInstances || 1;
301     }
302     return !(maxNodes > currentNodeCount);
303
304   }
305
306   getMenuAction(node: ITreeNode, serviceModelId: string): { [methodName: string]: { method: Function, visible: Function, enable: Function } } {
307     return {
308       edit: {
309         method: (node, serviceModelId) => {
310           this._iframeService.addClassOpenModal('content');
311           this._dialogService.addDialog(GenericFormPopupComponent, {
312             type: PopupType.VF_MODULE,
313             uuidData: <any>{
314               serviceId: serviceModelId,
315               modelName: node.data.modelName,
316               vFModuleStoreKey: node.data.dynamicModelName,
317               vnfStoreKey: node.parent.data.vnfStoreKey,
318               modelId: node.data.modelId,
319               type: node.data.type,
320               popupService: this._vfModulePopupService
321             },
322             node: node,
323             isUpdateMode: true
324           });
325         },
326         visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
327         enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
328       },
329       showAuditInfo: {
330         method: (node, serviceModelId) => {
331           let instance = this._store.getState().service.serviceInstance[serviceModelId].vnfs[node.parent.data.vnfStoreKey].vfModules[node.data.modelName][node.data.modelVersionId];
332           this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VFMODULE', this);
333         },
334         visible: (node) => this._sharedTreeService.shouldShowAuditInfo(node),
335         enable: (node) => this._sharedTreeService.shouldShowAuditInfo(node)
336       },
337       remove: {
338         method: (node, serviceModelId) => this._store.dispatch(removeVfModuleInstance(node.data.modelName, serviceModelId, node.parent.data.modelName, node.parent.data.vnfStoreKey, node.data.dynamicModelName)),
339         visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
340         enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
341       },
342       delete: {
343         method: (node, serviceModelId) => {
344           this._store.dispatch(deleteActionVfModuleInstance(node.data.dynamicModelName, node.parent.data.vnfStoreKey, serviceModelId))
345         },
346         visible: (node) => this._sharedTreeService.shouldShowDelete(node),
347         enable: (node) => this._sharedTreeService.shouldShowDelete(node)
348       },
349       undoDelete: {
350         method: (node, serviceModelId) => {
351           this._store.dispatch(undoDeleteVfModuleInstance(node.data.dynamicModelName, node.parent.data.vnfStoreKey, serviceModelId))
352         },
353         visible: (node) => this._sharedTreeService.shouldShowUndoDelete(node),
354         enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && this._sharedTreeService.shouldShowDelete(node.parent) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
355       }
356     };
357
358
359   }
360
361   updatePosition(that , node, instanceId, parentStoreKey): void {
362     that.store.dispatch(updateVFModulePosition(node, instanceId, parentStoreKey));
363   }
364
365
366   getNodePosition(instance, deepDynamicName): number {
367     return (!_.isNil(instance) && !_.isNil(instance[deepDynamicName])) ? instance[deepDynamicName].position : null;
368   }
369
370   onSelectedNode(node: ITreeNode): void {
371   }
372
373   getInfoForVFModule(model, instance): ComponentInfoModel {
374     let modelInfoItems: ModelInformationItem[] = [];
375     if (model && !_.isNil(model.properties))
376     {
377       modelInfoItems = [
378         ModelInformationItem.createInstance("Base Module", model.properties.baseModule),
379         ModelInformationItem.createInstance("Min Instances", model.properties.minCountInstances),
380         ModelInformationItem.createInstance("Max Instances", model.properties.maxCountInstances),
381         ModelInformationItem.createInstance("Initial Instances Count", model.properties.initialCount)
382       ];
383     }
384     return this._componentInfoService.addGeneralInfoItems(modelInfoItems, ComponentInfoType.VFMODULE, model, instance);
385   }
386
387
388 }