[sdc] update code of sdc
[sdc.git] / catalog-ui / src / app / directives / graphs-v2 / deployment-graph / deployment-graph.directive.ts
1 import { Component, Module, NodesFactory, ComponentInstance } from "app/models";
2 import { ComponentInstanceFactory } from "app/utils";
3 import { DeploymentGraphGeneralUtils } from "./deployment-utils/deployment-graph-general-utils";
4 import { CommonGraphUtils } from "../common/common-graph-utils";
5 import { ComponentInstanceNodesStyle } from "../common/style/component-instances-nodes-style";
6 import { ModulesNodesStyle } from "../common/style/module-node-style";
7 import { GRAPH_EVENTS } from "app/utils";
8 import { EventListenerService } from "app/services";
9 import '@bardit/cytoscape-expand-collapse';
10
11 interface IDeploymentGraphScope extends ng.IScope {
12     component: Component;
13 }
14
15 export class DeploymentGraph implements ng.IDirective {
16     private _cy: Cy.Instance;
17
18     constructor(private NodesFactory: NodesFactory,
19         private commonGraphUtils: CommonGraphUtils,
20         private deploymentGraphGeneralUtils: DeploymentGraphGeneralUtils,
21         private ComponentInstanceFactory: ComponentInstanceFactory,
22         private eventListenerService: EventListenerService) {
23     }
24
25     restrict = 'E';
26     template = require('./deployment-graph.html');
27     scope = {
28         component: '=',
29         isViewOnly: '='
30     };
31
32     link = (scope: IDeploymentGraphScope, el: JQuery) => {
33
34         if (scope.component.isResource()) {
35             if (scope.component.componentInstances && scope.component.componentInstancesRelations && scope.component.groups) {
36                 this.loadGraph(scope, el);
37             } else {
38                 this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DEPLOYMENT_GRAPH_DATA_LOADED, () => {
39                     this.loadGraph(scope, el);
40                 });
41             }
42         }
43     };
44
45     public initGraphNodes = (cy: Cy.Instance, component: Component): void => {
46         if (component.groups) { // Init module nodes
47             _.each(component.groups, (groupModule: Module) => {
48                 let moduleNode = this.NodesFactory.createModuleNode(groupModule);
49                 this.commonGraphUtils.addNodeToGraph(cy, moduleNode);
50
51             });
52         }
53         _.each(component.componentInstances, (instance: ComponentInstance) => { // Init component instance nodes
54             let componentInstanceNode = this.NodesFactory.createNode(instance);
55             componentInstanceNode.parent = this.deploymentGraphGeneralUtils.findInstanceModule(component.groups, instance.uniqueId);
56             if (componentInstanceNode.parent) { // we are not drawing instances that are not a part of a module
57                 this.commonGraphUtils.addComponentInstanceNodeToGraph(cy, componentInstanceNode);
58             }
59         });
60
61         // This is a special functionality to pass the cytoscape default behavior - we can't create Parent module node without children's
62         // so we must add an empty dummy child node
63         _.each(this._cy.nodes('[?isGroup]'), (moduleNode: Cy.CollectionFirstNode) => {
64             if (!moduleNode.isParent()) {
65                 let dummyInstance = this.ComponentInstanceFactory.createEmptyComponentInstance();
66                 let componentInstanceNode = this.NodesFactory.createNode(dummyInstance);
67                 componentInstanceNode.parent = moduleNode.id();
68                 let dummyNode = this.commonGraphUtils.addNodeToGraph(cy, componentInstanceNode, moduleNode.position());
69                 dummyNode.addClass('dummy-node');
70             }
71         })
72     };
73
74     private registerGraphEvents() {
75
76         this._cy.on('afterExpand', (event) => {
77             event.cyTarget.qtip({});
78         });
79
80         this._cy.on('afterCollapse', (event) => {
81             this.commonGraphUtils.initNodeTooltip(event.cyTarget);
82         });
83     }
84
85     private loadGraph = (scope: IDeploymentGraphScope, el: JQuery) => {
86
87         let graphEl = el.find('.sdc-deployment-graph-wrapper');
88         this._cy = cytoscape({
89             container: graphEl,
90             style: ComponentInstanceNodesStyle.getCompositionGraphStyle().concat(ModulesNodesStyle.getModuleGraphStyle()),
91             zoomingEnabled: false,
92             selectionType: 'single',
93
94         });
95
96         //adding expand collapse extension
97         this._cy.expandCollapse({
98             layoutBy: {
99                 name: "grid",
100                 animate: true,
101                 randomize: false,
102                 fit: true
103             },
104             fisheye: false,
105             undoable: false,
106             expandCollapseCueSize: 18,
107             expandCueImage: '/assets/styles/images/resource-icons/' + 'closeModule.png',
108             collapseCueImage: '/assets/styles/images/resource-icons/' + 'openModule.png',
109             expandCollapseCueSensitivity: 2,
110             cueOffset: -20
111         });
112
113         this.initGraphNodes(this._cy, scope.component); //creating instances nodes
114         this.commonGraphUtils.initGraphLinks(this._cy, scope.component.componentInstancesRelations);
115         this._cy.collapseAll();
116         this.registerGraphEvents();
117
118         scope.$on('$destroy', () => {
119             this._cy.destroy();
120             _.forEach(GRAPH_EVENTS, (event) => {
121                 this.eventListenerService.unRegisterObserver(event);
122             });
123         });
124
125     };
126
127     public static factory = (NodesFactory: NodesFactory, CommonGraphUtils: CommonGraphUtils, DeploymentGraphGeneralUtils: DeploymentGraphGeneralUtils, ComponentInstanceFactory: ComponentInstanceFactory, EventListenerService: EventListenerService) => {
128         return new DeploymentGraph(NodesFactory, CommonGraphUtils, DeploymentGraphGeneralUtils, ComponentInstanceFactory, EventListenerService)
129     }
130 }
131
132 DeploymentGraph.factory.$inject = ['NodesFactory', 'CommonGraphUtils', 'DeploymentGraphGeneralUtils', 'ComponentInstanceFactory', 'EventListenerService'];