18072a80528818168849b8a0439834712e2f3ba5
[osm/LW-UI.git] / static / src / descriptorhandler / composer.js
1 /*
2 Copyright 2018 EveryUP srl
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 //GraphEditor instance
18 var graph_editor = new TCD3.ModelGraphEditor();
19
20 var type_view = {
21 "nsd": ["vnf", "ns_vl"],
22 "vnfd": ["vdu", "cp", "vnf_vl", "int_cp"]
23 };
24
25 var map = {
26 'ip-address': 'IP', 'vnfd-id': 'Vnfd Id', 'vnfd-ref': 'Vnfd Ref', 'vim-account-id': 'Vim Id',
27 'member-vnf-index-ref': 'Member index', 'created-time': 'Created', 'id': 'Id', 'mgmt-network': 'Mgmt network',
28 'name': 'Name', 'type': 'Type', 'vim-network-name': 'Vim network name', 'connection-point-id': 'Cp Id',
29 'vdu-id-ref': 'Vdu Id', 'nsr-id-ref': 'Nsr Id'
30 };
31
32 var params = {
33 node: {
34 type: type_view[getUrlParameter('type')],
35 group: []
36 },
37 link: {
38 group: [],
39 view: [getUrlParameter('type')]
40 }
41 };
42
43 $(document).ready(function () {
44
45 graph_editor.addListener("filters_changed", changeFilter);
46 graph_editor.addListener("node:selected", refreshElementInfo);
47 graph_editor.addListener("node:deselected", refreshElementInfo);
48
49 // graph_editor initialization
50 graph_editor.init({
51 width: $('#graph_editor_container').width(),
52 height: $('#graph_editor_container').height(),
53
54 data_url: window.location.href,
55 //desc_id: getUrlParameter('id'),
56 gui_properties: osm_gui_properties,
57 edit_mode: true,
58 behaviorsOnEvents: {
59 viewBased: false,
60 behaviors: buildBehaviorsOnEvents()
61 }
62 });
63 graph_editor.handleFiltersParams(params);
64 initDropOnGraph();
65
66
67 $("#side_form").submit(function (event) {
68 event.preventDefault(); //prevent default action
69 console.log("ON submit")
70 var form_data = new FormData(this); //Encode form elements for submission
71 var formDataJson = {};
72 form_data.forEach(function (value, key) {
73 formDataJson[key] = value;
74 });
75 var dialog = bootbox.dialog({
76 message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Updating...</div>',
77 closeButton: true
78 });
79 if (graph_editor._selected_node) {
80 graph_editor.updateDataNode(graph_editor._selected_node, formDataJson, function () {
81 dialog.modal('hide');
82 }, function (result) {
83 var data = result.responseJSON;
84 var title = "Error " + (data && data.code ? data.code : 'unknown');
85 var message = data && data.detail ? data.detail : 'No detail available.';
86 dialog.modal('hide');
87 bootbox.alert({
88 title: title,
89 message: message
90 });
91 })
92 } else {
93 graph_editor.updateGraphParams(formDataJson, function () {
94 dialog.modal('hide');
95 }, function (result) {
96 var data = result.responseJSON;
97 var title = "Error " + (data && data.code ? data.code : 'unknown');
98 var message = data && data.detail ? data.detail : 'No detail available.';
99 dialog.modal('hide');
100 bootbox.alert({
101 title: title,
102 message: message
103 });
104 })
105 }
106
107 });
108 });
109
110
111 function initDropOnGraph() {
112
113 var dropZone = document.getElementById('graph_editor_container');
114 dropZone.ondrop = function (e) {
115 var group = graph_editor.getCurrentGroup();
116 e.preventDefault();
117 var elemet_id = e.dataTransfer.getData("text/plain");
118
119 var nodetype = $('#' + elemet_id).attr('type-name');
120 var random_name = nodetype + "_" + generateUID();
121 console.log(nodetype)
122 var node_information = {
123 'id': random_name,
124 'info': {
125 'type': nodetype,
126 'property': {
127 'custom_label': random_name
128 },
129 'group': null,
130 'desc_id': getUrlParameter('id'),
131 'desc_type': getUrlParameter('type'),
132 'osm': {}
133 },
134 'x': e.layerX,
135 'y': e.layerY
136 };
137
138 if (nodetype === 'vnf') {
139 node_information['id'] = $('#' + elemet_id).attr('desc_id');
140 }
141
142 graph_editor.addNode(node_information, function () {
143 console.log("OK")
144 }, function (error) {
145 showAlert(error)
146 })
147
148 };
149
150 dropZone.ondragover = function (ev) {
151 console.log("ondragover");
152 return false;
153 };
154
155 dropZone.ondragleave = function () {
156 console.log("ondragleave");
157 return false;
158 };
159 }
160
161
162 function handleForce(el) {
163 graph_editor.handleForce((el.getAttribute('aria-pressed') === "true"));
164 }
165
166 function changeFilter(e, c) {
167 if (c && c.link && c.link.view[0]) {
168 updateLegend(c.link.view[0]);
169 updatePalette(c.link.view[0]);
170 }
171 layerDetails(graph_editor.getCurrentFilters())
172 }
173
174 function resetFilters() {
175 graph_editor.handleFiltersParams(params);
176 }
177
178 function buildBehaviorsOnEvents() {
179 var contextmenuNodesAction = [];
180 return {
181 'nodes': contextmenuNodesAction
182 };
183
184 }
185
186 function refreshElementInfo(event, element) {
187 if (event.type === 'node:selected') {
188 switch (element.info.type) {
189 case 'vnf':
190 vnfDetails(element.info.osm);
191 break;
192 case 'vdu':
193 vduDetails(element.info.osm);
194 break;
195 case 'int_cp':
196 intcpDetails(element.info.osm);
197 break;
198 case 'cp':
199 cpDetails(element.info.osm);
200 break;
201 case 'vnf_vl':
202 case 'ns_vl':
203 vlDetails(element.info.osm);
204 break;
205 }
206 }
207 else if (event.type === 'node:deselected') {
208 layerDetails(graph_editor.getCurrentFilters())
209 }
210 }
211
212 function layerDetails(filters) {
213 var side = $('#side_form');
214 var graph_parameters = graph_editor.getGraphParams();
215 var layer_template = '';
216 if (graph_parameters['view'] && filters.link.view.length > 0 && filters.link.view[0]) {
217 if (filters.link.view[0] === 'nsd') {
218 layer_template = getMainSectionWithSubmitButton('NSD');
219 layer_template += getChildrenTable(graph_parameters['view']['nsd']);
220 }
221 else if (filters.link.view[0] === 'vnfd') {
222 layer_template = getMainSectionWithSubmitButton('VNFD');
223
224 layer_template += getChildrenTable(graph_parameters['view']['vnfd']);
225 }
226 }
227
228 side.empty();
229 side.append(layer_template)
230 }
231
232 function updateLegend(view) {
233 var legend = $('#legenda');
234 var nodes = type_view[view];
235 var legend_template = '';
236 var nodes_properties = osm_gui_properties['nodes'];
237 for (var n in nodes) {
238 var node = nodes[n];
239 if (nodes_properties[node]) {
240 legend_template += '<div class="node">' +
241 '<div class="icon" style="background-color:' + nodes_properties[node].color + '"></div>' +
242 '<div class="name">' + nodes_properties[node].name + '</div></div>';
243 }
244 }
245
246 legend.empty();
247 legend.append(legend_template)
248
249 }
250
251 function updatePalette(view) {
252 var palette = $('#palette');
253 var palette_template = '';
254 palette.empty();
255 if (view === 'vnfd') {
256 var nodes = type_view[view];
257 var nodes_properties = osm_gui_properties['nodes'];
258 for (var n in nodes) {
259 var node = nodes[n];
260 if (nodes_properties[node]) {
261 palette_template += '<div id="drag_' + n + '" class="node ui-draggable"' +
262 'type-name="' + node + '" draggable="true" ondragstart="nodeDragStart(event)">' +
263 '<div class="icon" style="background-color:' + nodes_properties[node].color + '"></div>' +
264 '<div class="name">' + nodes_properties[node].name + '</div></div>';
265 }
266 }
267
268 palette.append(palette_template)
269 } else if (view === 'nsd') {
270 $.ajax({
271 url: '/projects/descriptors/composer/availablenodes?layer=nsd',
272 type: 'GET',
273 cache: false,
274 success: function (result) {
275 palette_template += '<div id="drag_ns_vl" class="node ui-draggable"' +
276 'type-name="ns_vl" draggable="true" ondragstart="nodeDragStart(event)">' +
277 '<div class="icon" style="background-color:' + osm_gui_properties['nodes']['ns_vl'].color + '"></div>' +
278 '<div class="name">' + osm_gui_properties['nodes']['ns_vl'].name + '</div></div>';
279 palette_template += getSubSection('VNFD');
280 for (var d in result['descriptors']) {
281 var desc = result['descriptors'][d];
282 palette_template += '<div id="drag_' + desc.id + '" class="node ui-draggable"' +
283 'type-name="vnf" desc_id="' + desc.id + '" draggable="true" ondragstart="nodeDragStart(event)">' +
284 '<div class="icon" style="background-color:#605ca8"></div>' +
285 '<div class="name">' + desc.name + '</div></div>';
286 }
287 palette.append(palette_template)
288 },
289 error: function (result) {
290 showAlert(result);
291 }
292 });
293 }
294
295 }
296
297
298 function vnfDetails(vnfr) {
299 var side = $('#side_form');
300 var vnfr_template = getMainSection('VNF');
301
302 vnfr_template += getChildrenTable(vnfr, true);
303 side.empty();
304 side.append(vnfr_template)
305 }
306
307 function vduDetails(vdur) {
308 var side = $('#side_form');
309 var vdur_template = getMainSectionWithSubmitButton('VDU');
310 vdur_template += getChildrenTable(vdur);
311
312 side.empty();
313 side.append(vdur_template)
314 }
315
316 function intcpDetails(cp) {
317 var side = $('#side_form');
318 var cp_template = getMainSection('Int. Connection Point');
319
320 cp_template += getChildrenTable(cp, true);
321 side.empty();
322 side.append(cp_template);
323 }
324
325 function cpDetails(cp) {
326 var side = $('#side_form');
327 var cp_template = getMainSectionWithSubmitButton('Connection Point');
328
329 cp_template += getChildrenTable(cp);
330 side.empty();
331 side.append(cp_template);
332 }
333
334 function vlDetails(vl) {
335 var side = $('#side_form');
336 var vl_template = getMainSectionWithSubmitButton('Virtual Link');
337
338 vl_template += getChildrenTable(vl);
339 side.empty();
340 side.append(vl_template);
341 }
342
343
344 function getMainSection(title) {
345 return '<div class="section"><span style="font-weight: 500;">' + title + '</span></div>';
346 }
347
348 function getMainSectionWithSubmitButton(title) {
349 return '<div class="section"><span style="font-weight: 500;">' + title + '</span>' +
350 '<div class="status"><button id="update_button" class="btn btn-xs btn-default" ><i class="fa fa-save"></i> SAVE</button></div></div>';
351 }
352
353 function getSubSection(title) {
354 return '<div class="section"><span>' + title + '</span></div>';
355 }
356
357 function getMainSectionWithStatus(title, status) {
358 var template = '<div class="section"><span style="font-weight: 500;">' + title + '</span>';
359 if (status)
360 template += '<div class="status active"><span class="indicator"></span> ACTIVE</div>';
361 else
362 template += '<div class="status"><span class="indicator"></span>NO ACTIVE</div>';
363 template += '</div>';
364 return template;
365 }
366
367 function getChildrenTable(data, ro) {
368 var template = '<table class="children">';
369
370 for (var key in data) {
371 if (typeof data[key] !== 'object') {
372 var key_map = (map[key]) ? map[key] : key;
373 if (ro)
374 template += '<tr><td>' + key_map + '</td><td>' + data[key] + '</td></tr>';
375 else
376 template += '<tr><td>' + key_map + '</td><td><input name="' + key + '" class="form-control input-sm" type="text" value="' + data[key] + '"></td></tr>';
377
378 }
379 }
380 template += '</table>';
381 return template;
382 }
383
384 function openHelp() {
385 $('#modalTopologyInfoButton').modal('show');
386 }
387
388 function openTextedit() {
389 window.location.href = '/projects/descriptors/' + getUrlParameter('type') + '/' + getUrlParameter('id')
390 }