2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 import {Injectable} from "@angular/core";
22 import {CompositionGraphGeneralUtils, RequirementAndCapabilities} from "./composition-graph-general-utils";
23 import {CommonGraphUtils} from "../common/common-graph-utils";
24 import {EventListenerService} from "../../../../../services/event-listener-service";
25 import {ResourceNamePipe} from "app/ng2/pipes/resource-name.pipe";
26 import {ComponentInstanceFactory} from "app/utils/component-instance-factory";
27 import {GRAPH_EVENTS, GraphUIObjects} from "app/utils/constants";
28 import {TopologyTemplateService} from "app/ng2/services/component-services/topology-template.service";
29 import {DndDropEvent} from "ngx-drag-drop/ngx-drag-drop";
30 import {SdcUiServices} from "onap-ui-angular"
31 import { Component as TopologyTemplate, NodesFactory, CapabilitiesGroup, RequirementsGroup,
32 CompositionCiNodeBase, ComponentInstance, LeftPaletteComponent, Point } from "app/models";
33 import {CompositionService} from "../../composition.service";
34 import {WorkspaceService} from "app/ng2/pages/workspace/workspace.service";
35 import { QueueServiceUtils } from "app/ng2/utils/queue-service-utils";
36 import {ComponentGenericResponse} from "../../../../services/responses/component-generic-response";
37 import {MatchCapabilitiesRequirementsUtils} from "./match-capability-requierment-utils";
38 import {CompositionGraphNodesUtils} from "./index";
41 export class CompositionGraphPaletteUtils {
43 constructor(private generalGraphUtils:CompositionGraphGeneralUtils,
44 private nodesFactory:NodesFactory,
45 private commonGraphUtils:CommonGraphUtils,
46 private queueServiceUtils:QueueServiceUtils,
47 private eventListenerService:EventListenerService,
48 private topologyTemplateService: TopologyTemplateService,
49 private loaderService: SdcUiServices.LoaderService,
50 private compositionService: CompositionService,
51 private workspaceService: WorkspaceService,
52 private matchCapabilitiesRequirementsUtils: MatchCapabilitiesRequirementsUtils,
53 private nodesGraphUtils: CompositionGraphNodesUtils) {
58 * @param Calculate matching nodes, highlight the matching nodes and fade the non matching nodes
59 * @param leftPaletteComponent
65 public onComponentHoverIn = (leftPaletteComponent: LeftPaletteComponent, _cy: Cy.Instance) => {
66 const nodesData = this.nodesGraphUtils.getAllNodesData(_cy.nodes());
67 const nodesLinks = this.generalGraphUtils.getAllCompositionCiLinks(_cy);
69 if (this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.containsKey(leftPaletteComponent.uniqueId)) {
70 const reqAndCap: RequirementAndCapabilities = this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.getValue(leftPaletteComponent.uniqueId);
71 const filteredNodesData = this.matchCapabilitiesRequirementsUtils.findMatchingNodesToComponentInstance(
72 { uniqueId: leftPaletteComponent.uniqueId, requirements: reqAndCap.requirements, capabilities: reqAndCap.capabilities} as ComponentInstance, nodesData, nodesLinks);
74 this.matchCapabilitiesRequirementsUtils.highlightMatchingComponents(filteredNodesData, _cy);
75 this.matchCapabilitiesRequirementsUtils.fadeNonMachingComponents(filteredNodesData, nodesData, _cy);
78 this.topologyTemplateService.getCapabilitiesAndRequirements(leftPaletteComponent.componentType, leftPaletteComponent.uniqueId).subscribe((response: ComponentGenericResponse) => {
79 let reqAndCap: RequirementAndCapabilities = {
80 capabilities: response.capabilities,
81 requirements: response.requirements
83 this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.setValue(leftPaletteComponent.uniqueId, reqAndCap);
89 * Calculate the dragged element (html element) position on canvas
93 * @returns {Cy.BoundingBox}
96 private _getNodeBBox(cy:Cy.Instance, event:DragEvent, position?:Cy.Position, eventPosition?: Point) {
97 let bbox = <Cy.BoundingBox>{};
99 position = event ? this.commonGraphUtils.getCytoscapeNodePosition(cy, event) : eventPosition;
101 let cushionWidth:number = 40;
102 let cushionHeight:number = 40;
104 bbox.x1 = position.x - cushionWidth / 2;
105 bbox.y1 = position.y - cushionHeight / 2;
106 bbox.x2 = position.x + cushionWidth / 2;
107 bbox.y2 = position.y + cushionHeight / 2;
112 * Create the component instance, update data from parent component in the left palette and notify on_insert_to_ucpe if component was dragg into ucpe
114 * @param fullComponent
118 private _createComponentInstanceOnGraphFromPaletteComponent(cy:Cy.Instance, fullComponent:LeftPaletteComponent, event:DragEvent) {
120 let componentInstanceToCreate:ComponentInstance = ComponentInstanceFactory.createComponentInstanceFromComponent(fullComponent);
121 let cytoscapePosition:Cy.Position = this.commonGraphUtils.getCytoscapeNodePosition(cy, event);
122 componentInstanceToCreate.posX = cytoscapePosition.x;
123 componentInstanceToCreate.posY = cytoscapePosition.y;
125 let onFailedCreatingInstance:(error:any) => void = (error:any) => {
126 this.loaderService.deactivate();
129 //on success - update node data
130 let onSuccessCreatingInstance = (createInstance:ComponentInstance):void => {
132 this.loaderService.deactivate();
133 this.compositionService.addComponentInstance(createInstance);
134 createInstance.name = ResourceNamePipe.getDisplayName(createInstance.name);
135 createInstance.requirements = new RequirementsGroup(createInstance.requirements);
136 createInstance.capabilities = new CapabilitiesGroup(createInstance.capabilities);
137 createInstance.componentVersion = fullComponent.version;
138 createInstance.icon = fullComponent.icon;
139 createInstance.setInstanceRC();
141 let newNode:CompositionCiNodeBase = this.nodesFactory.createNode(createInstance);
142 this.commonGraphUtils.addComponentInstanceNodeToGraph(cy, newNode);
143 this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE);
146 this.queueServiceUtils.addBlockingUIAction(() => {
147 let uniqueId = this.workspaceService.metadata.uniqueId;
148 let componentType = this.workspaceService.metadata.componentType;
149 this.topologyTemplateService.createComponentInstance(componentType, uniqueId, componentInstanceToCreate).subscribe(onSuccessCreatingInstance, onFailedCreatingInstance);
155 // * Thid function applay red/green background when component dragged from palette
158 // * @param dragElement
159 // * @param dragComponent
161 // public onComponentDrag(cy:Cy.Instance, event) {
162 // let draggedElement = document.getElementById("draggable_element");
163 // // event.dataTransfer.setDragImage(draggableElement, 0, 0);
164 // if (event.clientX < GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET || event.clientY < GraphUIObjects.DIAGRAM_HEADER_OFFSET) { //hovering over palette. Dont bother computing validity of drop
165 // draggedElement.className = 'invalid-drag';
166 // event.dataTransfer.setDragImage(draggedElement.cloneNode(true), 0, 0);
170 // let offsetPosition = {
171 // x: event.clientX - GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET,
172 // y: event.clientY - GraphUIObjects.DIAGRAM_HEADER_OFFSET
174 // let bbox = this._getNodeBBox(cy, event, offsetPosition);
176 // if (this.generalGraphUtils.isPaletteDropValid(cy, bbox)) {
177 // draggedElement.className = 'valid-drag';
178 // event.dataTransfer.setDragImage(draggedElement.cloneNode(true), 0, 0);
179 // // event.dataTransfer.setDragImage(draggedElement, 0, 0);
180 // // event.dataTransfer.setDragImage(draggedElement, 0, 0);
183 // draggedElement.className = 'invalid-drag';
184 // event.dataTransfer.setDragImage(draggedElement.cloneNode(true), 0, 0);
188 public isDragValid(cy:Cy.Instance, position: Point):boolean {
189 if (position.x < GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET || position.y < GraphUIObjects.DIAGRAM_HEADER_OFFSET) { //hovering over palette. Dont bother computing validity of drop
193 let offsetPosition = {
194 x: position.x - GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET,
195 y: position.y - GraphUIObjects.DIAGRAM_HEADER_OFFSET
197 let bbox = this._getNodeBBox(cy, null, offsetPosition, position);
199 if (this.generalGraphUtils.isPaletteDropValid(cy, bbox)) {
206 * This function is called when after dropping node on canvas
207 * Check if the capability & requirements fulfilled and if not get from server
212 public addNodeFromPalette(cy:Cy.Instance, dragEvent:DndDropEvent) {
213 this.loaderService.activate();
215 let draggedComponent:LeftPaletteComponent = dragEvent.data;
217 if (this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.containsKey(draggedComponent.uniqueId)) {
218 let fullComponent = this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.getValue(draggedComponent.uniqueId);
219 draggedComponent.capabilities = fullComponent.capabilities;
220 draggedComponent.requirements = fullComponent.requirements;
221 this._createComponentInstanceOnGraphFromPaletteComponent(cy, draggedComponent, dragEvent.event);
225 this.topologyTemplateService.getFullComponent(draggedComponent.componentType, draggedComponent.uniqueId).subscribe((topologyTemplate:TopologyTemplate) => {
226 draggedComponent.capabilities = topologyTemplate.capabilities;
227 draggedComponent.requirements = topologyTemplate.requirements;
228 this._createComponentInstanceOnGraphFromPaletteComponent(cy, draggedComponent, dragEvent.event);