diff --git a/web/app/templates/jobs/job.html.j2 b/web/app/templates/jobs/job.html.j2
index 35154042aac8f8d79a0a85a2214e196573b39040..635d78a8065424d58e8e67add816740649f21bb1 100644
--- a/web/app/templates/jobs/job.html.j2
+++ b/web/app/templates/jobs/job.html.j2
@@ -157,145 +157,146 @@
 </div>
 
 
-<script>
-  class InformationUpdater {
-    constructor(jobId, foreignJobFlag) {
-      this.jobId = jobId;
-      this.foreignJobFlag = foreignJobFlag;
+<script type="module">
+import {RessourceList} from '../../static/js/nopaque.lists.js';
+class InformationUpdater {
+  constructor(jobId, foreignJobFlag) {
+    this.jobId = jobId;
+    this.foreignJobFlag = foreignJobFlag;
 
-      if (this.foreignJobFlag) {
-        nopaque.foreignJobsSubscribers.push(this);
-      } else {
-        nopaque.jobsSubscribers.push(this);
-      }
+    if (this.foreignJobFlag) {
+      nopaque.foreignJobsSubscribers.push(this);
+    } else {
+      nopaque.jobsSubscribers.push(this);
     }
+  }
 
-    _init() {
-      let job;
+  _init() {
+    let job;
 
-      job = (this.foreignJobFlag ? nopaque.foreignUser.jobs[this.jobId]
-                                 : nopaque.user.jobs[this.jobId]);
-      // Results
-      this.addResults(job.results);
-      // End date
-      this.setEndDate(job.end_date);
-      // Status
-      this.setStatus(job.status);
-    }
+    job = (this.foreignJobFlag ? nopaque.foreignUser.jobs[this.jobId]
+                               : nopaque.user.jobs[this.jobId]);
+    // Results
+    this.addResults(job.results);
+    // End date
+    this.setEndDate(job.end_date);
+    // Status
+    this.setStatus(job.status);
+  }
 
-    _update(patch) {
-      let pathArray;
+  _update(patch) {
+    let pathArray;
 
-      for (let operation of patch) {
-        /* "/jobs/{jobId}/..." -> ["{jobId}", ...] */
-        pathArray = operation.path.split("/").slice(2);
-        if (pathArray[0] != this.jobId) {continue;}
-        switch(operation.op) {
-          case "add":
-            if (pathArray[1] === "results") {
-              this.addResults([operation.value]);
-            }
-            break;
-          case "delete":
-            location.reload();
-            break;
-          case "replace":
-            if (pathArray[1] === "end_date") {
-              this.setEndDate(operation.value);
-            } else if (pathArray[1] === "status") {
-              this.setStatus(operation.value);
-            }
-            break;
-          default:
-            break;
-        }
+    for (let operation of patch) {
+      /* "/jobs/{jobId}/..." -> ["{jobId}", ...] */
+      pathArray = operation.path.split("/").slice(2);
+      if (pathArray[0] != this.jobId) {continue;}
+      switch(operation.op) {
+        case "add":
+          if (pathArray[1] === "results") {
+            this.addResults([operation.value]);
+          }
+          break;
+        case "delete":
+          location.reload();
+          break;
+        case "replace":
+          if (pathArray[1] === "end_date") {
+            this.setEndDate(operation.value);
+          } else if (pathArray[1] === "status") {
+            this.setStatus(operation.value);
+          }
+          break;
+        default:
+          break;
       }
     }
+  }
 
-    addResults(results) {
-      let resultsArray, resultsElements, resultsHTML, resultType;
-      resultsArray = Object.values(results);
-      resultsArray.sort(function (a, b) {
-        if (a.filename < b.filename) {return -1;}
-        if (a.filename > b.filename) {return 1;}
-        return 0;
-      });
-      resultsHTML = ``;
-      for (let result of resultsArray) {
-        if (result.filename.endsWith(".pdf.zip")) {
-          resultType = "PDF file with text layer";
-        } else if (result.filename.endsWith(".txt.zip")) {
-          resultType = "Raw text files";
-        } else if (result.filename.endsWith(".vrt.zip")) {
-          resultType = "VRT(XML dialect) files holding the NLP data";
-        } else if (result.filename.endsWith(".xml.zip")) {
-          resultType = "XML files";
-        } else if (result.filename.endsWith(".poco.zip")) {
-          resultType = "HCOR und image files needed for Post correction(PoCo)";
-        } else {
-          resultType = "All result files created during this job";
-        }
-        resultsHTML += `
-                        <tr>
-                          <td>${resultType}</td>
-                          <td>${result.filename}</td>
-                          <td class="right-align">
-                            <a class="btn-floating tooltipped waves-effect waves-light"
-                               download href="/jobs/${result.job_id}/results/${result.id}/download"
-                               data-position="top"
-                               data-tooltip="Download">
-                              <i class="material-icons">file_download</i>
-                            </a>
-                          </td>
-                        </tr>
-                       `;
-      };
+  addResults(results) {
+    let resultsArray, resultsElements, resultsHTML, resultType;
+    resultsArray = Object.values(results);
+    resultsArray.sort(function (a, b) {
+      if (a.filename < b.filename) {return -1;}
+      if (a.filename > b.filename) {return 1;}
+      return 0;
+    });
+    resultsHTML = ``;
+    for (let result of resultsArray) {
+      if (result.filename.endsWith(".pdf.zip")) {
+        resultType = "PDF file with text layer";
+      } else if (result.filename.endsWith(".txt.zip")) {
+        resultType = "Raw text files";
+      } else if (result.filename.endsWith(".vrt.zip")) {
+        resultType = "VRT(XML dialect) files holding the NLP data";
+      } else if (result.filename.endsWith(".xml.zip")) {
+        resultType = "XML files";
+      } else if (result.filename.endsWith(".poco.zip")) {
+        resultType = "HCOR und image files needed for Post correction(PoCo)";
+      } else {
+        resultType = "All result files created during this job";
+      }
       resultsHTML += `
-                      </tbody>
-                      </table>
+                      <tr>
+                        <td>${resultType}</td>
+                        <td>${result.filename}</td>
+                        <td class="right-align">
+                          <a class="btn-floating tooltipped waves-effect waves-light"
+                             download href="/jobs/${result.job_id}/results/${result.id}/download"
+                             data-position="top"
+                             data-tooltip="Download">
+                            <i class="material-icons">file_download</i>
+                          </a>
+                        </td>
+                      </tr>
                      `;
-      resultsElements = document.querySelectorAll(".results");
-      for (let resultsElement of resultsElements) {
-        resultsElement.innerHTML += resultsHTML;
-      }
+    };
+    resultsHTML += `
+                    </tbody>
+                    </table>
+                   `;
+    resultsElements = document.querySelectorAll(".results");
+    for (let resultsElement of resultsElements) {
+      resultsElement.innerHTML += resultsHTML;
     }
+  }
 
-    setEndDate(timestamp) {
-      let endDate;
+  setEndDate(timestamp) {
+    let endDate;
 
-      if (timestamp === null) {
-        endDate = "N.a.";
-      } else {
-        endDate = new Date(timestamp * 1000).toLocaleString("en-US");
-      }
-      document.getElementById("end-date").value = endDate;
-      M.updateTextFields();
+    if (timestamp === null) {
+      endDate = "N.a.";
+    } else {
+      endDate = new Date(timestamp * 1000).toLocaleString("en-US");
     }
+    document.getElementById("end-date").value = endDate;
+    M.updateTextFields();
+  }
 
-    setStatus(status) {
-      let progressIndicator, statusElements;
-      if (status === "complete" || status === "failed") {
-        progressIndicator = document.getElementById("progress-indicator");
-        progressIndicator.classList.add("hide");
-      }
-      statusElements = document.querySelectorAll(".status");
-      for (let statusElement of statusElements) {
-        statusElement.dataset.status = status;
-      }
+  setStatus(status) {
+    let progressIndicator, statusElements;
+    if (status === "complete" || status === "failed") {
+      progressIndicator = document.getElementById("progress-indicator");
+      progressIndicator.classList.add("hide");
+    }
+    statusElements = document.querySelectorAll(".status");
+    for (let statusElement of statusElements) {
+      statusElement.dataset.status = status;
     }
   }
+}
 
-  {% if job.creator == current_user %}
-  var informationUpdater = new InformationUpdater({{ job.id }}, false);
-  {% else %}
-  var informationUpdater = new InformationUpdater({{ job.id }}, true);
-  document.addEventListener("DOMContentLoaded", () => {
-    nopaque.socket.emit("foreign_user_data_stream_init", {{ job.user_id }});
-  });
-  {% endif %}
-  let jobInputsList = new RessourceList("inputs", null, "JobInput");
-  document.addEventListener("DOMContentLoaded", () => {
-    jobInputsList._add({{ job_inputs|tojson|safe }});
-  });
+{% if job.creator == current_user %}
+var informationUpdater = new InformationUpdater({{ job.id }}, false);
+{% else %}
+var informationUpdater = new InformationUpdater({{ job.id }}, true);
+document.addEventListener("DOMContentLoaded", () => {
+  nopaque.socket.emit("foreign_user_data_stream_init", {{ job.user_id }});
+});
+{% endif %}
+let jobInputsList = new RessourceList("inputs", null, "JobInput");
+document.addEventListener("DOMContentLoaded", () => {
+  jobInputsList._add({{ job_inputs|tojson|safe }});
+});
 </script>
 {% endblock %}