/*- * ============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 { EventListenerService, LoaderService } from "app/services"; import { CapabilitiesGroup, NodesFactory, ComponentInstance, Component, CompositionCiNodeBase, RequirementsGroup } from "app/models"; import { ComponentFactory, ComponentInstanceFactory, GRAPH_EVENTS, GraphUIObjects } from "app/utils"; import { CompositionGraphGeneralUtils } from "./composition-graph-general-utils"; import { CommonGraphUtils } from "../../common/common-graph-utils"; import 'sdc-angular-dragdrop'; import { LeftPaletteComponent } from "../../../../models/components/displayComponent"; export class CompositionGraphPaletteUtils { constructor(private ComponentFactory: ComponentFactory, private $filter: ng.IFilterService, private loaderService: LoaderService, private generalGraphUtils: CompositionGraphGeneralUtils, private componentInstanceFactory: ComponentInstanceFactory, private nodesFactory: NodesFactory, private commonGraphUtils: CommonGraphUtils, private eventListenerService: EventListenerService) { } /** * Calculate the dragged element (html element) position on canvas * @param cy * @param event * @param position * @returns {Cy.BoundingBox} * @private */ private _getNodeBBox(cy: Cy.Instance, event: IDragDropEvent, position?: Cy.Position) { let bbox = {}; if (!position) { position = this.commonGraphUtils.getCytoscapeNodePosition(cy, event); } let cushionWidth: number = 40; let cushionHeight: number = 40; bbox.x1 = position.x - cushionWidth / 2; bbox.y1 = position.y - cushionHeight / 2; bbox.x2 = position.x + cushionWidth / 2; bbox.y2 = position.y + cushionHeight / 2; return bbox; } /** * 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 * @param cy * @param fullComponent * @param event * @param component */ private _createComponentInstanceOnGraphFromPaletteComponent(cy: Cy.Instance, fullComponent: LeftPaletteComponent, event: IDragDropEvent, component: Component) { let componentInstanceToCreate: ComponentInstance = this.componentInstanceFactory.createComponentInstanceFromComponent(fullComponent); let cytoscapePosition: Cy.Position = this.commonGraphUtils.getCytoscapeNodePosition(cy, event); componentInstanceToCreate.posX = cytoscapePosition.x; componentInstanceToCreate.posY = cytoscapePosition.y; let onFailedCreatingInstance: (error: any) => void = (error: any) => { this.loaderService.hideLoader('composition-graph'); }; //on success - update node data let onSuccessCreatingInstance = (createInstance: ComponentInstance): void => { this.loaderService.hideLoader('composition-graph'); createInstance.name = this.$filter('resourceName')(createInstance.name); createInstance.requirements = new RequirementsGroup(createInstance.requirements); createInstance.capabilities = new CapabilitiesGroup(createInstance.capabilities); createInstance.componentVersion = fullComponent.version; createInstance.icon = fullComponent.icon; createInstance.setInstanceRC(); let newNode: CompositionCiNodeBase = this.nodesFactory.createNode(createInstance); let cyNode: Cy.CollectionNodes = this.commonGraphUtils.addComponentInstanceNodeToGraph(cy, newNode); //check if node was dropped into a UCPE let ucpe: Cy.CollectionElements = this.commonGraphUtils.isInUcpe(cy, cyNode.boundingbox()); if (ucpe.length > 0) { this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_INSERT_NODE_TO_UCPE, cyNode, ucpe, false); } this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE); }; this.loaderService.showLoader('composition-graph'); // Create the component instance on server this.generalGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIAction(() => { component.createComponentInstance(componentInstanceToCreate).then(onSuccessCreatingInstance, onFailedCreatingInstance); }); } /** * Thid function applay red/green background when component dragged from palette * @param cy * @param event * @param dragElement * @param dragComponent */ public onComponentDrag(cy: Cy.Instance, event: IDragDropEvent, dragElement: JQuery, dragComponent: ComponentInstance) { if (event.clientX < GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET || event.clientY < GraphUIObjects.DIAGRAM_HEADER_OFFSET) { //hovering over palette. Dont bother computing validity of drop dragElement.removeClass('red'); return; } let offsetPosition = { x: event.clientX - GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET, y: event.clientY - GraphUIObjects.DIAGRAM_HEADER_OFFSET }; let bbox = this._getNodeBBox(cy, event, offsetPosition); if (this.generalGraphUtils.isPaletteDropValid(cy, bbox, dragComponent)) { dragElement.removeClass('red'); } else { dragElement.addClass('red'); } } /** * This function is called when after dropping node on canvas * Check if the capability & requirements fulfilled and if not get from server * @param cy * @param event * @param component */ public addNodeFromPalette(cy: Cy.Instance, event: IDragDropEvent, component: Component) { this.loaderService.showLoader('composition-graph'); let draggedComponent: LeftPaletteComponent = event.dataTransfer.component; if (this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.containsKey(draggedComponent.uniqueId)) { let fullComponent = this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.getValue(draggedComponent.uniqueId); draggedComponent.capabilities = fullComponent.capabilities; draggedComponent.requirements = fullComponent.requirements; this._createComponentInstanceOnGraphFromPaletteComponent(cy, draggedComponent, event, component); } else { this.ComponentFactory.getComponentFromServer(draggedComponent.getComponentSubType(), draggedComponent.uniqueId) .then((fullComponent: Component) => { draggedComponent.capabilities = fullComponent.capabilities; draggedComponent.requirements = fullComponent.requirements; this._createComponentInstanceOnGraphFromPaletteComponent(cy, draggedComponent, event, component); }); } } } CompositionGraphPaletteUtils.$inject = [ 'ComponentFactory', '$filter', 'LoaderService', 'CompositionGraphGeneralUtils', 'ComponentInstanceFactory', 'NodesFactory', 'CommonGraphUtils', 'EventListenerService' ];