From 8ed7697a634ca564591192082c9b2265db318ade Mon Sep 17 00:00:00 2001
From: Patrick Jentsch <p.jentsch@uni-bielefeld.de>
Date: Mon, 2 Sep 2019 15:25:30 +0200
Subject: [PATCH] Add live information updates to job page.

---
 app/templates/main/jobs/job.html.j2 | 123 +++++++++++++++++++++++-----
 1 file changed, 104 insertions(+), 19 deletions(-)

diff --git a/app/templates/main/jobs/job.html.j2 b/app/templates/main/jobs/job.html.j2
index 2f97cc0f..ea3dd9a0 100644
--- a/app/templates/main/jobs/job.html.j2
+++ b/app/templates/main/jobs/job.html.j2
@@ -1,19 +1,104 @@
 {% extends "base.html.j2" %}
 
 {% block page_content %}
+<script>
+  var url = window.location.pathname;
+  var JOB_ID = url.substring(url.lastIndexOf('/') + 1);
+
+  class InformationUpdater {
+    constructor(jobId) {
+      this.jobId = jobId;
+      jobsSubscribers.push(this);
+    }
+
+    _init() {
+      var creationDateElement, descriptionElement, endDateElement,
+          memMbElement, nCoresElement, serviceElement, serviceArgsElement,
+          serviceVersionElement, statusColor, statusElement, titleElement;
+
+      this.job = jobs[this.jobId];
+      creationDateElement = document.getElementById("creation-date");
+      creationDateElement.value = this.job.creation_date;
+      descriptionElement = document.getElementById("description");
+      descriptionElement.innerHTML = this.job.description;
+      endDateElement = document.getElementById("end-date");
+      endDateElement.value = this.job.end_date;
+      memMbElement = document.getElementById("mem-mb");
+      memMbElement.value = this.job.mem_mb;
+      nCoresElement = document.getElementById("n-cores");
+      nCoresElement.value = this.job.n_cores;
+      serviceElement = document.getElementById("service");
+      serviceElement.value = this.job.service;
+      serviceArgsElement = document.getElementById("service-args");
+      serviceArgsElement.value = this.job.service_args;
+      serviceVersionElement = document.getElementById("service-version");
+      serviceVersionElement.value = this.job.service_version;
+      statusColor = JobList.STATUS_COLORS[this.job.status] || JobList.STATUS_COLORS['default'];
+      statusElement = document.getElementById("status");
+      statusElement.classList.add(statusColor);
+      statusElement.innerHTML = this.job.status;
+      titleElement = document.getElementById("title");
+      titleElement.innerHTML = this.job.title;
+
+      M.updateTextFields();
+    }
+
+    _update(patch) {
+      var newStatusColor, operation, pathArray, status, statusColor,
+          updatedElement;
+
+      for (operation of patch) {
+        /* "/jobId/valueName" -> ["jobId", "valueName"] */
+        pathArray = operation.path.split("/").slice(1);
+        if (pathArray[0] != this.jobId) {continue;}
+        switch(operation.op) {
+          case "add":
+            break;
+          case "delete":
+            location.reload();
+            break;
+          case "replace":
+            switch(pathArray[1]) {
+              case "description":
+                updatedElement = document.getElementById("description");
+                updatedElement.innerHTML = operation.value;
+                break;
+              case "end_date":
+                updatedElement = document.getElementById("end-date");
+                updatedElement.innerHTML = operation.value;
+                M.updateTextFields();
+                break;
+              case "status":
+                updatedElement = document.getElementById("status");
+                status = updatedElement.innerHTML;
+                statusColor = JobList.STATUS_COLORS[status] || JobList.STATUS_COLORS['default'];
+                newStatusColor = JobList.STATUS_COLORS[operation.value] || JobList.STATUS_COLORS['default'];
+                updatedElement.classList.remove(statusColor);
+                updatedElement.classList.add(newStatusColor);
+                updatedElement.innerHTML = operation.value;
+                Animations.pulse(updatedElement, 3000);
+                break;
+              case "title":
+                updatedElement = document.getElementById("title");
+                updatedElement.innerHTML = operation.value;
+                break;
+              default:
+                break;
+            }
+            break;
+          default:
+            break;
+        }
+      }
+    }
+  }
+  var informationUpdater = new InformationUpdater(JOB_ID);
+</script>
+
 <div class="col s12 m4">
-  <h3>{{ job.title }}</h3>
-  <p>{{ job.description }}</p>
-  {% if job.status == 'pending' %}
-    {% set status_color = 'amber' %}
-  {% elif job.status =='running' %}
-    {% set status_color = 'indigo' %}
-  {% elif job.status =='complete' %}
-    {% set status_color = 'teal' %}
-  {% else %}
-    {% set status_color = 'red' %}
-  {% endif %}
-  <p><a class="waves-effect waves-light btn {{ status_color }}">{{ job.status }}</a></p>
+  <h3 id="title"></h3>
+  <p id="description"></p>
+  <a class="waves-effect waves-light btn" id="status"></a>
 </div>
 
 <div class="col s12 m8">
@@ -23,13 +108,13 @@
       <div class="row">
         <div class="col s12 m6">
           <div class="input-field">
-            <input disabled value="{{ job.creation_date }}" id="creation-date" type="text" class="validate">
+            <input disabled value="" id="creation-date" type="text" class="validate">
             <label for="creation-date">Creation date</label>
           </div>
         </div>
         <div class="col s12 m6">
           <div class="input-field">
-            <input disabled value="{{ job.end_date }}" id="end-date" type="text" class="validate">
+            <input disabled value="" id="end-date" type="text" class="validate">
             <label for="end-date">End date</label>
           </div>
         </div>
@@ -38,13 +123,13 @@
       <div class="row">
         <div class="col s12 m6">
           <div class="input-field">
-            <input disabled value="{{ job.mem_mb }}" id="mem-mb" type="text" class="validate">
+            <input disabled value="" id="mem-mb" type="text" class="validate">
             <label for="mem-mb">Memory</label>
           </div>
         </div>
         <div class="col s12 m6">
           <div class="input-field">
-            <input disabled value="{{ job.n_cores }}" id="n-cores" type="text" class="validate">
+            <input disabled value="" id="n-cores" type="text" class="validate">
             <label for="n-cores">CPU cores</label>
           </div>
         </div>
@@ -53,19 +138,19 @@
       <div class="row">
         <div class="col s12 m4">
           <div class="input-field">
-            <input disabled value="{{ job.service }}" id="service" type="text" class="validate">
+            <input disabled value="" id="service" type="text" class="validate">
             <label for="service">Service</label>
           </div>
         </div>
         <div class="col s12 m4">
           <div class="input-field">
-            <input disabled value="{{ job.service_args|escape }}" id="service-args" type="text" class="validate">
+            <input disabled value="" id="service-args" type="text" class="validate">
             <label for="service-args">Service arguments</label>
           </div>
         </div>
         <div class="col s12 m4">
           <div class="input-field">
-            <input disabled value="{{ job.service_version }}" id="service-version" type="text" class="validate">
+            <input disabled value="" id="service-version" type="text" class="validate">
             <label for="service-version">Service version</label>
           </div>
         </div>
-- 
GitLab