From f792671ae247a931f34d902e9276202b5016ef9a Mon Sep 17 00:00:00 2001 From: Ittay Stern Date: Sun, 7 Jul 2019 19:23:03 +0300 Subject: Merge from ecomp 718fd196 - Modern UI Issue-ID: VID-378 Change-Id: I2736b98426e324ec3aa233b034229ba84d99839f Signed-off-by: Ittay Stern --- .../vnfGrouping/vnfGrouping.model.info.spec.ts | 158 +++++++++++++++-- .../models/vnfGrouping/vnfGrouping.model.info.ts | 189 ++++++++++++++++++--- 2 files changed, 305 insertions(+), 42 deletions(-) (limited to 'vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping') diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.spec.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.spec.ts index 532a8fe17..802047cb9 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.spec.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.spec.ts @@ -1,5 +1,4 @@ - -import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing"; +import {HttpClientTestingModule} from "@angular/common/http/testing"; import {getTestBed, TestBed} from "@angular/core/testing"; import {MockNgRedux, NgReduxTestingModule} from "@angular-redux/store/testing"; import {VnfGroupingModelInfo} from "./vnfGrouping.model.info"; @@ -10,9 +9,11 @@ import {DialogService} from "ng2-bootstrap-modal"; import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service"; import {VnfGroupModel} from "../../../../../shared/models/vnfGroupModel"; import {IframeService} from "../../../../../shared/utils/iframe.service"; -import {ActivatedRoute} from "@angular/router"; import {RouterTestingModule} from "@angular/router/testing"; import {DrawingBoardModes} from "../../../drawing-board.modes"; +import {AaiService} from "../../../../../shared/services/aaiService/aai.service"; +import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service"; +import {ITableContent} from "../../../../../shared/components/searchMembersModal/members-table/element-table-row.model"; describe('VnfGroupingModelInfo Model Info', () => { let injector; @@ -22,6 +23,7 @@ describe('VnfGroupingModelInfo Model Info', () => { let _sharedTreeService : SharedTreeService; let _iframeService : IframeService; let vnfGroupModel: VnfGroupingModelInfo; + let _aaiService : AaiService; beforeAll(done => (async () => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule, NgReduxTestingModule, RouterTestingModule], @@ -31,13 +33,16 @@ describe('VnfGroupingModelInfo Model Info', () => { DynamicInputsService, SharedTreeService, IframeService, + AaiService, + FeatureFlagsService, MockNgRedux] }); await TestBed.compileComponents(); injector = getTestBed(); _sharedTreeService = injector.get(SharedTreeService); + _aaiService = injector.get(AaiService); - vnfGroupModel = new VnfGroupingModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _vnfGroupPopupService, _iframeService, MockNgRedux.getInstance()); + vnfGroupModel = new VnfGroupingModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _vnfGroupPopupService, _iframeService, _aaiService, MockNgRedux.getInstance()); })().then(done).catch(done.fail)); @@ -59,7 +64,6 @@ describe('VnfGroupingModelInfo Model Info', () => { expect(isEcompGeneratedNaming).toBeTruthy(); }); - test('getTooltip should return "vnfGrouping"', () => { let tooltip: string = vnfGroupModel.getTooltip(); expect(tooltip).toEqual('VnfGroup'); @@ -75,7 +79,6 @@ describe('VnfGroupingModelInfo Model Info', () => { expect(nextLevel).not.toBeNull(); }); - test('showNodeIcons should return true if not reachLimit of max', ()=>{ let serviceId : string = 'servicedId'; let node = { @@ -199,6 +202,70 @@ describe('VnfGroupingModelInfo Model Info', () => { expect(result['showAuditInfo']['method']).toHaveBeenCalledWith(node, serviceModelId); }); + + test('generateRelatedMemberTableContent', ()=> { + const tableContents: ITableContent[] = vnfGroupModel.generateRelatedMemberTableContent(); + expect(tableContents).toEqual([ + { + id: 'vnfName', + contents: [{ + id: ['instanceName'], + value: ['instanceName'] + }, { + id: ['instanceId'], + value: ["instanceId"], + prefix: 'UUID: ' + }] + }, + { + id: 'version', + contents: [{ + id: ['modelInfo', 'modelVersion'], + value: ['modelInfo', 'modelVersion'] + }] + }, + { + id: 'modelName', + contents: [{ + id: ['modelInfo', 'modelName'], + value: ['modelInfo', 'modelName'] + }] + }, + { + id: 'provStatus', + contents: [{ + id: ['provStatus'], + value: ['provStatus'] + }] + }, + { + id: 'serviceInstance', + contents: [{ + id: ['serviceInstanceName'], + value: ['serviceInstanceName'] + }, { + id: ['serviceInstanceId'], + value: ["serviceInstanceId"], + prefix: 'UUID: ' + }] + }, + { + id: 'cloudRegion', + contents: [{ + id: ['lcpCloudRegionId'], + value: ['lcpCloudRegionId'] + }] + }, + { + id: 'tenantName', + contents: [{ + id: ['tenantName'], + value: ['tenantName'] + }] + } + ]); + }); + function getServiceHierarchy(){ return { "service": { @@ -214,7 +281,7 @@ describe('VnfGroupingModelInfo Model Info', () => { "serviceEcompNaming": "false", "instantiationType": "Macro", "inputs": { - "2017488_adiodvpe0_ASN": { + "2017488_pasqualevpe0_ASN": { "type": "string", "description": "AV/PE", "entry_schema": null, @@ -245,11 +312,11 @@ describe('VnfGroupingModelInfo Model Info', () => { "type": "LOAD-GROUP" }, "members": { - "vdbe_svc_vprs_proxy 0": { + "vdorothea_svc_vprs_proxy 0": { "uuid": "65fadfa8-a0d9-443f-95ad-836cd044e26c", "invariantUuid": "f4baae0c-b3a5-4ca1-a777-afbffe7010bc", - "description": "A Proxy for Service vDBE_Svc_vPRS", - "name": "vDBE_Svc_vPRS Service Proxy", + "description": "A Proxy for Service vDOROTHEA_Svc_vPRS", + "name": "vDOROTHEA_Svc_vPRS Service Proxy", "version": "1.0", "customizationUuid": "bdb63d23-e132-4ce7-af2c-a493b4cafac9", "inputs": {}, @@ -258,12 +325,12 @@ describe('VnfGroupingModelInfo Model Info', () => { "type": "Service Proxy", "sourceModelUuid": "da7827a2-366d-4be6-8c68-a69153c61274", "sourceModelInvariant": "24632e6b-584b-4f45-80d4-fefd75fd9f14", - "sourceModelName": "vDBE_Svc_vPRS" + "sourceModelName": "vDOROTHEA_Svc_vPRS" }, - "vdbe_svc_vprs_proxy 1": { + "vdorothea_svc_vprs_proxy 1": { "uuid": "111dfa8-a0d9-443f-95ad-836cd044e26c", "invariantUuid": "111ae0c-b3a5-4ca1-a777-afbffe7010bc", - "description": "A Proxy for Service vDBE_Svc_vPRS", + "description": "A Proxy for Service vDOROTHEA_Svc_vPRS", "name": "111_Svc_vPRS Service Proxy", "version": "1.0", "customizationUuid": "1113d23-e132-4ce7-af2c-a493b4cafac9", @@ -279,7 +346,7 @@ describe('VnfGroupingModelInfo Model Info', () => { } }, "networks": {}, - "collectionResource": {}, + "collectionResources": {}, "configurations": {}, "fabricConfigurations": {}, "serviceProxies": {}, @@ -288,4 +355,67 @@ describe('VnfGroupingModelInfo Model Info', () => { "pnfs": {} } } + + function loadMockMembers(): any[] { + return [ + { + "action": "None", + "instanceName": "VNF1_INSTANCE_NAME", + "instanceId": "VNF1_INSTANCE_ID", + "orchStatus": null, + "productFamilyId": null, + "lcpCloudRegionId": "hvf23b", + "tenantId": "3e9a20a3e89e45f884e09df0cc2d2d2a", + "tenantName": "APPC-24595-T-IST-02C", + "modelInfo": { + "modelInvariantId": "vnf-instance-model-invariant-id", + "modelVersionId": "7a6ee536-f052-46fa-aa7e-2fca9d674c44", + "modelVersion": "2.0", + "modelName": "vf_vEPDG", + "modelType": "vnf" + }, + "instanceType": "VNF1_INSTANCE_TYPE", + "provStatus": null, + "inMaint": false, + "uuid": "7a6ee536-f052-46fa-aa7e-2fca9d674c44", + "originalName": null, + "legacyRegion": null, + "lineOfBusiness": null, + "platformName": null, + "trackById": "7a6ee536-f052-46fa-aa7e-2fca9d674c44:002", + "serviceInstanceId": "service-instance-id1", + "serviceInstanceName": "service-instance-name" + }, + { + "action": "None", + "instanceName": "VNF2_INSTANCE_NAME", + "instanceId": "VNF2_INSTANCE_ID", + "orchStatus": null, + "productFamilyId": null, + "lcpCloudRegionId": "hvf23b", + "tenantId": "3e9a20a3e89e45f884e09df0cc2d2d2a", + "tenantName": "APPC-24595-T-IST-02C", + "modelInfo": { + "modelInvariantId": "vnf-instance-model-invariant-id", + "modelVersionId": "eb5f56bf-5855-4e61-bd00-3e19a953bf02", + "modelVersion": "1.0", + "modelName": "vf_vEPDG", + "modelType": "vnf" + }, + "instanceType": "VNF2_INSTANCE_TYPE", + "provStatus": null, + "inMaint": true, + "uuid": "eb5f56bf-5855-4e61-bd00-3e19a953bf02", + "originalName": null, + "legacyRegion": null, + "lineOfBusiness": null, + "platformName": null, + "trackById": "eb5f56bf-5855-4e61-bd00-3e19a953bf02:003", + "serviceInstanceId": "service-instance-id2", + "serviceInstanceName": "service-instance-name" + } + ]; + } + + }); diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.ts index 7f2052a0c..148ce22c7 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnfGrouping/vnfGrouping.model.info.ts @@ -20,10 +20,21 @@ import { undoDeleteActionVnfGroupInstance } from "../../../../../shared/storeUtil/utils/vnfGroup/vnfGroup.actions"; import {RelatedVnfMemberInfoModel} from "../relatedVnfMember/relatedVnfMember.info.model"; -import {SearchMembersModalComponent} from "../../../../../shared/components/searchMembersModal/search-members-modal.component"; +import {SearchElementsModalComponent} from "../../../../../shared/components/searchMembersModal/search-elements-modal.component"; import * as _ from "lodash"; import {MessageBoxData} from "../../../../../shared/components/messageBox/messageBox.data"; import {MessageBoxService} from "../../../../../shared/components/messageBox/messageBox.service"; +import {ComponentInfoType} from "../../../component-info/component-info-model"; +import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component"; +import {Level1Instance} from "../../../../../shared/models/level1Instance"; +import {AaiService} from "../../../../../shared/services/aaiService/aai.service"; +import {Observable} from "rxjs"; +import {createRelatedVnfMemberInstance} from "../../../../../shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.actions"; +import { + ITableContent, + SearchFieldItemType +} from "../../../../../shared/components/searchMembersModal/members-table/element-table-row.model"; +import {CustomTableColumnDefinition} from "../../../../../shared/components/searchMembersModal/members-table/elements-table.component"; export class VnfGroupingModelInfo implements ILevelNodeInfo { constructor(private _dynamicInputsService: DynamicInputsService, @@ -31,15 +42,16 @@ export class VnfGroupingModelInfo implements ILevelNodeInfo { private _dialogService: DialogService, private _vnfGroupPopupService: VnfGroupPopupService, private _iframeService: IframeService, + private _aaiService: AaiService, private _store: NgRedux) { } name: string = 'vnfGroups'; type: string = 'VnfGroup'; typeName: string = 'G'; - childType: string = 'RelatedVnfMemberInfoModel'; - childName: string = 'vnfs'; - limitMembers : number; + childNames: string[] = ['vnfs']; + componentInfoType = ComponentInfoType.VNFGROUP; + limitMembers: number; /*********************************************************** * return if user should provide instance name or not. @@ -78,7 +90,7 @@ export class VnfGroupingModelInfo implements ILevelNodeInfo { node.typeName = this.typeName; node.menuActions = this.getMenuAction(node, model.uuid); node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed; - node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage: ""; + node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : ""; node.limitMembers = (!_.isNil(model.properties.quantity)) ? model.properties.quantity : null; return node; } @@ -182,29 +194,61 @@ export class VnfGroupingModelInfo implements ILevelNodeInfo { visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node), enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node) }, + addGroupMember: { method: (node, serviceModelId) => { let serviceHierarchy = this._store.getState().service.serviceHierarchy[serviceModelId]; let serviceInstance = this._store.getState().service.serviceInstance[serviceModelId]; let vnfGroupModel = new VnfGroupModel(serviceHierarchy['vnfGroups'][node.data.modelName]); - this._dialogService.addDialog(SearchMembersModalComponent, { - title: 'Add members to group', - description: 'Select VNF instances to associate', - subscriberId: serviceInstance.globalSubscriberId, - serviceType: serviceInstance.subscriptionServiceType, - vnfGroupModel: vnfGroupModel, - serviceModelId: serviceModelId, - node: node.data, - searchFields: [{ - title: 'Service model name', - dataTestId: 'sourceModelName', - value: (Object.values(vnfGroupModel.members))[0].sourceModelName - }, - { - title: 'Service invariant UUID', - dataTestId: 'sourceModelInvariant', - value: (Object.values(vnfGroupModel.members))[0].sourceModelInvariant - }] + this._dialogService.addDialog(SearchElementsModalComponent, { + modalInformation: { + type: 'VNF', + serviceModelId : serviceModelId, + title: 'Add members to group', + description: 'Select VNF instances to associate', + noElementsMsg: 'No VNFs were found that can belong to this group.', + uniqObjectField: 'instanceId', + topButton: { + text: 'SET MEMBERS', + /******************************************************************************************************************************** + iterate over all current elements: + + 1) if element is selected then update REDUX store + 2) if element is not selected then delete member + + @searchElementsModalComponent - all modal information (allElementsStatusMap, vnfGroupStoreKey, serviceId) + ********************************************************************************************************************************/ + + action: (searchElementsModalComponent) => { + let tmpMembers = searchElementsModalComponent._membersTableService.allElementsStatusMap; + for (let key in tmpMembers) { + if (tmpMembers[key].isSelected) { + this._store.dispatch(createRelatedVnfMemberInstance(node.data.vnfGroupStoreKey, serviceModelId, tmpMembers[key])); + } + } + searchElementsModalComponent.closeDialog(); + } + }, + getElements: (): Observable => { + return this._aaiService.getOptionalGroupMembers(serviceModelId, serviceInstance.globalSubscriberId, serviceInstance.subscriptionServiceType, (Object.values(vnfGroupModel.members))[0].sourceModelInvariant, vnfGroupModel.properties.type, vnfGroupModel.properties.role).map((result) => { + return this.filterUsedVnfMembers(serviceModelId, result); + }); + }, + tableHeaders : this.getTableHeaders(), + tableContent: this.generateRelatedMemberTableContent(), + searchFields: [{ + title: 'Service model name', + dataTestId: 'sourceModelName', + value: (Object.values(vnfGroupModel.members))[0].sourceModelName, + type: SearchFieldItemType.LABEL + }, + { + title: 'Service invariant UUID', + dataTestId: 'sourceModelInvariant', + value: (Object.values(vnfGroupModel.members))[0].sourceModelInvariant, + type: SearchFieldItemType.LABEL + }] + } } ); }, @@ -223,9 +267,9 @@ export class VnfGroupingModelInfo implements ILevelNodeInfo { method: (node, serviceModelId) => { if ((!_.isNil(node.data.children) && node.data.children.length === 0) || _.isNil(node.data.children)) { this._store.dispatch(deleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId)); - }else { - this._sharedTreeService.shouldShowDeleteInstanceWithChildrenModal(node, serviceModelId, (node, serviceModelId)=>{ - this._sharedTreeService.removeDeleteAllChild(node, serviceModelId, (node, serviceModelId)=>{ + } else { + this._sharedTreeService.shouldShowDeleteInstanceWithChildrenModal(node, serviceModelId, (node, serviceModelId) => { + this._sharedTreeService.removeDeleteAllChild(node, serviceModelId, (node, serviceModelId) => { this._store.dispatch(deleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId)); }); }); @@ -252,13 +296,101 @@ export class VnfGroupingModelInfo implements ILevelNodeInfo { } + + generateRelatedMemberTableContent(): ITableContent[] { + return [ + { + id: 'vnfName', + contents: [{ + id: ['instanceName'], + value: ['instanceName'] + }, { + id: ['instanceId'], + value: ["instanceId"], + prefix: 'UUID: ' + }] + }, + { + id: 'version', + contents: [{ + id: ['modelInfo', 'modelVersion'], + value: ['modelInfo', 'modelVersion'] + }] + }, + { + id: 'modelName', + contents: [{ + id: ['modelInfo', 'modelName'], + value: ['modelInfo', 'modelName'] + }] + }, + { + id: 'provStatus', + contents: [{ + id: ['provStatus'], + value: ['provStatus'] + }] + }, + { + id: 'serviceInstance', + contents: [{ + id: ['serviceInstanceName'], + value: ['serviceInstanceName'] + }, { + id: ['serviceInstanceId'], + value: ["serviceInstanceId"], + prefix: 'UUID: ' + }] + }, + { + id: 'cloudRegion', + contents: [{ + id: ['lcpCloudRegionId'], + value: ['lcpCloudRegionId'] + }] + }, + { + id: 'tenantName', + contents: [{ + id: ['tenantName'], + value: ['tenantName'] + }] + } + ]; + } + + getTableHeaders() : CustomTableColumnDefinition[]{ + const type : string = 'VNF'; + return [ + {displayName: `${type} instance name`, key: ['instanceName']}, + {displayName: `${type} version`, key: ['modelInfo', 'modelVersion']}, + {displayName: `${type} model name`, key: ['modelInfo', 'modelName']}, + {displayName: 'Prov Status', key: ['provStatus']}, + {displayName: 'Service instance name', key: ['serviceInstanceName']}, + {displayName: 'Cloud Region', key: ['lcpCloudRegionId']}, + {displayName: 'Tenant Name', key: ['tenantName']} + ]; + } + + filterUsedVnfMembers = (serviceModelId: string, result: Level1Instance[]): Level1Instance[] => { + const allMembersMap = _.keyBy(result as Level1Instance[], 'instanceId'); + const vnfGroupsData = this._store.getState().service.serviceInstance[serviceModelId].vnfGroups; + const vnfMembersArr = _.flatMap(vnfGroupsData).map((vnfGroup) => vnfGroup.vnfs); + for (let vnf of vnfMembersArr) { + for (let member in vnf) { + delete allMembersMap[member]; + } + } + return _.flatMap(allMembersMap); + }; + removeGroup(this, node, serviceModelId) { this._store.dispatch(removeInstance(node.data.modelName, serviceModelId, node.data.vnfGroupStoreKey, node)); this._store.dispatch(changeInstanceCounter(node.data.modelUniqueId, serviceModelId, -1, node)); this._sharedTreeService.selectedVNF = null; } - updatePosition(that , node, instanceId): void { + updatePosition(that, node, instanceId): void { // TODO } @@ -266,7 +398,8 @@ export class VnfGroupingModelInfo implements ILevelNodeInfo { return !_.isNil(instance) ? instance.position : null; } - onSelectedNode(node: ITreeNode): void { + getInfo(model, instance): ModelInformationItem[] { + return []; } } -- cgit 1.2.3-korg