aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dashboard/views.py39
-rw-r--r--src/static/js/dashboard.js156
-rw-r--r--src/templates/base.html35
-rw-r--r--src/templates/dashboard/genericselect.html21
-rw-r--r--src/templates/dashboard/landing.html46
-rw-r--r--src/templates/dashboard/multiple_select_filter_widget.html3
-rw-r--r--src/templates/dashboard/searchable_select_multiple.html2
-rw-r--r--src/templates/resource/steps/pod_definition.html3
-rw-r--r--src/templates/workflow/confirm.html97
-rw-r--r--src/templates/workflow/viewport-base.html268
-rw-r--r--src/templates/workflow/viewport-element.html36
-rw-r--r--src/workflow/models.py6
-rw-r--r--src/workflow/urls.py6
-rw-r--r--src/workflow/views.py59
-rw-r--r--src/workflow/workflow_manager.py36
15 files changed, 243 insertions, 570 deletions
diff --git a/src/dashboard/views.py b/src/dashboard/views.py
index aaad7ab..9416cb4 100644
--- a/src/dashboard/views.py
+++ b/src/dashboard/views.py
@@ -63,36 +63,15 @@ def host_profile_detail_view(request):
def landing_view(request):
- manager = None
- manager_detected = False
- if 'manager_session' in request.session:
-
- try:
- manager = ManagerTracker.managers[request.session['manager_session']]
-
- except KeyError:
- pass
-
- if manager is not None:
- # no manager detected, don't display continue button
- manager_detected = True
-
- if request.method == 'GET':
- return render(request, 'dashboard/landing.html', {'manager': manager_detected, 'title': "Welcome to the Lab as a Service Dashboard"})
-
- if request.method == 'POST':
- try:
- create = request.POST['create']
-
- if manager is not None:
- del manager
-
- mgr_uuid = create_session(create, request=request,)
- request.session['manager_session'] = mgr_uuid
- return HttpResponseRedirect('/wf/')
-
- except KeyError:
- pass
+ manager = ManagerTracker.managers.get(request.session.get('manager_session'))
+ return render(
+ request,
+ 'dashboard/landing.html',
+ {
+ 'manager': manager is not None,
+ 'title': "Welcome to the Lab as a Service Dashboard"
+ }
+ )
class LandingView(TemplateView):
diff --git a/src/static/js/dashboard.js b/src/static/js/dashboard.js
index f1eff77..7f8a427 100644
--- a/src/static/js/dashboard.js
+++ b/src/static/js/dashboard.js
@@ -4,14 +4,107 @@
form_submission_callbacks = []; //all runnables will be executed before form submission
-
///////////////////
// Global Functions
///////////////////
+function update_page(response) {
+ if( response.redirect )
+ {
+ window.location.replace(response.redirect);
+ return;
+ }
+ draw_breadcrumbs(response.meta);
+ update_exit_button(response.meta);
+ update_side_buttons(response.meta);
+ $("#formContainer").html(response.content);
+}
+
+function update_side_buttons(meta) {
+ const step = meta.active;
+ const page_count = meta.steps.length;
+
+ const back_button = document.getElementById("gob");
+ if (step == 0) {
+ back_button.classList.add("disabled");
+ back_button.disabled = true;
+ } else {
+ back_button.classList.remove("disabled");
+ back_button.disabled = false;
+ }
+
+ const forward_btn = document.getElementById("gof");
+ if (step == page_count - 1) {
+ forward_btn.classList.add("disabled");
+ forward_btn.disabled = true;
+ } else {
+ forward_btn.classList.remove("disabled");
+ forward_btn.disabled = false;
+ }
+}
+
+function update_exit_button(meta) {
+ if (meta.workflow_count == 1) {
+ document.getElementById("cancel_btn").innerText = "Exit Workflow";
+ } else {
+ document.getElementById("cancel_btn").innerText = "Return to Parent";
+ }
+}
+
+function draw_breadcrumbs(meta) {
+ $("#topPagination").children().not(".page-control").remove();
+
+ for (const i in meta.steps) {
+ const step_btn = create_step(meta.steps[i], i == meta["active"]);
+ $("#topPagination li:last-child").before(step_btn);
+ }
+}
+
+function create_step(step_json, active) {
+ const step_dom = document.createElement("li");
+ // First create the dom object depending on active or not
+ step_dom.className = "topcrumb";
+ if (active) {
+ step_dom.classList.add("active");
+ }
+ $(step_dom).html(`<span class="d-flex align-items-center justify-content-center text-capitalize w-100">${step_json['title']}</span>`)
+
+ const code = step_json.valid;
+
+ let stat = "";
+ let msg = "";
+ if (code < 100) {
+ $(step_dom).children().first().append("<i class='ml-2 far fa-square'></i>")
+ stat = "";
+ msg = "";
+ } else if (code < 200) {
+ $(step_dom).children().first().append("<i class='ml-2 fas fa-minus-square'></i>")
+ stat = "invalid";
+ msg = step_json.message;
+ } else if (code < 300) {
+ $(step_dom).children().first().append("<i class='ml-2 far fa-check-square'></i>")
+ stat = "valid";
+ msg = step_json.message;
+ }
+
+ if (step_json.enabled == false) {
+ step_dom.classList.add("disabled");
+ }
+ if (active) {
+ update_message(msg, stat);
+ }
+
+ return step_dom;
+}
+
+function update_description(title, desc) {
+ document.getElementById("view_title").innerText = title;
+ document.getElementById("view_desc").innerText = desc;
+}
-function updatePage(data){
- updateBreadcrumbs(data['meta']);
- $("formContainer").html(data['content']);
+function update_message(message, stepstatus) {
+ document.getElementById("view_message").innerText = message;
+ document.getElementById("view_message").className = "step_message";
+ document.getElementById("view_message").classList.add("message_" + stepstatus);
}
function submitStepForm(next_step = "current"){
@@ -22,11 +115,10 @@ function submitStepForm(next_step = "current"){
"step_form": step_form_data,
"csrfmiddlewaretoken": $("[name=csrfmiddlewaretoken]").val()
});
- console.log(form_data);
$.post(
'/workflow/manager/',
form_data,
- (data) => updatePage(data),
+ (data) => update_page(data),
'json'
).fail(() => alert("failure"));
}
@@ -37,6 +129,58 @@ function run_form_callbacks(){
form_submission_callbacks = [];
}
+function create_workflow(type) {
+ $.ajax({
+ type: "POST",
+ url: "/workflow/create/",
+ data: {
+ "workflow_type": type
+ },
+ headers: {
+ "X-CSRFToken": $('input[name="csrfmiddlewaretoken"]').val()
+ }
+ }).done(function (data, textStatus, jqXHR) {
+ window.location = "/workflow/";
+ }).fail(function (jqxHR, textstatus) {
+ alert("Something went wrong...");
+ });
+}
+
+function add_workflow(type) {
+ data = $.ajax({
+ type: "POST",
+ url: "/workflow/add/",
+ data: {
+ "workflow_type": type
+ },
+ headers: {
+ "X-CSRFToken": $('input[name="csrfmiddlewaretoken"]').val()
+ }
+ }).done(function (data, textStatus, jqXHR) {
+ update_page(data);
+ }).fail(function (jqxHR, textstatus) {
+ alert("Something went wrong...");
+ });
+}
+
+function pop_workflow() {
+ data = $.ajax({
+ type: "POST",
+ url: "/workflow/pop/",
+ headers: {
+ "X-CSRFToken": $('input[name="csrfmiddlewaretoken"]').val()
+ }
+ }).done(function (data, textStatus, jqXHR) {
+ update_page(data);
+ }).fail(function (jqxHR, textstatus) {
+ alert("Something went wrong...");
+ });
+}
+
+function continue_workflow() {
+ window.location.replace("/workflow/");
+}
+
///////////////////
//Class Definitions
///////////////////
diff --git a/src/templates/base.html b/src/templates/base.html
index 891e0fc..f59740d 100644
--- a/src/templates/base.html
+++ b/src/templates/base.html
@@ -6,30 +6,7 @@
<!-- Custom CSS -->
<link href="{% static "css/base.css" %}" rel="stylesheet">
-<script type="text/javascript">
- function cwf(type) {
- $.ajax({
- type: "POST",
- url: "/",
- data: {
- "create": type
- },
- beforeSend: function (request) {
- request.setRequestHeader("X-CSRFToken",
- $('input[name="csrfmiddlewaretoken"]').val()
- );
- }
- }).done(function (data) {
- window.location.replace("/wf/");
- }).fail(function (jqxHR, textstatus) {
- alert("Something went wrong...");
- });
- }
-
- function continue_wf() {
- window.location.replace("/wf/");
- }
-</script>
+<script src="/static/js/dashboard.js"></script>
{% endblock %}
{% block basecontent %}
@@ -107,19 +84,19 @@
<a href="/booking/quick/" class="list-group-item list-group-item-action list-group-item-secondary">
Express Booking
</a>
- <a href="#" onclick="cwf(0)" class="list-group-item list-group-item-action list-group-item-secondary">
+ <a href="#" onclick="create_workflow(0)" class="list-group-item list-group-item-action list-group-item-secondary">
Book a Pod
</a>
- <a href="#" onclick="cwf(1)" class="list-group-item list-group-item-action list-group-item-secondary">
+ <a href="#" onclick="create_workflow(1)" class="list-group-item list-group-item-action list-group-item-secondary">
Design a Pod
</a>
- <a href="#" onclick="cwf(2)" class="list-group-item list-group-item-action list-group-item-secondary">
+ <a href="#" onclick="create_workflow(2)" class="list-group-item list-group-item-action list-group-item-secondary">
Configure a Pod
</a>
- <a href="#" onclick="cwf(3)" class="list-group-item list-group-item-action list-group-item-secondary">
+ <a href="#" onclick="create_workflow(3)" class="list-group-item list-group-item-action list-group-item-secondary">
Create a Snapshot
</a>
- <a href="#" onclick="cwf(4)" class="list-group-item list-group-item-action list-group-item-secondary">
+ <a href="#" onclick="create_workflow(4)" class="list-group-item list-group-item-action list-group-item-secondary">
Configure OPNFV
</a>
</div>
diff --git a/src/templates/dashboard/genericselect.html b/src/templates/dashboard/genericselect.html
index f54cd90..863d33f 100644
--- a/src/templates/dashboard/genericselect.html
+++ b/src/templates/dashboard/genericselect.html
@@ -1,27 +1,22 @@
{% extends "workflow/viewport-element.html" %}
-{% load staticfiles %}
{% load bootstrap4 %}
{% block content %}
-<div id="{{select_type}}_form_div" class="h-100 border d-flex flex-column p-4">
+<div id="select_form_div" class="h-100 border d-flex flex-column p-4">
<h3 id="create_section">Create a Resource
<button class="btn btn-primary {% if disabled %} disabled {% endif %}"
- {% if not disabled %}onclick="parent.add_wf({{addable_type_num}})"
+ {% if not disabled %}onclick="add_workflow({{addable_type_num}})"
{% endif %}>Here
</button>
</h3>
<div class="border-top"></div>
<h3 id="select_header_section">Or select from the list below:</h3>
<div id="select_section" class="d-flex flex-column">
- <form id="{{select_type}}_select_form" method="post" action=""
- class="form d-flex flex-column" id="{{select_type}}selectorform">
+ <form id="step_form" method="post" action="" class="form d-flex flex-column">
{% csrf_token %}
{{ form|default:"<p>no form loaded</p>" }}
- {% buttons %}
-
- {% endbuttons %}
</form>
</div>
</div>
@@ -33,13 +28,3 @@
</script>
{% endblock content %}
-{% block onleave %}
-var form = $("#{{select_type}}_select_form");
-var formData = form.serialize();
-var req = new XMLHttpRequest();
-req.open("POST", "/wf/workflow/", false);
-req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
-req.onerror = function() { alert("problem with form submission"); }
-req.send(formData);
-{% endblock %}
-
diff --git a/src/templates/dashboard/landing.html b/src/templates/dashboard/landing.html
index d4776cc..72f9e6e 100644
--- a/src/templates/dashboard/landing.html
+++ b/src/templates/dashboard/landing.html
@@ -47,13 +47,13 @@
</p>
<div class="row">
<div class="col-12 col-xl-4">
- <button class="btn btn-primary w-100" onclick="cwf(0)">Book a Pod</button>
+ <button class="btn btn-primary w-100" onclick="create_workflow(0)">Book a Pod</button>
</div>
<div class="col-12 col-xl-4">
- <button class="btn btn-primary w-100" onclick="cwf(1)">Design a Pod</button>
+ <button class="btn btn-primary w-100" onclick="create_workflow(1)">Design a Pod</button>
</div>
<div class="col-12 col-xl-4">
- <button class="btn btn-primary w-100" onclick="cwf(2)">Configure a Pod</button>
+ <button class="btn btn-primary w-100" onclick="create_workflow(2)">Configure a Pod</button>
</div>
</div>
{% endif %}
@@ -65,7 +65,7 @@
<p>If you're a returning user, some of the following options may be of interest:</p>
<div class="row">
<div class="col-12 col-xl-4">
- <button class="btn btn-primary w-100" onclick="cwf(3)">Snapshot a Host</button>
+ <button class="btn btn-primary w-100" onclick="create_workflow(3)">Snapshot a Host</button>
</div>
<div class="col-12 col-xl-4">
<a class="btn btn-primary w-100" href="{% url 'account:my-bookings' %}">
@@ -74,7 +74,7 @@
</div>
{% if manager == True %}
<div class="col-12 col-xl-4">
- <button class="btn btn-primary w-100" onclick="continue_wf()">
+ <button class="btn btn-primary w-100" onclick="continue_workflow()">
Resume Workflow
</button>
</div>
@@ -85,44 +85,10 @@
</div>
</div>
-<script type="text/javascript">
- function cwf(type) {
- $.ajax({
- type: "POST",
- url: "/",
- data: {
- "create": type
- },
- beforeSend: function (request) {
- request.setRequestHeader("X-CSRFToken",
- $('input[name="csrfmiddlewaretoken"]').val()
- );
- }
-
- }).done(function (data) {
- window.location.replace("/wf/");
- }).fail(function (jqxHR, textstatus) {
- alert("Something went wrong...");
- });
- }
-
- function continue_wf() {
- window.location.replace("/wf/");
- }
-</script>
-
<div class="hidden_form d-none" id="form_div">
<form method="post" action="" class="form" id="wf_selection_form">
{% csrf_token %}
-
- <input type="hidden" id="landing_action">
-
- <button type="submit" class="btn btn btn-success">
- Confirm Edit
- </button>
</form>
</div>
-{% block vport_comm %}
-{% endblock %}
-{% endblock content %} \ No newline at end of file
+{% endblock content %}
diff --git a/src/templates/dashboard/multiple_select_filter_widget.html b/src/templates/dashboard/multiple_select_filter_widget.html
index 4a65bd9..e97a41b 100644
--- a/src/templates/dashboard/multiple_select_filter_widget.html
+++ b/src/templates/dashboard/multiple_select_filter_widget.html
@@ -1,6 +1,3 @@
-<script src="/static/js/dashboard.js">
-</script>
-
<input name="filter_field" id="filter_field" type="hidden"/>
<div id="grid_wrapper" class="container-fluid p-4">
<div class="row">
diff --git a/src/templates/dashboard/searchable_select_multiple.html b/src/templates/dashboard/searchable_select_multiple.html
index 8299a55..44689da 100644
--- a/src/templates/dashboard/searchable_select_multiple.html
+++ b/src/templates/dashboard/searchable_select_multiple.html
@@ -1,5 +1,3 @@
-<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
-<script src="/static/js/dashboard.js"></script>
<div id="search_select_outer" class="d-flex flex-column">
{% if incompatible == "true" %}
<div class="alert alert-danger" role="alert">
diff --git a/src/templates/resource/steps/pod_definition.html b/src/templates/resource/steps/pod_definition.html
index 4392dbd..d0a28ed 100644
--- a/src/templates/resource/steps/pod_definition.html
+++ b/src/templates/resource/steps/pod_definition.html
@@ -7,8 +7,6 @@
<script>
var mxLoadStylesheets = false;
</script>
-<script type="text/javascript" src="/static/js/mxClient.min.js" ></script>
-<script type="text/javascript" src="/static/js/dashboard.js" ></script>
{% endblock extrahead %}
<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
@@ -41,7 +39,6 @@
{% csrf_token %}
<input type="hidden" id="hidden_xml_input" name="xml" />
</form>
- <script type="text/javascript" src="/static/js/mxClient.min.js" ></script>
<script>
//gather context data
let debug = false;
diff --git a/src/templates/workflow/confirm.html b/src/templates/workflow/confirm.html
index b7e6c46..2f99a41 100644
--- a/src/templates/workflow/confirm.html
+++ b/src/templates/workflow/confirm.html
@@ -8,11 +8,6 @@
<div class="text-center">
<h3>Confirm Session</h3>
</div>
-<div id="vlan_warning"></div>
-<form id="vlan_form" action="/wf/workflow/" method="post">
- {% csrf_token %}
- <input id="vlan_input" name="vlan_input" type="hidden"/>
-</form>
<div class="container">
<div class="row justify-content-center">
<div class="col-auto">
@@ -22,7 +17,7 @@
<div class="row">
<div class="col">
<div id="form_div" class="text-center p-4">
- <form id="confirmation_form" action="/wf/workflow/" method="post">
+ <form id="step_form" action="/workflow/manager/" method="post">
{% csrf_token %}
<div class="d-none">
{{form|default:"<p> No Form Loaded</p>"}}
@@ -33,7 +28,7 @@
<button id="cancel_button" class="btn btn-danger" onclick="formcancel()">Cancel</button>
</div>
<div class="d-none">
- <form id="manager_delete_form" action="/wf/workflow/finish/" method="post">
+ <form id="manager_delete_form" action="/workflow/finish/" method="post">
{% csrf_token %}
</form>
</div>
@@ -44,104 +39,24 @@
<script>
var select = document.getElementById("id_confirm");
- function processResponseText(json)
- {
- var dict = JSON.parse(json);
-
- if( !dict["redir_url"] ) {
- window.top.refresh_iframe();
- } else {
- top.window.location.href = dict["redir_url"];
- }
- }
-
- function delete_manager()
- {
- var form = $("#manager_delete_form");
- var formData = form.serialize();
- var req = new XMLHttpRequest();
- req.open("POST", "/wf/workflow/finish/", false);
- req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- req.onerror = function() { alert("problem with cleaning up session"); }
- req.onreadystatechange = function() { if(req.readyState === 4 ) {
- processResponseText(req.responseText);
- }}
- req.send(formData);
- }
-
- function submitForm()
- {
- var form = $("#confirmation_form");
- var formData = form.serialize();
- var req = new XMLHttpRequest();
- req.open("POST", "/wf/workflow/", false);
- req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- req.onerror = function() { alert("problem submitting confirmation"); }
- req.onreadystatechange = function() { if(req.readyState === 4 ) { delete_manager(); } }
- req.send(formData);
- }
-
-
function formconfirm()
{
select.value = "True";
- submitForm();
+ submitStepForm();
}
function formcancel()
{
select.value = "False";
- submitForm();
+ submitStepForm();
}
- var confirmed = {{bypassed|default:"false"}};
+ var confirmed = {{confirm_succeeded|default:"false"}};
if( confirmed )
{
- delete_manager();
- }
-</script>
-<script>
- function fixVlans() {
- document.getElementById("vlan_input").value = "True";
- var form = $("#vlan_form");
- var formData = form.serialize();
- var req = new XMLHttpRequest();
- req.open("POST", "/wf/workflow/", false);
- req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- req.onerror = function() { alert("problem submitting form"); }
- req.onreadystatechange = function() { //replaces current page with response
- if(req.readyState === 4 ) {
- var d = document.getElementById("vlan_warning").innerHTML = "";
- document.getElementById("confirm_button").disabled = false;
- document.getElementById("cancel_button").disabled = false;
- }
- }
- req.send(formData);
- }
- var problem = {{vlan_warning|default:'false'}};
- if(problem){
- var d = document.getElementById("vlan_warning");
- var h3 = document.createElement("h3");
- h3.innerHTML = "WARNING: Vlans not available";
- var h4 = document.createElement("h4");
- h4.innerHTML = "The vlans you selected are not currently available. Would you like to automatically change them?";
- var button1 = document.createElement("button");
- button1.innerHTML = "Correct Vlans For Me";
- button1.onclick = function() { fixVlans(); }
-
- var button2 = document.createElement("button");
- button2.innerHTML = "Cancel. I will change my vlans";
- button2.onclick = function() { formcancel(); }
- d.appendChild(h3);
- d.appendChild(h4);
- d.appendChild(button1);
- d.appendChild(button2);
- document.getElementById("confirm_button").disabled = true;
- document.getElementById("cancel_button").disabled = true;
+ pop_workflow();
}
</script>
{% block element_messages %}
{% endblock element_messages %}
{% endblock content %}
-{% block onleave %}
-{% endblock %}
diff --git a/src/templates/workflow/viewport-base.html b/src/templates/workflow/viewport-base.html
index 103a095..02c5597 100644
--- a/src/templates/workflow/viewport-base.html
+++ b/src/templates/workflow/viewport-base.html
@@ -15,29 +15,9 @@
<i class="fas fa-backward"></i> Back
</a>
</li>
- <li class="page-item flex-grow-1 active">
- <a class="page-link disabled" href="#">
- Select <i class="far fa-check-square"></i>
- </a>
- </li>
- <li class="page-item flex-grow-1">
- <a class="page-link disabled" href="#">
- Configure <i class="far fa-square"></i>
- </a>
- </li>
- <li class="page-item flex-grow-1">
- <a class="page-link disabled" href="#">
- Information <i class="far fa-square"></i>
- </a>
- </li>
- <li class="page-item flex-grow-1">
- <a class="page-link disabled" href="#">
- OPNFV <i class="far fa-square"></i>
- </a>
- </li>
<li class="page-item flex-grow-1">
<a class="page-link disabled" href="#">
- Confirm <i class="far fa-square"></i>
+ <i class="far"></i>
</a>
</li>
<li class="page-item flex-shrink-1 page-control">
@@ -58,22 +38,10 @@
<span class="description text-muted" id="view_desc"></span>
<p id="view_message"></p>
</div>
- <script>
- function update_description(title, desc) {
- document.getElementById("view_title").innerText = title;
- document.getElementById("view_desc").innerText = desc;
- }
-
- function update_message(message, stepstatus) {
- document.getElementById("view_message").innerText = message;
- document.getElementById("view_message").className = "step_message";
- document.getElementById("view_message").classList.add("message_" + stepstatus);
- }
- </script>
</div>
</div>
<div class="col-auto align-self-center d-flex">
- <button id="cancel_btn" class="btn btn-danger ml-auto" onclick="cancel_wf()">Cancel</button>
+ <button id="cancel_btn" class="btn btn-danger ml-auto" onclick="pop_workflow()">Cancel</button>
</div>
</div>
<div class="row d-flex flex-column flex-grow-1">
@@ -86,240 +54,24 @@
</div>
</div>
{% csrf_token %}
-<script src="{% static "js/dashboard.js" %}"></script>
<script type="text/javascript">
- update_context();
- var step = 0;
- var page_count = 0;
-
function submit_and_go(to) {
submitStepForm(to);
}
- function request_leave(to) {
- $.ajax({
- type: "GET",
- url: "/wf/manager/",
- beforeSend: function (request) {
- request.setRequestHeader("X-CSRFToken",
- $('input[name="csrfmiddlewaretoken"]').val());
- },
- success: function (data) {
- confirm_permission(to, data);
- update_page(data);
- }
- });
- }
-
- function confirm_permission(to, data) {
- if (errors_exist(data)) {
- if (to != "prev") {
- return;
- }
- }
-
- var problem = function () {
- alert("There was a problem");
- }
- //makes an asynch request
- req = new XMLHttpRequest();
- url = "/wf/workflow/?step=" + to;
- req.open("GET", url, true);
- req.onload = function (e) {
- if (req.readyState === 4) {
- if (req.status < 300) {
- write_iframe(this.responseText);
- } else {
- problem();
- }
- } else {
- problem();
- }
- }
- req.onerror = problem;
- req.send();
- }
-
- function errors_exist(data) {
- var stat = data['steps'][data['active']]['valid'];
- if (stat >= 100 && stat < 200) {
- return true;
- } else {
- return false;
- }
- }
-
- function update_context() {
- $.ajax({
- type: "GET",
- url: "/wf/manager/",
- beforeSend: function (request) {
- request.setRequestHeader("X-CSRFToken",
- $('input[name="csrfmiddlewaretoken"]').val());
- },
- success: function (data) {
- update_page(data);
- }
- });
- }
-
- function updateBreadcrumbs(data) {
- update_breadcrumbs(data);
- if (data["workflow_count"] == 1) {
- document.getElementById("cancel_btn").innerText = "Exit Workflow";
- } else {
- document.getElementById("cancel_btn").innerText = "Return to Parent";
- }
- }
-
- function update_breadcrumbs(meta_json) {
- step = meta_json['active'];
- page_count = meta_json['steps'].length;
- if (step == 0) {
- var btn = document.getElementById("gob");
- btn.classList.add("invisible");
- btn.disabled = true;
- } else {
- var btn = document.getElementById("gob");
- btn.classList.remove("invisible");
- btn.disabled = false;
- }
- if (step == page_count - 1) {
- var btn = document.getElementById("gof");
- btn.classList.add("invisible");
- btn.disabled = true;
- } else {
- var btn = document.getElementById("gof");
- btn.classList.remove("invisible");
- btn.disabled = false;
- }
- //remove all children of breadcrumbs so we can redraw
- $("#topPagination").children().not(".page-control").remove();
- draw_steps(meta_json);
- }
-
- function draw_steps(meta_json) {
- for (var i = 0; i < meta_json["steps"].length; i++) {
- meta_json["steps"][i]["index"] = i;
- var step_btn = create_step(meta_json["steps"][i], i == meta_json["active"]);
- $("#topPagination li:last-child").before(step_btn);
- }
- }
-
- function create_step(step_json, active) {
- var step_dom = document.createElement("li");
- // First create the dom object depending on active or not
- if (active) {
- step_dom.className = "topcrumb active";
- } else {
- step_dom.className = "topcrumb";
- }
- $(step_dom).html(`<span class="d-flex align-items-center justify-content-center text-capitalize w-100">${step_json['title']}</span>`)
- var code = step_json['valid'];
- stat = "";
- msg = "";
- if (code < 100) {
- $(step_dom).children().first().append("<i class='ml-2 far fa-square'></i>")
- stat = "";
- msg = "";
- } else if (code < 200) {
- $(step_dom).children().first().append("<i class='ml-2 fas fa-minus-square'></i>")
- stat = "invalid";
- msg = step_json['message'];
- } else if (code < 300) {
- $(step_dom).children().first().append("<i class='ml-2 far fa-check-square'></i>")
- stat = "valid";
- msg = step_json['message'];
- }
- if (step_json['enabled'] == false) {
- step_dom.classList.add("disabled");
- }
- if (active) {
- update_message(msg, stat);
- }
-
- var step_number = step_json['index'];
- return step_dom;
- }
-
- function cancel_wf() {
- var form = $("#workflow_pop_form");
- var formData = form.serialize();
- var req = new XMLHttpRequest();
- req.open("POST", "/wf/workflow/finish/", false);
- req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- req.onerror = function () {
- alert("problem occurred while trying to cancel current workflow");
- }
- req.onreadystatechange = function () {
- if (req.readyState === 4) {
- refresh_iframe();
- }
- };
- req.send(formData);
- }
-
- function refresh_iframe() {
- req = new XMLHttpRequest();
- url = "/wf/workflow/";
- req.open("GET", url, true);
- req.onload = function (e) {
- write_iframe(this.responseText);
- }
- req.send();
- }
-
- function write_iframe(contents) {
- $("#formContainer").html(contents);
- }
-
- function redirect_root() {
- window.location.replace('/wf/');
- }
-
- function add_wf(type) {
- add_wf_internal(type, false);
- }
-
- function add_edit_wf(type, target) {
- add_wf_internal(type, target);
- }
-
- function add_wf_internal(type, itemid) {
- data = {
- "add": type
- };
- if (itemid) {
- data['target'] = itemid;
- }
- $.ajax({
- type: "POST",
- url: "/wf/manager/",
- data: data,
- beforeSend: function (request) {
- request.setRequestHeader("X-CSRFToken",
- $('input[name="csrfmiddlewaretoken"]').val()
- );
- },
- success: refresh_wf_iframe()
- });
- }
-
- function refresh_wf_iframe() {
- window.location = window.location;
- }
-
- // Load the actual first page
$(document).ready(function(){
- $.ajax("/wf/workflow", {
- success: function(data) {
- write_iframe(data);
- }
+ $.ajax({
+ url: "/workflow/manager/",
+ dataType: "json",
+ success: update_page
});
});
</script>
+<!-- lazy load scripts -->
+<script type="text/javascript" src="/static/js/mxClient.min.js" ></script>
+<!-- end lazy load scripts -->
<div class="d-none" id="workflow_pop_form_div">
- <form id="workflow_pop_form" action="/wf/workflow/finish/" method="post">
+ <form id="workflow_pop_form" action="/workflow/finish/" method="post">
{% csrf_token %}
</form>
</div>
diff --git a/src/templates/workflow/viewport-element.html b/src/templates/workflow/viewport-element.html
index bf13304..d16c924 100644
--- a/src/templates/workflow/viewport-element.html
+++ b/src/templates/workflow/viewport-element.html
@@ -5,42 +5,6 @@
{% block content %}
{% endblock content %}
- {% block vport_comm %}
- <script type="text/javascript">
- var step_count = {{ step_number|default:0 }};
- var active_step = {{ active_step|default:0 }};
- var render_correct = {{ render_correct|default:"false" }};
- var title = "{{ step_title|default:"Workflow Step" }}";
- var description = "{{ description|default:"Contact the admins, because this field should have something else filled in here" }}";
- if(render_correct){
- parent.update_context();
- }
- parent.update_description(title, description);
- </script>
-
- {% endblock vport_comm %}
- {% block validate_step %}
- <script>
-
- function step_is_valid()
- {
- valid = confirm("Is this form valid?");
- if( valid )
- {
- return true;
- }
- else{
- return false;
- }
- }
-
- function onError()
- {
- alert("Error: something!");
- }
- </script>
-
- {% endblock validate_step %}
<div class="messages">
{% block element_messages %}
diff --git a/src/workflow/models.py b/src/workflow/models.py
index 866f442..0521165 100644
--- a/src/workflow/models.py
+++ b/src/workflow/models.py
@@ -318,6 +318,9 @@ class Confirmation_Step(WorkflowStep):
default_flow_style=False
).strip()
+ if self.valid == WorkflowStepStatus.VALID:
+ context["confirm_succeeded"] = "true"
+
return context
def flush_to_db(self):
@@ -329,9 +332,7 @@ class Confirmation_Step(WorkflowStep):
form = ConfirmationForm(post_data)
if form.is_valid():
data = form.cleaned_data['confirm']
- context = self.get_context()
if data == "True":
- context["bypassed"] = "true"
errors = self.flush_to_db()
if errors:
self.set_invalid("ERROR OCCURRED: " + errors)
@@ -339,7 +340,6 @@ class Confirmation_Step(WorkflowStep):
self.set_valid("Confirmed")
elif data == "False":
- context["bypassed"] = "true"
self.set_valid("Canceled")
else:
self.set_invalid("Bad Form Contents")
diff --git a/src/workflow/urls.py b/src/workflow/urls.py
index ae620d0..298db95 100644
--- a/src/workflow/urls.py
+++ b/src/workflow/urls.py
@@ -11,7 +11,7 @@
from django.conf.urls import url
from django.conf import settings
-from workflow.views import delete_session, manager_view, viewport_view, add_workflow, cancel_workflow
+from workflow.views import manager_view, viewport_view, add_workflow, remove_workflow, create_workflow
from workflow.models import Repository
from workflow.resource_bundle_workflow import Define_Hardware, Define_Nets, Resource_Meta_Info
from workflow.booking_workflow import SWConfig_Select, Booking_Resource_Select, Booking_Meta
@@ -19,10 +19,10 @@ from workflow.booking_workflow import SWConfig_Select, Booking_Resource_Select,
app_name = 'workflow'
urlpatterns = [
- url(r'^finish/$', delete_session, name='delete_session'),
url(r'^manager/$', manager_view, name='manager'),
url(r'^add/$', add_workflow, name='add_workflow'),
- url(r'^cancel/$', cancel_workflow, name='cancel_workflow'),
+ url(r'^create/$', create_workflow, name='create_workflow'),
+ url(r'^pop/$', remove_workflow, name='remove_workflow'),
url(r'^$', viewport_view, name='viewport')
]
diff --git a/src/workflow/views.py b/src/workflow/views.py
index 47241e2..3ab4d30 100644
--- a/src/workflow/views.py
+++ b/src/workflow/views.py
@@ -8,9 +8,8 @@
##############################################################################
-from django.http import HttpResponse, JsonResponse
+from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.shortcuts import render
-from django.urls import reverse
import uuid
@@ -31,33 +30,17 @@ def attempt_auth(request):
return None
-def get_redirect_response(result):
- if not result:
- return {}
-
- # need to get type of result, and switch on the type
- # since has_result, result must be populated with a valid object
- if isinstance(result, Booking):
- return {
- 'redir_url': reverse('booking:booking_detail', kwargs={'booking_id': result.id})
- }
- else:
- return {}
-
-
-def delete_session(request):
+def remove_workflow(request):
manager = attempt_auth(request)
if not manager:
return no_workflow(request)
- not_last_workflow, result = manager.pop_workflow()
+ has_more_workflows, result = manager.pop_workflow()
- if not_last_workflow: # this was not the last workflow, so don't redirect away
- return JsonResponse({})
- else:
+ if not has_more_workflows: # this was the last workflow, so delete the reference to it in the tracker
del ManagerTracker.managers[request.session['manager_session']]
- return JsonResponse(get_redirect_response(result))
+ return manager.render(request)
def add_workflow(request):
@@ -73,15 +56,6 @@ def add_workflow(request):
return manager.render(request) # do we want this?
-def cancel_workflow(request):
- manager = attempt_auth(request)
- if not manager:
- return no_workflow(request)
-
- if not manager.pop_workflow():
- del ManagerTracker.managers[request.session['manager_session']]
-
-
def manager_view(request):
manager = attempt_auth(request)
if not manager:
@@ -98,16 +72,27 @@ def viewport_view(request):
if manager is None:
return no_workflow(request)
- if request.method == 'GET':
- return render(request, 'workflow/viewport-base.html')
- else:
- pass
+ if request.method != 'GET':
+ return HttpResponse(status=405)
+ return render(request, 'workflow/viewport-base.html')
+
+
+def create_workflow(request):
+ if request.method != 'POST':
+ return HttpResponse(status=405)
+ workflow_type = request.POST.get('workflow_type')
+ try:
+ workflow_type = int(workflow_type)
+ except Exception:
+ return HttpResponse(status=400)
+ mgr_uuid = create_session(workflow_type, request=request,)
+ request.session['manager_session'] = mgr_uuid
+ return HttpResponse()
def create_session(wf_type, request):
- wf = int(wf_type)
smgr = SessionManager(request=request)
- smgr.add_workflow(workflow_type=wf, target_id=request.POST.get("target"))
+ smgr.add_workflow(workflow_type=wf_type, target_id=request.POST.get("target"))
manager_uuid = uuid.uuid4().hex
ManagerTracker.getInstance().managers[manager_uuid] = smgr
diff --git a/src/workflow/workflow_manager.py b/src/workflow/workflow_manager.py
index 605eee7..4677829 100644
--- a/src/workflow/workflow_manager.py
+++ b/src/workflow/workflow_manager.py
@@ -10,6 +10,7 @@
from django.http import JsonResponse
from django.http.request import QueryDict
+from django.urls import reverse
from booking.models import Booking
from workflow.workflow_factory import WorkflowFactory
@@ -32,10 +33,9 @@ class SessionManager():
def __init__(self, request=None):
self.workflows = []
-
self.owner = request.user
-
self.factory = WorkflowFactory()
+ self.result = None
def set_step_statuses(self, superclass_type, desired_enabled=True):
workflow = self.active_workflow()
@@ -62,6 +62,11 @@ class SessionManager():
)
)
+ def get_redirect(self):
+ if isinstance(self.result, Booking):
+ return reverse('booking:booking_detail', kwargs={'booking_id': self.result.id})
+ return "/"
+
def pop_workflow(self):
multiple_wfs = len(self.workflows) > 1
if multiple_wfs:
@@ -69,9 +74,13 @@ class SessionManager():
key = self.workflows[-1].repository.el[Repository.RESULT_KEY]
result = self.workflows[-1].repository.el[Repository.RESULT]
self.workflows[-2].repository.el[key] = result
- self.workflows.pop()
- current_repo = self.workflows[-1].repository
- return (multiple_wfs, current_repo.el[current_repo.RESULT])
+ prev_workflow = self.workflows.pop()
+ if self.workflows:
+ current_repo = self.workflows[-1].repository
+ else:
+ current_repo = prev_workflow.repository
+ self.result = current_repo.el[current_repo.RESULT]
+ return multiple_wfs, self.result
def status(self, request):
return {
@@ -82,7 +91,7 @@ class SessionManager():
def handle_post(self, request):
form = ManagerForm(request.POST)
- if form.is_valid:
+ if form.is_valid():
self.get_active_step().post(
QueryDict(form.cleaned_data['step_form']),
user=request.user
@@ -98,13 +107,18 @@ class SessionManager():
def handle_request(self, request):
if request.method == 'POST':
self.handle_post(request)
- return self.render()
+ return self.render(request)
def render(self, request, **kwargs):
- return JsonResponse({
- "meta": self.status(),
- "content": self.get_active_step().render_to_string(request)
- })
+ if self.workflows:
+ return JsonResponse({
+ "meta": self.status(request),
+ "content": self.get_active_step().render_to_string(request),
+ })
+ else:
+ return JsonResponse({
+ "redirect": self.get_redirect()
+ })
def post_render(self, request):
return self.active_workflow().steps[self.active_workflow().active_index].post_render(request)