Add bootstrap 4 support
[pharos-tools.git] / dashboard / src / templates / workflow / viewport-base.html
1 {% extends "base.html" %}
2 {% load staticfiles %}
3
4 {% load bootstrap4 %}
5
6 {% block content %}
7
8 <style>
9     .go_btn {
10
11         position: absolute;
12         width: 100px;
13         top: 170px;
14         height: calc(100% - 170px);
15
16     }
17
18     .go_btn_disabled {
19         background-color: #ffffff;
20     }
21
22     .go_forward {
23         right: 0px;
24         border-left: none;
25     }
26
27     .go_back {
28         left: 251px;
29         border-right: none;
30     }
31
32
33     .btn_wrapper {
34         text-align: center;
35         margin-bottom: 5px;
36
37     }
38
39     {% if DEBUG %}
40         .add_btn_wrapper {
41             right: 130px;
42             top: 10px;
43             position: absolute;
44         }
45     {% endif %}
46
47     #breadcrumbs {
48         margin-bottom: 0;
49     }
50
51     .btn_wrapper {
52         margin: 0;
53     }
54
55     .step {
56         display: inline;
57         padding: 7px;
58         margin: 1px;
59         font-size: 14pt;
60         cursor: default;
61     }
62
63     .step:active {
64         -webkit-box-shadow: inherit;
65         box-shadow: inherit;
66     }
67
68     .step_active:active {
69         -webkit-box-shadow: inherit;
70         box-shadow: inherit;
71     }
72
73     .step_active {
74         display: inline;
75         padding: 7px;
76         margin: 1px;
77         cursor: default;
78         font-size: 14pt;
79         padding-bottom: 4px !important;
80         border-bottom: 4px solid #41ba78 !important;
81     }
82
83     .step_hidden {
84         background: #EFEFEF;
85         color: #999999;
86     }
87
88     .step_invalid::after {
89         content: " \2612";
90         color: #CC3300;
91     }
92
93     .step_valid::after {
94         content: " \2611";
95         color: #41ba78;
96     }
97
98     .step_untouched::after {
99         content: " \2610";
100     }
101
102     .iframe_div {
103         width: calc(100% - 450px);
104         margin-left: 70px;
105         height: calc(100vh - 155px);
106         position: absolute;
107         border: none;
108     }
109
110     .iframe_elem {
111         width: 100%;
112         height: calc(100vh - 155px);
113         border: none;
114     }
115
116     #breadcrumbs {
117         background-color: inherit;
118     }
119
120     #breadcrumbs.breadcrumb>li {
121         border: 1px solid #cccccc;
122         border-left: none;
123     }
124
125     #breadcrumbs.breadcrumb>li:first-child {
126         border-left: 1px solid #cccccc;
127     }
128
129     #breadcrumbs.breadcrumb>li+li:before {
130         content: "";
131         width: 0;
132         margin: 0;
133         padding: 0;
134     }
135
136     #topPagination .topcrumb {
137         flex: 1 1 0;
138         display: flex;
139         align-content: center;
140         justify-content: center;
141         border: 1px solid #dee2e6;
142         border-left: none;
143     }
144
145     .topcrumb > span {
146         color: #343a40;
147         cursor: default;
148     }
149
150     .topcrumb.active > span {
151         background: #007bff;
152         color: white;
153     }
154
155     .topcrumb.disabled > span {
156         color: #6c757d;
157         background: #f8f9fa;
158     }
159 </style>
160 <!-- Pagination -->
161 <div class="row mt-3">
162     <div class="col">
163         <nav>
164             <ul class="pagination d-flex flex-row" id="topPagination">
165                 <li class="page-item flex-shrink-1 page-control">
166                     <a class="page-link" href="#" id="gob" onclick="go('prev')">
167                         <i class="fas fa-backward"></i> Back
168                     </a>
169                 </li>
170                 <li class="page-item flex-grow-1 active">
171                     <a class="page-link disabled" href="#">
172                         Select <i class="far fa-check-square"></i>
173                     </a>
174                 </li>
175                 <li class="page-item flex-grow-1">
176                     <a class="page-link disabled" href="#">
177                         Configure <i class="far fa-square"></i>
178                     </a>
179                 </li>
180                 <li class="page-item flex-grow-1">
181                     <a class="page-link disabled" href="#">
182                         Information <i class="far fa-square"></i>
183                     </a>
184                 </li>
185                 <li class="page-item flex-grow-1">
186                     <a class="page-link disabled" href="#">
187                         OPNFV <i class="far fa-square"></i>
188                     </a>
189                 </li>
190                 <li class="page-item flex-grow-1">
191                     <a class="page-link disabled" href="#">
192                         Confirm <i class="far fa-square"></i>
193                     </a>
194                 </li>
195                 <li class="page-item flex-shrink-1 page-control">
196                     <a class="page-link text-right" href="#" id="gof" onclick="go('next')">
197                         Next <i class="fas fa-forward"></i>
198                     </a>
199                 </li>
200             </ul>
201         </nav>
202     </div>
203 </div>
204 <!-- Top header -->
205 <div class="row px-4">
206     <div class="col">
207         <div id="iframe_header" class="row view-header">
208             <div class="col-lg-12 step_header">
209                 <h1 class="step_title d-inline-block" id="view_title"></h1>
210                 <span class="description text-muted" id="view_desc"></span>
211                 <p class="step_message" id="view_message"></p>
212             </div>
213             <script>
214                 function update_description(title, desc) {
215                     document.getElementById("view_title").innerText = title;
216                     document.getElementById("view_desc").innerText = desc;
217                 }
218
219                 function update_message(message, stepstatus) {
220                     document.getElementById("view_message").innerText = message;
221                     document.getElementById("view_message").className = "step_message";
222                     document.getElementById("view_message").classList.add("message_" + stepstatus);
223                 }
224             </script>
225             <!-- /.col-lg-12 -->
226         </div>
227     </div>
228     <div class="col-auto align-self-center d-flex">
229         <button id="cancel_btn" class="btn btn-danger ml-auto" onclick="cancel_wf()">Cancel</button>
230     </div>
231 </div>
232 <!-- Content here -->
233 <div class="row d-flex flex-column flex-grow-1">
234     <div class="container-fluid d-flex flex-column h-100">
235         <div class="row d-flex flex-grow-1 p-4">
236             <!-- iframe workflow -->
237             <div class="col-12 d-flex border flex-grow-1">
238                 <!-- This was where the iframe went -->
239                 <iframe src="/wf/workflow" class="w-100 h-100" scrolling="yes" id="viewport-iframe"
240                     frameBorder="0"></iframe>
241             </div>
242         </div>
243     </div>
244 </div>
245 <div class="btn_wrapper">
246 </div>
247 {% csrf_token %}
248
249 <script type="text/javascript">
250     update_context();
251     var step = 0;
252     var page_count = 0;
253     var context_data = false;
254
255     function go(to) {
256         step_on_leave();
257         request_leave(to);
258     }
259
260     function request_leave(to) {
261         $.ajax({
262             type: "GET",
263             url: "/wf/manager/",
264             beforeSend: function (request) {
265                 request.setRequestHeader("X-CSRFToken",
266                     $('input[name="csrfmiddlewaretoken"]').val());
267             },
268             success: function (data) {
269                 confirm_permission(to, data);
270                 update_page(data);
271             }
272         });
273     }
274
275     function confirm_permission(to, data) {
276         if (errors_exist(data)) {
277             if (to != "prev") {
278                 return;
279             }
280         }
281
282         var problem = function () {
283             alert("There was a problem");
284         }
285         //makes an asynch request
286         req = new XMLHttpRequest();
287         url = "/wf/workflow/?step=" + to;
288         req.open("GET", url, true);
289         req.onload = function (e) {
290             if (req.readyState === 4) {
291                 if (req.status < 300) {
292                     document.getElementById("viewport-iframe").srcdoc = this.responseText;
293                 } else {
294                     problem();
295                 }
296             } else {
297                 problem();
298             }
299         }
300         req.onerror = problem;
301         req.send();
302     }
303
304     function step_on_leave() {
305         document.getElementById("viewport-iframe").contentWindow.step_on_leave();
306     }
307
308     function errors_exist(data) {
309         var stat = data['steps'][data['active']]['valid'];
310         if (stat >= 100 && stat < 200) {
311             return true;
312         } else {
313             return false;
314         }
315     }
316
317     function update_context() {
318         $.ajax({
319             type: "GET",
320             url: "/wf/manager/",
321             beforeSend: function (request) {
322                 request.setRequestHeader("X-CSRFToken",
323                     $('input[name="csrfmiddlewaretoken"]').val());
324             },
325             success: function (data) {
326                 update_page(data);
327             }
328         });
329     }
330
331     function update_page(data) {
332         context_data = data;
333         update_breadcrumbs(data);
334         if (data["workflow_count"] == 1) {
335             document.getElementById("cancel_btn").innerText = "Exit Workflow";
336         } else {
337             document.getElementById("cancel_btn").innerText = "Return to Parent";
338         }
339     }
340
341     function update_breadcrumbs(meta_json) {
342         step = meta_json['active'];
343         page_count = meta_json['steps'].length;
344         if (step == 0) {
345             var btn = document.getElementById("gob");
346             btn.classList.add("invisible");
347             btn.disabled = true;
348         } else {
349             var btn = document.getElementById("gob");
350             btn.classList.remove("invisible");
351             btn.disabled = false;
352         }
353         if (step == page_count - 1) {
354             var btn = document.getElementById("gof");
355             btn.classList.add("invisible");
356             btn.disabled = true;
357         } else {
358             var btn = document.getElementById("gof");
359             btn.classList.remove("invisible");
360             btn.disabled = false;
361         }
362         //remove all children of breadcrumbs so we can redraw
363         $("#topPagination").children().not(".page-control").remove();
364         draw_steps(meta_json);
365     }
366
367     function draw_steps(meta_json) {
368         for (var i = 0; i < meta_json["steps"].length; i++) {
369             meta_json["steps"][i]["index"] = i;
370             var step_btn = create_step(meta_json["steps"][i], i == meta_json["active"]);
371             $("#topPagination li:last-child").before(step_btn);
372         }
373     }
374
375     function create_step(step_json, active) {
376         var step_dom = document.createElement("li");
377         // First create the dom object depending on active or not
378         if (active) {
379             step_dom.className = "topcrumb active";
380         } else {
381             step_dom.className = "topcrumb";
382         }
383         $(step_dom).html(`<span class="d-flex align-items-center justify-content-center text-capitalize w-100">${step_json['title']}</span>`)
384         var code = step_json['valid'];
385         stat = "";
386         msg = "";
387         if (code < 100) {
388             $(step_dom).children().first().append("<i class='ml-2 far fa-square'></i>")
389             stat = "";
390             msg = "";
391         } else if (code < 200) {
392             $(step_dom).children().first().append("<i class='ml-2 fas fa-minus-square'></i>")
393             stat = "invalid";
394             msg = step_json['message'];
395         } else if (code < 300) {
396             $(step_dom).children().first().append("<i class='ml-2 far fa-check-square'></i>")
397             stat = "valid";
398             msg = step_json['message'];
399         }
400         if (step_json['enabled'] == false) {
401             step_dom.classList.add("disabled");
402         }
403         if (active) {
404             update_message(msg, stat);
405         }
406
407         var step_number = step_json['index'];
408         return step_dom;
409     }
410
411     function cancel_wf() {
412         var form = $("#workflow_pop_form");
413         var formData = form.serialize();
414         var req = new XMLHttpRequest();
415         req.open("POST", "/wf/workflow/finish/", false);
416         req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
417         req.onerror = function () {
418             alert("problem occurred while trying to cancel current workflow");
419         }
420         req.onreadystatechange = function () {
421             if (req.readyState === 4) {
422                 refresh_iframe();
423             }
424         };
425         req.send(formData);
426     }
427
428     function refresh_iframe() {
429         req = new XMLHttpRequest();
430         url = "/wf/workflow/";
431         req.open("GET", url, true);
432         req.onload = function (e) {
433             var doc = document.getElementById("viewport-iframe").contentWindow.document;
434             doc.open();
435             doc.write(this.responseText);
436             doc.close();
437         }
438         req.send();
439     }
440
441     function write_iframe(contents) {
442         document.getElementById("viewport-iframe").contentWindow.document.innerHTML = contents;
443     }
444
445     function redirect_root() {
446         window.location.replace('/wf/');
447     }
448
449     function add_wf(type) {
450         add_wf_internal(type, false);
451     }
452
453     function add_edit_wf(type, target) {
454         add_wf_internal(type, target);
455     }
456
457     function add_wf_internal(type, itemid) {
458         data = {
459             "add": type
460         };
461         if (itemid) {
462             data['target'] = itemid;
463         }
464         $.ajax({
465             type: "POST",
466             url: "/wf/manager/",
467             data: data,
468             beforeSend: function (request) {
469                 request.setRequestHeader("X-CSRFToken",
470                     $('input[name="csrfmiddlewaretoken"]').val()
471                 );
472             },
473             success: refresh_wf_iframe()
474         });
475     }
476
477     function refresh_wf_iframe() {
478         window.location = window.location;
479     }
480 </script>
481 <div style="display: none;" id="workflow_pop_form_div">
482     <form id="workflow_pop_form" action="/wf/workflow/finish/" method="post">
483         {% csrf_token %}
484     </form>
485 </div>
486 {% endblock content %}