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