aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab')
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.html48
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.less61
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.spec.ts113
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.ts166
4 files changed, 388 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.html
new file mode 100644
index 0000000000..838fd8bb51
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.html
@@ -0,0 +1,48 @@
+<!--
+ ~ 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" titleTooltip="Targets">Targets
+ <svg-icon-label *ngIf="!isViewOnly"
+ class="add-policy-button"
+ name="plus-circle-o"
+ mode="primary"
+ size="medium"
+ label="ADD"
+ labelPlacement="right"
+ (click)="openAddTargetModal()">
+ </svg-icon-label>
+</h1>
+<div class="expand-collapse-content">
+ <ul>
+ <li *ngFor="let target of targets; let i = index" class="component-details-panel-large-item"
+ tooltip="{{target.name}}">
+ <span>{{target.name}}</span>
+ <svg-icon-label *ngIf="!isViewOnly"
+ name="trash-o"
+ clickable="true"
+ size="small"
+ class="component-details-panel-item-delete"
+ data-tests-id="delete_target"
+ (click)="deleteTarget(target)"></svg-icon-label>
+ </li>
+ </ul>
+
+ <div *ngIf="!targets || targets.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 targets to policy to see targets</div>
+ </div>
+</div>
+
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.less
new file mode 100644
index 0000000000..d16a1595df
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.less
@@ -0,0 +1,61 @@
+@import './../../../../../../../assets/styles/mixins';
+
+
+.expand-collapse-content {
+ padding: 20px;
+}
+
+.component-details-panel-tab-no-data {
+ margin: 0 auto;
+ padding-top: 30px;
+ text-align: center;
+
+ .component-details-panel-tab-no-data-title {
+ font-family: @font-opensans-bold;
+ }
+
+}
+
+.component-details-panel-large-item {
+ font-family: OpenSans-Semibold, sans-serif;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ height: 32px;
+ line-height: 32px;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+
+ &:hover {
+ background-color: #f8f8f8;
+ margin: 0 -20px; /* to fill expand-collapse-content padding */
+ padding: 0 20px;
+ .component-details-panel-item-delete {
+ visibility: visible;
+ }
+ }
+}
+
+.component-details-panel-item-delete {
+ cursor: pointer;
+ visibility: hidden;
+}
+
+/deep/ .w-sdc-designer-sidebar-section-title {
+ color: #5a5a5a;
+ font-family: OpenSans-Semibold, sans-serif;
+ font-size: 14px;
+ background-color: #eaeaea;
+ cursor: pointer;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ text-transform: uppercase;
+ line-height: 32px;
+ padding: 0 10px 0 20px;
+ margin-top: 1px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.spec.ts
new file mode 100644
index 0000000000..7774138cab
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.spec.ts
@@ -0,0 +1,113 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { async, ComponentFixture, TestBed } 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 { EventListenerService } from '../../../../../../services/event-listener-service';
+import { TranslateService } from '../../../../../shared/translator/translate.service';
+import { WorkspaceService } from '../../../../workspace/workspace.service';
+import { CompositionService } from '../../../composition.service';
+import { PolicyTargetsTabComponent } from "app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component";
+import { PoliciesService } from "app/services-ng2";
+import { PolicyInstance, GroupInstance } from "app/models";
+import { NgxsModule } from "@ngxs/store";
+import { GraphState } from "app/ng2/pages/composition/common/store/graph.state";
+import { WorkspaceState } from "app/ng2/store/states/workspace.state";
+import { TargetUiObject } from "app/models/ui-models/ui-target-object";
+import { TargetOrMemberType } from "app/utils";
+
+
+
+
+describe('policy targets tab component', () => {
+
+ let fixture: ComponentFixture<PolicyTargetsTabComponent>;
+ let component: PolicyTargetsTabComponent;
+
+ let policiesServiceMock = Mock.of<PoliciesService>(
+ {
+ updateTargets: jest.fn().mockImplementation((compType, uid, policyUniqueId, updatedTargets) => {
+ if (updatedTargets === undefined) {
+ return Observable.throwError('error');
+ } else {
+ return Observable.of(updatedTargets);
+ }
+ }
+ )});
+
+ let compositionServiceMock = {
+ componentInstances: [{uniqueId: '1', name: 'inst1'},
+ {uniqueId: '2', name: 'inst2'},
+ {uniqueId: '3', name: 'inst3'},
+ {uniqueId: '4', name: 'inst4'},
+ {uniqueId: '5', name: 'inst5'}
+ ],
+ groupInstances : [
+ Mock.of<GroupInstance>({uniqueId: "group1", name: "group1"}),
+ Mock.of<GroupInstance>({uniqueId: "group2", name: "group2"}),
+ Mock.of<GroupInstance>({uniqueId: "group3", name: "group3"})
+ ]
+ };
+
+ let workspaceServiceMock = {
+ metadata: Mock.of<ComponentMetadata>()
+ };
+
+ let modalServiceMock = {
+ openInfoModal: jest.fn(),
+ openCustomModal: jest.fn().mockImplementation(() => { return {
+ innerModalContent: { instance: { existingElements: targetsToAdd }},
+ closeModal: jest.fn()
+ }})
+ };
+
+ let loaderServiceMock = {
+ activate: jest.fn(),
+ deactivate: jest.fn()
+ };
+
+ const targetsToAdd = [
+ <TargetUiObject>{uniqueId: '1', name: 'inst1', type: TargetOrMemberType.COMPONENT_INSTANCES},
+ <TargetUiObject>{uniqueId: "group1", name: "group1", type: TargetOrMemberType.GROUPS}
+ ];
+
+ const policyInstanceMock = Mock.of<PolicyInstance>(
+ { getTargetsAsUiObject: jest.fn().mockImplementation( () => targetsToAdd)
+ });
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [PolicyTargetsTabComponent],
+ imports: [NgxsModule.forRoot([WorkspaceState])],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [
+ {provide: TranslateService, useValue: { translate: jest.fn() }},
+ {provide: PoliciesService, useValue: policiesServiceMock},
+ {provide: SdcUiServices.ModalService, useValue: modalServiceMock },
+ {provide: EventListenerService, useValue: {} },
+ {provide: CompositionService, useValue: compositionServiceMock },
+ {provide: WorkspaceService, useValue: workspaceServiceMock},
+ {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock }
+ ],
+ });
+
+ fixture = TestBed.createComponent(PolicyTargetsTabComponent);
+ component = fixture.componentInstance;
+ component.policy = policyInstanceMock;
+ });
+
+
+ it('if there are no existing targets, all component instances AND all groups are available for adding', () => {
+ component.targets = [];
+ const optionalTargetsToAdd = component.getOptionalsTargetsToAdd();
+ expect(optionalTargetsToAdd).toHaveLength(8);
+ });
+
+ it('list of available instances to add does not include existing targets', () => {
+ component.targets = targetsToAdd;
+ const optionalMembersToAdd = component.getOptionalsTargetsToAdd();
+ expect(optionalMembersToAdd).toHaveLength(6);
+ });
+});
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.ts
new file mode 100644
index 0000000000..f117290397
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policy-targets-tab/policy-targets-tab.component.ts
@@ -0,0 +1,166 @@
+/*-
+ * ============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 * as _ from "lodash";
+import { Component, Input, Output, EventEmitter, OnChanges, HostBinding, OnDestroy, OnInit } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { PoliciesService } from "../../../../../services/policies.service";
+import { PolicyInstance } from './../../../../../../models/graph/zones/policy-instance';
+import { SdcUiComponents, SdcUiCommon, SdcUiServices } from "onap-ui-angular";
+import { AddElementsComponent } from "../../../../../components/ui/modal/add-elements/add-elements.component";
+import { TargetUiObject } from "../../../../../../models/ui-models/ui-target-object";
+import { ComponentInstance } from "../../../../../../models/componentsInstances/componentInstance";
+import { TargetOrMemberType } from "../../../../../../utils/constants";
+import { GRAPH_EVENTS } from 'app/utils';
+import { EventListenerService } from 'app/services/event-listener-service';
+import { CompositionService } from "app/ng2/pages/composition/composition.service";
+import { WorkspaceService } from "app/ng2/pages/workspace/workspace.service";
+import { Store } from "@ngxs/store";
+import { Select } from "@ngxs/store";
+import { Observable } from "rxjs";
+import { tap } from "rxjs/operators";
+import {GraphState} from "../../../common/store/graph.state";
+
+@Component({
+ selector: 'policy-targets-tab',
+ templateUrl: './policy-targets-tab.component.html',
+ styleUrls: ['policy-targets-tab.component.less']
+})
+
+export class PolicyTargetsTabComponent implements OnInit {
+
+ @Input() input:any;
+
+
+ @Input() isViewOnly: boolean;
+ @HostBinding('class') classes = 'component-details-panel-tab-policy-targets';
+ @Select(GraphState.getSelectedComponent) policy$: Observable<PolicyInstance>;
+ public policy: PolicyInstance;
+ private subscription;
+
+ private addModalInstance: SdcUiComponents.ModalComponent;
+ public targets: Array<TargetUiObject>; // UI object to hold all targets with names.
+
+
+ constructor(private translateService: TranslateService,
+ private policiesService: PoliciesService,
+ private modalService: SdcUiServices.ModalService,
+ private eventListenerService: EventListenerService,
+ private compositionService: CompositionService,
+ private workspaceService: WorkspaceService,
+ private loaderService: SdcUiServices.LoaderService,
+ private store: Store
+ ) { }
+
+ ngOnInit() {
+ this.subscription = this.policy$.pipe(
+ tap((policy) => {
+ if(policy instanceof PolicyInstance){
+ this.policy = policy;
+ this.targets = this.policy.getTargetsAsUiObject(<ComponentInstance[]>this.compositionService.componentInstances, this.compositionService.groupInstances);
+ }
+ })).subscribe();
+ }
+
+ ngOnDestroy () {
+ if(this.subscription)
+ this.subscription.unsubscribe();
+ }
+
+ deleteTarget(target: TargetUiObject): void {
+ this.loaderService.activate();
+ this.policiesService.deletePolicyTarget(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.policy, target.uniqueId, target.type).subscribe(
+ (policyInstance:PolicyInstance) => {
+ this.targets = this.targets.filter(item => item.uniqueId !== target.uniqueId);
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, policyInstance);
+ // this.store.dispatch(new UpdateSelectedComponentAction({uniqueId: policyInstance.uniqueId, type:ComponentType.}));
+ },
+ error => {
+ console.log("Error deleting target!");
+ this.loaderService.deactivate();
+ },
+ () => this.loaderService.deactivate()
+ );
+ }
+
+
+ addTargets = ():void => {
+
+ var targetsToAdd:Array<TargetUiObject> = this.addModalInstance.innerModalContent.instance.existingElements; //TODO refactor sdc-ui modal in order to return the data
+ if(targetsToAdd.length > 0) {
+ this.addModalInstance.closeModal();
+ this.loaderService.activate();
+ var updatedTargets: Array<TargetUiObject> = _.union(this.targets, targetsToAdd);
+ this.policiesService.updateTargets(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.policy.uniqueId, updatedTargets).subscribe(
+ (updatedPolicyInstance:PolicyInstance) => {
+ this.targets = updatedTargets;
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, updatedPolicyInstance);
+ // this.store.dispatch(new UpdateSelectedComponentAction({component: updatedPolicyInstance}));
+ },
+ error => {
+ console.log("Error updating targets!");
+ this.loaderService.deactivate();
+ },
+ () => this.loaderService.deactivate()
+ );
+ }
+ }
+
+ getOptionalsTargetsToAdd():Array<TargetUiObject> {
+ let optionalsTargetsToAdd:Array<TargetUiObject> = [];
+ // adding all instances as optional targets to add if not already exist
+ _.forEach(this.compositionService.componentInstances, (instance:ComponentInstance) => {
+ if (!_.some(this.targets, (target:TargetUiObject) => {
+ return target.uniqueId === instance.uniqueId
+ })) {
+ optionalsTargetsToAdd.push(new TargetUiObject(instance.uniqueId, TargetOrMemberType.COMPONENT_INSTANCES, instance.name));
+ }
+ });
+
+ // adding all groups as optional targets to add if not already exist
+ _.forEach(this.compositionService.groupInstances, (groupInstance:ComponentInstance) => { // adding all instances as optional targets to add if not already exist
+ if (!_.some(this.targets, (target:TargetUiObject) => {
+ return target.uniqueId === groupInstance.uniqueId
+ })) {
+ optionalsTargetsToAdd.push(new TargetUiObject(groupInstance.uniqueId, TargetOrMemberType.GROUPS, groupInstance.name));
+ }
+ });
+
+ return optionalsTargetsToAdd;
+ }
+
+ openAddTargetModal(): void {
+ let addTargetModalConfig = {
+ title: this.policy.name + " ADD TARGETS",
+ size: "md",
+ type: SdcUiCommon.ModalType.custom,
+ testId: "addTargetsModal",
+ buttons: [
+ {text: "ADD TARGETS", size: 'xsm', callback: this.addTargets, closeModal: false},
+ {text: 'CANCEL', size: 'sm', type: "secondary", closeModal: true}
+ ]
+ } as SdcUiCommon.IModalConfig;
+ var optionalTargetsToAdd = this.getOptionalsTargetsToAdd();
+ this.addModalInstance = this.modalService.openCustomModal(addTargetModalConfig, AddElementsComponent, {
+ elementsToAdd: optionalTargetsToAdd,
+ elementName: "target"
+ });
+ }
+}