diff options
Diffstat (limited to 'src/templates')
-rw-r--r-- | src/templates/booking/booking_detail.html | 146 | ||||
-rw-r--r-- | src/templates/booking/quick_deploy.html | 206 | ||||
-rw-r--r-- | src/templates/booking/stats.html | 6 | ||||
-rw-r--r-- | src/templates/dashboard/landing.html | 1 | ||||
-rw-r--r-- | src/templates/dashboard/multiple_select_filter_widget.html | 74 | ||||
-rw-r--r-- | src/templates/dashboard/searchable_select_multiple.html | 7 |
6 files changed, 365 insertions, 75 deletions
diff --git a/src/templates/booking/booking_detail.html b/src/templates/booking/booking_detail.html index cae0e25..51dd328 100644 --- a/src/templates/booking/booking_detail.html +++ b/src/templates/booking/booking_detail.html @@ -1,20 +1,29 @@ {% extends "base.html" %} {% load staticfiles %} +{% load bootstrap3 %} {% block extrahead %} {{block.super}} <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?lang=yaml"></script> -<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script> {% endblock %} {% block content %} + +<style> +#modal_warning { + transition: max-height 0.5s ease-out; + overflow: hidden; +} + +</style> + <div class="container-fluid"> <div class="row"> - <div class="col-lg-6"> + <div class="col-lg-4"> <div class="panel panel-default"> <div class="panel-heading clearfix"> <h4 style="display: inline;">Overview</h4> - <a data-toggle="collapse" data-target="#panel_overview" class="btn pull-right" style="line-height: 1;" >Expand</a> + <a data-toggle="collapse" data-target="#panel_overview" class="btn pull-right" style="line-height: 1;">Expand</a> </div> <div class="panel-body" id="panel_overview"> <table class="table"> @@ -50,9 +59,7 @@ </div> </div> <div class="row"> - - <div class="col-lg-6"> - + <div class="col-lg-12"> <div class="panel panel-default"> <div class="panel-heading clearfix"> <h4 style="display: inline;">Pod</h4> @@ -79,7 +86,15 @@ </tr> <tr> <td>Image:</td> - <td>{{host.config.image}}</td> + <td id="host_image_{{host.id}}"> + {{host.config.image}} + <button + style="margin-left:10px;" + class="btn btn-primary" + data-toggle="modal" + data-target="#imageModal" + onclick="set_image_dropdown('{{host.profile.name}}', {{host.id}});" + >Change/Reset</button></td> </tr> <tr> <td>RAM:</td> @@ -152,10 +167,7 @@ </table> </td> </tr> - - </table> - </td> {% endfor %} </tr> @@ -163,31 +175,15 @@ </div> </div> </div> - <div class="col-lg-6"> - - <div class="panel panel-default"> - <div class="panel-heading clearfix"> - <h4 style="display: inline;">PDF</h4> - <a data-toggle="collapse" data-target="#pdf_panel" class="btn pull-right" style="line-height: 1;" >Expand</a> - </div> - - <div class="panel-body" id="pdf_panel" style="padding: 0px;"> - <pre class="prettyprint lang-yaml" style="margin: 0px; padding: 0px; border: none;"> -{{pdf}} - </pre> - </div> - </div> - </div> </div> </div> - <div class="col-lg-6"> + <div class="col-lg-8"> <div class="panel panel-default"> <div class="panel-heading clearfix"> <h4 style="display: inline;">Deployment Progress</h4> <p style="display: inline; margin-left: 10px;"> These are the different tasks that have to be completed before your deployment is ready</p> <a data-toggle="collapse" data-target="#panel_tasks" class="btn pull-right" style="line-height: 1;" >Expand</a> </div> - <div class="panel-body" id="panel_tasks"> <table class="table"> <style> @@ -215,7 +211,6 @@ border-radius: 50%; animation: fadeInOut 1s infinite alternate; - } @keyframes fadeInOut { from { opacity: 0;} @@ -244,9 +239,7 @@ {% else %} <div class="done"></div> {% endif %} - </td> - - + </td> <td> {% if task.status < 100 %} PENDING @@ -257,7 +250,6 @@ {% endif %} </td> <td> - {% if task.message %} {% if task.type_str == "Access Task" and user_id != task.config.user.id %} Message from Lab: <pre>--secret--</pre> @@ -270,16 +262,104 @@ </td> <td> {{ task.type_str }} - </td> </tr> {% endfor %} </table> </div> </div> + <div class="row"> + <div class="col-lg-8"> + <div class="panel panel-default"> + <div class="panel-heading clearfix"> + <h4 style="display: inline;">PDF</h4> + <a data-toggle="collapse" data-target="#pdf_panel" class="btn pull-right" style="line-height: 1;" >Expand</a> + </div> + <div class="panel-body" id="pdf_panel" style="padding: 0px;"> + <pre class="prettyprint lang-yaml" style="margin: 0px; padding: 15px; border: none;"> +{{pdf}} + </pre> + </div> + </div> + </div> + </div> </div> </div> </div> +<div class="modal fade" id="imageModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> + <div class="modal-dialog" style="width: 450px;" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title" id="exampleModalLabel" style="display: inline; float: left;">Host Image</h4> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <form id="image_host_form"> + {% csrf_token %} + <select class="form-control" style="width: 80%; margin-left: 10%" id="image_select" name="image_id"> + </select> + <input id="host_id_input" type="hidden" name="host_id"> + </input> + </form> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary" onclick="document.getElementById('modal_warning').style['max-height'] = '500px';">Reset Host</button> + </div> + <div id="modal_warning" class="modal-footer" style="max-height:0px;" > + <div style="text-align:center; margin: 5px"> + <h3>Are You Sure?</h3> + <p>This will wipe the disk and reimage the host</p> + <button class="btn" onclick="document.getElementById('modal_warning').style['max-height'] = '0px';">Nevermind</button> + <button class="btn btn-danger" data-dismiss="modal" onclick="submit_image_form();">I'm Sure</button> + </div> + </div> + </div> +</div> + +<script> + var image_mapping = {{image_mapping|safe}}; + var current_host_id = 0; + function set_image_dropdown(profile_name, host_id) { + document.getElementById("host_id_input").value = host_id; + current_host_id = host_id; + var dropdown = document.getElementById("image_select"); + var length = dropdown.length; + //clear dropdown + for(i=length-1; i>=0; i--){ + dropdown.options.remove(i); + } + var images = image_mapping[profile_name]; + var image_length = images.length; + for(i=0; i<image_length; i++){ + var opt = document.createElement("OPTION"); + opt.value = images[i].value; + opt.appendChild(document.createTextNode(images[i].name)); + dropdown.options.add(opt); + } + + document.getElementById("modal_warning").style['max-height'] = '0px'; + } + + function submit_image_form() { + var ajaxForm = $("#image_host_form"); + var formData = ajaxForm.serialize(); + req = new XMLHttpRequest(); + req.open("POST", "/booking/modify/{{booking.id}}/image/", true); + req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + req.onerror = function() { alert("problem submitting form"); } + req.onreadystatechange = function() { + if(req.readyState === 4) { + node = document.getElementById("host_image_" + current_host_id); + text = document.createTextNode(req.responseText); + node.replaceChild(text, node.firstChild); + } + } + req.send(formData); + } +</script> {% endblock content %} diff --git a/src/templates/booking/quick_deploy.html b/src/templates/booking/quick_deploy.html new file mode 100644 index 0000000..3837315 --- /dev/null +++ b/src/templates/booking/quick_deploy.html @@ -0,0 +1,206 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% load bootstrap3 %} +{% block content %} +<style> + .grid_container { + display: grid; + grid-template-columns: repeat(12, 1fr); + padding: 30px; + } + .grid_element { + border-radius: 3px; + box-shadow: 0px 0px 7px 0px rgba(0,0,0,0.75); + margin: 10px; + padding: 7px; + } + .grid_element_wide { + grid-column-start: span 12; + } + .grid_element_half { + grid-column-start: span 6; + } + .grid_element_1third { + grid-column-start: span 4; + } + .grid_element_2third { + grid-column-start: span 8; + } +</style> +{% bootstrap_form_errors form type='non_fields' %} +<form id="quick_booking_form" action="/booking/quick/" method="POST" class="form"> +{% csrf_token %} +<div class="grid_container"> +<div class="grid_element host_select_pane grid_element_wide"> +<p>Please select a host type you wish to book. Only available types are shown.</p> +{% bootstrap_field form.filter_field %} +</div> +<div class="grid_element booking_info_pane grid_element_1third"> + {% bootstrap_field form.purpose %} + {% bootstrap_field form.project %} + {% bootstrap_field form.length %} + <p style="display:inline;">Days: </p><output id="daysout" style="display:inline;">0</output> + <script> + document.getElementById("id_length").setAttribute("oninput", "daysout.value=this.value"); + document.getElementById("daysout").value = document.getElementById("id_length").value; + </script> +</div> +<div class="grid_element collaborator_pane grid_element_1third"> + <label>Collaborators</label> + {{ form.users }} +</div> +<div class="grid_element configuration_pane grid_element_1third"> + {% bootstrap_field form.hostname %} + {% bootstrap_field form.image %} + {% bootstrap_field form.installer %} + {% bootstrap_field form.scenario %} +</div> +</div> +<script type="text/javascript"> + var normalize = function(data) + { + //converts the top level keys in data to map to lists + var normalized = {} + for( var key in data ){ + normalized[key] = []; + for( var subkey in data[key] ){ + normalized[key].push(data[key][subkey]); + } + } + return normalized; + } + var update_page_contents = function(response) + { + document.open(); + document.write(response); + document.close(); + } + + //form hamdler code + submit_form = function() + { + //altered from initial prototype: form submits automatically, + //but needs formatting for multiple select field + var data = normalize(result); + data = JSON.stringify(data); + document.getElementById("filter_field").value = data; + } + + var sup_image_dict = {{ image_filter|safe }}; + var sup_installer_dict = {{ installer_filter|safe }}; + var sup_scenario_dict = {{ scenario_filter|safe }}; + + function imageHider() { + var data = normalize(result); + var drop = document.getElementById("id_image"); + for( var i=0; i < drop.length; i++ ) + { + if ( drop.options[i].text == '---------' ) + { + drop.selectedIndex = i; + } + } + + $('#id_image').children().hide(); + + var empty_map = {} + + for ( var i=0; i < drop.childNodes.length; i++ ) + { + var image_object = sup_image_dict[drop.childNodes[i].value]; + if( image_object ) //weed out empty option + { + var lab_pk = "" + for( var j in data["labs"][0] ) + { + if( j in {} ) { continue; } + else { lab_pk = j; break; } + } + var host_pk = ""; + for( var j in data["hosts"][0] ) + { + if( j in {} ) { continue; } + else { host_pk = j; break; } + } + if( image_object.host_profile == host_pk && image_object.lab == lab_pk ) + { + drop.childNodes[i].style.display = "inherit"; + } + } + } + } + + $('#id_image').children().hide(); + $('#id_installer').children().hide(); + $('#id_scenario').children().hide(); + + + Array.from(document.getElementsByClassName("grid-item-select-btn")).forEach(function(element) { + element.addEventListener('click', imageHider); + }); + + function installerHider() { + dropFilter("id_installer", sup_installer_dict, "id_image"); + scenarioHider(); + } + document.getElementById('id_image').addEventListener('change', installerHider); + + function scenarioHider() { + dropFilter("id_scenario", sup_scenario_dict, "id_installer"); + } + document.getElementById('id_installer').addEventListener('change', scenarioHider); + + function dropFilter(target, target_filter, master) { + ob = document.getElementById(target); + + for(var i=0; i<ob.options.length; i++) { + if ( ob.options[i].text == '---------' ) { + ob.selectedIndex = i; + } + } + + targ_id = "#" + target; + $(targ_id).children().hide(); + var drop = document.getElementById(master); + var opts = target_filter[drop.options[drop.selectedIndex].value]; + if (!opts) { + opts = {}; + } + var emptyMap = {} + + var map = Object.create(null); + for (var i = 0; i < opts.length; i++) { + var j = opts[i]; + map[j] = true; + } + + for (var i = 0; i < document.getElementById(target).childNodes.length; i++) { + if (document.getElementById(target).childNodes[i].value in opts && !(document.getElementById(target).childNodes[i].value in emptyMap) ) { + document.getElementById(target).childNodes[i].style.display = "inherit"; + } + } + } +</script> + <button onclick="submit_form();" class="btn btn-success">Confirm</button> +</form> +<script> + //context vars + var prefill_host_selection = "{{host_select_field_prefill_data|default:""|safe}}"; + var prefill_purpose = "{{prefill_purpose|default:""|safe}}"; + var prefill_project = "{{prefill_project|default:""|safe}}"; + var prefill_hostname = "{{prefill_hostname|default:""|safe}}"; + + //to handle prefill + function prefill_host_select_field(data) + { + // + if(data) + { + make_selection(data); + } + } + + //call init functions + prefill_host_select_field(prefill_host_selection); +</script> +{% endblock %} diff --git a/src/templates/booking/stats.html b/src/templates/booking/stats.html index abb153b..42eebdd 100644 --- a/src/templates/booking/stats.html +++ b/src/templates/booking/stats.html @@ -42,8 +42,10 @@ function getData(){ {% block content %} <p>Number of days to plot: </p> - <input id="number_days" type="number" min="1" step="1"/> - <button onclick="getData();">Submit</button> + <div class="form-group"> + <input id="number_days" type="number" class="form-control" min="1" step="1" style="display:inline;width:200px"/> + <button class="btn btn-primary" onclick="getData();" style="display:inline;">Submit</button> + </div> <div id="all_graph_container"> <div id="booking_graph_wrapper"> <div id="booking_graph_container"/> diff --git a/src/templates/dashboard/landing.html b/src/templates/dashboard/landing.html index 40e0146..6bbb25b 100644 --- a/src/templates/dashboard/landing.html +++ b/src/templates/dashboard/landing.html @@ -39,6 +39,7 @@ </style> {% if not request.user.is_anonymous %} <div class='wf_create_div'> +<a class="wf_create btn btn-primary" style="color: #FFF;" href="/booking/quick/">Create a Quick Booking</a> <button class="wf_create btn btn-primary" onclick="cwf(0)">Create a Booking</button> <button class="wf_create btn btn-primary" onclick="cwf(1)">Create a Pod</button> <button class="wf_create btn btn-primary" onclick="cwf(2)">Configure a Pod</button> diff --git a/src/templates/dashboard/multiple_select_filter_widget.html b/src/templates/dashboard/multiple_select_filter_widget.html index 31b8f33..4e47ce0 100644 --- a/src/templates/dashboard/multiple_select_filter_widget.html +++ b/src/templates/dashboard/multiple_select_filter_widget.html @@ -97,7 +97,7 @@ <script> var initialized = false; var mapping = {{ mapping|safe }}; -var items = {{ items|safe }}; +var filter_items = {{ filter_items|safe }}; var result = {}; var selection = {{selection_data|default_if_none:"null"|safe}}; var dropdown_count = 0; @@ -108,31 +108,32 @@ make_selection({{selection_data|safe}}); function make_selection( selection_data ){ if(!initialized) { - init(); + filter_field_init(); } for(var k in selection_data) { selected_items = selection_data[k]; - for( var item in selected_items ){ - var node = items[item]; + for( var selected_item in selected_items ){ + var node = filter_items[selected_item]; if(!node['multiple']){ - var input_value = selected_items[item]; + var input_value = selected_items[selected_item]; if( input_value != 'false' ) { select(node); markAndSweep(node); } - var div = document.getElementById(item) + var div = document.getElementById(selected_item) + var inputs = div.parentNode.getElementsByTagName("input") var input = div.parentNode.getElementsByTagName("input")[0] input.value = input_value; - updateResult(item); + updateResult(selected_item); } else { - make_multiple_selection(selected_items, item); + make_multiple_selection(selected_items, selected_item); } } } } function make_multiple_selection(data, item_class){ - var node = items[item_class]; + var node = filter_items[item_class]; select(node); markAndSweep(node); prepop_data = data[item_class]; @@ -143,8 +144,8 @@ function make_multiple_selection(data, item_class){ } function markAndSweep(root){ - for(var nodeId in items) { - node = items[nodeId]; + for(var nodeId in filter_items) { + node = filter_items[nodeId]; node['marked'] = true; //mark all nodes //clears grey background of everything } @@ -164,17 +165,17 @@ function markAndSweep(root){ var neighbors = mapping[mappingId]; for(var neighId in neighbors) { neighId = neighbors[neighId]; - var neighbor = items[neighId]; + var neighbor = filter_items[neighId]; toCheck.push(neighbor); } } } //now remove all nodes still marked - for(var nodeId in items){ - node = items[nodeId]; + for(var nodeId in filter_items){ + node = filter_items[nodeId]; if(node['marked']){ - disable(node); + disable_node(node); } } } @@ -186,8 +187,8 @@ function process(node) { else { var selected = [] //remember the currently selected, then reset everything and reselect one at a time - for(var nodeId in items) { - node = items[nodeId]; + for(var nodeId in filter_items) { + node = filter_items[nodeId]; if(node['selected']) { selected.push(node); } @@ -205,9 +206,9 @@ function process(node) { function select(node) { elem = document.getElementById(node['id']); node['selected'] = true; - elem.classList.remove('cleared_node') - elem.classList.remove('disabled_node') - elem.classList.add('selected_node') + elem.classList.remove('cleared_node'); + elem.classList.remove('disabled_node'); + elem.classList.add('selected_node'); var input = elem.parentNode.getElementsByTagName("input")[0]; input.disabled = false; input.value = true; @@ -218,27 +219,27 @@ function clear(node) { node['selected'] = false; node['selectable'] = true; elem.classList.add('cleared_node') - elem.classList.remove('disabled_node') - elem.classList.remove('selected_node') + elem.classList.remove('disabled_node'); + elem.classList.remove('selected_node'); elem.parentNode.getElementsByTagName("input")[0].disabled = true; } -function disable(node) { +function disable_node(node) { elem = document.getElementById(node['id']); node['selected'] = false; node['selectable'] = false; - elem.classList.remove('cleared_node') - elem.classList.add('disabled_node') - elem.classList.remove('selected_node') + elem.classList.remove('cleared_node'); + elem.classList.add('disabled_node'); + elem.classList.remove('selected_node'); elem.parentNode.getElementsByTagName("input")[0].disabled = true; } function processClick(id, multiple){ if(!initialized){ - init(); + filter_field_init(); } var element = document.getElementById(id); - var node = items[id]; + var node = filter_items[id]; if(!node['selectable']){ return; } @@ -259,11 +260,11 @@ function processClick(id, multiple){ function processClickMultipleObject(node){ select(node); - add_item(node); + add_node(node); process(node); } -function add_item(node){ +function add_node(node){ return add_item_prepopulate(node, {}); } @@ -364,18 +365,19 @@ function remove_dropdown(id){ } } if(deselect_class){ - clear(items[div_class]); + clear(filter_items[div_class]); } } function updateResult(nodeId){ if(!initialized){ - init(); + filter_field_init(); } - if(!items[nodeId]['multiple']){ + if(!filter_items[nodeId]['multiple']){ var node = document.getElementById(nodeId); var value = {} value[nodeId] = node.parentNode.getElementsByTagName("input")[0].value; + result[node.parentNode.parentNode.id] = {}; result[node.parentNode.parentNode.id][nodeId] = value; } } @@ -391,10 +393,10 @@ function updateObjectResult(parentElem){ result[node_type][parentElem.id] = input; } -function init() { - for(nodeId in items) { +function filter_field_init() { + for(nodeId in filter_items) { element = document.getElementById(nodeId); - node = items[nodeId]; + node = filter_items[nodeId]; result[element.parentNode.parentNode.id] = {} } initialized = true; diff --git a/src/templates/dashboard/searchable_select_multiple.html b/src/templates/dashboard/searchable_select_multiple.html index ee460dd..c08fbe5 100644 --- a/src/templates/dashboard/searchable_select_multiple.html +++ b/src/templates/dashboard/searchable_select_multiple.html @@ -116,6 +116,7 @@ string_trie.isComplete = false; var added_items = []; + var initial_log = {{ initial|safe }}; var added_template = {{ added_list|default:"{}" }}; @@ -128,7 +129,7 @@ entry_p.innerText = default_entry; } - init(); + search_field_init(); if( show_from_noentry ) { @@ -149,7 +150,7 @@ } } - function init() { + function search_field_init() { build_all_tries(items); var initial = {{ initial|safe }}; @@ -342,14 +343,12 @@ added_items.push(item); } } - update_selected_list(); document.getElementById("user_field").focus(); } function remove_item(item_ref) { - item = Object.values(items)[item_ref]; var index = added_items.indexOf(item); added_items.splice(index, 1); |