Hacking on AJAX 85/68185/7
authorParker Berberian <pberberian@iol.unh.edu>
Tue, 2 Jul 2019 21:33:09 +0000 (17:33 -0400)
committerSawyer Bergeron <sbergeron@iol.unh.edu>
Mon, 8 Jul 2019 14:32:53 +0000 (14:32 +0000)
This change incorporates the multiple changes we've made
in the past few days in order to actually get AJAX working.

Change-Id: Ia61a0395e7dbac26a143ca6e15049e6a4bdc8b0d
Signed-off-by: Parker Berberian <pberberian@iol.unh.edu>
Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu>
15 files changed:
src/dashboard/views.py
src/static/js/dashboard.js
src/templates/base.html
src/templates/dashboard/genericselect.html
src/templates/dashboard/landing.html
src/templates/dashboard/multiple_select_filter_widget.html
src/templates/dashboard/searchable_select_multiple.html
src/templates/resource/steps/pod_definition.html
src/templates/workflow/confirm.html
src/templates/workflow/viewport-base.html
src/templates/workflow/viewport-element.html
src/workflow/models.py
src/workflow/urls.py
src/workflow/views.py
src/workflow/workflow_manager.py

index aaad7ab..9416cb4 100644 (file)
@@ -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):
index f1eff77..7f8a427 100644 (file)
 
 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
 ///////////////////
index 891e0fc..f59740d 100644 (file)
@@ -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 %}
                                 <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>
index f54cd90..863d33f 100644 (file)
@@ -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>
 </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 %}
-
index d4776cc..72f9e6e 100644 (file)
             </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>
     </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 %}
index 4a65bd9..e97a41b 100644 (file)
@@ -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">
index 8299a55..44689da 100644 (file)
@@ -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">
index 4392dbd..d0a28ed 100644 (file)
@@ -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;
index b7e6c46..2f99a41 100644 (file)
@@ -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>
 <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 %}
index 103a095..02c5597 100644 (file)
                         <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">
                 <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">
     </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>
index bf13304..d16c924 100644 (file)
@@ -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 %}
index 866f442..0521165 100644 (file)
@@ -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")
index ae620d0..298db95 100644 (file)
@@ -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')
 ]
 
index 47241e2..3ab4d30 100644 (file)
@@ -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
 
index 605eee7..4677829 100644 (file)
@@ -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)