2447a063c6bd3f390921a5dac79b2c5d86942441
[vid.git] / vid-webpack-master / src / app / drawingBoard / service-planning / objectsToTree / models / vnfGrouping / vnfGrouping.model.info.ts
1 import {ILevelNodeInfo} from "../basic.model.info";
2 import {DynamicInputsService} from "../../dynamicInputs.service";
3 import {ITreeNode} from "angular-tree-component/dist/defs/api";
4 import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service";
5 import {VnfGroupModel} from "../../../../../shared/models/vnfGroupModel";
6 import {VnfGroupTreeNode} from "../../../../../shared/models/vnfGroupTreeNode";
7 import {SharedTreeService} from "../../shared.tree.service";
8 import {VnfGroupPopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vnfGroup/vnfGroup.popup.service";
9 import {
10   GenericFormPopupComponent,
11   PopupType
12 } from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
13 import {DialogService} from 'ng2-bootstrap-modal';
14 import {AppState} from "../../../../../shared/store/reducers";
15 import {NgRedux} from "@angular-redux/store";
16 import {changeInstanceCounter, removeInstance} from "../../../../../shared/storeUtil/utils/general/general.actions";
17 import {IframeService} from "../../../../../shared/utils/iframe.service";
18 import {
19   deleteActionVnfGroupInstance,
20   undoDeleteActionVnfGroupInstance
21 } from "../../../../../shared/storeUtil/utils/vnfGroup/vnfGroup.actions";
22 import {RelatedVnfMemberInfoModel} from "../relatedVnfMember/relatedVnfMember.info.model";
23 import {SearchElementsModalComponent} from "../../../../../shared/components/searchMembersModal/search-elements-modal.component";
24 import * as _ from "lodash";
25 import {MessageBoxData} from "../../../../../shared/components/messageBox/messageBox.data";
26 import {MessageBoxService} from "../../../../../shared/components/messageBox/messageBox.service";
27 import {ComponentInfoType} from "../../../component-info/component-info-model";
28 import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
29 import {Level1Instance} from "../../../../../shared/models/level1Instance";
30 import {AaiService} from "../../../../../shared/services/aaiService/aai.service";
31 import {Observable} from "rxjs";
32 import {createRelatedVnfMemberInstance} from "../../../../../shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.actions";
33 import {
34   ITableContent,
35   SearchFieldItemType
36 } from "../../../../../shared/components/searchMembersModal/members-table/element-table-row.model";
37 import {CustomTableColumnDefinition} from "../../../../../shared/components/searchMembersModal/members-table/elements-table.component";
38
39 export class VnfGroupingModelInfo implements ILevelNodeInfo {
40   constructor(private _dynamicInputsService: DynamicInputsService,
41               private _sharedTreeService: SharedTreeService,
42               private _dialogService: DialogService,
43               private _vnfGroupPopupService: VnfGroupPopupService,
44               private _iframeService: IframeService,
45               private _aaiService: AaiService,
46               private _store: NgRedux<AppState>) {
47   }
48
49   name: string = 'vnfGroups';
50   type: string = 'VnfGroup';
51   typeName: string = 'G';
52   childNames: string[] = ['vnfs'];
53   componentInfoType = ComponentInfoType.VNFGROUP;
54   limitMembers: number;
55
56   /***********************************************************
57    * return if user should provide instance name or not.
58    *        get info from parent (VNF)
59    * @param currentModel - current Model object
60    ************************************************************/
61   isEcompGeneratedNaming(currentModel): boolean {
62     const ecompGeneratedNaming = currentModel.properties.ecomp_generated_naming;
63     return ecompGeneratedNaming === "true";
64   }
65
66   /***********************************************************
67    * return model dynamic inputs
68    * @param currentModel - current Model object
69    ************************************************************/
70   updateDynamicInputsDataFromModel = (currentModel): any => {
71     let displayInputs = currentModel.inputs;
72     return _.isEmpty(displayInputs) ? [] : this._dynamicInputsService.getArbitraryInputs(displayInputs);
73   };
74
75   /***********************************************************
76    * return next level object (null because is last level)
77    ************************************************************/
78   getNextLevelObject = (): RelatedVnfMemberInfoModel => {
79     return new RelatedVnfMemberInfoModel(this._sharedTreeService, this._dynamicInputsService, this._store);
80   };
81
82   getTooltip = (): string => 'VnfGroup';
83
84   getType = (): string => 'VnfGroup';
85
86   createInstanceTreeNode(instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any {
87     let node = new VnfGroupTreeNode(instance, model, storeKey);
88     node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
89     node = this._sharedTreeService.addingStatusProperty(node);
90     node.typeName = this.typeName;
91     node.menuActions = this.getMenuAction(<any>node, serviceModelId);
92     node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
93     node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
94     node.limitMembers = (!_.isNil(model.properties.quantity)) ? model.properties.quantity : null;
95     return node;
96   }
97
98   getModel(modelId: string, instance: any, serviceHierarchy): any {
99     const originalModelName = instance.originalName ? instance.originalName : modelId;
100     return new VnfGroupModel(this._sharedTreeService.modelByIdentifier(serviceHierarchy, this.name, originalModelName));
101   }
102
103   hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean): boolean {
104     return this._sharedTreeService.hasMissingData(instance, dynamicInputs, isEcompGeneratedNaming, []);
105   }
106
107   onClickAdd(node: ITreeNode, serviceModelId: string): void {
108     this._dialogService.addDialog(GenericFormPopupComponent, {
109       type: PopupType.VNF_GROUP,
110       uuidData: <any>{
111         serviceId: serviceModelId,
112         modelName: node.data.name,
113         vnfGroupStoreKey: null,
114         modelId: node.data.modelVersionId,
115         type: node.data.type,
116         popupService: this._vnfGroupPopupService
117       },
118       node: node,
119       isUpdateMode: false
120     });
121   }
122
123   getNodeCount(node: ITreeNode, serviceModelId: string): number {
124     let map = null;
125     if (!_.isNil(this._store.getState().service.serviceInstance[serviceModelId])) {
126       map = this._store.getState().service.serviceInstance[serviceModelId].existingVnfGroupCounterMap || 0;
127       if (!_.isNil(map)) {
128         let count = map[node.data.modelUniqueId] || 0;
129         count -= this._sharedTreeService.getExistingInstancesWithDeleteMode(node, serviceModelId, 'vnfGroups');
130         return count;
131       }
132     }
133     return 0;
134   }
135
136   /***********************************************************
137    * should show node icon
138    * @param node - current ITrees node
139    * @param serviceModelId - service id
140    ************************************************************/
141   showNodeIcons(node: ITreeNode, serviceModelId: string): AvailableNodeIcons {
142     const showAddIcon = this._sharedTreeService.shouldShowAddIcon();
143     return new AvailableNodeIcons(showAddIcon, false);
144   }
145
146   getMenuAction(node: ITreeNode, serviceModelId: string): { [methodName: string]: { method: Function, visible: Function, enable: Function } } {
147     return {
148       edit: {
149         method: (node, serviceModelId) => {
150           this._iframeService.addClassOpenModal('content');
151           this._dialogService.addDialog(GenericFormPopupComponent, {
152             type: PopupType.VNF_GROUP,
153             uuidData: <any>{
154               serviceId: serviceModelId,
155               modelName: node.data.modelName,
156               vnfGroupStoreKey: node.data.vnfGroupStoreKey,
157               modelId: node.data.modelId,
158               type: node.data.type,
159               popupService: this._vnfGroupPopupService
160             },
161             node: node,
162             isUpdateMode: true
163           });
164         },
165         visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
166         enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node)
167       },
168       remove: {
169         method: (node, serviceModelId) => {
170           if ((!_.isNil(node.data.children) && node.data.children.length === 0) || _.isNil(node.data.children)) {
171             let storeKey: string = node.data.vnfGroupStoreKey;
172             this._store.dispatch(removeInstance(node.data.vnfGroupStoreKey, serviceModelId, storeKey, node));
173             this._store.dispatch(changeInstanceCounter(node.data.modelUniqueId, serviceModelId, -1, node));
174             this._sharedTreeService.selectedVNF = null;
175           } else {
176             let messageBoxData: MessageBoxData = new MessageBoxData(
177               "Remove VNFGroup",  // modal title
178               "You are about to remove this group and all its children from this service. Are you sure you want to remove it?",
179               <any>"warning",
180               <any>"md",
181               [
182                 {
183                   text: "Remove Group",
184                   size: "large",
185                   callback: this.removeGroup.bind(this, node, serviceModelId),
186                   closeModal: true
187                 },
188                 {text: "Don’t Remove", size: "medium", closeModal: true}
189               ]);
190
191             MessageBoxService.openModal.next(messageBoxData);
192           }
193         },
194         visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
195         enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node)
196       },
197
198       addGroupMember: {
199         method: (node, serviceModelId) => {
200           let serviceHierarchy = this._store.getState().service.serviceHierarchy[serviceModelId];
201           let serviceInstance = this._store.getState().service.serviceInstance[serviceModelId];
202           let vnfGroupModel = new VnfGroupModel(serviceHierarchy['vnfGroups'][node.data.modelName]);
203           this._dialogService.addDialog(SearchElementsModalComponent, {
204               modalInformation: {
205                 type: 'VNF',
206                 serviceModelId : serviceModelId,
207                 title: 'Add members to group',
208                 description: 'Select VNF instances to associate',
209                 noElementsMsg: 'No VNFs were found that can belong to this group.',
210                 uniqObjectField: 'instanceId',
211                 topButton: {
212                   text: 'SET MEMBERS',
213                   /********************************************************************************************************************************
214                    iterate over all current elements:
215
216                    1) if element is selected then update REDUX store
217                    2) if element is not selected then delete member
218
219                    @searchElementsModalComponent - all modal information (allElementsStatusMap, vnfGroupStoreKey, serviceId)
220                    ********************************************************************************************************************************/
221
222                   action: (searchElementsModalComponent) => {
223                     let tmpMembers = searchElementsModalComponent._membersTableService.allElementsStatusMap;
224                     for (let key in tmpMembers) {
225                       if (tmpMembers[key].isSelected) {
226                         this._store.dispatch(createRelatedVnfMemberInstance(node.data.vnfGroupStoreKey, serviceModelId, tmpMembers[key]));
227                       }
228                     }
229                     searchElementsModalComponent.closeDialog();
230                   }
231                 },
232                 getElements: (): Observable<Level1Instance[]> => {
233                   return this._aaiService.getOptionalGroupMembers(serviceModelId, serviceInstance.globalSubscriberId, serviceInstance.subscriptionServiceType, (Object.values(vnfGroupModel.members))[0].sourceModelInvariant, vnfGroupModel.properties.type, vnfGroupModel.properties.role).map((result) => {
234                     return this.filterUsedVnfMembers(serviceModelId, result);
235                   });
236                 },
237                 tableHeaders : this.getTableHeaders(),
238                 tableContent: this.generateRelatedMemberTableContent(),
239                 searchFields: [{
240                   title: 'Service model name',
241                   dataTestId: 'sourceModelName',
242                   value: (Object.values(vnfGroupModel.members))[0].sourceModelName,
243                   type: SearchFieldItemType.LABEL
244                 },
245                   {
246                     title: 'Service invariant UUID',
247                     dataTestId: 'sourceModelInvariant',
248                     value: (Object.values(vnfGroupModel.members))[0].sourceModelInvariant,
249                     type: SearchFieldItemType.LABEL
250                   }]
251               }
252             }
253           );
254         },
255         visible: (node) => !_.isNil(node.data.action) ? node.data.action.split('_').pop() !== 'Delete' : true,
256         enable: (node) => !_.isNil(node.data.action) ? node.data.action.split('_').pop() !== 'Delete' : true
257       },
258       showAuditInfo: {
259         method: (node, serviceModelId) => {
260           let instance = this._store.getState().service.serviceInstance[serviceModelId].vnfGroups[node.data.vnfGroupStoreKey];
261           this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VNFGROUP', this);
262         },
263         visible: (node) => this._sharedTreeService.shouldShowAuditInfo(node),
264         enable: (node) => this._sharedTreeService.shouldShowAuditInfo(node)
265       },
266       delete: {
267         method: (node, serviceModelId) => {
268           if ((!_.isNil(node.data.children) && node.data.children.length === 0) || _.isNil(node.data.children)) {
269             this._store.dispatch(deleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
270           } else {
271             this._sharedTreeService.shouldShowDeleteInstanceWithChildrenModal(node, serviceModelId, (node, serviceModelId) => {
272               this._sharedTreeService.removeDeleteAllChild(node, serviceModelId, (node, serviceModelId) => {
273                 this._store.dispatch(deleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
274               });
275             });
276           }
277         },
278         visible: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId),
279         enable: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId)
280       },
281       undoDelete: {
282         method: (node, serviceModelId) => {
283           if ((!_.isNil(node.data.children) && node.data.children.length === 0) || _.isNil(node.data.children)) {
284             this._store.dispatch(undoDeleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
285           } else {
286             this._sharedTreeService.undoDeleteAllChild(node, serviceModelId, (node, serviceModelId) => {
287               this._store.dispatch(undoDeleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
288             });
289           }
290         },
291         visible: (node) => this._sharedTreeService.shouldShowUndoDelete(node),
292         enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
293       }
294     };
295
296
297   }
298
299
300   generateRelatedMemberTableContent(): ITableContent[] {
301     return [
302       {
303         id: 'vnfName',
304         contents: [{
305           id: ['instanceName'],
306           value: ['instanceName']
307         }, {
308           id: ['instanceId'],
309           value: ["instanceId"],
310           prefix: 'UUID: '
311         }]
312       },
313       {
314         id: 'version',
315         contents: [{
316           id: ['modelInfo', 'modelVersion'],
317           value: ['modelInfo', 'modelVersion']
318         }]
319       },
320       {
321         id: 'modelName',
322         contents: [{
323           id: ['modelInfo', 'modelName'],
324           value: ['modelInfo', 'modelName']
325         }]
326       },
327       {
328         id: 'provStatus',
329         contents: [{
330           id: ['provStatus'],
331           value: ['provStatus']
332         }]
333       },
334       {
335         id: 'serviceInstance',
336         contents: [{
337           id: ['serviceInstanceName'],
338           value: ['serviceInstanceName']
339         }, {
340           id: ['serviceInstanceId'],
341           value: ["serviceInstanceId"],
342           prefix: 'UUID: '
343         }]
344       },
345       {
346         id: 'cloudRegion',
347         contents: [{
348           id: ['lcpCloudRegionId'],
349           value: ['lcpCloudRegionId']
350         }]
351       },
352       {
353         id: 'tenantName',
354         contents: [{
355           id: ['tenantName'],
356           value: ['tenantName']
357         }]
358       }
359     ];
360   }
361
362   getTableHeaders() : CustomTableColumnDefinition[]{
363     const type : string = 'VNF';
364     return  [
365       {displayName: `${type} instance name`, key: ['instanceName']},
366       {displayName: `${type} version`, key: ['modelInfo', 'modelVersion']},
367       {displayName: `${type} model name`, key: ['modelInfo', 'modelName']},
368       {displayName: 'Prov Status', key: ['provStatus']},
369       {displayName: 'Service instance name', key: ['serviceInstanceName']},
370       {displayName: 'Cloud Region', key: ['lcpCloudRegionId']},
371       {displayName: 'Tenant Name', key: ['tenantName']}
372     ];
373   }
374
375   filterUsedVnfMembers = (serviceModelId: string, result: Level1Instance[]): Level1Instance[] => {
376     const allMembersMap = _.keyBy(result as Level1Instance[], 'instanceId');
377     const vnfGroupsData = this._store.getState().service.serviceInstance[serviceModelId].vnfGroups;
378     const vnfMembersArr = _.flatMap(vnfGroupsData).map((vnfGroup) => vnfGroup.vnfs);
379     for (let vnf of vnfMembersArr) {
380       for (let member in vnf) {
381         delete allMembersMap[member];
382       }
383     }
384     return _.flatMap(allMembersMap);
385   };
386
387   removeGroup(this, node, serviceModelId) {
388     this._store.dispatch(removeInstance(node.data.modelName, serviceModelId, node.data.vnfGroupStoreKey, node));
389     this._store.dispatch(changeInstanceCounter(node.data.modelUniqueId, serviceModelId, -1, node));
390     this._sharedTreeService.selectedVNF = null;
391   }
392
393   updatePosition(that, node, instanceId): void {
394     // TODO
395   }
396
397   getNodePosition(instance): number {
398     return !_.isNil(instance) ? instance.position : null;
399   }
400
401   getInfo(model, instance): ModelInformationItem[] {
402     return [];
403   }
404
405 }