summaryrefslogtreecommitdiffstats
path: root/vid-webpack-master/src/app/shared/components/searchMembersModal
diff options
context:
space:
mode:
authorIttay Stern <ittay.stern@att.com>2019-07-07 19:23:03 +0300
committerIttay Stern <ittay.stern@att.com>2019-07-08 16:13:43 +0300
commitf792671ae247a931f34d902e9276202b5016ef9a (patch)
tree6104971e8074c9a3d720836276ff18619719ec02 /vid-webpack-master/src/app/shared/components/searchMembersModal
parentfc62274e8d15964d63c62bf0e2f4abc040252ee9 (diff)
Merge from ecomp 718fd196 - Modern UI
Issue-ID: VID-378 Change-Id: I2736b98426e324ec3aa233b034229ba84d99839f Signed-off-by: Ittay Stern <ittay.stern@att.com>
Diffstat (limited to 'vid-webpack-master/src/app/shared/components/searchMembersModal')
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/element-table-row.model.ts88
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.html71
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.component.ts144
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.spec.ts (renamed from vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.spec.ts)161
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.ts187
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/member-table-row.model.ts6
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.html75
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.scss66
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.component.ts57
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/members-table.service.ts153
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.html64
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.scss (renamed from vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.scss)34
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.ts91
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.html35
-rw-r--r--vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.ts82
15 files changed, 813 insertions, 501 deletions
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<any[]> 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<any[]>;
+ 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<string>;
+ 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 @@
+<div class="table-header">
+ <div class="left-header">
+ <span class="title-header">{{modalInformation.description}}</span>
+ <div class="sub-title-header">
+ <span class="vnf-match-your-criteria" class="total" [attr.data-tests-id]="'total-amount'" style="margin-right: 5px;"><span
+ [attr.data-tests-id]="'numberOfNotHideRows'">{{membersTableService.numberOfNotHideRows}}</span> {{modalInformation.type}}s match your criteria |</span>
+ <span class="vnf-selected" class="total" [attr.data-tests-id]="'total-selected'"><span
+ [attr.data-tests-id]="'numberOfSelectedRows'">{{membersTableService.numberOfSelectedRows}}</span> {{modalInformation.type}}{{membersTableService.numberOfSelectedRows>1?'s':'' }} selected</span>
+ </div>
+ </div>
+
+ <div class="search-container">
+ <sdc-filter-bar
+ [placeHolder]="'Filter'"
+ [debounceTime]="250"
+ [testId]="'vnf-members-search'"
+ (valueChange)="search($event)">
+ </sdc-filter-bar>
+ </div>
+</div>
+<table id="member-table" class="table table-bordered" style="table-layout: fixed" *ngIf="data?.length > 0">
+ <thead class="thead-dark">
+ <tr>
+ <th class="allCheckboxAreSelected" style="position: relative;">
+ <sdc-checkbox
+ [disabled]="membersTableService.isCheckAllDisabled(modalInformation.maxSelectRow)"
+ [(checked)]="membersTableService.allCheckboxAreSelected"
+ [testId]="'all-checkbox-selected'"
+ (checkedChange)="changeAllCheckboxStatus($event)"
+ ></sdc-checkbox>
+ </th>
+ <th class="header-title" *ngFor="let header of headers">{{header.displayName}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class="member-table-row" *ngFor="let item of membersTableService.filteredMembers">
+ <td class="sdcCheckboxMember" style="position: relative;" [attr.data-tests-id]="item[membersTableService.staticUniqObjectField]">
+ <sdc-checkbox
+ [disabled]="membersTableService.isRowDisabled( membersTableService.allElementsStatusMap[item[membersTableService.staticUniqObjectField]]?.isSelected, modalInformation.maxSelectRow)"
+ [checked]="membersTableService.allElementsStatusMap[item[membersTableService.staticUniqObjectField]]?.isSelected"
+ [testId]="item[membersTableService.staticUniqObjectField]"
+ (checkedChange)="changeCheckboxStatus(item[membersTableService.staticUniqObjectField])"
+ ></sdc-checkbox></td>
+
+ <td *ngFor="let tdInformation of modalInformation.tableContent" [id]="tdInformation.id">
+ <div *ngIf="tdInformation.contents[0].type === 'LIST'; else noList">
+ <custom-ellipsis
+ *ngFor="let tdInformationItem of getTdListInformationItemValue(tdInformation.contents[0], item) "
+ [id]="tdInformationItem"
+ [value]="tdInformationItem"
+ [breakWord]="true"
+ [hightlight]="filterValue"></custom-ellipsis>
+ </div>
+ <ng-template #noList>
+ <custom-ellipsis
+ *ngFor="let tdInformationItem of tdInformation.contents; index as i"
+ [id]="getTdInformationItemId(tdInformationItem, item)"
+ [value]="getTdInformationItemValue(tdInformationItem, item)"
+ [ngClass]="{'second-line' : i%2 === 1}"
+ [breakWord]="true"
+ [hightlight]="filterValue"></custom-ellipsis>
+ </ng-template>
+
+ </td>
+ </tr>
+
+ </tbody>
+</table>
+<div class="no-result" *ngIf="data?.length == 0">{{modalInformation?.noElementsMsg}}</div>
+
+
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<number> = new EventEmitter();
+ constructor(private _membersTableService : ElementsTableService, private _store : NgRedux<AppState>){
+ 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/members-table.service.spec.ts b/vid-webpack-master/src/app/shared/components/searchMembersModal/members-table/elements-table.service.spec.ts
index e53c63be1..db56836bd 100644
--- 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/elements-table.service.spec.ts
@@ -1,11 +1,9 @@
-import {MembersTableService} from "./members-table.service";
+import {ElementsTableService} from "./elements-table.service";
import {TestBed, getTestBed} from "@angular/core/testing";
import {NgRedux} from "@angular-redux/store";
-import {CustomTableColumnDefinition} from "./members-table.component";
+import {CustomTableColumnDefinition} from "./elements-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";
@@ -27,7 +25,7 @@ class MockAppStore<T> {
"instanceName": "VNF1_INSTANCE_NAME",
"instanceId": "VNF1_INSTANCE_ID",
"orchStatus": null,
- "lcpCloudRegionId": "mtn23b",
+ "lcpCloudRegionId": "hvf23b",
"tenantId": "3e9a20a3e89e45f884e09df0cc2d2d2a",
"tenantName": "APPC-24595-T-IST-02C",
"modelInfo": {
@@ -62,9 +60,9 @@ class MockAppStore<T> {
}
}
-describe('MembersTableService view member count', () => {
+describe('ElementsTableService view member count', () => {
let injector;
- let service: MembersTableService;
+ let service: ElementsTableService;
let store: NgRedux<AppState>;
let data = loadMockMembers();
@@ -73,7 +71,7 @@ describe('MembersTableService view member count', () => {
TestBed.configureTestingModule(
{
providers: [
- MembersTableService,
+ ElementsTableService,
{provide: NgRedux, useClass: MockAppStore},
DataFilterPipe
@@ -83,94 +81,80 @@ describe('MembersTableService view member count', () => {
await TestBed.compileComponents();
injector = getTestBed();
- service = injector.get(MembersTableService);
+ service = injector.get(ElementsTableService);
store = injector.get(NgRedux)
})().then(done).catch(done.fail));
test('should return number of displayed members', () => {
- service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(<any>data);
+ service.modalInformation = <any>{
+ uniqObjectField : "instanceId"
+ };
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>data);
service.filteredMembers = <any>data;
- expect(service.calculateNotHideVnfMembers()).toEqual(2);
+ expect(service.calculateNotHideRows()).toEqual(2);
});
test('should return number of selected members', () => {
- service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(<any>data);
- service.allMemberStatusMap['VNF1_INSTANCE_ID'].isSelected = true;
- service.allMemberStatusMap['VNF2_INSTANCE_ID'].isSelected = true;
- expect(service.calculateSelectedVnfMembers()).toEqual(2);
+ ElementsTableService.uniqObjectField = "instanceId";
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>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.allMemberStatusMap = MembersTableService.generateAllMembersStatus(<any>data);
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>data);
service.filteredMembers = <any>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(<any>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']));
+ 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 = MembersTableService.generateAllMembersStatus(<any>data);
+ let allMemberStatusMapMock = service.generateAllMembersStatus(<any>data);
for (const key in allMemberStatusMapMock) {
expect(allMemberStatusMapMock[key].isSelected).toBeFalsy();
}
});
test('changeAllCheckboxStatus', () => {
+ service.modalInformation = <any>{
+ type : 'SomeType',
+ uniqObjectField : 'instanceId'
+ };
let data = loadMockMembers();
- service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(<any>data);
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>data);
service.filteredMembers = <any>data;
service.changeAllCheckboxStatus(true);
- for (let key in service.allMemberStatusMap) {
- expect(service.allMemberStatusMap[key].isSelected).toEqual(true);
+ for (let key in service.allElementsStatusMap) {
+ expect(service.allElementsStatusMap[key].isSelected).toEqual(true);
}
});
test('should reset all numbers and lists', () => {
+ service.modalInformation = <any>{
+ type : 'SomeType',
+ uniqObjectField : 'instanceId'
+ };
let data = loadMockMembers();
- service.allMemberStatusMap = MembersTableService.generateAllMembersStatus(<any>data);
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>data);
service.filteredMembers = <any>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({});
+ 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.allMemberStatusMap = MembersTableService.generateAllMembersStatus(<any>loadMockMembers());
- service.updateAmountsAndCheckAll();
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>loadMockMembers());
+ service.updateAmountsAndCheckAll("instanceId", <any>{});
expect(service.allCheckboxAreSelected).toEqual(false);
});
@@ -178,7 +162,7 @@ describe('MembersTableService view member count', () => {
test('sortVnfMembersByName should sort list by vnf name', () => {
let data = <any>loadMockMembers();
- let sortedList = MembersTableService.sortVnfMembersByName(data, "instanceName");
+ let sortedList = service.sortElementsByName(data, "instanceName");
expect(sortedList[0].instanceName).toEqual("VNF1_INSTANCE_NAME");
expect(sortedList[1].instanceName).toEqual("VNF2_INSTANCE_NAME");
@@ -187,22 +171,63 @@ describe('MembersTableService view member count', () => {
data[0] = data[1];
data[1] = tmp;
- sortedList = MembersTableService.sortVnfMembersByName(data, "instanceName");
+ sortedList = service.sortElementsByName(data, "instanceName");
expect(sortedList[1].instanceName).toEqual("VNF1_INSTANCE_NAME");
expect(sortedList[0].instanceName).toEqual("VNF2_INSTANCE_NAME");
- sortedList = MembersTableService.sortVnfMembersByName(null, "instanceName");
+ sortedList = service.sortElementsByName(null, "instanceName");
expect(sortedList).toEqual([]);
- sortedList = MembersTableService.sortVnfMembersByName(data, undefined);
+ sortedList = service.sortElementsByName(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");
+ 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 = <any>{
+ uniqObjectField : "instanceId"
+ };
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>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(<any>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 = <any>{
+ uniqObjectField : "instanceId"
+ };
+ service.allElementsStatusMap = service.generateAllMembersStatus(<any>data);
+ service.allElementsStatusMap['VNF1_INSTANCE_ID'].isSelected = true;
+ service.allElementsStatusMap['VNF2_INSTANCE_ID'].isSelected = true;
+
+ let isDisabled = service.isCheckAllDisabled( 2);
+ expect(isDisabled).toBeFalsy();
});
+
});
@@ -214,7 +239,7 @@ function loadMockMembers(): any[] {
"instanceId": "VNF1_INSTANCE_ID",
"orchStatus": null,
"productFamilyId": null,
- "lcpCloudRegionId": "mtn23b",
+ "lcpCloudRegionId": "hvf23b",
"tenantId": "3e9a20a3e89e45f884e09df0cc2d2d2a",
"tenantName": "APPC-24595-T-IST-02C",
"modelInfo": {
@@ -242,7 +267,7 @@ function loadMockMembers(): any[] {
"instanceId": "VNF2_INSTANCE_ID",
"orchStatus": null,
"productFamilyId": null,
- "lcpCloudRegionId": "mtn23b",
+ "lcpCloudRegionId": "hvf23b",
"tenantId": "3e9a20a3e89e45f884e09df0cc2d2d2a",
"tenantName": "APPC-24595-T-IST-02C",
"modelInfo": {
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<any> = new Subject();
+ static changeModalInformationDataTrigger : Subject<{modalInformation, selectedRowsIds}> = new Subject();
+ static selectRowsTrigger : Subject<string[]> = new Subject();
+
+ get staticUniqObjectField() { return ElementsTableService.uniqObjectField; }
+
+ constructor(private _store: NgRedux<AppState>, 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 @@
-<div class="table-header">
- <div class="left-header">
- <span class="title-header">{{description}}</span>
- <div class="sub-title-header">
- <span class="vnf-match-your-criteria" class="total" [attr.data-tests-id]="'total-amount'" style="margin-right: 5px;"><span
- [attr.data-tests-id]="'numberOfNotHideVnfMembers'">{{membersTableService.numberOfNotHideVnfMembers}}</span> VNFs match your criteria</span>
- <span class="vnf-selected" class="total" [attr.data-tests-id]="'total-selected'"><span
- [attr.data-tests-id]="'numberOfSelectedVnfMembers'">{{membersTableService.numberOfSelectedVnfMembers}}</span> VNF{{membersTableService.numberOfSelectedVnfMembers>1?'s':'' }} selected</span>
- </div>
- </div>
-
- <div class="search-container">
- <sdc-filter-bar
- [placeHolder]="'Search...'"
- [debounceTime]="250"
- [testId]="'vnf-members-search'"
- (valueChange)="search($event)">
- </sdc-filter-bar>
- </div>
-</div>
-<table id="member-table" class="table table-bordered" *ngIf="data?.length > 0">
- <thead class="thead-dark">
- <tr>
- <th class="allCheckboxAreSelected" style="position: relative;">
- <sdc-checkbox
- [(checked)]="membersTableService.allCheckboxAreSelected"
- [testId]="'all-checkbox-selected'"
- (checkedChange)="changeAllCheckboxStatus($event)"
- ></sdc-checkbox>
- </th>
- <th class="header-title" *ngFor="let header of headers">{{header.displayName}}</th>
- </tr>
- </thead>
- <tbody>
- <tr class="member-table-row" *ngFor="let vnf of membersTableService.filteredMembers">
- <td class="sdcCheckboxMember" style="position: relative;" [attr.data-tests-id]="vnf?.instanceId">
- <sdc-checkbox
- [checked]="membersTableService.allMemberStatusMap[vnf.instanceId]?.isSelected"
- [testId]="vnf?.instanceId"
- (checkedChange)="changeCheckboxStatus(vnf.instanceId)"
- ></sdc-checkbox></td>
- <td id="vnfName">
- <custom-ellipsis [id]="vnf?.instanceName" [value]="vnf?.instanceName"
- [hightlight]="filterValue"></custom-ellipsis>
- <custom-ellipsis class="second-line" [id]="vnf?.instanceId" [value]="'UUID: '+ vnf?.instanceId"
- [hightlight]="filterValue"></custom-ellipsis>
- </td>
- <td id="version">
- <custom-ellipsis [id]="vnf?.modelInfo?.modelVersion" [value]="vnf?.modelInfo?.modelVersion" [hightlight]="filterValue"></custom-ellipsis>
- </td>
- <td id="modelName">
- <custom-ellipsis [id]="vnf?.modelInfo?.modelName" [value]="vnf?.modelInfo?.modelName" [hightlight]="filterValue"></custom-ellipsis>
- </td>
- <td id="provStatus">
- <custom-ellipsis [id]="vnf?.provStatus" [value]="vnf?.provStatus" [hightlight]="filterValue"></custom-ellipsis>
- </td>
- <td id="serviceInstance">
- <custom-ellipsis [id]="vnf?.serviceInstanceName" [value]="vnf?.serviceInstanceName"
- [hightlight]="filterValue"></custom-ellipsis>
- <custom-ellipsis class="second-line" [id]="vnf?.serviceInstanceId" [value]="'UUID: '+ vnf?.serviceInstanceId"
- [hightlight]="filterValue"></custom-ellipsis>
- </td>
- <td id="cloudRegion">
- <custom-ellipsis [id]="vnf?.lcpCloudRegionId" [value]="vnf?.lcpCloudRegionId" [hightlight]="filterValue"></custom-ellipsis>
- </td>
- <td id="tenantName">
- <custom-ellipsis [id]="vnf?.tenantName" [value]="vnf?.tenantName" [hightlight]="filterValue"></custom-ellipsis>
- </td>
- </tr>
-
- </tbody>
-</table>
-<div class="no-result" *ngIf="data?.length == 0">No VNFs were found that can belong to this group.</div>
-
-
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<number> = 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.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<AppState>, 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 @@
+<div class="modal-search-member-content">
+ <div class="header">
+ <vid-svg-icon
+ [attr.data-tests-id]="'cancelBtn'"
+ (click)="backAction()"
+ class="navigation-arrow-back"
+ [mode]="'primary'"
+ [size]="'large'"
+ [name]="'navigation-arrow-back'"
+ [clickable]="true"
+ [fill]="'#FFFFFF'"
+ [widthViewBox]="'24'"
+ [heightViewBox]="'24'">
+ </vid-svg-icon>
+
+ <span class="title">
+ {{modalInformation.title}}
+ </span>
+ <button type="submit" data-tests-id="setMembersBtn" [disabled]="disableSetElements" (click)="doneAction()" class="sdc-button sdc-button__primary">{{modalInformation?.topButton?.text}}</button>
+ </div>
+ <div class="content-wrapper">
+ <div class="sidebar-left">
+ <div class="search-criteria-wrapper">
+ <div class="search-criteria-title">SEARCH CRITERIA</div>
+ <div class="search-item" *ngFor="let searchFieldItem of modalInformation?.searchFields">
+ <div>
+ <div><span class="label-item" >{{searchFieldItem.title}}</span></div>
+ <div><span attr.data-tests-id="{{searchFieldItem.dataTestId}}" class="text-item">{{searchFieldItem.value}}</span></div>
+ </div>
+ </div>
+ <div class="search-item" *ngFor="let criteria of modalInformation?.criteria">
+ <div *ngIf="criteria.type === 'DROPDOWN'">
+ <div><span class="label-item" [ngClass]="{'required': criteria.isRequired}">{{criteria.label}}</span></div>
+ <div>
+ <select class="form-control input-text select-criteria"
+ id="{{criteria?.dataTestId}}-select"
+ [attr.data-tests-id]="criteria?.dataTestId"
+ (change)="criteria.onChange(criteria, $event.target.value)">
+
+ <option *ngFor="let option of criteria.onInit() | async"
+ class="{{option}} {{option}}-Option"
+ [value]="option">{{option}}
+ </option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="search-button" *ngIf="modalInformation.criteria && modalInformation.criteria.length > 0">
+ <button type="submit"
+ data-tests-id="searchByNetworkRole"
+ [disabled]="disableSearchByNetworkRole"
+ (click)="searchByCriteriaAction()"
+ class="sdc-button sdc-button__primary">Search...</button>
+ </div>
+ </div>
+ </div>
+ <div class="sidebar-right">
+ <app-members-table
+ [data]="elementsData"
+ [modalInformation]="modalInformation"
+ (selectedMembersAmountChange)="selectedMembersAmountChange($event)"></app-members-table>
+ </div>
+ </div>
+</div>
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-elements-modal.component.scss
index d49653934..7d9d139d1 100644
--- a/vid-webpack-master/src/app/shared/components/searchMembersModal/search-members-modal.component.scss
+++ b/vid-webpack-master/src/app/shared/components/searchMembersModal/search-elements-modal.component.scss
@@ -44,12 +44,12 @@
}
.content-wrapper {
- display: flex;
.sidebar-left {
- flex-basis: 285px;
+ width: 20%;
border-right: 1px solid #D2D2D2;
height: calc(100vh - 60px);
+ float: left;
.search-criteria-wrapper{
@@ -82,8 +82,34 @@
}
.sidebar-right {
- flex: 1;
- margin: 80px 50px;
+ 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<AppState>) {
+ 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 @@
-<div class="modal-search-member-content">
- <div class="header">
- <vid-svg-icon
- [attr.data-tests-id]="'cancelBtn'"
- (click)="closeDialog()"
- class="navigation-arrow-back"
- [mode]="'primary'"
- [size]="'large'"
- [name]="'navigation-arrow-back'"
- [clickable]="true"
- [fill]="'#FFFFFF'"
- [widthViewBox]="'24'"
- [heightViewBox]="'24'">
- </vid-svg-icon>
-
- <span class="title">
- {{title}}
- </span>
- <button type="submit" data-tests-id="setMembersBtn" [disabled]="disableSetMembers" (click)="setMembers()" class="sdc-button sdc-button__primary">SET MEMBERS</button>
- </div>
- <div class="content-wrapper">
- <div class="sidebar-left">
- <div class="search-criteria-wrapper">
- <div class="search-criteria-title">SEARCH CRITERIA</div>
- <div class="search-item" *ngFor="let searchFieldItem of searchFields">
- <span class="label-item">{{searchFieldItem.title}}</span>
- <span attr.data-tests-id="{{searchFieldItem.dataTestId}}" class="text-item">{{searchFieldItem.value}}</span>
- </div>
- </div>
- </div>
- <div class="sidebar-right">
- <app-members-table [data]="membersData" [description]="description" (selectedMembersAmountChange)="selectedMembersAmountChange($event)"></app-members-table>
- </div>
- </div>
-</div>
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<PopupModel, boolean> 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();
- }
-}
-
-