diff options
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone')
10 files changed, 645 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/__snapshots__/zone-container.component.spec.ts.snap b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/__snapshots__/zone-container.component.spec.ts.snap new file mode 100644 index 0000000000..d4e2a7a359 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/__snapshots__/zone-container.component.spec.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ZoneContainerComponent should match current snapshot of palette element component 1`] = ` +<zone-container + backgroundClick={[Function EventEmitter]} + backgroundClicked={[Function Function]} + minimize={[Function EventEmitter]} + unminifyZone={[Function Function]} +> + <div> + <div + class="sdc-canvas-zone__header" + > + <div + class="sdc-canvas-zone__title" + > + + <span + class="sdc-canvas-zone__counter" + > + + </span> + </div> + <span + class="sdc-canvas-zone__state-button" + > + – + </span> + </div> + <div + class="sdc-canvas-zone__container" + /> + </div> +</zone-container> +`; diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.html b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.html new file mode 100644 index 0000000000..d6343a4a4f --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.html @@ -0,0 +1,30 @@ +<!-- + ~ 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. + --> + + +<div class="sdc-canvas-zone {{class}}-zone" [class.minimized]="minimized" [class.hidden]="!visible" + (click)="backgroundClicked()"> + <div class="sdc-canvas-zone__header" (click)="unminifyZone(); $event.stopPropagation();"> + <div class="sdc-canvas-zone__title">{{title}} + <span class="sdc-canvas-zone__counter">{{count}}</span> + </div> + <span class="sdc-canvas-zone__state-button">–</span> + </div> + <div class="sdc-canvas-zone__container" #scrollDiv> + <ng-content></ng-content> + </div> +</div> + diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.less b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.less new file mode 100644 index 0000000000..827786cc49 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.less @@ -0,0 +1,62 @@ +.sdc-canvas-zone { + width: 285px; + max-height:186px; + display:flex; + flex-direction:column; + color:white; + font-family:OpenSans-Regular, sans-serif; + transition: width .2s ease-in-out, max-height .2s ease-in-out .1s; + position:relative; + bottom:0px; + margin-right: 5px; + + .sdc-canvas-zone__header { + background: #5A5A5A; + border-radius: 2px 2px 0 0; + padding: 5px 10px; + display:flex; + justify-content: space-between; + font-size: 14px; + text-transform:uppercase; + .sdc-canvas-zone__state-button { + font-weight:bold; + cursor:pointer; + } + } + + .sdc-canvas-zone__container { + padding:5px; + background-color: #5A5A5A; + opacity:0.9; + flex: 1; + display:flex; + flex-direction: row; + align-items: flex-start; + flex-wrap:wrap; + overflow-y:auto; + min-height: 80px; + max-height: 170px; + } + + + &.minimized { + max-height:30px; + width:120px; + cursor:pointer; + + .sdc-canvas-zone__state-button { + display:none; + } + .sdc-canvas-zone__container { + flex: 0 0 0; + min-height: 0; + padding: 0; + overflow-y:hidden; + transition: min-height .2s ease-in-out .2s; + transition: padding .1s ease-in-out 0s; + } + } + &.hidden { + display:none; + } +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.spec.ts new file mode 100644 index 0000000000..c432054492 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.spec.ts @@ -0,0 +1,46 @@ +import {async, ComponentFixture} from '@angular/core/testing'; +import {By} from '@angular/platform-browser'; +import {ConfigureFn, configureTests} from '../../../../../../jest/test-config.helper'; +import 'jest-dom/extend-expect'; +import {ZoneInstanceType} from '../../../../../../app/models/graph/zones/zone-instance'; +import {ZoneContainerComponent} from './zone-container.component'; + + +describe('ZoneContainerComponent', () => { + let fixture: ComponentFixture<ZoneContainerComponent>; + + beforeEach( + async(() => { + const configure: ConfigureFn = testBed => { + testBed.configureTestingModule({ + declarations: [ZoneContainerComponent] + }); + }; + + configureTests(configure).then(testBed => { + fixture = testBed.createComponent(ZoneContainerComponent); + }); + }) + ); + + + it('should match current snapshot of palette element component', () => { + expect(fixture).toMatchSnapshot(); + }); + + it('should have a group-zone class when the ZoneInstanceType is GROUP', + () => { + fixture.componentInstance.type = ZoneInstanceType.GROUP; + fixture.detectChanges(); + const compiled = fixture.debugElement.query(By.css('.sdc-canvas-zone')); + expect(compiled.nativeElement).toHaveClass('group-zone'); + }); + + it('should have a policy-zone class when the ZoneInstanceType is POLICY', + () => { + fixture.componentInstance.type = ZoneInstanceType.POLICY; + fixture.detectChanges(); + const compiled = fixture.debugElement.query(By.css('.sdc-canvas-zone')); + expect(compiled.nativeElement).toHaveClass('policy-zone'); + }); +});
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.ts b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.ts new file mode 100644 index 0000000000..4757c1f36d --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-container.component.ts @@ -0,0 +1,35 @@ +import { Component, Input, Output, ViewEncapsulation, EventEmitter, OnInit } from '@angular/core'; +import { ZoneInstanceType } from 'app/models/graph/zones/zone-instance'; + +@Component({ + selector: 'zone-container', + templateUrl: './zone-container.component.html', + styleUrls: ['./zone-container.component.less'], + encapsulation: ViewEncapsulation.None +}) + +export class ZoneContainerComponent implements OnInit { + @Input() title:string; + @Input() type:ZoneInstanceType; + @Input() count:number; + @Input() visible:boolean; + @Input() minimized:boolean; + @Output() minimize: EventEmitter<any> = new EventEmitter<any>(); + @Output() backgroundClick: EventEmitter<void> = new EventEmitter<void>(); + private class:string; + + constructor() {} + + ngOnInit() { + this.class = ZoneInstanceType[this.type].toLowerCase(); + } + + private unminifyZone = () => { + this.minimize.emit(); + } + + private backgroundClicked = () => { + this.backgroundClick.emit(); + } + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.html b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.html new file mode 100644 index 0000000000..d97be69e34 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.html @@ -0,0 +1,27 @@ +<!-- + ~ 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. + --> + + +<div #currentComponent class="zone-instance mode-{{zoneInstance.mode}}" [class.locked]="activeInstanceMode > MODE.HOVER" + [class.hiding]="hidden" + (mouseenter)="setMode(MODE.HOVER)" (mouseleave)="setMode(MODE.NONE)" (click)="setMode(MODE.SELECTED, $event)"> + <div class="zone-instance__body" sdc-tooltip tooltip-text="{{zoneInstance.instanceData.name}}" [attr.data-tests-id]="zoneInstance.instanceData.name"> + <div *ngIf="zoneInstance.handle" class="target-handle {{zoneInstance.handle}}" + (click)="tagHandleClicked($event)"></div> + <div *ngIf="!isViewOnly" class="zone-instance__handle" (click)="setMode(MODE.TAG, $event)">+</div> + <div class="zone-instance__body-content">{{zoneInstance.assignments.length || defaultIconText}}</div> + </div> + <div class="zone-instance__name">{{zoneInstance.instanceData.name}}</div> +</div> diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.less b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.less new file mode 100644 index 0000000000..c34b8e149a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.less @@ -0,0 +1,135 @@ +@import '../../../../../../../assets/styles/variables'; + +.zone-instance { + + width:76px; + margin:5px; + opacity:1; + + .zone-instance__handle { + display:none; + position:absolute; + left: 31px; + top: 8px; + width:22px; + height:22px; + cursor:pointer; + border: solid @main_color_p 1px; + border-radius: 2px; + text-align: center; + font-weight:bold; + } + + .zone-instance__body { + position:relative; + margin:0 auto; + width:43px; + height:43px; + display:flex; + padding:3px; + } + + .zone-instance__body-content { + border-radius: 2px; + flex:1; + color:@main_color_p; + font-size:16px; + text-align:center; + display:flex; + align-items: center; + justify-content: center; + box-shadow:none; + transition:box-shadow 5s; + } + + .zone-instance__name { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + text-align:center; + } + /* Dynamic classes below */ + + .target-handle { + position:absolute; + width:18px; + height:18px; + display:block; + top: -4px; + right: -6px; + background-size: 100% 100%; + cursor: url("../../../../../../../assets/styles/images/canvas-tagging-icons/policy_2.svg"), pointer; + + &.tagged-policy { + background-image: url('../../../../../../../assets/styles/images/canvas-tagging-icons/policy_added.svg'); + } + + &.tag-available { + background-image: url('../../../../../../../assets/styles/images/canvas-tagging-icons/indication.svg'); + } + } + + + &.mode-1, &.mode-2, &.mode-3 { //hover, selected, tag + .zone-instance__body { + border:solid 2px; + border-radius: 2px; + padding:2px; + cursor:pointer; + } + } + + &.mode-1, &.mode-2:hover{ + .zone-instance__handle{ + display:block; + } + } + + &.locked { + cursor: inherit; + } + + &.hiding { + opacity:0; + .zone-instance__body-content { + box-shadow: #CCC 0px 0px 15px; + } + } + + + &.mode-3 .zone-instance__handle { + width:24px; + height:24px; + right:-6px; + top:7px; + display:block; + background-image: linear-gradient(-140deg, #009E98 0%, #97D648 100%); + border: 2px solid @main_color_p; + border-radius: 2px; + box-shadow: inset 2px -2px 3px 0 #007A3E; + } + +} +.sdc-canvas-zone.group-zone { + .zone-instance__handle { + background-color:@main_color_a; + } + .zone-instance__body { + border-color:@main_color_a; + .zone-instance__body-content { + background: @main_color_a; + } + } +} + +.sdc-canvas-zone.policy-zone { + .zone-instance__handle { + background-color:@main_color_r; + } + .zone-instance__body { + border-color:@main_color_r; + .zone-instance__body-content { + background: @main_color_r; + } + } +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.spec.ts new file mode 100644 index 0000000000..f5a5f6f546 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.spec.ts @@ -0,0 +1,132 @@ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { SimpleChanges } from '@angular/core'; +import { PoliciesService } from 'app/ng2/services/policies.service'; +import { GroupsService } from 'app/ng2/services/groups.service'; +import { EventListenerService } from 'app/services'; +import { Store } from '@ngxs/store'; +import { CompositionService } from 'app/ng2/pages/composition/composition.service'; +import { ZoneInstanceComponent } from './zone-instance.component'; +import { ZoneInstanceType, ZoneInstance, ZoneInstanceMode, ZoneInstanceAssignmentType, IZoneInstanceAssignment } from "app/models"; +import { PolicyInstance } from "app/models/graph/zones/policy-instance"; +import { Subject, of } from 'rxjs'; +import { _throw } from 'rxjs/observable/throw'; + +describe('ZoneInstanceComponent', () => { + let component: ZoneInstanceComponent; + let fixture: ComponentFixture<ZoneInstanceComponent>; + + let createPolicyInstance = () => { + let policy = new PolicyInstance(); + policy.targets = {COMPONENT_INSTANCES: [], GROUPS: []}; + return new ZoneInstance(policy, '', ''); + } + + beforeEach(() => { + const policiesServiceStub = {updateZoneInstanceAssignments : jest.fn()}; + const groupsServiceStub = {}; + const eventListenerServiceStub = {}; + const storeStub = {}; + const compositionServiceStub = {}; + TestBed.configureTestingModule({ + schemas: [NO_ERRORS_SCHEMA], + declarations: [ZoneInstanceComponent], + providers: [ + { provide: PoliciesService, useValue: policiesServiceStub }, + { provide: GroupsService, useValue: groupsServiceStub }, + { provide: EventListenerService, useValue: eventListenerServiceStub }, + { provide: Store, useValue: storeStub }, + { provide: CompositionService, useValue: compositionServiceStub } + ] + }).compileComponents().then(() => { + fixture = TestBed.createComponent(ZoneInstanceComponent); + component = fixture.componentInstance; + }); + }); + + it('can load instance', async((done) => { + component.zoneInstance = <ZoneInstance>{type : ZoneInstanceType.POLICY, instanceData: {name: 'test policy'}, assignments: []}; + component.forceSave = new Subject<Function>(); + fixture.detectChanges(); + expect(component).toBeTruthy(); + })); + + + it('if another instance is already tagging, i cannot change my mode', ()=> { + component.zoneInstance = <ZoneInstance>{ mode: ZoneInstanceMode.NONE }; + component.isActive = false; + component.activeInstanceMode = ZoneInstanceMode.TAG; + component.setMode(ZoneInstanceMode.SELECTED); + expect(component.zoneInstance.mode).toBe(ZoneInstanceMode.NONE); + }); + + it('if i am active(selected) and NOT in tag mode, I can set another mode', ()=> { + component.isActive = true; + component.zoneInstance = <ZoneInstance>{ mode: ZoneInstanceMode.SELECTED }; + jest.spyOn(component.modeChange, 'emit'); + component.setMode(ZoneInstanceMode.NONE); + expect(component.modeChange.emit).toHaveBeenCalledWith({instance: component.zoneInstance, newMode: ZoneInstanceMode.NONE }); + }); + + it('if i am active and in tag mode and i try to set mode other than tag, I am not allowed', ()=> { + component.isActive = true; + component.zoneInstance = <ZoneInstance>{ mode: ZoneInstanceMode.TAG }; + component.setMode(ZoneInstanceMode.SELECTED); + expect(component.zoneInstance.mode).toBe(ZoneInstanceMode.TAG); + }); + + it('if i am active and in tag mode and click tag again and no changes, does NOT call save, but DOES turn tagging off', ()=> { + component.isActive = true; + component.zoneInstance = createPolicyInstance(); + component.zoneService = component.policiesService; + component.zoneInstance.mode = ZoneInstanceMode.TAG; + jest.spyOn(component.zoneService, 'updateZoneInstanceAssignments'); + jest.spyOn(component.modeChange, 'emit'); + + component.setMode(ZoneInstanceMode.TAG); + + expect(component.zoneService.updateZoneInstanceAssignments).not.toHaveBeenCalled(); + expect(component.modeChange.emit).toHaveBeenCalledWith({instance: component.zoneInstance, newMode: ZoneInstanceMode.NONE }); + + }); + it('if i am active and in tag mode and click tag again and HAVE changes, calls save AND turns tagging off', ()=> { + component.isActive = true; + component.zoneInstance = createPolicyInstance(); + component.zoneService = component.policiesService; + component.zoneInstance.mode = ZoneInstanceMode.TAG; + component.zoneInstance.assignments.push(<IZoneInstanceAssignment>{uniqueId: '123', type: ZoneInstanceAssignmentType.COMPONENT_INSTANCES}); + jest.spyOn(component.zoneService, 'updateZoneInstanceAssignments').mockReturnValue(of(true)); + jest.spyOn(component.modeChange, 'emit'); + + component.setMode(ZoneInstanceMode.TAG); + + expect(component.zoneService.updateZoneInstanceAssignments).toHaveBeenCalled(); + expect(component.modeChange.emit).toHaveBeenCalledWith({instance: component.zoneInstance, newMode: ZoneInstanceMode.NONE }); + }); + + it('on save error, temporary assignment list is reverted to saved assignments', ()=> { + component.isActive = true; + component.zoneInstance = createPolicyInstance(); + component.zoneService = component.policiesService; + component.zoneInstance.mode = ZoneInstanceMode.TAG; + component.zoneInstance.assignments.push(<IZoneInstanceAssignment>{uniqueId: '123', type: ZoneInstanceAssignmentType.COMPONENT_INSTANCES}); + jest.spyOn(component.zoneService, 'updateZoneInstanceAssignments').mockReturnValue(_throw({status: 404})); + + component.setMode(ZoneInstanceMode.TAG); + + expect(component.zoneInstance.assignments.length).toEqual(0); + }); + + it('on save success, all changes are saved to zoneInstance.savedAssignments', ()=> { + component.isActive = true; + component.zoneInstance = createPolicyInstance(); + component.zoneService = component.policiesService; + component.zoneInstance.mode = ZoneInstanceMode.TAG; + component.zoneInstance.assignments.push(<IZoneInstanceAssignment>{uniqueId: '123', type: ZoneInstanceAssignmentType.COMPONENT_INSTANCES}); + jest.spyOn(component.zoneService, 'updateZoneInstanceAssignments').mockReturnValue(of(true)); + + component.setMode(ZoneInstanceMode.TAG); + + expect(component.zoneInstance.instanceData.getSavedAssignments().length).toEqual(1); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.ts b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.ts new file mode 100644 index 0000000000..1b1363e576 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zone-instance/zone-instance.component.ts @@ -0,0 +1,128 @@ +import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit, SimpleChange, ElementRef, ViewChild, SimpleChanges } from '@angular/core'; +import { + ZoneInstance, ZoneInstanceMode, ZoneInstanceType, + IZoneInstanceAssignment +} from 'app/models/graph/zones/zone-instance'; +import { PoliciesService } from 'app/ng2/services/policies.service'; +import { GroupsService } from 'app/ng2/services/groups.service'; +import { IZoneService } from "app/models/graph/zones/zone"; +import { EventListenerService } from 'app/services'; +import { GRAPH_EVENTS } from 'app/utils'; +import { Subject } from 'rxjs'; +import { Store } from "@ngxs/store"; +import { CompositionService } from "app/ng2/pages/composition/composition.service"; +import { PolicyInstance } from "app/models"; +import {SelectedComponentType, SetSelectedComponentAction} from "../../../common/store/graph.actions"; + + +@Component({ + selector: 'zone-instance', + templateUrl: './zone-instance.component.html', + styleUrls: ['./zone-instance.component.less'], + encapsulation: ViewEncapsulation.None +}) +export class ZoneInstanceComponent implements OnInit { + + @Input() zoneInstance:ZoneInstance; + @Input() defaultIconText:string; + @Input() isActive:boolean; + @Input() isViewOnly:boolean; + @Input() activeInstanceMode: ZoneInstanceMode; + @Input() hidden:boolean; + @Input() forceSave:Subject<Function>; + @Output() modeChange: EventEmitter<any> = new EventEmitter<any>(); + @Output() assignmentSaveStart: EventEmitter<void> = new EventEmitter<void>(); + @Output() assignmentSaveComplete: EventEmitter<boolean> = new EventEmitter<boolean>(); + @Output() tagHandleClick: EventEmitter<ZoneInstance> = new EventEmitter<ZoneInstance>(); + @ViewChild('currentComponent') currentComponent: ElementRef; + private MODE = ZoneInstanceMode; + private zoneService:IZoneService; + + constructor(private policiesService:PoliciesService, private groupsService:GroupsService, private eventListenerService:EventListenerService, private compositionService:CompositionService, private store:Store){} + + ngOnInit(){ + if(this.zoneInstance.type == ZoneInstanceType.POLICY){ + this.zoneService = this.policiesService; + } else { + this.zoneService = this.groupsService; + } + if(this.forceSave) { + this.forceSave.subscribe((afterSaveFunction:Function) => { + this.setMode(ZoneInstanceMode.TAG, null, afterSaveFunction); + }) + } + } + + ngOnChanges(changes:SimpleChanges) { + if(changes.hidden){ + this.currentComponent.nativeElement.scrollIntoView({behavior: "smooth", block: "nearest", inline:"end"}); + } + } + + ngOnDestroy() { + if(this.forceSave) { + this.forceSave.unsubscribe(); + } + } + + private setMode = (mode:ZoneInstanceMode, event?:any, afterSaveCallback?:Function):void => { + + if(event){ //prevent event from handle and then repeat event from zone instance + event.stopPropagation(); + } + + if(!this.isActive && this.activeInstanceMode === ZoneInstanceMode.TAG) { + return; //someone else is tagging. No events allowed + } + + if(this.isActive && this.zoneInstance.mode === ZoneInstanceMode.TAG){ + if(mode !== ZoneInstanceMode.TAG) { + return; //ignore all other events. The only valid option is saving changes. + } + + let oldAssignments:Array<IZoneInstanceAssignment> = this.zoneInstance.instanceData.getSavedAssignments(); + if(this.zoneInstance.isZoneAssignmentChanged(oldAssignments, this.zoneInstance.assignments)) { + + this.assignmentSaveStart.emit(); + + this.zoneService.updateZoneInstanceAssignments(this.zoneInstance.parentComponentType, this.zoneInstance.parentComponentID, this.zoneInstance.instanceData.uniqueId, this.zoneInstance.assignments).subscribe( + (success) => { + this.zoneInstance.instanceData.setSavedAssignments(this.zoneInstance.assignments); + + if(this.zoneInstance.instanceData instanceof PolicyInstance){ + this.compositionService.updatePolicy(this.zoneInstance.instanceData); + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, this.zoneInstance.instanceData); + this.store.dispatch(new SetSelectedComponentAction({component: this.zoneInstance.instanceData, type: SelectedComponentType.POLICY})); + } else { + this.compositionService.updateGroup(this.zoneInstance.instanceData); + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.zoneInstance.instanceData); + this.store.dispatch(new SetSelectedComponentAction({component: this.zoneInstance.instanceData, type: SelectedComponentType.GROUP})); + } + + this.assignmentSaveComplete.emit(true); + if(afterSaveCallback) afterSaveCallback(); + }, (error) => { + this.zoneInstance.assignments = oldAssignments; + this.assignmentSaveComplete.emit(false); + }); + } else { + if(afterSaveCallback) afterSaveCallback(); + } + this.modeChange.emit({newMode: ZoneInstanceMode.NONE, instance: this.zoneInstance}); + // this.store.dispatch(new unsavedChangesActions.RemoveUnsavedChange(this.zoneInstance.instanceData.uniqueId)); + + + } else { + this.modeChange.emit({newMode: mode, instance: this.zoneInstance}); + if(mode == ZoneInstanceMode.TAG){ + // this.store.dispatch(new unsavedChangesActions.AddUnsavedChange(this.zoneInstance.instanceData.uniqueId)); + } + } + } + + private tagHandleClicked = (event:Event) => { + this.tagHandleClick.emit(this.zoneInstance); + event.stopPropagation(); + }; + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zones-module.ts b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zones-module.ts new file mode 100644 index 0000000000..3287c01f5a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/canvas-zone/zones-module.ts @@ -0,0 +1,15 @@ +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { ZoneContainerComponent } from "./zone-container.component"; +import { ZoneInstanceComponent } from "./zone-instance/zone-instance.component"; +import { SdcUiComponentsModule } from "onap-ui-angular"; + +@NgModule({ + declarations: [ZoneContainerComponent, ZoneInstanceComponent], + imports: [CommonModule, SdcUiComponentsModule], + entryComponents: [ZoneContainerComponent, ZoneInstanceComponent], + exports: [ZoneContainerComponent, ZoneInstanceComponent], + providers: [] +}) +export class ZoneModules { +}
\ No newline at end of file |