aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab
diff options
context:
space:
mode:
authorys9693 <ys9693@att.com>2020-01-19 13:50:02 +0200
committerOfir Sonsino <ofir.sonsino@intl.att.com>2020-01-22 12:33:31 +0000
commit16a9fce0e104a38371a9e5a567ec611ae3fc7f33 (patch)
tree03a2aff3060ddb5bc26a90115805a04becbaffc9 /catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab
parentaa83a2da4f911c3ac89318b8e9e8403b072942e1 (diff)
Catalog alignment
Issue-ID: SDC-2724 Signed-off-by: ys9693 <ys9693@att.com> Change-Id: I52b4aacb58cbd432ca0e1ff7ff1f7dd52099c6fe
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab')
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.html47
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.spec.ts127
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.ts158
3 files changed, 332 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.html
new file mode 100644
index 0000000000..8c5c9c7663
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.html
@@ -0,0 +1,47 @@
+<!--
+ ~ Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<h1 class="w-sdc-designer-sidebar-section-title" tooltip="Members">Members
+ <svg-icon-label *ngIf="!isViewOnly"
+ class="add-members-btn"
+ name="plus-circle-o"
+ mode="primary"
+ size="medium"
+ label="ADD"
+ labelPlacement="right"
+ (click)="openAddMembersModal()">
+ </svg-icon-label>
+</h1>
+<div class="expand-collapse-content">
+ <ul>
+ <li *ngFor="let member of members; let i = index" class="component-details-panel-large-item"
+ tooltip="{{member.name}}">
+ <span>{{member.name}}</span>
+ <svg-icon-label *ngIf="!isViewOnly"
+ name="trash-o"
+ clickable="true"
+ size="small"
+ class="component-details-panel-item-delete"
+ data-tests-id="delete_member"
+ (click)="deleteMember(member)"></svg-icon-label>
+ </li>
+ </ul>
+
+ <div *ngIf="!members || members.length===0" class="component-details-panel-tab-no-data">
+ <div class="component-details-panel-tab-no-data-title">No data to display yet</div>
+ <div class="component-details-panel-tab-no-data-content">Add members to group to see members</div>
+ </div>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.spec.ts
new file mode 100644
index 0000000000..43f6aac2c7
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.spec.ts
@@ -0,0 +1,127 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { async, ComponentFixture } from '@angular/core/testing';
+import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular';
+import { Observable } from 'rxjs/Rx';
+import { Mock } from 'ts-mockery';
+import { ConfigureFn, configureTests } from '../../../../../../../jest/test-config.helper';
+import { ComponentMetadata } from '../../../../../../models/component-metadata';
+import { GroupInstance } from '../../../../../../models/graph/zones/group-instance';
+import { EventListenerService } from '../../../../../../services/event-listener-service';
+import { GroupsService } from '../../../../../services/groups.service';
+import { TranslateService } from '../../../../../shared/translator/translate.service';
+import { WorkspaceService } from '../../../../workspace/workspace.service';
+import { CompositionService } from '../../../composition.service';
+import { GroupMembersTabComponent } from './group-members-tab.component';
+
+describe('group members tab component', () => {
+
+ let fixture: ComponentFixture<GroupMembersTabComponent>;
+
+ // Mocks
+ let workspaceServiceMock: Partial<WorkspaceService>;
+ let eventsListenerServiceMock: Partial<EventListenerService>;
+ let groupServiceMock: Partial<GroupsService>;
+ let loaderServiceMock: Partial<SdcUiServices.LoaderService>;
+ let compositionServiceMock: Partial<CompositionService>;
+ let modalServiceMock: Partial<SdcUiServices.ModalService>;
+
+ const membersToAdd = [
+ {uniqueId: '1', name: 'inst1'},
+ {uniqueId: '2', name: 'inst2'},
+ ];
+
+ beforeEach(
+ async(() => {
+
+ eventsListenerServiceMock = {};
+
+ groupServiceMock = Mock.of<GroupsService>(
+ {
+ updateMembers: jest.fn().mockImplementation((compType, uid, groupUniqueId, updatedMembers) => {
+ if (updatedMembers === undefined) {
+ return Observable.throwError('error');
+ } else {
+ return Observable.of(updatedMembers);
+ }
+ }
+ )});
+
+ compositionServiceMock = {
+ getComponentInstances: jest.fn().mockImplementation( () => {
+ return [{uniqueId: '1', name: 'inst1'},
+ {uniqueId: '2', name: 'inst2'},
+ {uniqueId: '3', name: 'inst3'},
+ {uniqueId: '4', name: 'inst4'},
+ {uniqueId: '5', name: 'inst5'}
+ ];
+ }
+ )
+ };
+
+ workspaceServiceMock = {
+ metadata: Mock.of<ComponentMetadata>()
+ };
+
+ const addMemberModalInstance = {
+ innerModalContent: { instance: { existingElements: membersToAdd }},
+ closeModal: jest.fn()
+ };
+
+ modalServiceMock = {
+ openInfoModal: jest.fn(),
+ openCustomModal: jest.fn().mockImplementation(() => addMemberModalInstance)
+ };
+
+ loaderServiceMock = {
+ activate: jest.fn(),
+ deactivate: jest.fn()
+ };
+
+ const groupInstanceMock = Mock.of<GroupInstance>();
+
+ const configure: ConfigureFn = (testBed) => {
+ testBed.configureTestingModule({
+ declarations: [GroupMembersTabComponent],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [
+ {provide: TranslateService, useValue: { translate: jest.fn() }},
+ {provide: GroupsService, useValue: groupServiceMock},
+ {provide: SdcUiServices.ModalService, useValue: modalServiceMock },
+ {provide: EventListenerService, useValue: eventsListenerServiceMock },
+ {provide: CompositionService, useValue: compositionServiceMock },
+ {provide: WorkspaceService, useValue: workspaceServiceMock},
+ {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock }
+ ],
+ });
+ };
+
+ configureTests(configure).then((testBed) => {
+ fixture = testBed.createComponent(GroupMembersTabComponent);
+ fixture.componentInstance.group = groupInstanceMock;
+ });
+ })
+ );
+
+ it('test that initially all members are available for adding', () => {
+ const testedComponent = fixture.componentInstance;
+
+ // No members are currently in the group, all 5 members should be returned
+ const optionalMembersToAdd = testedComponent.getOptionalsMembersToAdd();
+ expect(optionalMembersToAdd).toHaveLength(5);
+ });
+
+ it('test list of available instances to add does not include existing members', () => {
+ const testedComponent = fixture.componentInstance;
+
+ // Mock the group instance to return the members that we are about to add
+ testedComponent.group.getMembersAsUiObject = jest.fn().mockImplementation( () => membersToAdd);
+
+ // The opened modal shall return 2 members to be added
+ testedComponent.openAddMembersModal();
+ testedComponent.addMembers(); // Shall add 2 members (1,2)
+
+ // Now the getOptionalsMembersToAdd shall return 3 which are the members that were no added yet
+ const optionalMembersToAdd = testedComponent.getOptionalsMembersToAdd();
+ expect(optionalMembersToAdd).toHaveLength(3);
+ });
+});
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.ts
new file mode 100644
index 0000000000..7f1222367d
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/group-members-tab/group-members-tab.component.ts
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
+import { Select } from '@ngxs/store';
+import { GroupInstance } from 'app/models/graph/zones/group-instance';
+import { CompositionService } from 'app/ng2/pages/composition/composition.service';
+import { WorkspaceService } from 'app/ng2/pages/workspace/workspace.service';
+import { EventListenerService } from 'app/services/event-listener-service';
+import { GRAPH_EVENTS } from 'app/utils';
+import * as _ from 'lodash';
+import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular';
+import { Observable, Subscription } from 'rxjs';
+import { tap } from 'rxjs/operators';
+import { ComponentInstance } from '../../../../../../models/componentsInstances/componentInstance';
+import { MemberUiObject } from '../../../../../../models/ui-models/ui-member-object';
+import { AddElementsComponent } from '../../../../../components/ui/modal/add-elements/add-elements.component';
+import {GraphState} from "../../../common/store/graph.state";
+import { GroupsService } from '../../../../../services/groups.service';
+import { TranslateService } from '../../../../../shared/translator/translate.service';
+
+@Component({
+ selector: 'group-members-tab',
+ templateUrl: './group-members-tab.component.html',
+ styleUrls: ['./../policy-targets-tab/policy-targets-tab.component.less']
+})
+
+export class GroupMembersTabComponent implements OnInit, OnDestroy {
+
+ @Input() group: GroupInstance;
+ @Input() isViewOnly: boolean;
+ @Select(GraphState.getSelectedComponent) group$: Observable<GroupInstance>;
+ @HostBinding('class') classes = 'component-details-panel-tab-group-members';
+
+ private members: MemberUiObject[];
+ private addMemberModalInstance: SdcUiComponents.ModalComponent;
+ private subscription: Subscription;
+
+ constructor(
+ private translateService: TranslateService,
+ private groupsService: GroupsService,
+ private modalService: SdcUiServices.ModalService,
+ private eventListenerService: EventListenerService,
+ private compositionService: CompositionService,
+ private workspaceService: WorkspaceService,
+ private loaderService: SdcUiServices.LoaderService
+ ) {
+ }
+
+ ngOnInit() {
+ this.subscription = this.group$.pipe(
+ tap((group) => {
+ this.group = group;
+ this.members = this.group.getMembersAsUiObject(this.compositionService.componentInstances);
+ })).subscribe();
+ }
+
+ ngOnDestroy() {
+ if (this.subscription) {
+ this.subscription.unsubscribe();
+ }
+ }
+
+ deleteMember = (member: MemberUiObject): void => {
+ this.loaderService.activate();
+ this.groupsService.deleteGroupMember(
+ this.workspaceService.metadata.componentType,
+ this.workspaceService.metadata.uniqueId,
+ this.group,
+ member.uniqueId).subscribe(
+ (updatedMembers: string[]) => {
+ this.group.members = updatedMembers;
+ this.initMembers();
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.group);
+ },
+ () => console.log('Error deleting member!'),
+ () => this.loaderService.deactivate()
+ );
+ }
+
+ addMembers = (): void => {
+ // TODO refactor sdc-ui modal in order to return the data
+ const membersToAdd: MemberUiObject[] = this.addMemberModalInstance.innerModalContent.instance.existingElements;
+ if (membersToAdd.length > 0) {
+ this.addMemberModalInstance.closeModal();
+ this.loaderService.activate();
+ const locallyUpdatedMembers: MemberUiObject[] = _.union(this.members, membersToAdd);
+ this.groupsService.updateMembers(
+ this.workspaceService.metadata.componentType,
+ this.workspaceService.metadata.uniqueId,
+ this.group.uniqueId,
+ locallyUpdatedMembers).subscribe(
+ (updatedMembers: string[]) => {
+ this.group.members = updatedMembers;
+ this.initMembers();
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.group);
+ },
+ () => {
+ console.log('Error updating members!');
+ }, () =>
+ this.loaderService.deactivate()
+ );
+ }
+ }
+
+ getOptionalsMembersToAdd(): MemberUiObject[] {
+ const optionalsMembersToAdd: MemberUiObject[] = [];
+ // adding all instances as optional members to add if not already exist
+ _.forEach(this.compositionService.getComponentInstances(), (instance: ComponentInstance) => {
+ if (!_.some(this.members, (member: MemberUiObject) => {
+ return member.uniqueId === instance.uniqueId;
+ })) {
+ optionalsMembersToAdd.push(new MemberUiObject(instance.uniqueId, instance.name));
+ }
+ });
+ return optionalsMembersToAdd;
+ }
+
+ openAddMembersModal(): void {
+ const addMembersModalConfig = {
+ title: this.group.name + ' ADD MEMBERS',
+ size: 'md',
+ type: SdcUiCommon.ModalType.custom,
+ testId: 'addMembersModal',
+ buttons: [
+ {text: 'ADD MEMBERS', size: 'medium', callback: this.addMembers, closeModal: false},
+ {text: 'CANCEL', size: 'sm', type: 'secondary', closeModal: true}
+ ]
+ } as SdcUiCommon.IModalConfig;
+ const optionalsMembersToAdd = this.getOptionalsMembersToAdd();
+ this.addMemberModalInstance = this.modalService.openCustomModal(addMembersModalConfig, AddElementsComponent, {
+ elementsToAdd: optionalsMembersToAdd,
+ elementName: 'member'
+ });
+ }
+
+ private initMembers = (groupInstance?: GroupInstance) => {
+ this.group = groupInstance ? groupInstance : this.group;
+ this.members = this.group.getMembersAsUiObject(this.compositionService.getComponentInstances());
+ }
+}