d56e22fd9c97b0f90ecbc799c83f1a5abebb9e23
[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
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 if (nodetype === 'ns_vl') {
138
139 graph_editor.addNode(node_information, function () {
140 console.log("OK")
141 }, function (error) {
142 showAlert(error)
143 })
144 } else if (nodetype === 'vnf') {
145 node_information['id'] = $('#' + elemet_id).attr('desc_id');
146 graph_editor.addNode(node_information, function () {
147 console.log("OK")
148 }, function (error) {
149 showAlert(error)
150 })
151 }
152 };
153
154 dropZone.ondragover = function (ev) {
155 console.log("ondragover");
156 return false;
157 };
158
159 dropZone.ondragleave = function () {
160 console.log("ondragleave");
161 return false;
162 };
163 }
164
165
166 function handleForce(el) {
167 graph_editor.handleForce((el.getAttribute('aria-pressed') === "true"));
168 }
169
170 function changeFilter(e, c) {
171 if (c && c.link && c.link.view[0]) {
172 updateLegend(c.link.view[0]);
173 updatePalette(c.link.view[0]);
174 }
175 layerDetails(graph_editor.getCurrentFilters())
176 }
177
178 function resetFilters() {
179 graph_editor.handleFiltersParams(params);
180 }
181
182 function buildBehaviorsOnEvents() {
183 var contextmenuNodesAction = [];
184 return {
185 'nodes': contextmenuNodesAction
186 };
187
188 }
189
190 function refreshElementInfo(event, element) {
191 if (event.type === 'node:selected') {
192 switch (element.info.type) {
193 case 'vnf':
194 vnfDetails(element.info.osm);
195 break;
196 case 'vdu':
197 vduDetails(element.info.osm);
198 break;
199 case 'int_cp':
200 case 'cp':
201 cpDetails(element.info.osm);
202 break;
203 case 'vnf_vl':
204 case 'ns_vl':
205 vlDetails(element.info.osm);
206 break;
207 }
208 }
209 else if (event.type === 'node:deselected') {
210 layerDetails(graph_editor.getCurrentFilters())
211 }
212 }
213
214 function layerDetails(filters) {
215 var side = $('#side_form');
216 var graph_parameters = graph_editor.getGraphParams();
217 var layer_template = '';
218 if (graph_parameters['view'] && filters.link.view.length > 0 && filters.link.view[0]) {
219 if (filters.link.view[0] === 'nsd') {
220 layer_template = getMainSectionWithSubmitButton('NSD');
221 layer_template += getChildrenTable(graph_parameters['view']['nsd']);
222 }
223 else if (filters.link.view[0] === 'vnfd') {
224 layer_template = getMainSectionWithSubmitButton('VNFD');
225
226 layer_template += getChildrenTable(graph_parameters['view']['vnfd']);
227 }
228 }
229
230 side.empty();
231 side.append(layer_template)
232 }
233
234 function updateLegend(view) {
235 var legend = $('#legenda');
236 var nodes = type_view[view];
237 var legend_template = '';
238 var nodes_properties = osm_gui_properties['nodes'];
239 for (var n in nodes) {
240 var node = nodes[n];
241 if (nodes_properties[node]) {
242 legend_template += '<div class="node">' +
243 '<div class="icon" style="background-color:' + nodes_properties[node].color + '"></div>' +
244 '<div class="name">' + nodes_properties[node].name + '</div></div>';
245 }
246 }
247
248 legend.empty();
249 legend.append(legend_template)
250
251 }
252
253 function updatePalette(view) {
254 var palette = $('#palette');
255 var palette_template = '';
256 palette.empty();
257 if (view === 'vnfd') {
258 var nodes = type_view[view];
259 var nodes_properties = osm_gui_properties['nodes'];
260 for (var n in nodes) {
261 var node = nodes[n];
262 if (nodes_properties[node]) {
263 palette_template += '<div id="drag_' + n + '" class="node ui-draggable"' +
264 'type-name="' + n + '" draggable="true" ondragstart="nodeDragStart(event)">' +
265 '<div class="icon" style="background-color:' + nodes_properties[node].color + '"></div>' +
266 '<div class="name">' + nodes_properties[node].name + '</div></div>';
267 }
268 }
269
270 palette.append(palette_template)
271 } else if (view === 'nsd') {
272 $.ajax({
273 url: '/projects/descriptors/composer/availablenodes?layer=nsd',
274 type: 'GET',
275 cache: false,
276 success: function (result) {
277 palette_template += '<div id="drag_ns_vl" class="node ui-draggable"' +
278 'type-name="ns_vl" draggable="true" ondragstart="nodeDragStart(event)">' +
279 '<div class="icon" style="background-color:' + osm_gui_properties['nodes']['ns_vl'].color + '"></div>' +
280 '<div class="name">' + osm_gui_properties['nodes']['ns_vl'].name + '</div></div>';
281 palette_template += getSubSection('VNFD');
282 for (var d in result['descriptors']) {
283 var desc = result['descriptors'][d];
284 palette_template += '<div id="drag_' + desc.id + '" class="node ui-draggable"' +
285 'type-name="vnf" desc_id="' + desc.id + '" draggable="true" ondragstart="nodeDragStart(event)">' +
286 '<div class="icon" style="background-color:#605ca8"></div>' +
287 '<div class="name">' + desc.name + '</div></div>';
288 }
289 palette.append(palette_template)
290 },
291 error: function (result) {
292 showAlert(result);
293 }
294 });
295 }
296
297 }
298
299
300 function vnfDetails(vnfr) {
301 var side = $('#side_form');
302 var vnfr_template = getMainSection('VNF');
303
304 vnfr_template += getChildrenTable(vnfr, true);
305 side.empty();
306 side.append(vnfr_template)
307 }
308
309 function vduDetails(vdur) {
310 var side = $('#side_form');
311 var vdur_template = getMainSectionWithSubmitButton('VDU');
312 vdur_template += getChildrenTable(vdur);
313
314 side.empty();
315 side.append(vdur_template)
316 }
317
318 function cpDetails(cp) {
319 var side = $('#side_form');
320 var cp_template = getMainSectionWithSubmitButton('Connection Point');
321
322 cp_template += getChildrenTable(cp);
323 side.empty();
324 side.append(cp_template);
325 }
326
327 function vlDetails(vl) {
328 var side = $('#side_form');
329 var vl_template = getMainSectionWithSubmitButton('Virtual Link');
330
331 vl_template += getChildrenTable(vl);
332 side.empty();
333 side.append(vl_template);
334 }
335
336
337 function getMainSection(title) {
338 return '<div class="section"><span style="font-weight: 500;">' + title + '</span></div>';
339 }
340
341 function getMainSectionWithSubmitButton(title) {
342 return '<div class="section"><span style="font-weight: 500;">' + title + '</span>' +
343 '<div class="status"><button id="update_button" class="btn btn-xs btn-default" ><i class="fa fa-save"></i> SAVE</button></div></div>';
344 }
345
346 function getSubSection(title) {
347 return '<div class="section"><span>' + title + '</span></div>';
348 }
349
350 function getMainSectionWithStatus(title, status) {
351 var template = '<div class="section"><span style="font-weight: 500;">' + title + '</span>';
352 if (status)
353 template += '<div class="status active"><span class="indicator"></span> ACTIVE</div>';
354 else
355 template += '<div class="status"><span class="indicator"></span>NO ACTIVE</div>';
356 template += '</div>';
357 return template;
358 }
359
360 function getChildrenTable(data, ro) {
361 var template = '<table class="children">';
362
363 for (var key in data) {
364 if (typeof data[key] !== 'object') {
365 var key_map = (map[key]) ? map[key] : key;
366 if (ro)
367 template += '<tr><td>' + key_map + '</td><td>' + data[key] + '</td></tr>';
368 else
369 template += '<tr><td>' + key_map + '</td><td><input name="' + key + '" class="form-control input-sm" type="text" value="' + data[key] + '"></td></tr>';
370
371 }
372 }
373 template += '</table>';
374 return template;
375 }
376
377 function openHelp() {
378 $('#modalTopologyInfoButton').modal('show');
379 }
380
381 function openTextedit() {
382 window.location.href = '/projects/descriptors/' + getUrlParameter('type') + '/' + getUrlParameter('id')
383 }