[sdc] update code of sdc
[sdc.git] / catalog-ui / src / app / directives / graphs-v2 / composition-graph / utils / composition-graph-palette-utils.ts
1 import {EventListenerService, LoaderService} from "app/services";
2 import {CapabilitiesGroup, NodesFactory, ComponentInstance, Component, CompositionCiNodeBase, RequirementsGroup} from "app/models";
3 import {ComponentFactory, ComponentInstanceFactory, GRAPH_EVENTS, GraphUIObjects} from "app/utils";
4 import {CompositionGraphGeneralUtils} from "./composition-graph-general-utils";
5 import {CommonGraphUtils} from "../../common/common-graph-utils";
6 import 'sdc-angular-dragdrop';
7 import {LeftPaletteComponent} from "../../../../models/components/displayComponent";
8
9 export class CompositionGraphPaletteUtils {
10
11     constructor(private ComponentFactory:ComponentFactory,
12                 private $filter:ng.IFilterService,
13                 private loaderService:LoaderService,
14                 private generalGraphUtils:CompositionGraphGeneralUtils,
15                 private componentInstanceFactory:ComponentInstanceFactory,
16                 private nodesFactory:NodesFactory,
17                 private commonGraphUtils:CommonGraphUtils,
18                 private eventListenerService:EventListenerService) {
19     }
20
21     /**
22      * Calculate the dragged element (html element) position on canvas
23      * @param cy
24      * @param event
25      * @param position
26      * @returns {Cy.BoundingBox}
27      * @private
28      */
29     private _getNodeBBox(cy:Cy.Instance, event:IDragDropEvent, position?:Cy.Position) {
30         let bbox = <Cy.BoundingBox>{};
31         if (!position) {
32             position = this.commonGraphUtils.getCytoscapeNodePosition(cy, event);
33         }
34         let cushionWidth:number = 40;
35         let cushionHeight:number = 40;
36
37         bbox.x1 = position.x - cushionWidth / 2;
38         bbox.y1 = position.y - cushionHeight / 2;
39         bbox.x2 = position.x + cushionWidth / 2;
40         bbox.y2 = position.y + cushionHeight / 2;
41         return bbox;
42     }
43
44     /**
45      * 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
46      * @param cy
47      * @param fullComponent
48      * @param event
49      * @param component
50      */
51     private _createComponentInstanceOnGraphFromPaletteComponent(cy:Cy.Instance, fullComponent:LeftPaletteComponent, event:IDragDropEvent, component:Component) {
52
53         let componentInstanceToCreate:ComponentInstance = this.componentInstanceFactory.createComponentInstanceFromComponent(fullComponent);
54         let cytoscapePosition:Cy.Position = this.commonGraphUtils.getCytoscapeNodePosition(cy, event);
55
56         componentInstanceToCreate.posX = cytoscapePosition.x;
57         componentInstanceToCreate.posY = cytoscapePosition.y;
58
59
60         let onFailedCreatingInstance:(error:any) => void = (error:any) => {
61             this.loaderService.hideLoader('composition-graph');
62         };
63
64         //on success - update node data
65         let onSuccessCreatingInstance = (createInstance:ComponentInstance):void => {
66
67             this.loaderService.hideLoader('composition-graph');
68
69             createInstance.name = this.$filter('resourceName')(createInstance.name);
70             createInstance.requirements = new RequirementsGroup(createInstance.requirements);
71             createInstance.capabilities = new CapabilitiesGroup(createInstance.capabilities);
72             createInstance.componentVersion = fullComponent.version;
73             createInstance.icon = fullComponent.icon;
74             createInstance.setInstanceRC();
75
76             let newNode:CompositionCiNodeBase = this.nodesFactory.createNode(createInstance);
77             let cyNode:Cy.CollectionNodes = this.commonGraphUtils.addComponentInstanceNodeToGraph(cy, newNode);
78
79             //check if node was dropped into a UCPE
80             let ucpe:Cy.CollectionElements = this.commonGraphUtils.isInUcpe(cy, cyNode.boundingbox());
81             if (ucpe.length > 0) {
82                 this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_INSERT_NODE_TO_UCPE, cyNode, ucpe, false);
83             }
84             this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE);
85
86         };
87
88         this.loaderService.showLoader('composition-graph');
89
90         // Create the component instance on server
91         this.generalGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIAction(() => {
92             component.createComponentInstance(componentInstanceToCreate).then(onSuccessCreatingInstance, onFailedCreatingInstance);
93         });
94     }
95
96     /**
97      * Thid function applay red/green background when component dragged from palette
98      * @param cy
99      * @param event
100      * @param dragElement
101      * @param dragComponent
102      */
103     public onComponentDrag(cy:Cy.Instance, event:IDragDropEvent, dragElement:JQuery, dragComponent:ComponentInstance) {
104
105         if (event.clientX < GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET || event.clientY < GraphUIObjects.DIAGRAM_HEADER_OFFSET) { //hovering over palette. Dont bother computing validity of drop
106             dragElement.removeClass('red');
107             return;
108         }
109
110         let offsetPosition = {
111             x: event.clientX - GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET,
112             y: event.clientY - GraphUIObjects.DIAGRAM_HEADER_OFFSET
113         };
114         let bbox = this._getNodeBBox(cy, event, offsetPosition);
115
116         if (this.generalGraphUtils.isPaletteDropValid(cy, bbox, dragComponent)) {
117             dragElement.removeClass('red');
118         } else {
119             dragElement.addClass('red');
120         }
121     }
122
123     /**
124      *  This function is called when after dropping node on canvas
125      *  Check if the capability & requirements fulfilled and if not get from server
126      * @param cy
127      * @param event
128      * @param component
129      */
130     public addNodeFromPalette(cy:Cy.Instance, event:IDragDropEvent, component:Component) {
131         this.loaderService.showLoader('composition-graph');
132
133         let draggedComponent:LeftPaletteComponent = event.dataTransfer.component;
134
135         if (this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.containsKey(draggedComponent.uniqueId)) {
136             let fullComponent = this.generalGraphUtils.componentRequirementsAndCapabilitiesCaching.getValue(draggedComponent.uniqueId);
137             draggedComponent.capabilities = fullComponent.capabilities;
138             draggedComponent.requirements = fullComponent.requirements;
139             this._createComponentInstanceOnGraphFromPaletteComponent(cy, draggedComponent, event, component);
140
141         } else {
142
143             this.ComponentFactory.getComponentFromServer(draggedComponent.getComponentSubType(), draggedComponent.uniqueId)
144                 .then((fullComponent:Component) => {
145                     draggedComponent.capabilities = fullComponent.capabilities;
146                     draggedComponent.requirements = fullComponent.requirements;
147                     this._createComponentInstanceOnGraphFromPaletteComponent(cy, draggedComponent, event, component);
148                 });
149         }
150     }
151 }
152
153
154 CompositionGraphPaletteUtils.$inject = [
155     'ComponentFactory',
156     '$filter',
157     'LoaderService',
158     'CompositionGraphGeneralUtils',
159     'ComponentInstanceFactory',
160     'NodesFactory',
161     'CommonGraphUtils',
162     'EventListenerService'
163 ];