From 18c3ce8d1e1d166d5302f9708036202b0258110e Mon Sep 17 00:00:00 2001 From: Ittay Stern Date: Thu, 26 Dec 2019 15:21:17 +0200 Subject: Fixing the issue which prevents from clicking the [+] button on templates i) Use modelUniqueName instead of obsolete originalName ii) Add RECREATE as "editable" case iii) Lift vfModules limitation in model to 3 Issue-ID: VID-724 Change-Id: I9e55142ee379f4eead3c8634f5b816d2d1db1f8e Signed-off-by: Ittay Stern --- .../available-models-tree.component.ts | 4 +- .../available-models-tree.service.ts | 12 +-- .../models/vfModule/vfModule.model.info.spec.ts | 111 ++++++--------------- .../models/vfModule/vfModule.model.info.ts | 28 ++++-- .../objectsToTree/shared.tree.service.ts | 13 ++- 5 files changed, 71 insertions(+), 97 deletions(-) (limited to 'vid-webpack-master/src') diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.component.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.component.ts index e277cb28c..13147b7e5 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.component.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.component.ts @@ -166,11 +166,11 @@ export class AvailableModelsTreeComponent { if (this._sharedTreeService.selectedVNF) { this.store.dispatch(createVFModuleInstance(vfModule, node.data.name, this.serviceModelId, null, this._sharedTreeService.selectedVNF)); DrawingBoardTreeComponent.triggerreCalculateIsDirty.next(this.serviceModelId); - } else if (this._availableModelsTreeService.getOptionalVNFs(this.serviceModelId, node.parent.data.name).length === 1) { + } else if (this._availableModelsTreeService.getOptionalVNFs(this.serviceModelId, node.parent.data.modelUniqueId).length === 1) { let existVnf = this._store.getState().service.serviceInstance[this.serviceModelId].vnfs; if(!_.isNil(existVnf)){ for(let vnfKey in existVnf){ - const modelUniqueId = existVnf[vnfKey]['modelInfo'].modelCustomizationId || existVnf[vnfKey]['modelInfo'].modelInvariantId; + const modelUniqueId = this._sharedTreeService.modelUniqueId(existVnf[vnfKey]); if(modelUniqueId === node.parent.data.id){ this.store.dispatch(createVFModuleInstance(vfModule, node.data.name, this.serviceModelId, null, vnfKey)); DrawingBoardTreeComponent.triggerreCalculateIsDirty.next(this.serviceModelId); diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.service.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.service.ts index 39a3c5070..c9a89cf6f 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.service.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/available-models-tree/available-models-tree.service.ts @@ -4,11 +4,11 @@ import {NgRedux} from "@angular-redux/store"; import {AppState} from "../../../shared/store/reducers"; import {MessageBoxData} from "../../../shared/components/messageBox/messageBox.data"; import {MessageBoxService} from "../../../shared/components/messageBox/messageBox.service"; -import * as _ from "lodash"; -import { SdcUiCommon} from "onap-ui-angular"; +import {SdcUiCommon} from "onap-ui-angular"; import {SharedTreeService} from "../objectsToTree/shared.tree.service"; import {VrfModel} from "../../../shared/models/vrfModel"; import {clearAllGenericModalhelper} from "../../../shared/storeUtil/utils/global/global.actions"; +import * as _ from "lodash"; export class AvailableNodeIcons { addIcon: boolean; @@ -25,7 +25,7 @@ export class AvailableNodeIcons { export class AvailableModelsTreeService { constructor(private _defaultDataGeneratorService: DefaultDataGeneratorService, private store: NgRedux, - public _shareTreeService : SharedTreeService) { + public _sharedTreeService : SharedTreeService) { } @@ -45,19 +45,17 @@ export class AvailableModelsTreeService { return false; } - getOptionalVNFs(serviceUUID: string, vnfOriginalModelName : string) : any[] { + getOptionalVNFs(serviceUUID: string, vnfModelUniqueId: string) : any[] { let result = []; if(!_.isNil(this.store.getState().service.serviceInstance) && !_.isNil(this.store.getState().service.serviceInstance[serviceUUID])){ const serviceVNFsInstances = this.store.getState().service.serviceInstance[serviceUUID].vnfs; for(let vnfKey in serviceVNFsInstances){ - if(serviceVNFsInstances[vnfKey].originalName === vnfOriginalModelName){ + if (this._sharedTreeService.modelUniqueId(serviceVNFsInstances[vnfKey]) === vnfModelUniqueId) { serviceVNFsInstances[vnfKey].vnfStoreKey = vnfKey; result.push(serviceVNFsInstances[vnfKey]); } } } - - return result; } diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts index 8bdab11e3..216231813 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts @@ -195,21 +195,21 @@ describe('VFModule Model Info', () => { }); test('showNodeIcons should return true, false if reachLimit of max', ()=>{ - let serviceId : string = 'servicedId'; let node = { data : { id : 'vfModuleId', - name : 'vfModuleName' + modelUniqueId : 'vfModuleCustomizationId' }, parent : { data : { id : 'vnfId', - name : 'vnfName' + modelUniqueId : 'vnfCustomizationId' } } }; jest.spyOn(_sharedTreeService, 'getSelectedVNF').mockReturnValue('vnfName'); - jest.spyOn(vfModuleModel, 'getOptionalVNFs').mockReturnValue(['vnfName']); + jest.spyOn(_sharedTreeService, 'modelUniqueId').mockReturnValue('vnfCustomizationId'); + jest.spyOn(vfModuleModel, 'getOptionalVNFs').mockReturnValue([{vnfStoreKey: 'vnfName'}]); jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ global : {}, service : { @@ -217,6 +217,9 @@ describe('VFModule Model Info', () => { 'servicedId' : { 'vnfs' : { 'vnfName' : { + modelInfo: { + modelCustomizationId: 'vnfCustomizationId' + }, 'properties' : { 'max_instances' : 1 } @@ -224,8 +227,11 @@ describe('VFModule Model Info', () => { }, 'vfModules' : { 'vfModuleName' : { + modelInfo: { + modelCustomizationId: 'vfModuleCustomizationId' + }, 'properties' : { - maxCountInstances : 1 + maxCountInstances : 2 } } } @@ -238,7 +244,6 @@ describe('VFModule Model Info', () => { }, 'vnfs' : { 'vnfName' :{ - 'originalName' : 'vnfName', 'vfModules' : { 'vfModuleName' : { @@ -256,68 +261,6 @@ describe('VFModule Model Info', () => { }); - test('showNodeIcons should return false, true if reachLimit of max', ()=>{ - let serviceId : string = 'servicedId'; - let node = { - data : { - id : 'vfModuleId', - name : 'vfModuleName' - }, - parent : { - data : { - id : 'vnfId', - name : 'vnfName' - } - } - }; - jest.spyOn(_sharedTreeService, 'getSelectedVNF').mockReturnValue('vnfName'); - jest.spyOn(vfModuleModel, 'getOptionalVNFs').mockReturnValue(['vnfName']); - jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ - global : {}, - service : { - serviceHierarchy : { - 'servicedId' : { - 'vnfs' : { - 'vnfName' : { - 'properties' : { - 'max_instances' : 1 - } - } - }, - 'vfModules' : { - 'vfModuleName' : { - 'properties' : { - maxCountInstances : 2 - } - } - } - } - }, - serviceInstance : { - 'servicedId' : { - 'existingVNFCounterMap' : { - 'vnfId' : 1 - }, - 'vnfs' : { - 'vnfName' :{ - 'originalName' : 'vnfName', - 'vfModules' : { - 'vfModuleName' : { - - } - } - } - } - } - } - } - }); - - let result = vfModuleModel.showNodeIcons(node, 'servicedId'); - expect(result).toEqual(new AvailableNodeIcons(true , false)); - }); - - test('getOptionalVNFs should instance if exist', ()=>{ let serviceId : string = 'servicedId'; jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ @@ -379,6 +322,8 @@ describe('VFModule Model Info', () => { test('getNodeCount should return number of nodes', ()=>{ let serviceId : string = 'servicedId'; + let vfModuleModelUniqueId = 'vfModuleCustomizationId'; + jest.spyOn(_sharedTreeService, 'modelUniqueId').mockReturnValue(vfModuleModelUniqueId); jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ global : {}, service : { @@ -386,6 +331,9 @@ describe('VFModule Model Info', () => { 'servicedId' : { 'vnfs' : { 'vnfName' : { + modelInfo: { + modelCustomizationId: 'vnfCustomizationId' + }, 'properties' : { 'max_instances' : 1 } @@ -393,6 +341,9 @@ describe('VFModule Model Info', () => { }, 'vfModules' : { 'vfModuleName' : { + modelInfo: { + modelCustomizationId: vfModuleModelUniqueId + }, 'properties' : { maxCountInstances : 2 } @@ -414,13 +365,13 @@ describe('VFModule Model Info', () => { 'vnfModuleName_111': { 'action': 'Create', 'modelInfo' : { - modelVersionId : 'vfModuleId' + modelCustomizationId : vfModuleModelUniqueId } }, 'vnfModuleName_111_1': { 'action': 'Create', 'modelInfo' : { - modelVersionId : 'vfModuleId' + modelCustomizationId : vfModuleModelUniqueId } } } @@ -434,13 +385,13 @@ describe('VFModule Model Info', () => { 'vnfModuleName_111': { 'action': 'Create', 'modelInfo' : { - modelVersionId : 'vfModuleId' + modelCustomizationId : vfModuleModelUniqueId } }, 'vnfModuleName_111_1': { 'action': 'Create', 'modelInfo' : { - modelVersionId : 'vfModuleId' + modelCustomizationId : vfModuleModelUniqueId } } } @@ -455,13 +406,13 @@ describe('VFModule Model Info', () => { let node = { data : { id : 'vfModuleId', - name : 'vfModuleName', + modelUniqueId: vfModuleModelUniqueId, 'action': 'Create', }, parent : { data : { id : 'vnfId', - name : 'vnfName', + modelUniqueId: 'vnfCustomizationId', 'action': 'Create', } } @@ -473,6 +424,8 @@ describe('VFModule Model Info', () => { test('getNodeCount should return number of nodes : there is selectedVNF', ()=>{ let serviceId : string = 'servicedId'; + let vfModuleModelUniqueId = 'vfModuleCustomizationId'; + jest.spyOn(_sharedTreeService, 'modelUniqueId').mockReturnValue(vfModuleModelUniqueId); jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ global : {}, service : { @@ -508,13 +461,13 @@ describe('VFModule Model Info', () => { 'vnfModuleName_111': { 'action': 'Create', 'modelInfo' : { - modelVersionId : 'vfModuleId' + modelCustomizationId : vfModuleModelUniqueId } }, 'vnfModuleName_111_1': { 'action': 'Create', 'modelInfo' : { - modelVersionId : 'vfModuleId' + modelCustomizationId : vfModuleModelUniqueId } } } @@ -528,7 +481,7 @@ describe('VFModule Model Info', () => { 'vnfModuleName_111': { 'action': 'Create', 'modelInfo' : { - modelVersionId : 'vfModuleId' + modelCustomizationId: vfModuleModelUniqueId } } } @@ -544,13 +497,13 @@ describe('VFModule Model Info', () => { let node = { data : { id : 'vfModuleId', - name : 'vfModuleName', + modelUniqueId: vfModuleModelUniqueId, 'action': 'Create', }, parent : { data : { id : 'vnfId', - name : 'vnfName_1', + modelUniqueId: 'vnfCustomizationId', 'action': 'Create', } } diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts index 73f35279f..36b5ed072 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts @@ -8,7 +8,10 @@ import {VfModuleInstance} from "../../../../../shared/models/vfModuleInstance"; import {VfModule} from "../../../../../shared/models/vfModule"; import {NgRedux} from "@angular-redux/store"; import {ITreeNode} from "angular-tree-component/dist/defs/api"; -import {GenericFormPopupComponent, PopupType} from "../../../../../shared/components/genericFormPopup/generic-form-popup.component"; +import { + GenericFormPopupComponent, + PopupType +} from "../../../../../shared/components/genericFormPopup/generic-form-popup.component"; import {DialogService} from "ng2-bootstrap-modal"; import {VfModulePopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModule/vfModule.popup.service"; import {AppState} from "../../../../../shared/store/reducers"; @@ -16,7 +19,15 @@ import {MessageBoxData} from "../../../../../shared/components/messageBox/messag import {MessageBoxService} from "../../../../../shared/components/messageBox/messageBox.service"; import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service"; import {IframeService} from "../../../../../shared/utils/iframe.service"; -import {deleteActionVfModuleInstance, deleteVFModuleField, removeVfModuleInstance, undoDeleteVfModuleInstance, undoUgradeVFModule, updateVFModulePosition, upgradeVFModule} from "../../../../../shared/storeUtil/utils/vfModule/vfModule.actions"; +import { + deleteActionVfModuleInstance, + deleteVFModuleField, + removeVfModuleInstance, + undoDeleteVfModuleInstance, + undoUgradeVFModule, + updateVFModulePosition, + upgradeVFModule +} from "../../../../../shared/storeUtil/utils/vfModule/vfModule.actions"; import {ComponentInfoService} from "../../../component-info/component-info.service"; import {ComponentInfoType} from "../../../component-info/component-info-model"; import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component"; @@ -166,7 +177,7 @@ export class VFModuleModelInfo implements ILevelNodeInfo { getDefaultVNF(node: ITreeNode, serviceModelId: string): string { let keys = _.keys(_.pickBy(this._store.getState().service.serviceInstance[serviceModelId].vnfs, vnf => { - return (vnf.originalName == node.data.name); + return (this._sharedTreeService.modelUniqueId(vnf) === node.data.modelUniqueId); })); return keys.length === 1 ? this._store.getState().service.serviceInstance[serviceModelId].vnfs[keys[0]].vnfStoreKey : null; } @@ -198,7 +209,7 @@ export class VFModuleModelInfo implements ILevelNodeInfo { let count = 0; for (let vfModuleKey in vnf['vfModules']) { for (let vfModule in vnf['vfModules'][vfModuleKey]) { - if (vnf['vfModules'][vfModuleKey][vfModule]['modelInfo'].modelCustomizationId === node.data.modelUniqueId) { + if (this._sharedTreeService.modelUniqueId(vnf['vfModules'][vfModuleKey][vfModule]) === node.data.modelUniqueId) { const vfModuleObj = vnf['vfModules'][vfModuleKey][vfModule]; if (!(!_.isNil(vfModuleObj) && !_.isNil(vfModuleObj.action) && vfModuleObj.action.split('_').pop() === 'Delete')) count++; } @@ -228,7 +239,7 @@ export class VFModuleModelInfo implements ILevelNodeInfo { if (selectedVNF) { return this.showVFModuleOnSelectedVNF(node, selectedVNF, serviceModelId); } else { - const optionalSelected = this.getOptionalVNFs(serviceModelId, node.parent.data.name); + const optionalSelected = this.getOptionalVNFs(serviceModelId, node.parent.data.modelUniqueId); if (optionalSelected.length === 1) { return this.showVFModuleOnSelectedVNF(node, optionalSelected[0].vnfStoreKey, serviceModelId); } else { @@ -239,7 +250,8 @@ export class VFModuleModelInfo implements ILevelNodeInfo { showVFModuleOnSelectedVNF(node: ITreeNode, selectedVNF: string, serviceModelId: string): AvailableNodeIcons { - if (!_.isNil(this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF]) && node.parent.data.name === this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF].originalName) { + if (!_.isNil(this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF]) + && node.parent.data.modelUniqueId === this._sharedTreeService.modelUniqueId(this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF])) { const existingVFModules = this.getCountVFModuleOfSelectedVNF(node, selectedVNF, serviceModelId); const reachedLimit = this.isVFModuleReachedLimit(node, this._store.getState().service.serviceHierarchy, serviceModelId, existingVFModules); const showAddIcon = this._sharedTreeService.shouldShowAddIcon() && !reachedLimit; @@ -249,12 +261,12 @@ export class VFModuleModelInfo implements ILevelNodeInfo { } - getOptionalVNFs(serviceUUID: string, vnfOriginalModelName: string): any[] { + getOptionalVNFs(serviceUUID: string, vnfModelUniqueId: string): any[] { let result = []; if (!_.isNil(this._store.getState().service.serviceInstance) && !_.isNil(this._store.getState().service.serviceInstance[serviceUUID])) { const serviceVNFsInstances = this._store.getState().service.serviceInstance[serviceUUID].vnfs; for (let vnfKey in serviceVNFsInstances) { - if (serviceVNFsInstances[vnfKey].originalName === vnfOriginalModelName) { + if (this._sharedTreeService.modelUniqueId(serviceVNFsInstances[vnfKey]) === vnfModelUniqueId) { serviceVNFsInstances[vnfKey].vnfStoreKey = vnfKey; result.push(serviceVNFsInstances[vnfKey]); } diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts index 7f5b6e33c..1115d1bc6 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts @@ -15,6 +15,7 @@ import {VNFMethods} from "../../../shared/storeUtil/utils/vnf/vnf.actions"; import {FeatureFlagsService, Features} from "../../../shared/services/featureFlag/feature-flags.service"; import {Utils} from "../../../shared/utils/utils"; import {Constants} from "../../../shared/utils/constants"; +import {NodeInstance} from "../../../shared/models/nodeInstance"; @Injectable() export class SharedTreeService { @@ -43,6 +44,16 @@ export class SharedTreeService { } } + /** + * Determines a consistent unique ID for a given right-tree + * node instance. + */ + modelUniqueId = (nodeInstance: NodeInstance): string => { + return _.isNil(nodeInstance.modelInfo) + ? null + : (nodeInstance.modelInfo.modelCustomizationId || nodeInstance.modelInfo.modelInvariantId); + }; + hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean, requiredFields: string[]): boolean { if (!isEcompGeneratedNaming && _.isEmpty(instance.instanceName)) { return true; @@ -239,7 +250,7 @@ export class SharedTreeService { **********************************************/ shouldShowAddIcon(): boolean{ const mode = this._store.getState().global.drawingBoardStatus; - return mode === DrawingBoardModes.EDIT || mode=== DrawingBoardModes.CREATE; + return mode === DrawingBoardModes.EDIT || mode=== DrawingBoardModes.CREATE || mode=== DrawingBoardModes.RECREATE; } -- cgit 1.2.3-korg