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 --- .../members-table/element-table-row.model.ts | 88 ++++++ .../members-table/elements-table.component.html | 71 +++++ .../members-table/elements-table.component.ts | 144 ++++++++++ .../members-table/elements-table.service.spec.ts | 295 +++++++++++++++++++++ .../members-table/elements-table.service.ts | 187 +++++++++++++ .../members-table/member-table-row.model.ts | 6 - .../members-table/members-table.component.html | 75 ------ .../members-table/members-table.component.scss | 66 +++-- .../members-table/members-table.component.ts | 57 ---- .../members-table/members-table.service.spec.ts | 270 ------------------- .../members-table/members-table.service.ts | 153 ----------- .../search-elements-modal.component.html | 64 +++++ .../search-elements-modal.component.scss | 115 ++++++++ .../search-elements-modal.component.ts | 91 +++++++ .../search-members-modal.component.html | 35 --- .../search-members-modal.component.scss | 89 ------- .../search-members-modal.component.ts | 82 ------ 17 files changed, 1100 insertions(+), 788 deletions(-) create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/element-table-row.model.ts create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.html create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.ts create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.spec.ts create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.ts delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/member-table-row.model.ts delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.html delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.ts delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.spec.ts delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.ts create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.html create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.scss create mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.ts delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.html delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.scss delete mode 100644 vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.ts (limited to 'vid-webpack-master/src/app/shared/components/searchMembersModal') diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/element-table-row.model.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/element-table-row.model.ts new file mode 100644 index 000000000..250e2c1fa --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/element-table-row.model.ts @@ -0,0 +1,88 @@ +import {VnfMember} from "../../../models/VnfMember"; +import {Observable} from "rxjs"; +import {CustomTableColumnDefinition} from "./elements-table.component"; + +export class ElementTableRowModel extends VnfMember { + isSelected: boolean = false; +} + + +/******************************************************************************************************************************* + ModalInformation + * @type: popup type (VPN, NETWORK, VNFGROUP) + * @title: popup title + * @description: popup upper message + * @topButtonText: (optional) + * @text: button text + * @action: button action + * @backAction : arrow back button action (can close the modal/move to next step) + * @uniqObjectField: uniq object field that we can find in O(1) + * @maxSelectRow: max number of row that user can select (default = no limit)(optional) + * @getElements: function that should return Observable of collection of elements to show in the table + * @noElementsMsg : when there are no element some message should shown + * @searchFields : extra information in the left section + * @criteria: extra criteria on table content (optional) + * @tableHeaders : table headers + * @tableContent: table td's information. + + ******************************************************************************************************************************/ + +export class ModalInformation { + type : string; + currentCriteriaInfo? : Object; + title ?: string; + description ?: string; + topButton?: { + text ?: string, + action ?: (...args) => any + }; + searchButton?: { + text ?: string, + action ?: (...args)=> any + }; + backAction? : (...args) => any; + uniqObjectField : string; + maxSelectRow ?: number; + getElements : (...args) => Observable; + noElementsMsg : string; + searchFields: ISearchField[]; + criteria ?: ICriteria[]; + tableHeaders : CustomTableColumnDefinition[]; + tableContent : ITableContent[]; + serviceModelId: string; +} + + +export interface ISearchField { + title: string; + value: any; + dataTestId: string; + type : string; +} + + +export interface ICriteria { + label: string; + defaultValue: any; + onInit?: (...args) => Observable; + onChange? : (...arg) => void; + type : string; + dataTestId : string; + isRequired ?: boolean; + currentValue ?: any; +} + + +export interface ITableContent { + id : string; + contents : {id : string[], value : string[], prefix ?: string, type? : string}[]; +} + +export enum SearchFieldItemType { + LABEL = 'LABEL', + DROPDOWN = 'DROPDOWN' +} + + + + diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.html b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.html new file mode 100644 index 000000000..036a1240f --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.html @@ -0,0 +1,71 @@ +
+
+ {{modalInformation.description}} +
+ {{membersTableService.numberOfNotHideRows}} {{modalInformation.type}}s match your criteria | + {{membersTableService.numberOfSelectedRows}} {{modalInformation.type}}{{membersTableService.numberOfSelectedRows>1?'s':'' }} selected +
+
+ +
+ + +
+
+ + + + + + + + + + + + + + + +
+ + {{header.displayName}}
+ +
+ +
+ + + + +
+
{{modalInformation?.noElementsMsg}}
+ + diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.ts new file mode 100644 index 000000000..485a63c43 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.ts @@ -0,0 +1,144 @@ +import {Component, Input, OnChanges, Output, SimpleChanges, EventEmitter} from '@angular/core'; +import {ElementsTableService} from "./elements-table.service"; +import {ModalInformation} from "./element-table-row.model"; +import * as _ from 'lodash'; +import {Level1Instance} from "../../../models/level1Instance"; +import {NgRedux} from "@angular-redux/store"; +import {AppState} from "../../../store/reducers"; +import { + deleteGenericModalhelper, + deleteGenericModalTableDataHelper +} from "../../../storeUtil/utils/global/global.actions"; + +export class CustomTableColumnDefinition { + public displayName = ''; + public key : any = ''; + public type? = 'text'; + public filter? = ''; +} + +@Component({ + selector: 'app-members-table', + templateUrl: './elements-table.component.html', + styleUrls: ['./members-table.component.scss'] +}) + +export class ElementsTableComponent implements OnChanges{ + filterValue: string = null; + allMemberStatusMap = null; + membersTableService : ElementsTableService; + headers: CustomTableColumnDefinition[] = []; + searchQuery = null; + + @Input() modalInformation : ModalInformation; + @Input() data: Level1Instance[]; + @Output() selectedMembersAmountChange : EventEmitter = new EventEmitter(); + constructor(private _membersTableService : ElementsTableService, private _store : NgRedux){ + this.membersTableService = this._membersTableService; + } + + ngOnChanges(changes: SimpleChanges): void { + if(_.isNil(this.data)){ + this._membersTableService.resetAll(this.modalInformation.uniqObjectField, this.modalInformation.maxSelectRow); + }else { + ElementsTableService.uniqObjectField = this.modalInformation.uniqObjectField; + this.headers = this.modalInformation.tableHeaders; + const genericModalHelper = this._store.getState().global.genericModalHelper; + if(!_.isNil(genericModalHelper) && !_.isNil(genericModalHelper[`${this.modalInformation.type}_TABLE_DATA`]) && !_.isNil(genericModalHelper[`selected${this.modalInformation.type}`])){ + this.updateTablWithDefaultData(this._store.getState().global.genericModalHelper[`${this.modalInformation.type}_TABLE_DATA`]); + }else { + this.modalInformation.getElements().subscribe((res)=>{ + this.updateTablWithDefaultData(res); + }); + } + } + } + + updateTablWithDefaultData(tableData) : void{ + this._membersTableService.allElementsStatusMap = this._membersTableService.generateAllMembersStatus(tableData); + this._membersTableService.filteredMembers = this._membersTableService.sortElementsByName(tableData, "instanceName"); + this._membersTableService.updateAmountsAndCheckAll(this.modalInformation.uniqObjectField, this.modalInformation, this.modalInformation.maxSelectRow); + this.updateDefaultSelectedRows(); + } + + search(searchStr: string): void { + this.filterValue = searchStr; + this._membersTableService.filterMembers(this.filterValue, this.modalInformation.type); + } + + selectItem(item , maxNumberOfRows : number) : void { + if (maxNumberOfRows === 1) { + for (let currentItem in this.membersTableService.allElementsStatusMap) { + if (this.membersTableService.allElementsStatusMap[currentItem].isSelected) { + this.membersTableService.allElementsStatusMap[currentItem].isSelected = false; + this.membersTableService.allElementsStatusMap[item[this.membersTableService.staticUniqObjectField]].isSelected = !this.membersTableService.allElementsStatusMap[item[this.membersTableService.staticUniqObjectField]].isSelected; + return; + } + } + this.membersTableService.allElementsStatusMap[item[this.membersTableService.staticUniqObjectField]].isSelected = !this.membersTableService.allElementsStatusMap[item[this.membersTableService.staticUniqObjectField]].isSelected; + } + } + + updateDefaultSelectedRows(): void { + if(this._store.getState().global.genericModalHelper && this._store.getState().global.genericModalHelper[`selected${this.modalInformation.type}`]){ + const selectedIds = this._store.getState().global.genericModalHelper[`selected${this.modalInformation.type}`]; + for(const id in selectedIds){ + if(!_.isNil(this._membersTableService.allElementsStatusMap[id])){ + this._membersTableService.allElementsStatusMap[id].isSelected = true; + } + } + this._membersTableService.updateAmountsAndCheckAll(this.modalInformation.uniqObjectField, this.modalInformation, this.modalInformation.maxSelectRow); + this.selectedMembersAmountChange.emit(this._membersTableService.numberOfSelectedRows); + } + } + + changeAllCheckboxStatus(status: boolean) : void { + this._membersTableService.changeAllCheckboxStatus(status); + this.selectedMembersAmountChange.emit(this._membersTableService.numberOfSelectedRows); + } + + + changeCheckboxStatus(vnfInstanceId: string) : void { + if (this.modalInformation.maxSelectRow === 1) { + for (let currentItem in this.membersTableService.allElementsStatusMap) { + if (this.membersTableService.allElementsStatusMap[currentItem].isSelected) { + this.membersTableService.allElementsStatusMap[currentItem].isSelected = false; + this._store.dispatch(deleteGenericModalhelper(`selected${this.modalInformation.type}`, this.membersTableService.allElementsStatusMap[currentItem][this.modalInformation.uniqObjectField])); + this._store.dispatch(deleteGenericModalTableDataHelper(`${this.modalInformation.type}_TABLE_DATA`)); + } + } + } + this._membersTableService.changeCheckboxStatus(vnfInstanceId, this.data); + this.selectedMembersAmountChange.emit(this._membersTableService.numberOfSelectedRows); + } + + + getTdInformationItemId(data : {id : string[], value : string[], prefix ?: string}, item) : string { + let result = item; + for(const idVal of data.id){ + if(_.isNil(result)) return null; + result = result[idVal]; + } + return result; + } + + getTdInformationItemValue(data : {id : string[], value : string[], prefix ?: string}, item) : string { + let result = item; + for(const idVal of data.value){ + if(_.isNil(result)) return null; + result = result[idVal]; + } + return !_.isNil(data.prefix) ? data.prefix + result : result; + } + + + getTdListInformationItemValue(data : {id : string[], value : string[], prefix ?: string}, item) : string[] { + let result = item; + + for(let i = 0 ; i < data.value.length -1 ; i++){ + if(_.isNil(result)) return null; + result = result[data.value[i]]; + } + return _.map(result, _.last(data.value)); + } +} diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.spec.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.spec.ts new file mode 100644 index 000000000..db56836bd --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.spec.ts @@ -0,0 +1,295 @@ +import {ElementsTableService} from "./elements-table.service"; +import {TestBed, getTestBed} from "@angular/core/testing"; +import {NgRedux} from "@angular-redux/store"; +import {CustomTableColumnDefinition} from "./elements-table.component"; +import {AppState} from "../../../store/reducers"; +import {DataFilterPipe} from "../../../pipes/dataFilter/data-filter.pipe"; + + + +class MockAppStore { + dispatch() { + } + getState() { + return { + service : { + serviceHierarchy: { + }, + serviceInstance : { + "serviceModelId" : { + vnfGroups:{ + "aa1":{ + vnfs:{ + "VNF1_INSTANCE_ID":{ + "action": "None", + "instanceName": "VNF1_INSTANCE_NAME", + "instanceId": "VNF1_INSTANCE_ID", + "orchStatus": 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", + "trackById": "7a6ee536-f052-46fa-aa7e-2fca9d674c44:002", + "serviceInstanceId": "service-instance-id1", + "serviceInstanceName": "service-instance-name" + + }, + "aa1-vnf1":{ + vnfName: "", + instanceId:"", + serviceInstanceId:"" + } + } + } + } + } + + } + } + } + } +} + +describe('ElementsTableService view member count', () => { + let injector; + let service: ElementsTableService; + let store: NgRedux; + let data = loadMockMembers(); + + beforeAll(done => (async () => { + + TestBed.configureTestingModule( + { + providers: [ + ElementsTableService, + {provide: NgRedux, useClass: MockAppStore}, + DataFilterPipe + + ], + declarations: [DataFilterPipe] + }); + await TestBed.compileComponents(); + + injector = getTestBed(); + service = injector.get(ElementsTableService); + store = injector.get(NgRedux) + + })().then(done).catch(done.fail)); + + + test('should return number of displayed members', () => { + service.modalInformation = { + uniqObjectField : "instanceId" + }; + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.filteredMembers = data; + expect(service.calculateNotHideRows()).toEqual(2); + }); + + test('should return number of selected members', () => { + ElementsTableService.uniqObjectField = "instanceId"; + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.allElementsStatusMap['VNF1_INSTANCE_ID'].isSelected = true; + service.allElementsStatusMap['VNF2_INSTANCE_ID'].isSelected = true; + expect(service.calculateSelectedRows()).toEqual(2); + }); + + test('should return number of selected members', () => { + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.filteredMembers = data; + service.allElementsStatusMap['VNF1_INSTANCE_ID'].isSelected = true; + service.filterMembers('VNF2', "VNF"); + service.allElementsStatusMap['VNF2_INSTANCE_ID'].isSelected = true; + expect(service.calculateNotHideRows()).toEqual(1); + }); + + test('generateAllMembersStatus should add to each instance isHide and isSelected and convert to map', () => { + + let allMemberStatusMapMock = service.generateAllMembersStatus(data); + for (const key in allMemberStatusMapMock) { + expect(allMemberStatusMapMock[key].isSelected).toBeFalsy(); + } + }); + + test('changeAllCheckboxStatus', () => { + service.modalInformation = { + type : 'SomeType', + uniqObjectField : 'instanceId' + }; + let data = loadMockMembers(); + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.filteredMembers = data; + service.changeAllCheckboxStatus(true); + for (let key in service.allElementsStatusMap) { + expect(service.allElementsStatusMap[key].isSelected).toEqual(true); + } + }); + + test('should reset all numbers and lists', () => { + service.modalInformation = { + type : 'SomeType', + uniqObjectField : 'instanceId' + }; + let data = loadMockMembers(); + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.filteredMembers = data; + service.changeAllCheckboxStatus(true); + service.resetAll("instanceId"); + expect(service.numberOfNotHideRows).toEqual(0); + expect(service.numberOfSelectedAndNotHideRows).toEqual(0); + expect(service.numberOfSelectedRows).toEqual(0); + expect(service.allElementsStatusMap).toEqual({}); + expect(service.filteredMembers.length).toEqual(0); + }); + + test('checkAllCheckboxStatus should be false if not all are selected', () => { + service.allElementsStatusMap = service.generateAllMembersStatus(loadMockMembers()); + service.updateAmountsAndCheckAll("instanceId", {}); + + expect(service.allCheckboxAreSelected).toEqual(false); + }); + + + test('sortVnfMembersByName should sort list by vnf name', () => { + let data = loadMockMembers(); + let sortedList = service.sortElementsByName(data, "instanceName"); + + expect(sortedList[0].instanceName).toEqual("VNF1_INSTANCE_NAME"); + expect(sortedList[1].instanceName).toEqual("VNF2_INSTANCE_NAME"); + + let tmp = data[0]; + data[0] = data[1]; + data[1] = tmp; + + sortedList = service.sortElementsByName(data, "instanceName"); + + expect(sortedList[1].instanceName).toEqual("VNF1_INSTANCE_NAME"); + expect(sortedList[0].instanceName).toEqual("VNF2_INSTANCE_NAME"); + sortedList = service.sortElementsByName(null, "instanceName"); + expect(sortedList).toEqual([]); + sortedList = service.sortElementsByName(data, undefined); + expect(sortedList).toEqual([]); + }); + + test('isRowDisabled should return false current row is selected', ()=> { + let isDisabled = service.isRowDisabled(true, null); + expect(isDisabled).toBeFalsy(); + }); + + + test('isRowDisabled should return false if there is no limit', ()=> { + let isDisabled = service.isRowDisabled(false, null); + expect(isDisabled).toBeFalsy(); + }); + + test('isRowDisabled should return false if number of rows are less then limit ', ()=> { + service.modalInformation = { + uniqObjectField : "instanceId" + }; + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.allElementsStatusMap['VNF1_INSTANCE_ID'].isSelected = true; + service.allElementsStatusMap['VNF2_INSTANCE_ID'].isSelected = true; + + let isDisabled = service.isRowDisabled(false, 3); + expect(isDisabled).toBeFalsy(); + }); + + test('isRowDisabled should return true if number of rows are equal or more then limit ', ()=> { + ElementsTableService.uniqObjectField = "instanceId"; + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.allElementsStatusMap['VNF1_INSTANCE_ID'].isSelected = true; + service.allElementsStatusMap['VNF2_INSTANCE_ID'].isSelected = true; + + let isDisabled = service.isRowDisabled(false, 2); + expect(isDisabled).toBeTruthy(); + }); + + + test('isCheckAllDisabled should false true if number of rows are equal or more then limit ', ()=> { + service.modalInformation = { + uniqObjectField : "instanceId" + }; + service.allElementsStatusMap = service.generateAllMembersStatus(data); + service.allElementsStatusMap['VNF1_INSTANCE_ID'].isSelected = true; + service.allElementsStatusMap['VNF2_INSTANCE_ID'].isSelected = true; + + let isDisabled = service.isCheckAllDisabled( 2); + expect(isDisabled).toBeFalsy(); + }); + + +}); + + +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/shared/components/searchMembersModal/members-table/elements-table.service.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.ts new file mode 100644 index 000000000..bd7f3979d --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.ts @@ -0,0 +1,187 @@ +import {Injectable} from "@angular/core";; +import {NgRedux} from "@angular-redux/store"; +import {AppState} from "../../../store/reducers"; +import {DataFilterPipe} from "../../../pipes/dataFilter/data-filter.pipe"; +import {ElementTableRowModel, ModalInformation} from "./element-table-row.model"; +import {Level1Instance} from "../../../models/level1Instance"; +import * as _ from 'lodash'; +import {Subject} from "rxjs"; +import {CustomTableColumnDefinition} from "./elements-table.component"; +import { + deleteGenericModalhelper, + deleteGenericModalTableDataHelper, + updateGenericModalhelper, updateGenericModalTableDataHelper +} from "../../../storeUtil/utils/global/global.actions"; + +@Injectable() +export class ElementsTableService { + allElementsStatusMap : { [key:string]: ElementTableRowModel; }; + filteredMembers : any[]; + allCheckboxAreSelected : boolean; + numberOfNotHideRows : number; + numberOfSelectedRows : number; + numberOfSelectedAndNotHideRows : number; + numberOfNotSelectedAndNotHideRows : number; + maxSelectedRow : number; + modalInformation : ModalInformation; + + static uniqObjectField : string; + static changeFnTableDataTrigger : Subject = new Subject(); + static changeModalInformationDataTrigger : Subject<{modalInformation, selectedRowsIds}> = new Subject(); + static selectRowsTrigger : Subject = new Subject(); + + get staticUniqObjectField() { return ElementsTableService.uniqObjectField; } + + constructor(private _store: NgRedux, private dataFilter: DataFilterPipe){ + this.resetAll(ElementsTableService.uniqObjectField, this.maxSelectedRow); + } + + updateAmountsAndCheckAll = (uniqObjectField: string, modalInformation : ModalInformation, maxSelectedRow? : number) : void => { + this.maxSelectedRow = maxSelectedRow; + this.modalInformation = modalInformation; + ElementsTableService.uniqObjectField = uniqObjectField; + this.numberOfSelectedRows = this.calculateSelectedRows(); + this.numberOfNotHideRows = this.calculateNotHideRows(); + this.numberOfSelectedAndNotHideRows = this.calculateSelectedAndNotHide(); + this.numberOfNotSelectedAndNotHideRows = this.calculateNotSelectedAndNotHide(); + this.allCheckboxAreSelected = this.numberOfNotHideRows > 0 && ((this.numberOfNotHideRows === this.numberOfSelectedAndNotHideRows) || (this.numberOfSelectedAndNotHideRows === this.maxSelectedRow)); + }; + + resetAll = (uniqObjectField: string, maxSelectedRow? : number) : void => { + this.allElementsStatusMap = {}; + this.filteredMembers = []; + this.numberOfSelectedRows = 0; + this.numberOfNotHideRows = 0; + this.numberOfSelectedAndNotHideRows = 0; + this.numberOfNotSelectedAndNotHideRows = 0; + this.allCheckboxAreSelected = false; + this.maxSelectedRow = maxSelectedRow; + ElementsTableService.uniqObjectField = uniqObjectField; + }; + + changeAllCheckboxStatus = (status : boolean) : void =>{ + for(const member of this.filteredMembers){ + this.allElementsStatusMap[member[this.modalInformation.uniqObjectField]].isSelected = status; + if(status){ + this._store.dispatch(updateGenericModalhelper(`selected${this.modalInformation.type}`, this.allElementsStatusMap[member[this.modalInformation.uniqObjectField]], this.modalInformation.uniqObjectField)); + }else { + this._store.dispatch(deleteGenericModalhelper(`selected${this.modalInformation.type}`,this.allElementsStatusMap[member[this.modalInformation.uniqObjectField]][this.modalInformation.uniqObjectField])); + } + } + this.updateAmountsAndCheckAll(ElementsTableService.uniqObjectField, this.modalInformation, this.maxSelectedRow); + }; + + changeCheckboxStatus = (vnfInstanceId : string, tableData) : void => { + if(_.isNil(this.allElementsStatusMap[vnfInstanceId].isSelected)){ + this.allElementsStatusMap[vnfInstanceId].isSelected = true; + this._store.dispatch(updateGenericModalhelper(`selected${this.modalInformation.type}`, this.allElementsStatusMap[vnfInstanceId], this.modalInformation.uniqObjectField)); + this._store.dispatch(updateGenericModalTableDataHelper(`${this.modalInformation.type}_TABLE_DATA`, tableData)); + }else { + this.allElementsStatusMap[vnfInstanceId].isSelected = !this.allElementsStatusMap[vnfInstanceId].isSelected; + if(this.allElementsStatusMap[vnfInstanceId].isSelected){ + this._store.dispatch(updateGenericModalhelper(`selected${this.modalInformation.type}`, this.allElementsStatusMap[vnfInstanceId], this.modalInformation.uniqObjectField)); + this._store.dispatch(updateGenericModalTableDataHelper(`${this.modalInformation.type}_TABLE_DATA`, tableData)); + }else { + this._store.dispatch(deleteGenericModalhelper(`selected${this.modalInformation.type}`, this.modalInformation.uniqObjectField)); + this._store.dispatch(deleteGenericModalhelper(`selected${this.modalInformation.type}`, vnfInstanceId)); + + this._store.dispatch(deleteGenericModalTableDataHelper(`${this.modalInformation.type}_TABLE_DATA`)); + } + } + + this.updateAmountsAndCheckAll(ElementsTableService.uniqObjectField, this.modalInformation, this.maxSelectedRow); + }; + + filterMembers(searchStr: string, type :string): void { + const keys: string[][] = this.getDataKeys(type); + const types :string[] = this.getDataType(type); + this.filteredMembers = this.dataFilter.transform(_.values(this.allElementsStatusMap), searchStr || '', keys, types); + this.updateAmountsAndCheckAll(ElementsTableService.uniqObjectField, this.modalInformation, this.maxSelectedRow); + } + + /************************************************** + generate elements data for select/ unselect rows + **************************************************/ + generateAllMembersStatus(tableData : Level1Instance[]) : { [key:string]: ElementTableRowModel; }{ + tableData.map((item) => { + item['isSelected'] = false + }); + return _.keyBy(tableData as ElementTableRowModel[],this.staticUniqObjectField); + } + + sortElementsByName(list : Level1Instance[], keyName : string) :Level1Instance[]{ + if(!_.isNil(list) && !_.isNil(keyName)) { + return list.sort(function(itemA, itemB) { return itemA[keyName]- itemB[keyName];}) + } + return []; + } + + /******************************** + table columns headers and key's + ********************************/ + static getHeaders(type: string) : CustomTableColumnDefinition[] { + 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']} + ]; + } + + getDataKeys(type: string): string[][]{ + const headers = (!_.isNil(this.modalInformation) && !_.isNil(this.modalInformation.tableHeaders)) ? this.modalInformation.tableHeaders : ElementsTableService.getHeaders(type); + return headers.map((header)=> header.key).concat([[ElementsTableService.uniqObjectField]],[['serviceInstanceId']]); + } + + getDataType(type: string): string[]{ + const headers = (!_.isNil(this.modalInformation) && !_.isNil(this.modalInformation.tableHeaders)) ? this.modalInformation.tableHeaders : ElementsTableService.getHeaders(type); + return headers.map((header)=> header.type); + + } + + /************************************************************************************* + calculate the number of selected vnf members - include not visible and visible rows + @allElementsStatusMap: current vnf member status + *************************************************************************************/ + calculateSelectedRows() : number { + const flatObject = _.values(this.allElementsStatusMap); + return _.filter(flatObject, (item) => { if (item.isSelected) return item }).length; + } + + /************************************************ + calculate the number of display vnf members + @allElementsStatusMap: current vnf member status + ************************************************/ + calculateNotHideRows() : number { + return this.filteredMembers ? this.filteredMembers.length : 0; + } + + /************************************************ + calculate the number of display vnf members + @allElementsStatusMap: current vnf member status + ************************************************/ + calculateSelectedAndNotHide() : number { + return _.filter(this.filteredMembers, (item) => { if ( this.allElementsStatusMap[item[ElementsTableService.uniqObjectField]].isSelected) return item }).length; + } + + calculateNotSelectedAndNotHide() : number { + return _.filter(this.filteredMembers, (item) => { if ( !this.allElementsStatusMap[item[ElementsTableService.uniqObjectField]].isSelected) return item }).length; + } + + + isRowDisabled(currentRowIsSelected : boolean, maxSelectRow?: number) : boolean { + return _.isNil(maxSelectRow) || currentRowIsSelected || maxSelectRow === 1 ? false : maxSelectRow <= this.calculateSelectedRows(); + } + + isCheckAllDisabled(maxSelectRow?: number) : boolean{ + if(_.isNil(maxSelectRow)) return false; + else { + return this.numberOfNotSelectedAndNotHideRows > maxSelectRow; + } + } + + +} diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/member-table-row.model.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/member-table-row.model.ts deleted file mode 100644 index c5f1a7a07..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/member-table-row.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {VnfMember} from "../../../models/VnfMember"; - -export class MemberTableRowModel extends VnfMember{ - isSelected : boolean = false; -} - diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.html b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.html deleted file mode 100644 index 3a29ed824..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.html +++ /dev/null @@ -1,75 +0,0 @@ -
-
- {{description}} -
- {{membersTableService.numberOfNotHideVnfMembers}} VNFs match your criteria - {{membersTableService.numberOfSelectedVnfMembers}} VNF{{membersTableService.numberOfSelectedVnfMembers>1?'s':'' }} selected -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - -
- - {{header.displayName}}
- - - - - - - - - - - - - - - - -
-
No VNFs were found that can belong to this group.
- - diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.scss b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.scss index 3be975222..2fa90b859 100644 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.scss +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.scss @@ -42,32 +42,46 @@ #member-table { border: 1px solid #D2D2D2; + display: flex; + flex-flow: column; + max-height: calc(100vh - 135px); + overflow-y: auto; thead { background: #F8F8F8; - th.allCheckboxAreSelected { - vertical-align: middle !important; - width: 48px; - max-width: 48px; - min-width: 48px; - height: 48px; - } - th.header-title { - font-family: OpenSans-SemiBold; - vertical-align: middle !important; - height: 48px; - font-size: 12px; + tr { + table-layout: fixed; + display: table; + width: 100%; + th.allCheckboxAreSelected { + vertical-align: middle !important; + width: 48px; + max-width: 48px; + min-width: 48px; + height: 48px; + } + th.header-title { + font-family: OpenSans-SemiBold; + vertical-align: middle !important; + height: 48px; + font-size: 12px; + } } } tbody { - td{ - text-align: center; - height: 60px; - padding-top: 0; - padding-bottom: 0; - max-height: 60px; - vertical-align: middle; - .second-line { - font-size: 12px; + tr { + table-layout: fixed; + display: table; + width: 100%; + td{ + text-align: center; + height: 60px; + padding-top: 0; + padding-bottom: 0; + max-height: 60px; + vertical-align: middle; + .second-line { + font-size: 12px; + } } } } @@ -89,3 +103,13 @@ align-items: center; justify-content: center; } + +td.sdcCheckboxMember { + vertical-align: middle !important; + width: 48px !important; + max-width: 48px !important; + min-width: 48px !important; + height: 48px !important; +} + + diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.ts deleted file mode 100644 index 9736563af..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {Component, Input, OnChanges, Output, SimpleChanges, EventEmitter} from '@angular/core'; -import {VnfMember} from "../../../models/VnfMember"; -import {MembersTableService} from "./members-table.service"; -import * as _ from 'lodash'; - -export class CustomTableColumnDefinition { - public displayName = ''; - public key : any = ''; - public type? = 'text'; - public filter? = ''; -} - -@Component({ - selector: 'app-members-table', - templateUrl: './members-table.component.html', - styleUrls: ['./members-table.component.scss'] -}) - -export class MembersTableComponent implements OnChanges{ - filterValue: string = null; - allMemberStatusMap = null; - membersTableService : MembersTableService; - headers: CustomTableColumnDefinition[] = MembersTableService.getHeaders(); - @Input() data: VnfMember[]; - @Input() description: string; - @Output() selectedMembersAmountChange : EventEmitter = new EventEmitter(); - constructor(private _membersTableService : MembersTableService){ - this.membersTableService = this._membersTableService; - } - - ngOnChanges(changes: SimpleChanges): void { - if(_.isNil(this.data)){ - this._membersTableService.resetAll(); - }else { - this._membersTableService.allMemberStatusMap = MembersTableService.generateAllMembersStatus(this.data); - this._membersTableService.filteredMembers = MembersTableService.sortVnfMembersByName(this.data, "instanceName"); - this._membersTableService.updateAmountsAndCheckAll(); - } - } - - search(searchStr: string): void { - this.filterValue = searchStr; - this._membersTableService.filterMembers(this.filterValue); - } - - changeAllCheckboxStatus(status: boolean) : void { - this._membersTableService.changeAllCheckboxStatus(status); - this.selectedMembersAmountChange.emit(this._membersTableService.numberOfSelectedVnfMembers); - } - - - changeCheckboxStatus(vnfInstanceId: string) : void { - this._membersTableService.changeCheckboxStatus(vnfInstanceId); - this.selectedMembersAmountChange.emit(this._membersTableService.numberOfSelectedVnfMembers); - } - -} diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.spec.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.spec.ts deleted file mode 100644 index e53c63be1..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.spec.ts +++ /dev/null @@ -1,270 +0,0 @@ -import {MembersTableService} from "./members-table.service"; -import {TestBed, getTestBed} from "@angular/core/testing"; -import {NgRedux} from "@angular-redux/store"; -import {CustomTableColumnDefinition} from "./members-table.component"; -import {AppState} from "../../../store/reducers"; -import {createRelatedVnfMemberInstance} from "../../../storeUtil/utils/relatedVnfMember/relatedVnfMember.actions"; -import {DataFilterPipe} from "../../../pipes/dataFilter/data-filter.pipe"; -import {VnfMember} from "../../../models/VnfMember"; - - - -class MockAppStore { - dispatch() { - } - getState() { - return { - service : { - serviceHierarchy: { - }, - serviceInstance : { - "serviceModelId" : { - vnfGroups:{ - "aa1":{ - vnfs:{ - "VNF1_INSTANCE_ID":{ - "action": "None", - "instanceName": "VNF1_INSTANCE_NAME", - "instanceId": "VNF1_INSTANCE_ID", - "orchStatus": null, - "lcpCloudRegionId": "mtn23b", - "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", - "trackById": "7a6ee536-f052-46fa-aa7e-2fca9d674c44:002", - "serviceInstanceId": "service-instance-id1", - "serviceInstanceName": "service-instance-name" - - }, - "aa1-vnf1":{ - vnfName: "", - instanceId:"", - serviceInstanceId:"" - } - } - } - } - } - - } - } - } - } -} - -describe('MembersTableService view member count', () => { - let injector; - let service: MembersTableService; - let store: NgRedux; - let data = loadMockMembers(); - - beforeAll(done => (async () => { - - TestBed.configureTestingModule( - { - providers: [ - MembersTableService, - {provide: NgRedux, useClass: MockAppStore}, - DataFilterPipe - - ], - declarations: [DataFilterPipe] - }); - await TestBed.compileComponents(); - - injector = getTestBed(); - service = injector.get(MembersTableService); - store = injector.get(NgRedux) - - })().then(done).catch(done.fail)); - - - test('should return number of displayed members', () => { - service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(data); - service.filteredMembers = data; - expect(service.calculateNotHideVnfMembers()).toEqual(2); - }); - - test('should return number of selected members', () => { - service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(data); - service.allMemberStatusMap['VNF1_INSTANCE_ID'].isSelected = true; - service.allMemberStatusMap['VNF2_INSTANCE_ID'].isSelected = true; - expect(service.calculateSelectedVnfMembers()).toEqual(2); - }); - - test('should return number of selected members', () => { - service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(data); - service.filteredMembers = data; - service.allMemberStatusMap['VNF1_INSTANCE_ID'].isSelected = true; - service.filterMembers('VNF2'); - service.allMemberStatusMap['VNF2_INSTANCE_ID'].isSelected = true; - expect(service.calculateNotHideVnfMembers()).toEqual(1); - }); - - test('getHeader should return labels with array of keys', () => { - const headers: CustomTableColumnDefinition[] = MembersTableService.getHeaders(); - expect(headers).toEqual([ - {displayName: 'VNF instance name', key: ['instanceName']}, - {displayName: 'VNF version', key: ['modelInfo', 'modelVersion']}, - {displayName: 'VNF 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']} - ]); - }); - - - test('setMembers should dispatch action only on selected members', () => { - const vnfGroupStoreKey: string = 'vnfGroupStoreKey'; - const serviceId: string = 'serviceId'; - - jest.spyOn(store, 'dispatch'); - service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(data); - service.allMemberStatusMap['VNF1_INSTANCE_ID'].isSelected = true; - service.setMembers({serviceId: serviceId, vnfGroupStoreKey: vnfGroupStoreKey}); - expect(store.dispatch).toHaveBeenCalledTimes(1); - expect(store.dispatch).toHaveBeenCalledWith(createRelatedVnfMemberInstance(vnfGroupStoreKey, serviceId, service.allMemberStatusMap['VNF1_INSTANCE_ID'])); - }); - - test('generateAllMembersStatus should add to each instance isHide and isSelected and convert to map', () => { - - let allMemberStatusMapMock = MembersTableService.generateAllMembersStatus(data); - for (const key in allMemberStatusMapMock) { - expect(allMemberStatusMapMock[key].isSelected).toBeFalsy(); - } - }); - - test('changeAllCheckboxStatus', () => { - let data = loadMockMembers(); - service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(data); - service.filteredMembers = data; - service.changeAllCheckboxStatus(true); - for (let key in service.allMemberStatusMap) { - expect(service.allMemberStatusMap[key].isSelected).toEqual(true); - } - }); - - test('should reset all numbers and lists', () => { - let data = loadMockMembers(); - service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(data); - service.filteredMembers = data; - service.changeAllCheckboxStatus(true); - service.resetAll(); - expect(service.numberOfNotHideVnfMembers).toEqual(0); - expect(service.numberOfSelectedAndNotHideVnfMembers).toEqual(0); - expect(service.numberOfSelectedVnfMembers).toEqual(0); - expect(service.allMemberStatusMap).toEqual({}); - expect(service.filteredMembers.length).toEqual(0); - }); - - test('checkAllCheckboxStatus should be false if not all are selected', () => { - service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(loadMockMembers()); - service.updateAmountsAndCheckAll(); - - expect(service.allCheckboxAreSelected).toEqual(false); - }); - - - test('sortVnfMembersByName should sort list by vnf name', () => { - let data = loadMockMembers(); - let sortedList = MembersTableService.sortVnfMembersByName(data, "instanceName"); - - expect(sortedList[0].instanceName).toEqual("VNF1_INSTANCE_NAME"); - expect(sortedList[1].instanceName).toEqual("VNF2_INSTANCE_NAME"); - - let tmp = data[0]; - data[0] = data[1]; - data[1] = tmp; - - sortedList = MembersTableService.sortVnfMembersByName(data, "instanceName"); - - expect(sortedList[1].instanceName).toEqual("VNF1_INSTANCE_NAME"); - expect(sortedList[0].instanceName).toEqual("VNF2_INSTANCE_NAME"); - sortedList = MembersTableService.sortVnfMembersByName(null, "instanceName"); - expect(sortedList).toEqual([]); - sortedList = MembersTableService.sortVnfMembersByName(data, undefined); - expect(sortedList).toEqual([]); - }); - - test('should return only vnf members not associated to any vnf group', ()=>{ - const result: VnfMember[] = service.filterUsedVnfMembers("serviceModelId",loadMockMembers()); - expect(result.length).toEqual(1); - expect(result[0].instanceId).toEqual("VNF2_INSTANCE_ID"); - }); - -}); - - -function loadMockMembers(): any[] { - return [ - { - "action": "None", - "instanceName": "VNF1_INSTANCE_NAME", - "instanceId": "VNF1_INSTANCE_ID", - "orchStatus": null, - "productFamilyId": null, - "lcpCloudRegionId": "mtn23b", - "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": "mtn23b", - "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/shared/components/searchMembersModal/members-table/members-table.service.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.ts deleted file mode 100644 index 5b9cd39a2..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.ts +++ /dev/null @@ -1,153 +0,0 @@ -import {Injectable} from "@angular/core"; -import {VnfMember} from "../../../models/VnfMember"; -import {CustomTableColumnDefinition} from "./members-table.component"; -import {NgRedux} from "@angular-redux/store"; -import {AppState} from "../../../store/reducers"; -import {createRelatedVnfMemberInstance} from "../../../storeUtil/utils/relatedVnfMember/relatedVnfMember.actions"; -import * as _ from 'lodash'; -import {DataFilterPipe} from "../../../pipes/dataFilter/data-filter.pipe"; -import {MemberTableRowModel} from "./member-table-row.model"; - -@Injectable() -export class MembersTableService { - allMemberStatusMap : { [key:string]: MemberTableRowModel; }; - filteredMembers : VnfMember[]; - allCheckboxAreSelected : boolean; - numberOfNotHideVnfMembers : number; - numberOfSelectedVnfMembers : number; - numberOfSelectedAndNotHideVnfMembers : number; - - constructor(private _store: NgRedux, private dataFilter: DataFilterPipe){ - this.resetAll(); - } - - filterUsedVnfMembers = (serviceModelId: string, result: VnfMember[]): VnfMember[] => { - const allMembersMap = _.keyBy(result as VnfMember[], '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); - }; - - updateAmountsAndCheckAll = () : void => { - this.numberOfSelectedVnfMembers = this.calculateSelectedVnfMembers(); - this.numberOfNotHideVnfMembers = this.calculateNotHideVnfMembers(); - this.numberOfSelectedAndNotHideVnfMembers = this.calculateSelectedAndNotHide(); - this.allCheckboxAreSelected = this.numberOfNotHideVnfMembers > 0 && this.numberOfNotHideVnfMembers === this.numberOfSelectedAndNotHideVnfMembers; - }; - - resetAll = () : void => { - this.allMemberStatusMap = {}; - this.filteredMembers = []; - this.numberOfSelectedVnfMembers = 0; - this.numberOfNotHideVnfMembers = 0; - this.numberOfSelectedAndNotHideVnfMembers = 0; - this.allCheckboxAreSelected = false; - }; - - changeAllCheckboxStatus = (status : boolean) : void =>{ - for(const member of this.filteredMembers){ - this.allMemberStatusMap[member.instanceId].isSelected = status; - } - this.updateAmountsAndCheckAll(); - }; - - changeCheckboxStatus = (vnfInstanceId : string ) : void =>{ - this.allMemberStatusMap[vnfInstanceId].isSelected = !this.allMemberStatusMap[vnfInstanceId].isSelected; - this.updateAmountsAndCheckAll(); - }; - - /************************************************ - iterate over all current vnf members: - 1) if vnf member is selected then update REDUX store - 2) if vnf member is not selected then delete member - @allMemberStatusMap: current vnf member status - @vnfGroupStoreKey: vnf group store key - @serviceId: service model id - ************************************************/ - setMembers = (data : {serviceId : string, vnfGroupStoreKey : string}) : void =>{ - let tmpMembers = this.allMemberStatusMap; - for(let key in tmpMembers){ - if(tmpMembers[key].isSelected){ - this._store.dispatch(createRelatedVnfMemberInstance( data.vnfGroupStoreKey, data.serviceId, tmpMembers[key])); - } - } - }; - - filterMembers(searchStr: string): void { - const keys: string[][] = MembersTableService.getDataKeys(); - this.filteredMembers = this.dataFilter.transform(_.values(this.allMemberStatusMap), searchStr || '', keys); - this.updateAmountsAndCheckAll(); - } - - /************************************ - generate vnf member data for select/ unselect rows - ************************************/ - static generateAllMembersStatus(tableData : VnfMember[]) : { [key:string]: MemberTableRowModel; }{ - - tableData.map((vnf) => { - vnf['isSelected'] = false - }); - return _.keyBy(tableData as MemberTableRowModel[], 'instanceId'); - } - - - static sortVnfMembersByName(list : VnfMember[], keyName : string) :VnfMember[]{ - if(!_.isNil(list) && !_.isNil(keyName)) { - return list.sort(function(itemA, itemB) { return itemA[keyName]- itemB[keyName];}) - } - return []; - - } - - /******************************** - table columns headers and key's - ********************************/ - static getHeaders() : CustomTableColumnDefinition[] { - return [ - {displayName: 'VNF instance name', key: ['instanceName']}, - {displayName: 'VNF version', key: ['modelInfo', 'modelVersion']}, - {displayName: 'VNF 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']} - ]; - } - - static getDataKeys(): string[][]{ - const headers = MembersTableService.getHeaders(); - return headers.map((header)=> header.key).concat([['instanceId']],[['serviceInstanceId']]); - } - - /************************************************************************************* - calculate the number of selected vnf members - include not visible and visible rows - @allMemberStatusMap: current vnf member status - *************************************************************************************/ - calculateSelectedVnfMembers() : number { - const flatObject = _.values(this.allMemberStatusMap); - return _.filter(flatObject, (item) => { if (item.isSelected) return item }).length; - } - - /************************************************ - calculate the number of display vnf members - @allMemberStatusMap: current vnf member status - ************************************************/ - calculateNotHideVnfMembers() : number { - return this.filteredMembers.length; - } - - /************************************************ - calculate the number of display vnf members - @allMemberStatusMap: current vnf member status - ************************************************/ - calculateSelectedAndNotHide() : number { - return _.filter(this.filteredMembers, (item) => { if ( this.allMemberStatusMap[item.instanceId].isSelected) return item }).length; - } - - -} diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.html b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.html new file mode 100644 index 000000000..7e79ca6f1 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.html @@ -0,0 +1,64 @@ + diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.scss b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.scss new file mode 100644 index 000000000..7d9d139d1 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.scss @@ -0,0 +1,115 @@ +.modal-search-member-content { + height: 100vh; + width: 100vw; + position: relative; + background: white; + .header { + height: 60px; + font-family: OpenSans-Regular; + display: -webkit-box; + display: flex; + font-size: 14px; + box-shadow: 2px 2px 6px #D2D2D2; + color: white; + background: #009fdb; + z-index: 1; + position: relative; + .navigation-arrow-back { + border-right: 1px solid #1eb9f3; + width: 60px; + height: 60px; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + } + .title { + font-size: 18px; + line-height: 60px; + margin-left: 20px; + } + button { + width: 125px; + font-family: OpenSans-Regular; + font-size: 14px; + margin-left: auto; + margin-right: 20px; + margin-top: 12px; + border: 1px solid white; + &:disabled { + opacity: 0.5; + background: none; + } + } + } + + .content-wrapper { + + .sidebar-left { + width: 20%; + border-right: 1px solid #D2D2D2; + height: calc(100vh - 60px); + float: left; + + .search-criteria-wrapper{ + + .search-criteria-title{ + font-family: OpenSans-SemiBold; + font-size: 14px; + color: #191919; + border-bottom: 1px solid #D2D2D2; + line-height: 50px; + padding-left: 30px; + } + .search-item{ + color: #191919; + display: flex; + flex-direction: column; + margin: 25px 30px; + .label-item { + font-family: OpenSans-SemiBold; + font-size: 12px; + } + .text-item{ + font-family: OpenSans-Regular; + font-size: 14px; + color: #5a5a5a; + word-break: break-all; + } + + } + } + } + + .sidebar-right { + padding: 15px 30px 0px 30px; + width: 80%; + float: right; + } + } +} + +select.select-criteria { + webkit-appearance: none; + background: url('../../../../assets/img/chevron.svg') 0 0 no-repeat; + background-size: 24px; + background-position-x: right; + background-position-y: center; + font-family: OpenSans-Italic; + font-size: 14px; + height: 38px; + -webkit-appearance: none; + -moz-appearance: none; +} + +.required:after { + content: " * "; + color: #cf2a2a; + margin-left: 3px; +} + +.search-button { + display: flex; + justify-content: space-around; +} + diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.ts new file mode 100644 index 000000000..211f59337 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.ts @@ -0,0 +1,91 @@ +import {Component, Input, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {DialogComponent, DialogService} from "ng2-bootstrap-modal"; +import {IframeService} from "../../utils/iframe.service"; +import {AaiService} from "../../services/aaiService/aai.service"; +import {VnfGroupModel} from "../../models/vnfGroupModel"; +import {ElementsTableService} from "./members-table/elements-table.service"; +import {Level1Instance} from "../../models/level1Instance"; +import {ModalInformation} from "./members-table/element-table-row.model"; +import {NgRedux} from "@angular-redux/store"; +import {AppState} from "../../store/reducers"; +import {FormGroup} from "@angular/forms"; +import * as _ from "lodash"; +import {clearAllGenericModalhelper} from "../../storeUtil/utils/global/global.actions"; +@Component({ + selector: 'search-members-modal', + templateUrl: 'search-elements-modal.component.html', + styleUrls: ['search-elements-modal.component.scss'] +}) + +export class SearchElementsModalComponent extends DialogComponent<{ modalInformation: ModalInformation }, boolean> implements OnInit, OnDestroy { + modalInformation: ModalInformation; + parentElementClassName = 'content'; + elementsData: Level1Instance[]; + vnfGroupModel: VnfGroupModel; + disableSetElements: boolean = true; + disableSearchByNetworkRole: boolean = false; + dynamicFormGroup: FormGroup = null; + + constructor(dialogService: DialogService, + private _iframeService: IframeService, + private _aaiService: AaiService, + private _membersTableService: ElementsTableService, + private _store: NgRedux) { + super(dialogService); + ElementsTableService.changeFnTableDataTrigger.subscribe((triggerRes) => { + this._membersTableService.resetAll(this.modalInformation.uniqObjectField, this.modalInformation.maxSelectRow); + this.elementsData = triggerRes; + }); + + ElementsTableService.changeModalInformationDataTrigger.subscribe(({modalInformation, selectedRowsIds}) => { + this.disableSetElements = true; + this.modalInformation = modalInformation; + this.ngOnInit(selectedRowsIds); + }) + } + + @ViewChild('ElementsTableComponent') membersTable; + + ngOnInit(selectedRowsIds?: string[]): void { + const genericModalHelper = this._store.getState().global.genericModalHelper; + if(!_.isNil(genericModalHelper) && !_.isNil(genericModalHelper[`${this.modalInformation.type}_TABLE_DATA`]) && !_.isNil(genericModalHelper[`selected${this.modalInformation.type}`])){ + this.elementsData = this._store.getState().global.genericModalHelper[`${this.modalInformation.type}_TABLE_DATA`]; + } else { + this.modalInformation.getElements() + .subscribe((result) => { + this.elementsData = result; + }); + } + }; + + closeDialog(): void { + this._iframeService.removeFullScreen(); + this._iframeService.removeClassCloseModal(this.parentElementClassName); + this.dialogService.removeDialog(this); + setTimeout(() => { + window.parent.postMessage("closeIframe", "*"); + }, 15); + } + + selectedMembersAmountChange(selectedMembersAmount: number): void { + this.disableSetElements = selectedMembersAmount == 0; + } + + doneAction(): void { + this.modalInformation.topButton.action.call(this, this); + } + + searchByCriteriaAction(): void { + this.modalInformation.searchButton.action.call(this, this); + } + + backAction(): void { + if (this.modalInformation.backAction) { + this.modalInformation.backAction.call(this, this); + } else { + this.closeDialog(); + } + } +} + + diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.html b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.html deleted file mode 100644 index 899bc9889..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.html +++ /dev/null @@ -1,35 +0,0 @@ - diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.scss b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.scss deleted file mode 100644 index d49653934..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.scss +++ /dev/null @@ -1,89 +0,0 @@ -.modal-search-member-content { - height: 100vh; - width: 100vw; - position: relative; - background: white; - .header { - height: 60px; - font-family: OpenSans-Regular; - display: -webkit-box; - display: flex; - font-size: 14px; - box-shadow: 2px 2px 6px #D2D2D2; - color: white; - background: #009fdb; - z-index: 1; - position: relative; - .navigation-arrow-back { - border-right: 1px solid #1eb9f3; - width: 60px; - height: 60px; - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - } - .title { - font-size: 18px; - line-height: 60px; - margin-left: 20px; - } - button { - width: 125px; - font-family: OpenSans-Regular; - font-size: 14px; - margin-left: auto; - margin-right: 20px; - margin-top: 12px; - border: 1px solid white; - &:disabled { - opacity: 0.5; - background: none; - } - } - } - - .content-wrapper { - display: flex; - - .sidebar-left { - flex-basis: 285px; - border-right: 1px solid #D2D2D2; - height: calc(100vh - 60px); - - .search-criteria-wrapper{ - - .search-criteria-title{ - font-family: OpenSans-SemiBold; - font-size: 14px; - color: #191919; - border-bottom: 1px solid #D2D2D2; - line-height: 50px; - padding-left: 30px; - } - .search-item{ - color: #191919; - display: flex; - flex-direction: column; - margin: 25px 30px; - .label-item { - font-family: OpenSans-SemiBold; - font-size: 12px; - } - .text-item{ - font-family: OpenSans-Regular; - font-size: 14px; - color: #5a5a5a; - word-break: break-all; - } - - } - } - } - - .sidebar-right { - flex: 1; - margin: 80px 50px; - } - } -} diff --git a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.ts deleted file mode 100644 index 9c65d222d..000000000 --- a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {DialogComponent, DialogService} from "ng2-bootstrap-modal"; -import {IframeService} from "../../utils/iframe.service"; -import {AaiService} from "../../services/aaiService/aai.service"; -import {VnfMember} from "../../models/VnfMember"; -import {VnfGroupModel} from "../../models/vnfGroupModel"; -import {MembersTableService} from "./members-table/members-table.service"; -import {VnfGroupInstance} from "../../models/vnfGroupInstance"; - - -export interface PopupModel { - title: string; - serviceModelId : string; - searchFields: ISearchField[]; - description : string; - subscriberId: string, - serviceType: string, - node: VnfGroupInstance, - vnfGroupModel: VnfGroupModel; - -} - -export interface ISearchField { - title: string; - value: any; - dataTestId: string; -} - -@Component({ - selector : 'search-members-modal', - templateUrl : 'search-members-modal.component.html', - styleUrls : ['search-members-modal.component.scss'] -}) - -export class SearchMembersModalComponent extends DialogComponent implements OnInit, OnDestroy { - title: string; - serviceModelId : string; - parentElementClassName = 'content'; - membersData: VnfMember[]; - description : string; - searchFields: ISearchField[]; - vnfGroupModel: VnfGroupModel; - subscriberId: string; - serviceType: string; - node: VnfGroupInstance; - disableSetMembers: boolean = true; - constructor(dialogService: DialogService , - private _iframeService : IframeService, - private _aaiService : AaiService, - private _membersTableService: MembersTableService){ - super(dialogService); - - } - @ViewChild('MembersTableComponent') membersTable; - - ngOnInit() : void{ - this._aaiService.getOptionalGroupMembers(this.serviceModelId, this.subscriberId, this.serviceType, (Object.values(this.vnfGroupModel.members))[0].sourceModelInvariant, this.vnfGroupModel.properties.type, this.vnfGroupModel.properties.role) - .subscribe((result: VnfMember[])=>{ - this.membersData = this._membersTableService.filterUsedVnfMembers(this.serviceModelId, result); - }); - }; - - - closeDialog() : void{ - this._iframeService.removeClassCloseModal(this.parentElementClassName); - this.dialogService.removeDialog(this); - setTimeout(() => { - window.parent.postMessage("closeIframe", "*"); - }, 15); - } - selectedMembersAmountChange(selectedMembersAmount: number) : void { - this.disableSetMembers = selectedMembersAmount==0; - } - - - setMembers() : void { - this._membersTableService.setMembers({serviceId : this.serviceModelId, vnfGroupStoreKey : this.node.vnfGroupStoreKey}); - this.closeDialog(); - } -} - - -- cgit 1.2.3-korg