aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/pharos_dashboard/urls.py2
-rw-r--r--src/static/css/base.css3
-rw-r--r--src/static/js/dashboard.js52
-rw-r--r--src/templates/booking/quick_deploy.html33
-rw-r--r--src/templates/booking/steps/booking_meta.html12
-rw-r--r--src/templates/config_bundle/steps/config_software.html12
-rw-r--r--src/templates/config_bundle/steps/define_software.html9
-rw-r--r--src/templates/config_bundle/steps/pick_installer.html12
-rw-r--r--src/templates/config_bundle/steps/table_formset.html13
-rw-r--r--src/templates/dashboard/multiple_select_filter_widget.html30
-rw-r--r--src/templates/resource/steps/define_hardware.html10
-rw-r--r--src/templates/resource/steps/host_info.html11
-rw-r--r--src/templates/resource/steps/meta_info.html12
-rw-r--r--src/templates/resource/steps/pod_definition.html3
-rw-r--r--src/templates/snapshot_workflow/steps/meta.html12
-rw-r--r--src/templates/snapshot_workflow/steps/select_host.html12
-rw-r--r--src/templates/workflow/viewport-base.html15
-rw-r--r--src/templates/workflow/viewport-element.html8
-rw-r--r--src/workflow/forms.py19
-rw-r--r--src/workflow/urls.py7
-rw-r--r--src/workflow/views.py57
-rw-r--r--src/workflow/workflow_manager.py52
22 files changed, 168 insertions, 228 deletions
diff --git a/src/pharos_dashboard/urls.py b/src/pharos_dashboard/urls.py
index 8535bed..fd791c3 100644
--- a/src/pharos_dashboard/urls.py
+++ b/src/pharos_dashboard/urls.py
@@ -32,7 +32,7 @@ from django.contrib import admin
urlpatterns = [
- url(r'^wf/', include('workflow.urls', namespace='workflow')),
+ url(r'^workflow/', include('workflow.urls', namespace='workflow')),
url(r'^', include('dashboard.urls', namespace='dashboard')),
url(r'^booking/', include('booking.urls', namespace='booking')),
url(r'^accounts/', include('account.urls', namespace='account')),
diff --git a/src/static/css/base.css b/src/static/css/base.css
index 72ecc40..9fec97e 100644
--- a/src/static/css/base.css
+++ b/src/static/css/base.css
@@ -66,9 +66,6 @@ a[aria-expanded="true"] > i.rotate {
box-shadow: 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(109, 243, 76, 0.6);
transition: border-color ease-in-out .1s,box-shadow ease-in-out .1s;
}
-#grid_wrapper > .row > div:first-child {
- border-right: 1px solid gray;
-}
/* Cursor effects */
.not-allowed {
diff --git a/src/static/js/dashboard.js b/src/static/js/dashboard.js
index e0c0085..a03dc98 100644
--- a/src/static/js/dashboard.js
+++ b/src/static/js/dashboard.js
@@ -1,3 +1,46 @@
+///////////////////
+// Global Variables
+///////////////////
+
+form_submission_callbacks = []; //all runnables will be executed before form submission
+
+
+///////////////////
+// Global Functions
+///////////////////
+
+function updatePage(data){
+ updateBreadcrumbs(data['meta']);
+ $("formContainer").html(data['content']);
+}
+
+function submitStepForm(next_step = "current"){
+ run_form_callbacks();
+ const step_form_data = $("#step_form").serialize();
+ const form_data = $.param({
+ "step": next_step,
+ "step_form": step_form_data,
+ "csrfmiddlewaretoken": $("[name=csrfmiddlewaretoken]").val()
+ });
+ console.log(form_data);
+ $.post(
+ '/workflow/manager/',
+ form_data,
+ (data) => updatePage(data),
+ 'json'
+ ).fail(() => alert("failure"));
+}
+
+function run_form_callbacks(){
+ for(f of form_submission_callbacks)
+ f();
+ form_submission_callbacks = [];
+}
+
+///////////////////
+//Class Definitions
+///////////////////
+
class MultipleSelectFilterWidget {
constructor(neighbors, items, initial) {
@@ -826,16 +869,9 @@ class NetworkStep {
this.graph.refresh(host);
}
- submitForm() {
- const form = document.getElementById("xml_form");
+ prepareForm() {
const input_elem = document.getElementById("hidden_xml_input");
input_elem.value = this.encodeGraph(this.graph);
- const 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"); }
- const formData = $("#xml_form").serialize();
- req.send(formData);
}
}
diff --git a/src/templates/booking/quick_deploy.html b/src/templates/booking/quick_deploy.html
index f1ba491..6776980 100644
--- a/src/templates/booking/quick_deploy.html
+++ b/src/templates/booking/quick_deploy.html
@@ -7,13 +7,13 @@
<form id="quick_booking_form" action="/booking/quick/" method="POST" class="form">
{% csrf_token %}
<div class="container-fluid">
- <div class="row">
- <div class="col-12 px-1 my-2">
- <div class="col py-2 rounded border">
- <p>Please select a host type you wish to book. Only available types are shown.</p>
- {% bootstrap_field form.filter_field show_label=False %}
- </div>
+ <div class="row mx-0 px-0">
+ <div class="col-12 mx-0 px-0 mt-2">
+ <p class="my-0">Please select a host type you wish to book. Only available types are shown.</p>
+ {% bootstrap_field form.filter_field show_label=False %}
</div>
+ </div>
+ <div class="row">
<div class="col-12 col-lg-3 px-1 my-2">
<div class="col border rounded py-2 h-100">
{% bootstrap_field form.purpose %}
@@ -55,10 +55,7 @@
<script type="text/javascript">
function submit_form()
{
- //formats data for form submission
- multi_filter_widget.finish();
- // Submit the form manually since confirm button is type="button" now
- // due to the form submitting before the data was even created by finish()
+ run_form_callbacks();
document.getElementById("quick_booking_form").submit();
}
@@ -83,11 +80,8 @@
var sup_installer_dict = {{installer_filter | safe}};
var sup_scenario_dict = {{scenario_filter | safe}};
- function imageHider() {
+ function imageFilter() {
var drop = document.getElementById("id_image");
-
- hide_dropdown("id_image");
-
var lab_pk = get_selected_value("lab");
var host_pk = get_selected_value("host");
@@ -95,21 +89,18 @@
var image_object = sup_image_dict[childNode.value];
if (image_object) //weed out empty option
{
- if (image_object.host_profile == host_pk && image_object.lab == lab_pk) {
- childNode.style.display = "inherit";
- childNode.disabled = false;
- }
+ childNode.disabled = !(image_object.host_profile == host_pk && image_object.lab == lab_pk);
}
}
}
- imageHider();
+ imageFilter();
$('#id_installer').children().hide();
$('#id_scenario').children().hide();
Array.from(document.getElementsByClassName("grid-item-select-btn")).forEach(function (element) {
- element.addEventListener('click', imageHider);
+ element.addEventListener('click', imageFilter);
});
function installerHider() {
@@ -148,4 +139,4 @@
}
}
</script>
-{% endblock %} \ No newline at end of file
+{% endblock %}
diff --git a/src/templates/booking/steps/booking_meta.html b/src/templates/booking/steps/booking_meta.html
index a7bb8b9..f12496e 100644
--- a/src/templates/booking/steps/booking_meta.html
+++ b/src/templates/booking/steps/booking_meta.html
@@ -6,7 +6,7 @@
{% block content %}
{% bootstrap_form_errors form type='non_fields' %}
-<form id="booking_meta_form" action="/wf/workflow/" method="POST" class="form">
+<form id="step_form" method="POST" class="form">
{% csrf_token %}
<div id="form_div" class="container-fluid">
<div class="row">
@@ -36,13 +36,3 @@
</div>
</form>
{% endblock content %}
-
-{% block onleave %}
-var ajaxForm = $("#booking_meta_form");
-var formData = ajaxForm.serialize();
-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.send(formData);
-{% endblock %}
diff --git a/src/templates/config_bundle/steps/config_software.html b/src/templates/config_bundle/steps/config_software.html
index 68417bc..6fe0ac1 100644
--- a/src/templates/config_bundle/steps/config_software.html
+++ b/src/templates/config_bundle/steps/config_software.html
@@ -5,7 +5,7 @@
{% block content %}
-<form action="/wf/workflow/" method="POST" id="software_config_form" class="form">
+<form method="POST" id="step_form" class="form">
{% csrf_token %}
<p>Give it a name:</p>
{% bootstrap_field form.name %}
@@ -16,13 +16,3 @@
{% endblock content %}
-
-{% block onleave %}
-var ajaxForm = $("#software_config_form");
-var formData = ajaxForm.serialize();
-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.send(formData);
-{% endblock %}
diff --git a/src/templates/config_bundle/steps/define_software.html b/src/templates/config_bundle/steps/define_software.html
index 87e5997..7c47569 100644
--- a/src/templates/config_bundle/steps/define_software.html
+++ b/src/templates/config_bundle/steps/define_software.html
@@ -44,12 +44,3 @@ for(var i=0; i<parents.length; i++){
checkbox.value = "True";
}
}
-
-var form = $("#table_formset");
-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 onleave %}
diff --git a/src/templates/config_bundle/steps/pick_installer.html b/src/templates/config_bundle/steps/pick_installer.html
index 31a06de..c3b505d 100644
--- a/src/templates/config_bundle/steps/pick_installer.html
+++ b/src/templates/config_bundle/steps/pick_installer.html
@@ -9,7 +9,7 @@
<h1>Please choose a config bundle first</h1>
{% else %}
-<form id="installer_form" action="/wf/workflow/" method="POST" id="installer_config_form" class="form">
+<form id="step_form" method="POST" class="form">
{% csrf_token %}
<p>Choose your installer:</p>
{% bootstrap_field form.installer %}
@@ -20,13 +20,3 @@
{% endif %}
{% endblock content %}
-
-{% block onleave %}
-var form = $("#installer_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/config_bundle/steps/table_formset.html b/src/templates/config_bundle/steps/table_formset.html
index e19f3df..d25621e 100644
--- a/src/templates/config_bundle/steps/table_formset.html
+++ b/src/templates/config_bundle/steps/table_formset.html
@@ -18,7 +18,7 @@
<h1 class="text-center">{{ error }}</h1>
{% else %}
<div class="p-2">
- <form method="post" action="" class="form" id="table_formset">
+ <form method="post" class="form" id="step_form"> <!-- formset, requires special consideration -->
{% csrf_token %}
<div class="row">
@@ -51,14 +51,3 @@
{% block tablejs %}
{% endblock tablejs %}
{% endblock extrajs %}
-
-
-{% block onleave %}
-var form = $("#table_formset");
-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/multiple_select_filter_widget.html b/src/templates/dashboard/multiple_select_filter_widget.html
index 7fb8bcf..4068919 100644
--- a/src/templates/dashboard/multiple_select_filter_widget.html
+++ b/src/templates/dashboard/multiple_select_filter_widget.html
@@ -2,17 +2,17 @@
</script>
<input name="filter_field" id="filter_field" type="hidden"/>
-<div id="grid_wrapper" class="container-fluid p-4">
- <div class="row">
- {% for object_class, object_list in display_objects %}
- <div class="col-12 col-lg d-flex flex-column pt-2 my-2">
+<div class="row">
+ {% for object_class, object_list in display_objects %}
+ <div class="col-12 col-lg-6 d-flex flex-column pt-2 mx-0 px-1">
+ <div class="col mx-0 border rounded py-2 flex-grow-1 d-flex flex-column">
<div class="w-100">
<h4 class="text-capitalize">{{object_class}}</h4>
</div>
- <div id="{{object_class}}" class="row h-100">
+ <div id="{{object_class}}" class="row flex-grow-1">
{% for obj in object_list %}
- <div class="col-12 col-md-6 col-xl-4 my-2">
- <div id="{{ obj.id|default:'not_provided' }}" class="card h-100" onclick="multi_filter_widget.processClick('{{obj.id}}');">
+ <div class="col-12 col-md-6 col-xl-4 my-2 d-flex flex-grow-1">
+ <div id="{{ obj.id|default:'not_provided' }}" class="card flex-grow-1">
<div class="card-header">
<p class="h5 font-weight-bold mt-2">{{obj.name}}</p>
</div>
@@ -20,15 +20,22 @@
<p class="grid-item-description">{{obj.description}}</p>
</div>
<div class="card-footer">
- <button type="button" class="btn btn-success grid-item-select-btn w-100">{% if obj.multiple %}Add{% else %}Select{% endif %}</button>
+ <button type="button" class="btn btn-success grid-item-select-btn w-100 stretched-link"
+ onclick="multi_filter_widget.processClick('{{obj.id}}');">
+ {% if obj.multiple %}
+ Add
+ {% else %}
+ Select
+ {% endif %}
+ </button>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
- {% endfor %}
- </div>
+ </div>
+ {% endfor %}
</div>
<div id="dropdown_wrapper" class="px-3 list-group-flush w-25 mt-2">
@@ -39,8 +46,9 @@ function multipleSelectFilterWidgetEntry() {
const filter_items = {{ filter_items|safe }};
const initial_value = {{ initial_value|default_if_none:"{}"|safe }};
- //global variable
+ //global variables
multi_filter_widget = new MultipleSelectFilterWidget(graph_neighbors, filter_items, initial_value);
+ form_submission_callbacks.push(() => multi_filter_widget.finish());
}
multipleSelectFilterWidgetEntry();
diff --git a/src/templates/resource/steps/define_hardware.html b/src/templates/resource/steps/define_hardware.html
index 57078e9..2cb37da 100644
--- a/src/templates/resource/steps/define_hardware.html
+++ b/src/templates/resource/steps/define_hardware.html
@@ -9,16 +9,8 @@ As you make your selections, labs and hosts that are not compatible
with your current configuration will become unavailable.</p>
<h4>NOTE: Only PTL's are able to create multi-node PODs. See <a href="https://google.com">here</a>
for more details</h4>
-<form id="define_hardware_form" action="/wf/workflow/" method="post">
+<form id="step_form" method="post" class="px-3">
{% csrf_token %}
{{form.filter_field|default:"<p>No Form</p>"}}
</form>
{% endblock content %}
-{% block onleave %}
-multi_filter_widget.finish();
-var formData = $("#define_hardware_form").serialize();
-req = new XMLHttpRequest();
-req.open('POST', '/wf/workflow/', false);
-req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
-req.send(formData);
-{% endblock %}
diff --git a/src/templates/resource/steps/host_info.html b/src/templates/resource/steps/host_info.html
index bbbafdc..3230d8f 100644
--- a/src/templates/resource/steps/host_info.html
+++ b/src/templates/resource/steps/host_info.html
@@ -10,7 +10,7 @@
{% else %}
-<form id="host_meta_form" method="post" action="/wf/workflow/">
+<form id="step_form" method="post">
{% csrf_token %}
<table>
<thead>
@@ -32,12 +32,3 @@
</form>
{% endif %}
{% endblock content %}
-
-{% block onleave %}
-var formData = $("#host_meta_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("There was a problem submitting the form"); }
-req.send(formData);
-{% endblock %}
diff --git a/src/templates/resource/steps/meta_info.html b/src/templates/resource/steps/meta_info.html
index 62230dc..b6a17a9 100644
--- a/src/templates/resource/steps/meta_info.html
+++ b/src/templates/resource/steps/meta_info.html
@@ -5,20 +5,10 @@
{% block content %}
-<form id="resource_meta_form" method="post" action="/wf/workflow/">
+<form id="step_form" method="post">
{% csrf_token %}
<table class="px-4">
{% bootstrap_form form field_class="px-4" label_class="px-4 mt-2" %}
</table>
</form>
{% endblock content %}
-
-{% block onleave %}
-var ajaxForm = $("#resource_meta_form");
-var formData = ajaxForm.serialize();
-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.send(formData);
-{% endblock %}
diff --git a/src/templates/resource/steps/pod_definition.html b/src/templates/resource/steps/pod_definition.html
index 4c9aa83..4392dbd 100644
--- a/src/templates/resource/steps/pod_definition.html
+++ b/src/templates/resource/steps/pod_definition.html
@@ -37,7 +37,7 @@
<button type="button" class="d-none" onclick="network_step.submitForm();">Submit</button>
</div>
</div>
- <form id="xml_form" method="post" action="/wf/workflow/">
+ <form id="step_form" method="post">
{% csrf_token %}
<input type="hidden" id="hidden_xml_input" name="xml" />
</form>
@@ -77,6 +77,7 @@
document.getElementById('toolbarContainer'),
document.getElementById('sidebarContainer')
);
+ form_submission_callbacks.push(() => network_step.prepareForm());
</script>
{% endblock content %}
{% block onleave %}
diff --git a/src/templates/snapshot_workflow/steps/meta.html b/src/templates/snapshot_workflow/steps/meta.html
index 7c3e98b..88136d2 100644
--- a/src/templates/snapshot_workflow/steps/meta.html
+++ b/src/templates/snapshot_workflow/steps/meta.html
@@ -6,7 +6,7 @@
{% block content %}
{% bootstrap_form_errors form type='non_fields' %}
<div class="p-4">
- <form id="meta_form" action="/wf/workflow/" method="POST" class="form">
+ <form id="step_form" method="POST" class="form">
{% csrf_token %}
<div class="form-group">
{% bootstrap_field form.name %}
@@ -15,13 +15,3 @@
</form>
</div>
{% endblock content %}
-
-{% block onleave %}
-var ajaxForm = $("#meta_form");
-var formData = ajaxForm.serialize();
-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.send(formData);
-{% endblock %}
diff --git a/src/templates/snapshot_workflow/steps/select_host.html b/src/templates/snapshot_workflow/steps/select_host.html
index a0af67b..4243145 100644
--- a/src/templates/snapshot_workflow/steps/select_host.html
+++ b/src/templates/snapshot_workflow/steps/select_host.html
@@ -6,7 +6,7 @@
{% block content %}
{% bootstrap_form_errors form type='non_fields' %}
-<form id="host_select_form" action="/wf/workflow/" method="POST" class="form">
+<form id="step_form" method="POST" class="form">
{% csrf_token %}
<input type="hidden" id="hidden_json_input", name="host"/>
</form>
@@ -81,13 +81,3 @@ if(initial){
}
</script>
{% endblock content %}
-
-{% block onleave %}
-var ajaxForm = $("#host_select_form");
-var formData = ajaxForm.serialize();
-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.send(formData);
-{% endblock %}
diff --git a/src/templates/workflow/viewport-base.html b/src/templates/workflow/viewport-base.html
index ed367c7..103a095 100644
--- a/src/templates/workflow/viewport-base.html
+++ b/src/templates/workflow/viewport-base.html
@@ -11,7 +11,7 @@
<nav>
<ul class="pagination d-flex flex-row" id="topPagination">
<li class="page-item flex-shrink-1 page-control">
- <a class="page-link" href="#" id="gob" onclick="go('prev')">
+ <a class="page-link" href="#" id="gob" onclick="submit_and_go('prev')">
<i class="fas fa-backward"></i> Back
</a>
</li>
@@ -41,7 +41,7 @@
</a>
</li>
<li class="page-item flex-shrink-1 page-control">
- <a class="page-link text-right" href="#" id="gof" onclick="go('next')">
+ <a class="page-link text-right" href="#" id="gof" onclick="submit_and_go('next')">
Next <i class="fas fa-forward"></i>
</a>
</li>
@@ -91,11 +91,9 @@
update_context();
var step = 0;
var page_count = 0;
- var context_data = false;
- function go(to) {
- step_on_leave();
- request_leave(to);
+ function submit_and_go(to) {
+ submitStepForm(to);
}
function request_leave(to) {
@@ -165,8 +163,7 @@
});
}
- function update_page(data) {
- context_data = data;
+ function updateBreadcrumbs(data) {
update_breadcrumbs(data);
if (data["workflow_count"] == 1) {
document.getElementById("cancel_btn").innerText = "Exit Workflow";
@@ -326,4 +323,4 @@
{% csrf_token %}
</form>
</div>
-{% endblock content %} \ No newline at end of file
+{% endblock content %}
diff --git a/src/templates/workflow/viewport-element.html b/src/templates/workflow/viewport-element.html
index 2c917e1..bf13304 100644
--- a/src/templates/workflow/viewport-element.html
+++ b/src/templates/workflow/viewport-element.html
@@ -42,14 +42,6 @@
{% endblock validate_step %}
- <script>
- step_on_leave = function() {
- {% block onleave %}
- alert("override onleave");
- {% endblock %}
- }
- </script>
-
<div class="messages">
{% block element_messages %}
{% bootstrap_messages %}
diff --git a/src/workflow/forms.py b/src/workflow/forms.py
index ee44ecd..a2746f9 100644
--- a/src/workflow/forms.py
+++ b/src/workflow/forms.py
@@ -15,6 +15,7 @@ from django.template.loader import render_to_string
from django.forms.widgets import NumberInput
import json
+import urllib
from account.models import Lab
from account.models import UserProfile
@@ -428,6 +429,24 @@ class ConfirmationForm(forms.Form):
)
+def validate_step(value):
+ if value not in ["prev", "next", "current"]:
+ raise ValidationError(str(value) + " is not allowed")
+
+
+def validate_step_form(value):
+ try:
+ urllib.parse.unquote_plus(value)
+ except Exception:
+ raise ValidationError("Value is not url encoded data")
+
+
+class ManagerForm(forms.Form):
+ step = forms.CharField(widget=forms.widgets.HiddenInput, validators=[validate_step])
+ step_form = forms.CharField(widget=forms.widgets.HiddenInput, validators=[validate_step_form])
+ # other fields?
+
+
class OPNFVSelectionForm(forms.Form):
installer = forms.ModelChoiceField(queryset=Installer.objects.all(), required=True)
scenario = forms.ModelChoiceField(queryset=Scenario.objects.all(), required=True)
diff --git a/src/workflow/urls.py b/src/workflow/urls.py
index 5a97904..ae620d0 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 step_view, delete_session, manager_view, viewport_view
+from workflow.views import delete_session, manager_view, viewport_view, add_workflow, cancel_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,9 +19,10 @@ from workflow.booking_workflow import SWConfig_Select, Booking_Resource_Select,
app_name = 'workflow'
urlpatterns = [
- url(r'^workflow/$', step_view, name='workflow'),
- url(r'^workflow/finish/$', delete_session, name='delete_session'),
+ 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'^$', viewport_view, name='viewport')
]
diff --git a/src/workflow/views.py b/src/workflow/views.py
index 7ed9031..47241e2 100644
--- a/src/workflow/views.py
+++ b/src/workflow/views.py
@@ -8,7 +8,7 @@
##############################################################################
-from django.http import HttpResponseGone, JsonResponse
+from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.urls import reverse
@@ -49,7 +49,7 @@ def delete_session(request):
manager = attempt_auth(request)
if not manager:
- return HttpResponseGone("No session found that relates to current request")
+ return no_workflow(request)
not_last_workflow, result = manager.pop_workflow()
@@ -60,48 +60,34 @@ def delete_session(request):
return JsonResponse(get_redirect_response(result))
-def step_view(request):
+def add_workflow(request):
manager = attempt_auth(request)
if not manager:
- # no manager found, redirect to "lost" page
return no_workflow(request)
- if request.GET.get('step') is not None:
- if request.GET.get('step') == 'next':
- manager.go_next()
- elif request.GET.get('step') == 'prev':
- manager.go_prev()
- else:
- raise Exception("requested action for new step had malformed contents: " + request.GET.get('step'))
- return manager.render(request)
+ try:
+ workflow_type = int(request.POST.get('workflow_type'))
+ except ValueError:
+ return HttpResponse(status=400)
+ manager.add_workflow(workflow_type=workflow_type)
+ return manager.render(request) # do we want this?
-def manager_view(request):
- manager = attempt_auth(request)
+def cancel_workflow(request):
+ manager = attempt_auth(request)
if not manager:
- return HttpResponseGone("No session found that relates to current request")
+ return no_workflow(request)
- if request.method == 'GET':
- # no need for this statement if only intercepting post requests
+ if not manager.pop_workflow():
+ del ManagerTracker.managers[request.session['manager_session']]
- # return general context for viewport page
- return manager.status(request)
- if request.method == 'POST':
- if request.POST.get('add') is not None:
- logger.debug("add found")
- target_id = None
- if 'target' in request.POST:
- target_id = int(request.POST.get('target'))
- manager.add_workflow(workflow_type=int(request.POST.get('add')), target_id=target_id)
- elif request.POST.get('edit') is not None and request.POST.get('edit_id') is not None:
- logger.debug("edit found")
- manager.add_workflow(workflow_type=request.POST.get('edit'), edit_object=int(request.POST.get('edit_id')))
- elif request.POST.get('cancel') is not None:
- if not manager.pop_workflow():
- del ManagerTracker.managers[request.session['manager_session']]
+def manager_view(request):
+ manager = attempt_auth(request)
+ if not manager:
+ return no_workflow(request)
- return manager.status(request)
+ return manager.handle_request(request)
def viewport_view(request):
@@ -129,10 +115,7 @@ def create_session(wf_type, request):
def no_workflow(request):
-
- logger.debug("There is no active workflow")
-
- return render(request, 'workflow/no_workflow.html', {'title': "Not Found"})
+ return render(request, 'workflow/no_workflow.html', {'title': "Not Found"}, status=404)
def login(request):
diff --git a/src/workflow/workflow_manager.py b/src/workflow/workflow_manager.py
index 80b8a67..605eee7 100644
--- a/src/workflow/workflow_manager.py
+++ b/src/workflow/workflow_manager.py
@@ -9,6 +9,7 @@
from django.http import JsonResponse
+from django.http.request import QueryDict
from booking.models import Booking
from workflow.workflow_factory import WorkflowFactory
@@ -19,6 +20,7 @@ from resource_inventory.models import (
HostConfiguration,
OPNFVConfig
)
+from workflow.forms import ManagerForm
import logging
logger = logging.getLogger(__name__)
@@ -45,10 +47,7 @@ class SessionManager():
else:
step.disable()
- def add_workflow(self, workflow_type=None, target_id=None, **kwargs):
- if target_id is not None:
- self.prefill_repo(target_id, workflow_type)
-
+ def add_workflow(self, workflow_type=None, **kwargs):
repo = Repository()
if(len(self.workflows) >= 1):
defaults = self.workflows[-1].repository.get_child_defaults()
@@ -75,24 +74,37 @@ class SessionManager():
return (multiple_wfs, current_repo.el[current_repo.RESULT])
def status(self, request):
- try:
- meta_json = []
- for step in self.active_workflow().steps:
- meta_json.append(step.to_json())
- responsejson = {}
- responsejson["steps"] = meta_json
- responsejson["active"] = self.active_workflow().repository.el['active_step']
- responsejson["workflow_count"] = len(self.workflows)
- return JsonResponse(responsejson, safe=False)
- except Exception:
- pass
+ return {
+ "steps": [step.to_json() for step in self.active_workflow().steps],
+ "active": self.active_workflow().repository.el['active_step'],
+ "workflow_count": len(self.workflows)
+ }
+
+ def handle_post(self, request):
+ form = ManagerForm(request.POST)
+ if form.is_valid:
+ self.get_active_step().post(
+ QueryDict(form.cleaned_data['step_form']),
+ user=request.user
+ )
+ # change step
+ if form.cleaned_data['step'] == 'prev':
+ self.go_prev()
+ if form.cleaned_data['step'] == 'next':
+ self.go_next()
+ else:
+ pass # Exception?
+
+ def handle_request(self, request):
+ if request.method == 'POST':
+ self.handle_post(request)
+ return self.render()
def render(self, request, **kwargs):
- # filter out when a step needs to handle post/form data
- # if 'workflow' in post data, this post request was meant for me, not step
- if request.method == 'POST' and request.POST.get('workflow', None) is None:
- return self.active_workflow().steps[self.active_workflow().active_index].post_render(request)
- return self.active_workflow().steps[self.active_workflow().active_index].render(request)
+ return JsonResponse({
+ "meta": self.status(),
+ "content": self.get_active_step().render_to_string(request)
+ })
def post_render(self, request):
return self.active_workflow().steps[self.active_workflow().active_index].post_render(request)