Lab as a Service 2.0
[pharos-tools.git] / dashboard / src / templates / workflow / viewport-base.html
1 {% extends "base.html" %}
2 {% load staticfiles %}
3
4 {% load bootstrap3 %}
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     .go_forward{
18         right: 0px;
19         border-left: none;
20     }
21
22     .go_back{
23         left: 251px;
24         border-right: none;
25     }
26
27
28     .btn_wrapper{
29         text-align: center;
30         margin-bottom: 5px;
31
32     }
33
34     {% if DEBUG %}
35
36     .add_btn_wrapper{
37         right: 130px;
38         top: 10px;
39         position: absolute;
40     }
41     {% endif %}
42
43
44
45     .options{
46         position: absolute;
47         top: 60px;
48         right: 20px;
49     }
50
51     #breadcrumbs {
52         padding: 4px;
53     }
54     .step{
55         background: #DEEED3;
56         display: inline;
57         padding: 5px;
58         margin: 1px;
59     }
60
61     .step_active{
62         background: #5EC392;
63         display: inline;
64         padding: 5px;
65         margin: 1px;
66         font-weight: bold;
67     }
68
69     .step_untouched
70     {
71         background: #98B0AF;
72     }
73
74     .step_invalid
75     {
76         background: #CC3300;
77     }
78
79     .step_valid
80     {
81         background: #0FD57D;
82     }
83
84  #viewport-iframe
85  {
86      height: calc(100vh - 450);
87  }
88
89
90 </style>
91
92 <button id="gof" onclick="go(step+1)" class="btn go_btn go_forward">Go Forward</button>
93 <button id="gob" onclick="go(step-1)" class="btn btn go_btn go_back">Go Back</button>
94
95 <div class="options">
96     <button class="btn" onclick="cancel_wf()">Cancel</button>
97 </div>
98 <div class="btn_wrapper">
99 <div id="breadcrumbs">
100 </div>
101 </div>
102 {% csrf_token %}
103
104 <script type="text/javascript">
105
106
107     update_context();
108     var step = 0;
109     var page_count = 0;
110     var context_data = false;
111
112     function go(to)
113     {
114         step_on_leave();
115         request_leave(to);
116     }
117
118     function request_leave(to)
119     {
120         $.ajax({
121             type: "GET",
122             url: "/wf/manager/",
123             beforeSend: function(request) {
124                 request.setRequestHeader("X-CSRFToken",
125                 $('input[name="csrfmiddlewaretoken"]').val());
126             },
127             success: function (data) {
128                 confirm_permission(to, data);
129                 update_page(data);
130             }
131         });
132     }
133
134     function confirm_permission(to, data)
135     {
136         if( errors_exist(data) )
137         {
138             var continueanyway = confirm("The current step has errors that will prevent it from saving. Continue anyway?");
139             if( !continueanyway )
140             {
141                 return;
142             }
143         }
144         if( to >= page_count )
145         {
146             to = page_count-1;
147         }
148         else if( to < 0 )
149         {
150             to = 0;
151         }
152         var problem = function() {
153             alert("There was a problem");
154         }
155         //makes an asynch request
156         req = new XMLHttpRequest();
157         url = "/wf/workflow/?step=" + to;
158         req.open("GET", url, true);
159         req.onload = function(e) {
160             if(req.readyState === 4){
161                 if(req.status < 300){
162                     document.getElementById("viewport-iframe").srcdoc = this.responseText;
163                 } else { problem(); }
164             } else { problem(); }
165         }
166         req.onerror = problem;
167         req.send();
168     }
169
170     function step_on_leave()
171     {
172         document.getElementById("viewport-iframe").contentWindow.step_on_leave();
173     }
174
175     function errors_exist(data)
176     {
177         var stat = data['steps'][data['active']]['valid'];
178         if( stat >= 100 && stat < 200 )
179         {
180             return true;
181         }
182         else
183         {
184             return false;
185         }
186     }
187
188     function update_context() {
189         $.ajax({
190             type: "GET",
191             url: "/wf/manager/",
192             beforeSend: function(request) {
193                 request.setRequestHeader("X-CSRFToken",
194                 $('input[name="csrfmiddlewaretoken"]').val());
195             },
196             success: function (data) {
197                 update_page(data);
198             }
199         });
200     }
201
202     function update_page(data)
203     {
204         context_data = data;
205         update_breadcrumbs(data);
206     }
207
208     function update_breadcrumbs(meta_json) {
209         step = meta_json['active'];
210         page_count = meta_json['steps'].length;
211         //remove all children of breadcrumbs so we can redraw
212         var container = document.getElementById("breadcrumbs");
213         while(container.firstChild){
214             container.removeChild(container.firstChild);
215         }
216         //draw enough rows for all steps
217         var depth = meta_json['max_depth'];
218         for(var i=0; i<=depth; i++){
219             var div = document.createElement("DIV");
220             div.id = "row"+i;
221             if(i<depth){
222                 div.style['margin-bottom'] = "7px";
223             }
224             if(i>0){
225                 div.style['margin-top'] = "7px";
226             }
227             container.appendChild(div);
228         }
229         draw_steps(meta_json);
230     }
231
232     function draw_steps(meta_json){
233         var all_relations = meta_json['relations'];
234         var relations = [];
235         var active_steps = [];
236         var active_step = step;
237         while(active_step < meta_json['steps'].length){
238             active_steps.push(active_step);
239             var index = meta_json['parents'][active_step];
240             var relation = all_relations[index];
241             relations.push(relation);
242             active_step = relation['parent'];
243         }
244         var child_index = meta_json['children'][step];
245         var my_children = all_relations[child_index];
246         if(my_children){
247             relations.push(my_children);
248         }
249         draw_relations(relations, meta_json, active_steps);
250     }
251
252     function draw_relations(relations, meta_json, active_steps){
253         for(var i=0; i<relations.length; i++){
254             var relation = relations[i];
255             var children_container = document.createElement("DIV");
256             children_container.style['display'] = "inline";
257             children_container.style['margin'] = "3px";
258             children_container.style['padding'] = "3px";
259             console.log("meta_json: ");
260             console.log(meta_json);
261             for(var j=0; j<relation['children'].length; j++){
262                 var step_json = meta_json['steps'][relation['children'][j]];
263                 step_json['index'] = relation['children'][j];
264                 var active = active_steps.indexOf(step_json['index']) > -1;
265                 var step_button = create_step(meta_json['steps'][relation['children'][j]], active);
266                 children_container.appendChild(step_button);
267             }
268             var parent_div = document.getElementById("row" + relation['depth']);
269             parent_div.appendChild(children_container);
270         }
271     }
272
273     function create_step(step_json, active){
274         var step_dom = document.createElement("DIV");
275         if(active){
276             step_dom.className = "step_active";
277             console.log(step_json['message']);
278
279         } else{
280             step_dom.className = "step";
281         }
282         step_dom.appendChild(document.createTextNode(step_json['title']));
283         var code = step_json['valid'];
284         stat = "";
285         msg = "";
286         if( code < 100 )
287         {
288             step_dom.classList.add("step_untouched");
289
290             stat = "";
291             msg = "";
292         }
293         else if( code < 200 )
294         {
295             step_dom.classList.add("step_invalid");
296             stat = "invalid";
297             msg = step_json['message'];
298         }
299         else if( code < 300 )
300         {
301             step_dom.classList.add("step_valid");
302             stat = "valid";
303             msg = step_json['message'];
304         }
305         if(active)
306         {
307             update_message(msg, stat);
308         }
309
310         var step_number = step_json['index'];
311         step_dom.onclick = function(){ go(step_number); }
312         //TODO: background color and other style
313         return step_dom;
314     }
315
316     function cancel_wf(){
317         $.ajax({
318             type: "POST",
319             url: "/wf/manager/",
320             data: {"cancel":"",},
321             beforeSend: function(request) {
322                 request.setRequestHeader("X-CSRFToken",
323                 $('input[name="csrfmiddlewaretoken"]').val()
324                 );
325             },
326             success: redirect_root()
327         });
328     }
329
330     function redirect_root()
331     {
332         window.location.replace('/');
333     }
334
335     function add_wf(type){
336         add_wf_internal(type, false);
337     }
338
339     function add_edit_wf(type, target){
340         add_wf_internal(type, target);
341     }
342
343     function add_wf_internal(type, itemid){
344         data = {"add": type};
345         if(itemid){
346             data['target'] = itemid;
347         }
348         $.ajax({
349             type: "POST",
350             url: "/wf/manager/",
351             data: data,
352             beforeSend: function(request) {
353                 request.setRequestHeader("X-CSRFToken",
354                 $('input[name="csrfmiddlewaretoken"]').val()
355                 );
356             },
357             success: refresh_wf_iframe()
358         });
359     }
360
361     function refresh_wf_iframe() {
362         window.location=window.location;
363     }
364 </script>
365 <div id="iframe_header" class="row view-header">
366     <div class="col-lg-12 step_header">
367         <h1 class="step_title" id="view_title"></h1>
368         <p class="description" id="view_desc"></p>
369         <p class="step_message" id="view_message"></p>
370     </div>
371     <style>
372         #view_desc{
373             margin-bottom: 15px;
374             margin-top: 5px;
375             margin-left: 30px;
376             display: inline;
377         }
378         #view_title{
379             margin-top: 5px;
380             margin-bottom: 0px;
381             display: inline;
382         }
383         #view_message{
384             margin-top: 10px;
385             margin-bottom: 5px;
386             float: right;
387         }
388         .message_invalid{
389             color: #ff4400;
390         }
391         .message_valid{
392             color: #44cc00;
393         }
394         .step_header{
395             border-bottom: 1px solid #eee;
396             border-top: 1px solid #eee;
397             left: 101px;
398             width: calc(100% - 202px);
399         }
400     </style>
401     <script>
402         function update_description(title, desc){
403             document.getElementById("view_title").innerText = title;
404             document.getElementById("view_desc").innerText = desc;
405         }
406         function update_message(message, stepstatus){
407             document.getElementById("view_message").innerText = message;
408             document.getElementById("view_message").className = "step_message";
409             document.getElementById("view_message").classList.add("message_" + stepstatus);
410         }
411         function resize_iframe(){
412             var page_rect = document.getElementById("wrapper").getBoundingClientRect();
413             var title_rect = document.getElementById("iframe_header").getBoundingClientRect();
414             var iframe_height = page_rect.bottom - title_rect.bottom;
415             console.log("setting height to " + iframe_height);
416             document.getElementById("viewport-iframe").height = iframe_height;
417
418         }
419      window.addEventListener('load', resize_iframe);
420      window.addEventListener('resize', resize_iframe);
421     </script>
422     <!-- /.col-lg-12 -->
423 </div>
424
425 <iframe src="/wf/workflow" style="position: absolute; left: 351px; right: 105px; width: calc(100% - 450px); border-style: none; border-width: 1px; border-color: #888888;" scrolling="yes" id="viewport-iframe" onload="resize_iframe();"></iframe>
426 {% endblock content %}