Fix test identities
[groupbasedpolicy.git] / groupbasedpolicy-ui / module / src / main / resources / gbp / common / topology / next_topology.directive.js
1 define(['next-ui'], function() {
2
3         var NextTopology = function (NextTopologyService){
4         return {
5                             restrict: 'E',
6                 scope: {
7                     topologyData: '=',
8                     cbkFunctions: '=?',
9                     dictionaries: '=?',
10                     topo: '=?',
11                     topoColors: '=?'
12                 },
13                             template: '<div id="graph-container" class="col-md-12"></div>',
14                             link: function(scope) {
15                                 var saveTopoInterval = null;
16
17                                 scope.topo = null;
18
19                                 /**
20                                  * Colors used for topology objects
21                                  * @type {nx.data.Dictionary}
22                                  */
23                                 scope.topoColors = new nx.data.Dictionary({
24                                         'operational': '#0f9d58',
25                                         'configured': '#464646',
26                                         'operational-mixed': '#C4AF00',
27                                         'down': '#FF0000',
28                                         'default': '#8C8C8C',
29                                         'forwarding-box': '#0386d2',
30                                         'host': '#8C8C8C'
31                                 });
32
33                                 /**
34                                  * init next topology graph
35                                  */
36                                 scope.init = function (successCbk) {
37                                         // register "font" icon
38                                         nx.graphic.Icons.registerFontIcon('devicedown', 'FontAwesome', "\uf057", 20);
39
40                     var circle = "<defs xmlns='http://www.w3.org/2000/svg'><marker id='circle' viewBox='-3 -3 6 6' markerWidth='6' markerHeight='6' orient='auto'> <circle r='3' fill='#68BD6B'></circle></marker></defs>";
41
42                                         var app = new nx.ui.Application();
43                                         // set app containter
44                                         document.getElementById('graph-container').innerHTML = '';
45                                         app.container(document.getElementById('graph-container'));
46
47                     scope.topo = NextTopologyService.getNxTopClass(scope.topoColors);
48                     scope.setTopoEvents();
49                     scope.topo.stage().addDefString(circle);
50
51                                         extendLinkClass();
52                                         extendNodeClass();
53                                         extendedTooltip();
54                                         // TODO: remove when come to decision about depiction of node status
55                                         //createNodeStatusLayer();
56                                         defineCustomEvents();
57
58
59
60                                         // App events - if app is resized
61                                         app.on('resize', function(){
62                                                 scope.topo.adaptToContainer();
63                                         });
64
65                                         // Attach topo to app
66                                         scope.topo.attach(app);
67
68                                         if ( successCbk ) {
69                                                 successCbk();
70                                         }
71                                 };
72
73                                 /**
74                                  * NX topo events
75                                  */
76                                 scope.setTopoEvents = function () {
77                                         // Fired when the app is ready and displayed
78                                         scope.topo.on('ready', function (sender, event) {
79                                                 scope.topo.data(scope.topologyData);
80
81                                                 // load saved data
82                                                 if ( scope.dictionaries ){
83                                                         var data = NextTopologyService.readTopologyDataFromLS();
84                                                         NextTopologyService.setTopologyDataFromLS(data, scope.topo, scope.dictionaries.nodes);
85                                                 }
86
87                                                 // clear interval after reload data
88                                                 if ( saveTopoInterval ) {
89                                                         clearInterval(saveTopoInterval);
90                                                 }
91
92                                                 // set interval for saving topo nodes position
93                                                 saveTopoInterval = window.setInterval(function(){NextTopologyService.saveTopologyDataToLS(scope.topo);}, 5000);
94                                         });
95
96                                         // Fired when topology is generated
97                                         scope.topo.on('topologyGenerated', function(sender, event) {
98
99                                                 // use custom events for the topology
100                                                 // TODO: remove when come to decision about depiction of node status
101                                                 //sender.attachLayer("status", "NodeStatus");
102                                                 sender.registerScene('ce', 'CustomEvents');
103                                                 sender.activateScene('ce');
104                                                 scope.topo.tooltipManager().showNodeTooltip(false);
105                                         });
106                                 };
107
108                                 /**
109                                  * Watching topology data
110                                  */
111                                 scope.$watch('topologyData', function(){
112                                         //console.log('scope.topologyData', scope.topologyData);
113
114                                         //if( scope.topologyData.nodes.length ) { //&& initialized === false
115                                                 scope.init(scope.cbkFunctions.topologyGenerated);
116                                         //}
117                                 });
118
119                                 /**
120                                  * Extend base nx node class function
121                                  */
122                                 function extendNodeClass(){
123                                         nx.define('ExtendedNode', nx.graphic.Topology.Node, {
124                                                 view: function(view){
125
126                                                         view.content.push({
127                                                                 "name": "deviceDownBadge",
128                                                                 "type": "nx.graphic.Group",
129                                                                 "content": [
130                                                                         {
131                                                                                 "name": "deviceDownBadgeBg",
132                                                                                 "type": "nx.graphic.Rect",
133                                                                                 "props": {
134                                                                                         "class": "device-down-bg",
135                                                                                         "height": 1,
136                                                                                         "visible": false
137                                                                                 }
138                                                                         },
139                                                                         {
140                                                                                 "name": "deviceDownBadgeText",
141                                                                                 "type": "nx.graphic.Icon",
142                                                                                 "props": {
143                                                                                         "class": "icon",
144                                                                                         "iconType": "devicedown",
145                                                                                         "color": "#ff0000",
146                                                                                         "showIcon": true,
147                                                                                         "scale": 1,
148                                                                                         "visible": false
149                                                                                 }
150                                                                         }
151                                                                 ]
152                                                         });
153                                                         return view;
154                                                 },
155                                                 methods: {
156                                                         // inherit properties/parent's data
157                                                         init: function(args){
158                                                                 this.inherited(args);
159                                                                 var stageScale = this.topology().stageScale();
160                                                                 this.view('label').setStyle('font-size', 14 * stageScale);
161                                                         },
162                                                         // inherit parent's model
163                                                         'setModel': function(model) {
164                                                                 this.inherited(model);
165
166                                                                 // if status is down
167                                 this._drawDeviceDownBadge(this.model());
168
169                                                         },
170                                                         "_drawDeviceDownBadge": function(model){
171
172                                                                 var badge, badgeBg, badgeText,
173                                                                         icon, iconSize, iconScale,
174                                                                         bound, boundMax, badgeTransform,
175                                                                         badgeVisibility = model.get("status") === "configured";
176
177                                                                 // views of badge
178                                                                 badge = this.view("deviceDownBadge");
179                                                                 badgeBg = this.view("deviceDownBadgeBg");
180                                                                 badgeText = this.view("deviceDownBadgeText");
181
182                                                                 // view of device icon
183                                                                 icon = this.view('icon');
184                                                                 iconSize = icon.size();
185                                                                 iconScale = icon.scale();
186
187                                                                 // define position of the badge
188                                                                 badgeTransform = {
189                                                                         x: iconSize.width * iconScale / -2.5,
190                                                                         y: iconSize.height * iconScale / 3
191                                                                 };
192
193                                                                 // make badge visible
194                                                                 badgeText.set("visible", badgeVisibility);
195
196                                                                 // get bounds and apply them for white background
197                                                                 bound = badge.getBound();
198                                                                 boundMax = Math.max(bound.width - 6, 1);
199                                                                 badgeBg.sets({
200                                                                         width: boundMax,
201                                                                         visible: badgeVisibility
202                                                                 });
203
204                                                                 // set position of the badge
205                                                                 badgeBg.setTransform(badgeTransform.x, badgeTransform.y);
206                                                                 badgeText.setTransform(badgeTransform.x, badgeTransform.y);
207
208                                                         },
209                                                         "_showDownBadge": function(){
210                                                                 this.view("deviceDownBadgeBg").set("visible", true);
211                                                                 this.view("deviceDownBadgeText").set("visible", true);
212                                                         },
213                                                         "_hideDownBadge": function(){
214                                                                 this.view("deviceDownBadgeBg").set("visible", false);
215                                                                 this.view("deviceDownBadgeText").set("visible", false);
216                                                         }
217                                                 }
218                                         });
219                                 }
220
221                                 /**
222                                  * Extend base nx link class function
223                                  */
224                                 function extendLinkClass () {
225                                         nx.define('ExtendedLink', nx.graphic.Topology.Link, {
226                                                 view: function(view){
227                                                         view.content.push({
228                                                                 name: 'badge',
229                                                                 type: 'nx.graphic.Group',
230                                                                 content: [
231                                                                         {
232                                                                                 name: 'badgeBg',
233                                                                                 type: 'nx.graphic.Rect',
234                                                                                 props: {
235                                                                                         'class': 'link-set-circle',
236                                                                                         height: 1
237                                                                                 }
238                                                                         },
239                                                                         {
240                                                                                 name: 'badgeText',
241                                                                                 type: 'nx.graphic.Text',
242                                                                                 props: {
243                                                                                         'class': 'link-set-text',
244                                                                                         y: 1
245                                                                                 }
246                                                                         }
247                                                                 ]
248                                                         });
249                                                         return view;
250                                                 },
251                                                 properties: {
252                                                         stageScale: {
253                                                                 set: function (a) {
254                                                                         this.view("badge").setTransform(null, null, a);
255                                                                         var b = (this._width || 1) * a;
256                                                                         this.view("line").dom().setStyle("stroke-width", b);
257                                                                         this.view("path").dom().setStyle("stroke-width", b);
258                                                                         this._stageScale = a;
259                                                                         this.update();
260                                                                 }
261                                                         }
262                                                 },
263                                                 methods: {
264                                                         // inherit properties/parent's data
265                                                         init: function(args){
266                                                                 this.inherited(args);
267                                                                 this.topology().fit();
268                                                         },
269                                                         // inherit parent's model
270                                                         'setModel': function(model) {
271                                                                 this.inherited(model);
272                                                                 //if(model._data.linksIntegrity){
273                                                                 //      this.view('statusIcon').set('src', 'assets/images/attention.png');
274                                                                 //}
275                                                         },
276                                                         // when topology's updated
277                                                         update: function(){
278                                                                 /*
279                                                                 this.inherited();
280
281                                                                 // ECMP badge settings
282                                                                 var badge = this.view('badge');
283                                                                 var badgeText = this.view('badgeText');
284                                                                 var badgeBg = this.view('badgeBg');
285                                                                 var statusIcon = this.view('statusIcon');
286                                                                 var status = this.model()._data.status;
287                                                                 ECMP, not needed here
288                                                                 if( this.model()._data.gLinks.length > 2 ) {
289                                                                         badgeText.sets({
290                                                                                 text: status.operational + '/' + status.configured,
291                                                                                 visible: true
292                                                                         });
293                                                                         var bound = badge.getBound();
294                                                                         var boundMax = Math.max(bound.width - 6, 1);
295                                                                         badgeBg.sets({width: boundMax, visible: true});
296                                                                         badgeBg.setTransform(boundMax / -2);
297                                                                         var centerPoint = this.centerPoint();
298                                                                         badge.setTransform(centerPoint.x, centerPoint.y);
299                                                                 }
300                                                                 // record source & target 'node-id's
301                                                                 var sourceNode = this.model().source()._data;
302                                                                 this.model()._data.sourceName = this.model().source()._data.label;
303                                                                 this.model()._data.targetName = this.model().target()._data.label;
304
305                                                                 this.view("badge").visible(true);
306                                                                 this.view("badgeBg").visible(true);
307                                                                 this.view("badgeText").visible(true);
308
309                                 //set correct link color
310                                 this.set('color',this.getColor());
311                                 */
312
313                                 this.setProviderStyleLine();
314                                                                 this.set('color', this.getColor());
315                                                         },
316                                                         // generate the color for a link
317                                                         getColor: function(){
318                                                                 // get color depend on status
319                                                                 var color = this.model()._data.type === 'chain' ? '#3366ff' : '#009900';
320                                                                 // make it available outside next
321                                                                 this.model()._data.linkColor = color;
322                                                                 return color;
323                             },
324
325                             setProviderStyleLine: function() {
326                                 var _offset = this.getOffset();
327                                 var offset = new nx.geometry.Vector(0, _offset);
328                                 var stageScale = this.stageScale();
329                                 var line = this.reverse() ? this.line().negate() : this.line();
330                                 var lineEl = this.view('line');
331                                 var newLine = line.translate(offset).pad(25 * stageScale, 17 * stageScale);
332                                 lineEl.sets({
333                                     x1: newLine.start.x,
334                                     y1: newLine.start.y,
335                                     x2: newLine.end.x,
336                                     y2: newLine.end.y
337                                 });
338                                 lineEl.setStyle('marker-start', 'url(#circle)');
339                             }
340                                                 }
341                                         });
342                                 }
343
344                                 /**
345                                  * Extended class for tooltip nx component
346                                  */
347                                 function extendedTooltip(){
348                                         nx.define('ExtendedTooltip', nx.ui.Component, {
349                                                 properties: {
350                                                         node: {},
351                                                         topology: {}
352                                                 },
353                                                 view: NextTopologyService.getTooltipContent()
354                                         });
355
356                                 }
357
358                                 /**
359                                  * Define custom events for topology componets
360                                  */
361                                 function defineCustomEvents(){
362                                         nx.define('CustomEvents', nx.graphic.Topology.DefaultScene, {
363                                                 methods: {
364                                                         clickNode: function(sender, node){
365                                                                 if ( scope.cbkFunctions.clickNode ) {
366                                                                         scope.cbkFunctions.clickNode(node);
367                                                                 }
368                                                         },
369                                                         clickLink: function(sender, link){
370                                                                 if ( scope.cbkFunctions.clickLink ) {
371                                                                         scope.cbkFunctions.clickLink(link);
372                                                                 }
373                                                         }
374                                                 }
375
376                                         });
377                                 }
378
379                                 // TODO: remove when come to decision about depiction of node status
380                                 ///**
381                                 // * Creating new node status layer - circles representing device status - up, down
382                                 // */
383                                 //function createNodeStatusLayer(){
384                                 //      nx.define("NodeStatus", nx.graphic.Topology.Layer, {
385                                 //      nx.define("NodeStatus", nx.graphic.Topology.Layer, {
386                                 //              methods: {
387                                 //                      draw: function() {
388                                 //                              var topo = this.topology();
389                                 //                              topo.eachNode(function(node) {
390                                 //                                      var nodeStatus = node._model._data.status === 'operational' ? node._model._data.status : 'down',
391                                 //                                              //type = node._model._data.type,
392                                 //                                              dot = new nx.graphic.Circle({
393                                 //                                                      r: 6,
394                                 //                                                      cx: -30,
395                                 //                                                      cy: -0
396                                 //                                              });
397                                 //
398                                 //                                      dot.set("fill", topoColors.getItem(nodeStatus));
399                                 //                                      dot.attach(node);
400                                 //                                      node.dot = dot;
401                                 //                              }, this);
402                                 //                      }
403                                 //              }
404                                 //      });
405                                 //}
406
407                         }
408                 };
409         };
410
411         NextTopology.$inject=['NextTopologyService'];
412
413         return NextTopology;
414 });