summaryrefslogtreecommitdiffstats
path: root/dashboard/src/templates
diff options
context:
space:
mode:
Diffstat (limited to 'dashboard/src/templates')
-rw-r--r--dashboard/src/templates/booking/booking_detail.html146
-rw-r--r--dashboard/src/templates/booking/quick_deploy.html206
-rw-r--r--dashboard/src/templates/booking/stats.html6
-rw-r--r--dashboard/src/templates/dashboard/landing.html1
-rw-r--r--dashboard/src/templates/dashboard/multiple_select_filter_widget.html74
-rw-r--r--dashboard/src/templates/dashboard/searchable_select_multiple.html7
6 files changed, 365 insertions, 75 deletions
diff --git a/dashboard/src/templates/booking/booking_detail.html b/dashboard/src/templates/booking/booking_detail.html
index cae0e25..51dd328 100644
--- a/dashboard/src/templates/booking/booking_detail.html
+++ b/dashboard/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">&times;</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/dashboard/src/templates/booking/quick_deploy.html b/dashboard/src/templates/booking/quick_deploy.html
new file mode 100644
index 0000000..3837315
--- /dev/null
+++ b/dashboard/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/dashboard/src/templates/booking/stats.html b/dashboard/src/templates/booking/stats.html
index abb153b..42eebdd 100644
--- a/dashboard/src/templates/booking/stats.html
+++ b/dashboard/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/dashboard/src/templates/dashboard/landing.html b/dashboard/src/templates/dashboard/landing.html
index 40e0146..6bbb25b 100644
--- a/dashboard/src/templates/dashboard/landing.html
+++ b/dashboard/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/dashboard/src/templates/dashboard/multiple_select_filter_widget.html b/dashboard/src/templates/dashboard/multiple_select_filter_widget.html
index 31b8f33..4e47ce0 100644
--- a/dashboard/src/templates/dashboard/multiple_select_filter_widget.html
+++ b/dashboard/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/dashboard/src/templates/dashboard/searchable_select_multiple.html b/dashboard/src/templates/dashboard/searchable_select_multiple.html
index ee460dd..c08fbe5 100644
--- a/dashboard/src/templates/dashboard/searchable_select_multiple.html
+++ b/dashboard/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);