From 03f66995b023648ebea93ac154b12faaff1dfacc Mon Sep 17 00:00:00 2001
From: Tim Kreuzer <t.kreuzer@fz-juelich.de>
Date: Mon, 3 Feb 2025 09:26:17 +0100
Subject: [PATCH] update frontend

---
 static/images/workshop/login_01.png           |  Bin 0 -> 47768 bytes
 static/images/workshop/partition_01.png       |  Bin 0 -> 63853 bytes
 static/images/workshop/project_01.png         |  Bin 0 -> 22663 bytes
 static/js/home/dropdown-options.js            |  586 -----
 static/js/home/handle-events.js               |  451 ----
 static/js/home/handle-servers.js              |  505 -----
 static/js/home/lab-configs.js                 |  383 ----
 static/js/home/utils.js                       |  280 ---
 static/js/jhapi.js                            |   17 +-
 templates/footer.html                         |   64 +-
 templates/header.html                         |    3 +
 templates/home.html                           |  516 +----
 templates/macros/home.jinja                   |  332 ++-
 templates/macros/svgs.jinja                   |    5 +
 templates/macros/table/config/home.jinja      |  722 +++++++
 templates/macros/table/config/workshop.jinja  |  667 ++++++
 .../table/config/workshop_manager.jinja       |  775 +++++++
 templates/macros/table/content.jinja          |  362 ++++
 templates/macros/table/elements.jinja         |  836 ++++++++
 templates/macros/table/elements_js.jinja      |  646 ++++++
 .../macros/table/helpers/options_js.jinja     |   88 +
 .../macros/table/helpers/systems_js.jinja     |  630 ++++++
 templates/macros/table/table.jinja            |  149 ++
 templates/macros/table/table_js.jinja         | 1884 +++++++++++++++++
 templates/macros/table/variables.jinja        |    5 +
 templates/page.html                           |   40 +-
 templates/spawn_pending.html                  |  312 +--
 templates/spawn_pending_prev.html             |  310 +++
 templates/token.html                          |    1 +
 templates/workshop.html                       |   44 +
 templates/workshop_list.html                  |  239 +++
 templates/workshop_manager.html               |   38 +
 32 files changed, 7685 insertions(+), 3205 deletions(-)
 create mode 100644 static/images/workshop/login_01.png
 create mode 100644 static/images/workshop/partition_01.png
 create mode 100644 static/images/workshop/project_01.png
 delete mode 100644 static/js/home/dropdown-options.js
 delete mode 100644 static/js/home/handle-events.js
 delete mode 100644 static/js/home/handle-servers.js
 delete mode 100644 static/js/home/lab-configs.js
 delete mode 100644 static/js/home/utils.js
 create mode 100644 templates/macros/table/config/home.jinja
 create mode 100644 templates/macros/table/config/workshop.jinja
 create mode 100644 templates/macros/table/config/workshop_manager.jinja
 create mode 100644 templates/macros/table/content.jinja
 create mode 100644 templates/macros/table/elements.jinja
 create mode 100644 templates/macros/table/elements_js.jinja
 create mode 100644 templates/macros/table/helpers/options_js.jinja
 create mode 100644 templates/macros/table/helpers/systems_js.jinja
 create mode 100644 templates/macros/table/table.jinja
 create mode 100644 templates/macros/table/table_js.jinja
 create mode 100644 templates/macros/table/variables.jinja
 create mode 100644 templates/spawn_pending_prev.html
 create mode 100644 templates/workshop.html
 create mode 100644 templates/workshop_list.html
 create mode 100644 templates/workshop_manager.html

diff --git a/static/images/workshop/login_01.png b/static/images/workshop/login_01.png
new file mode 100644
index 0000000000000000000000000000000000000000..77452370e8ce430fd2170911d4f59b32263ca695
GIT binary patch
literal 47768
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%0Dxja#M}1y6hrjds~-E
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
XH<RcE^BWi#7#KWV{an^LB{Ts52u>T}

literal 0
HcmV?d00001

diff --git a/static/images/workshop/partition_01.png b/static/images/workshop/partition_01.png
new file mode 100644
index 0000000000000000000000000000000000000000..73385950db63ade4573a2bfc334462f28606fc95
GIT binary patch
literal 63853
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

literal 0
HcmV?d00001

diff --git a/static/images/workshop/project_01.png b/static/images/workshop/project_01.png
new file mode 100644
index 0000000000000000000000000000000000000000..1cb770ae5b6f90ca54024eb608f56c3d602fe69d
GIT binary patch
literal 22663
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

literal 0
HcmV?d00001

diff --git a/static/js/home/dropdown-options.js b/static/js/home/dropdown-options.js
deleted file mode 100644
index eb50a40..0000000
--- a/static/js/home/dropdown-options.js
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
-* This module takes care of updating the user options, which are received from the backend and shown on the UI
-*/
-define(["jquery", "home/utils"], function (
-  $,
-  utils
-) {
-  "use strict";
-
-  var updateServices = function (software, id, value=false) {
-    const serviceInfo = getServiceInfo();
-
-    let select = $(`select#${id}-version-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-
-    const options = (serviceInfo[software].options || {});
-    for (const [serviceName, serviceInfo] of Object.entries(options)) {
-      var displayName = serviceInfo.name;
-      select.append(`<option value="${serviceName}">${displayName}</option>`);
-    }
-    if (!value) value = serviceInfo.JupyterLab.defaultOption;
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updateServicesPrev = function (id, value) {
-    const dropdownOptions = getDropdownOptions();
-    const serviceInfo = getServiceInfo();
-
-    let select = $(`select#${id}-version-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-    var valueName = (serviceInfo.JupyterLab.options[value] || {}).name || "new-jupyterlab";
-    for (const service of Object.keys(dropdownOptions).sort().reverse()) {
-      var serviceName = (serviceInfo.JupyterLab.options[service] || {}).name || service;
-      if ( valueName.includes("deprecated") || ! serviceName.includes("deprecated")) {
-        select.append(`<option value="${service}">${serviceName}</option>`);
-      }
-    }
-    if (!value) value = serviceInfo.JupyterLab.defaultOption;
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updateSystems = function (id, service, value) {
-    const dropdownOptions = getDropdownOptions();
-    const systemInfo = getSystemInfo();
-
-    let select = $(`select#${id}-system-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-
-    const systemsAllowed = dropdownOptions[service] || {};
-    for (const system of Object.keys(systemInfo).sort((a, b) => (systemInfo[a]["weight"] || 99) < (systemInfo[b]["weight"] || 99) ? -1 : 1)) {
-      if (system in systemsAllowed) select.append(`<option value="${system}">${system}</option>`);
-    }
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updateFlavors = function (id, service, system, value) {
-    const systemInfo = getSystemInfo();
-    const backendInfo = getBackendServiceInfo();
-
-    let select = $(`select#${id}-flavor-select`);
-    const currentVal = select.val();
-
-    resetInputElement(select);
-    if ($(`#${id}-na-info`).length && $(`#${id}-na-info`).html().includes("flavor")) {
-      $(`#${id}-na-btn`).hide();
-      $(`#${id}-na-info`).empty().hide();
-      if (!window.spawnActive[id])
-        $(`#${id}-start-btn`).removeClass("disabled").show();
-    }
-
-    let systemFlavors = window.flavorInfo[system];
-    if (!systemFlavors) {
-      // Check if system should have flavor info but doesn't first
-      let backend = (systemInfo[system] || {}).backendService;
-      if (backend && (backendInfo[backend].flavorsRequired || backendInfo[backend].userflavors)) {
-        // If so, we still want to create the flavor info to show the error message
-        utils.createFlavorInfo(id, system);
-        utils.setLabAsNA(id, "due to flavor");
-        $(`#${id}-flavor-select-div, #${id}-flavor-legend-div, #${id}-flavor-info-div`).show();
-      }
-      else {
-        // Otherwise, we can just skip showing the flavor info entirely
-        $(`#${id}-flavor-select-div, #${id}-flavor-legend-div, #${id}-flavor-info-div`).hide();
-      }
-      updateLabConfigSelect(select, value, currentVal);
-      return;
-    };
-
-    // Sort systemFlavors by flavor weights
-    for (const [flavor, description] of Object.entries(systemFlavors).sort(([, a], [, b]) => (a["weight"] || 99) < (b["weight"] || 99) ? 1 : -1)) {
-      // Flavor not valid, so skip
-      if (description.max == 0 || description.current < 0 || description.max == null || description.current == null) continue;
-      if (description.max == -1 || description.current < description.max)
-        select.append(`<option value="${flavor}">${description.display_name}</option>`);
-    }
-    utils.createFlavorInfo(id, system);
-    enableTooltips();  // Defined in page.html
-    $.isEmptyObject(systemFlavors) ? $(`#${id}-flavor-select-div, #${id}-flavor-legend-div, #${id}-flavor-info-div`).hide() : $(`#${id}-flavor-select-div, #${id}-flavor-legend-div, #${id}-flavor-info-div`).show();
-
-    if (select.html() == "") {
-      if (window.spawnActive[id]) {
-        // Lab is active, so we should still append the current flavor to the select
-        const flavor = window.userOptions[id].flavor;
-        const description = (systemFlavors[system] || {})[flavor] || {};
-        if (flavor) {
-          select.append(`<option disabled value="${flavor}">${description.display_name || flavor}</option>`);
-        }
-      }
-      else {
-        // Show info text and disable start
-        select.append(`<option disabled value="">No flavors currently available</option>`);
-        utils.setLabAsNA(id, "due to flavor limits");
-      }
-
-      select.addClass("disabled");
-      select.prop("selectedIndex", 0);
-    }
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updateAccounts = function (id, service, system, value) {
-    const dropdownOptions = getDropdownOptions();
-
-    let select = $(`select#${id}-account-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-
-    const accountsAllowed = (dropdownOptions[service] || {})[system] || {};
-    for (const account of Object.keys(accountsAllowed).sort()) {
-      select.append(`<option value="${account}">${account}</option>`);
-    }
-    $.isEmptyObject(accountsAllowed) ? $(`#${id}-account-select-div`).hide() : $(`#${id}-account-select-div`).show();
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updateProjects = function (id, service, system, account, value) {
-    const dropdownOptions = getDropdownOptions();
-
-    let select = $(`select#${id}-project-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-
-    const projectsAllowed = ((dropdownOptions[service] || {})[system] || {})[account] || {};
-    for (const project of Object.keys(projectsAllowed).sort()) {
-      select.append(`<option value="${project}">${project}</option>`);
-    }
-    $.isEmptyObject(projectsAllowed) ? $(`#${id}-project-select-div`).hide() : $(`#${id}-project-select-div`).show();
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updatePartitions = function (id, service, system, account, project, value) {
-    const dropdownOptions = getDropdownOptions();
-    const systemInfo = getSystemInfo();
-
-    let select = $(`select#${id}-partition-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-    // Distinguish between login and compute nodes
-    var loginNodes = [];
-    var computeNodes = [];
-    const partitionsAllowed = (((dropdownOptions[service] || {})[system] || {})[account] || {})[project] || {};
-    const interactivePartitions = (systemInfo[system] || {}).interactivePartitions || [];
-    for (const partition of Object.keys(partitionsAllowed).sort()) {
-      if (interactivePartitions.includes(partition)) loginNodes.push(partition);
-      else computeNodes.push(partition);
-    }
-    // Append options to select in groups
-    if (loginNodes.length > 0) {
-      select.append('<optgroup label="Login Nodes">');
-      loginNodes.forEach((x) => select.append(`<option value="${x}">${x}</option>`))
-      select.append('</optgroup>');
-    }
-    if (computeNodes.length > 0) {
-      select.append('<optgroup label="Compute Nodes">');
-      const systemUpper = system.replace('-', '').toUpperCase();
-      if ((window.systemsHealth[systemUpper] || 0) >= (window.systemsHealth.threshold.compute || 40)) {
-        computeNodes.forEach((x) => select.append(`<option value="${x}" disabled>${x} (in maintenance)</option>`));
-      }
-      else {
-        computeNodes.forEach((x) => select.append(`<option value="${x}">${x}</option>`));
-      }
-      select.append('</optgroup>');
-    }
-    $.isEmptyObject(partitionsAllowed) ? $(`#${id}-partition-select-div`).hide() : $(`#${id}-partition-select-div`).show();
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updateReservations = function (id, service, system, account, project, partition, value) {
-
-    function _toggle_show_reservation(show) {
-      if (show) {
-        $(`#${id}-reservation-select-div`).show();
-        $(`#${id}-reservation-hr`).show();
-      }
-      else {
-        $(`#${id}-reservation-select-div`).hide();
-        $(`#${id}-reservation-hr`).hide();
-      }
-    }
-
-    const dropdownOptions = getDropdownOptions();
-    const reservationInfo = getReservationInfo();
-    const systemInfo = getSystemInfo();
-
-    let select = $(`select#${id}-reservation-select`);
-    const currentVal = select.val();
-    resetInputElement(select, false);
-
-    const interactivePartitions = (systemInfo[system] || {}).interactivePartitions || [];
-    if (interactivePartitions.includes(partition)){
-      _toggle_show_reservation(false);
-      updateLabConfigSelect(select, value, currentVal);
-      return;
-    }
-
-    const reservationsAllowed = ((((dropdownOptions[service] || {})[system] || {})[account] || {})[project] || {})[partition] || {};
-    if (reservationsAllowed.length > 0 && JSON.stringify(reservationsAllowed) !== JSON.stringify(["None"])) {
-      for (const reservation of reservationsAllowed) {
-        if (reservation == "None") select.append(`<option value="${reservation}">${reservation}</option>`);
-        else {
-          const reservationName = reservation.ReservationName;
-          const systemReservationInfo = reservationInfo[system] || {};
-          for (const reservationInfo of systemReservationInfo) {
-            if (reservationInfo.ReservationName == reservationName) {
-              if (reservationInfo.State == "ACTIVE") select.append(`<option value="${reservationName}">${reservationName}</option>`);
-              else select.append(`<option value="${reservationName}" disabled style="color: #6c757d;">${reservationName} [INACTIVE]</option>`);
-            }
-          }
-        }
-      }
-      select.attr("required", true);
-      _toggle_show_reservation(true);
-    }
-    else {
-      _toggle_show_reservation(false);
-    }
-    updateLabConfigSelect(select, value, currentVal);
-  }
-
-  var updateResources = function (id, service, system, account, project, partition, nodes, gpus, runtime, xserver) {
-    const resourceInfo = getResourceInfo();
-    let nodesInput = $(`input#${id}-nodes-input`);
-    let gpusInput = $(`input#${id}-gpus-input`);
-    let runtimeInput = $(`input#${id}-runtime-input`);
-    let xserverCheckboxInput = $(`input#${id}-xserver-cb-input`);
-    let xserverInput = $(`input#${id}-xserver-input`);
-    let tabWarning = $(`#${id}-resources-tab-warning`);
-    const currentNodeVal = nodesInput.val();
-    const currentGpusVal = gpusInput.val();
-    const currentRuntimeVal = runtimeInput.val();
-    const currentXserverCbVal = xserverCheckboxInput[0].checked;
-    const currentXserverVal = xserverInput.val();
-    [nodesInput, gpusInput, runtimeInput, xserverInput].forEach(input => resetInputElement(input, false));
-    xserverCheckboxInput[0].checked = false;
-
-    $(`#${id}-resources-tab`).show();
-    const systemResources = (resourceInfo[service] || {})[system] || {};
-    if ($.isEmptyObject(systemResources)) {
-      $(`#${id}-resources-tab`).addClass("disabled");
-      $(`#${id}-resources-tab`).hide();
-      tabWarning.addClass("invisible");
-    }
-    else {
-      const partitionResources = systemResources[partition];
-      if ($.isEmptyObject(partitionResources)) {
-        $(`#${id}-resources-tab`).addClass("disabled");
-        $(`#${id}-resources-tab`).hide();
-        tabWarning.addClass("invisible");
-      }
-      else {
-        $(`#${id}-resources-tab`).removeClass("disabled");
-        $(`#${id}-resources-tab`).show();
-        if ("nodes" in partitionResources) {
-          let min = (partitionResources.nodes.minmax || [0, 1])[0];
-          let max = (partitionResources.nodes.minmax || [0, 1])[1];
-          $(`label[for*=${id}-nodes-input]`).text("Nodes [" + min + "," + max + "]");
-          let defaultNodes = partitionResources.nodes.default || 0;
-          updateLabConfigInput(nodesInput, nodes, currentNodeVal, min, max, defaultNodes);
-          $(`#${id}-nodes-input-div`).show();
-          if (!currentNodeVal) tabWarning.removeClass("invisible");
-        }
-        else {
-          $(`#${id}-nodes-input-div`).hide();
-          if (currentNodeVal) tabWarning.removeClass("invisible");
-        }
-
-        if ("gpus" in partitionResources) {
-          let min = (partitionResources.gpus.minmax || [0, 1])[0];
-          let max = (partitionResources.gpus.minmax || [0, 1])[1];
-          $(`label[for*=${id}-gpus-input]`).text("GPUs [" + min + "," + max + "]");
-          let defaultGpus = partitionResources.gpus.default || 0;
-          updateLabConfigInput(gpusInput, gpus, currentGpusVal, min, max, defaultGpus);
-          $(`#${id}-gpus-input-div`).show();
-          if (!currentGpusVal) tabWarning.removeClass("invisible");
-        }
-        else {
-          $(`#${id}-gpus-input-div`).hide();
-          if (currentGpusVal) tabWarning.removeClass("invisible");
-        }
-
-        if ("runtime" in partitionResources) {
-          let min = (partitionResources.runtime.minmax || [0, 1])[0];
-          let max = (partitionResources.runtime.minmax || [0, 1])[1];
-          $(`label[for*=${id}-runtime-input]`).text("Runtime (minutes) [" + min + "," + max + "]");
-          let defaultRuntime = partitionResources.runtime.default || 0;
-          updateLabConfigInput(runtimeInput, runtime, currentRuntimeVal, min, max, defaultRuntime);
-          $(`#${id}-runtime-input-div`).show();
-          if (!currentRuntimeVal) tabWarning.removeClass("invisible");
-        }
-        else {
-          $(`#${id}-runtime-input-div`).hide();
-          if (currentRuntimeVal) tabWarning.removeClass("invisible");
-        }
-
-        if ("xserver" in partitionResources) {
-          let cblabel = partitionResources.xserver.cblabel || "Activate XServer";
-          $(`label[for*=${id}-xserver-cb-input]`).text(cblabel);
-          var min = (partitionResources.xserver.minmax || [0, 1])[0];
-          var max = (partitionResources.xserver.minmax || [0, 1])[1];
-          let label = partitionResources.xserver.label || "Use XServer GPU Index";
-          $(`label[for*=${id}-xserver-input]`).text(label + " [" + min + "," + max + "]");
-
-          if (xserver) { xserverCheckboxInput[0].checked = true; }
-          else {
-            xserver = partitionResources.xserver.default || 0;
-            if (!currentXserverVal) tabWarning.removeClass("invisible");
-            // Determine if XServer checkbox should be shown
-            if (partitionResources.xserver.checkbox || false) {
-              $(`#${id}-xserver-cb-input-div`).show();
-              if (currentXserverCbVal) xserverCheckboxInput[0].checked = true;
-              else {
-                if (partitionResources.xserver.default_checkbox || false)
-                  xserverCheckboxInput[0].checked = true;
-                else xserverCheckboxInput[0].checked = false;
-              }
-              if (!currentXserverCbVal && xserverCheckboxInput[0].checked) tabWarning.removeClass("invisible");
-            }
-            else {
-              $(`#${id}-xserver-cb-input-div`).hide();
-              xserverCheckboxInput[0].checked = true;
-              if (!currentXserverCbVal) tabWarning.removeClass("invisible");
-            }
-          }
-          updateLabConfigInput(xserverInput, xserver, currentXserverVal, min, max, min, false);
-          if (xserverCheckboxInput[0].checked) $(`#${id}-xserver-input-div`).show();
-          else $(`#${id}-xserver-input-div`).hide();
-        }
-        else {
-          $(`#${id}-xserver-cb-input-div`).hide();
-          $(`#${id}-xserver-input-div`).hide();
-          if (currentXserverCbVal || currentXserverVal) tabWarning.removeClass("invisible");
-        }
-      }
-    }
-  }
-
-  var updateModules = function updateModules(id, service, system, account, project, partition, values) {
-    const moduleInfo = getModuleInfo();
-    const systemInfo = getSystemInfo();
-    const interactivePartitions = (systemInfo[system] || {}).interactivePartitions || [];
-
-    var tabWarning = $(`#${id}-modules-tab-warning`);
-    var currentOptions = [];
-    $(`#${id}-modules-form`).find(`input[type=checkbox]`).each(function () {
-      currentOptions.push($(this).val());
-    })
-
-    var defaultOptions = [];
-    var enableModulesTab = false;
-
-    for (const [moduleSet, modules] of Object.entries(moduleInfo)) {
-      $(`#${id}-${moduleSet}-div`).hide();
-      var insertIndex = -1;
-      for (const [module, moduleInfo] of Object.entries(modules)) {
-        if (moduleInfo.sets.includes(service)) {
-          if (moduleInfo.allowed_systems && !moduleInfo.allowed_systems.includes(system)) {
-            // Module not in allowed systems, so do nothing.
-          }
-          else {
-            if (moduleInfo.compute_only && interactivePartitions.includes(partition)) {
-              // Module is compute only, but partition is interactive, so do nothing.
-            }
-            else if (moduleInfo.interactive_only && !interactivePartitions.includes(partition)) {
-              // Module is interactive only, but partition is compute, so do nothing.
-            }
-            else {
-              $(`#${id}-${moduleSet}-div`).show();
-              enableModulesTab = true;
-              defaultOptions.push(module);
-              // If checkbox already exists, do nothing
-              // Else create it and set the default value
-              if (!currentOptions.includes(module)) {
-                let parent = $(`#${id}-${moduleSet}-checkboxes-div`);
-                var checked = "";
-                if (typeof moduleInfo.default == "boolean") {
-                  var checked = moduleInfo.default ? "checked" : "";
-                } else if ( typeof moduleInfo.default == "object" && service in moduleInfo.default ) {
-                  var checked = ( moduleInfo.default[service] || false) ? "checked" : "";
-                } else if ( typeof moduleInfo.default == "object" && "default" in moduleInfo.default ) {
-                  var checked = moduleInfo.default.default ? "checked" : "";
-                } else {
-                  var checked = "";
-                }
-                // let checked = moduleInfo.default ? "checked" : "";
-                let module_cols = "col-sm-6 col-md-4 col-lg-3";
-                let cbHtml = `
-                  <div id="${id}-${module}-cb-div" class="form-check ${module_cols}">
-                    <input type="checkbox" class="form-check-input" id="${id}-${module}-check" value="${module}" ${checked}>
-                      <label class="form-check-label" for="${id}-${module}-check">
-                        <span class="align-middle">${moduleInfo.displayName}</span>
-                        <a href="${moduleInfo.href}" target="_blank" class="module-info text-muted ms-3">
-                          <span>${getInfoSvg()}</span>
-                            <div class="module-info-link-div d-inline-block">
-                              <span class="module-info-link" id="${module}-info-link">
-                                ${getLinkSvg()}
-                              </span>
-                            </div>
-                        </a>
-                      </label>
-                    </input>
-                  </div>
-                `
-                // No checkboxes exist yet, so we can simply append to the parent div
-                if (parent.children().length == 0) {
-                  parent.append(cbHtml);
-                }
-                // Otherwise, we need to determine where to insert the new checkbox
-                else {
-                  // Get the current element at index
-                  var target = parent.children().eq(insertIndex);
-                  target.before(cbHtml);
-                }
-                // Show tab warning to indicate changes in checkbox options
-                tabWarning.removeClass("invisible");
-              }
-              insertIndex++;
-            }
-          }
-        }
-      }
-    }
-    // Remove checkboxes which still exist but should not anymore
-    var shouldRemove = currentOptions.filter(x => !defaultOptions.includes(x));
-    for (const module of shouldRemove) {
-      $(`#${id}-${module}-cb-div`).remove();
-      // Show tab warning to indicate changes in checkbox options
-      tabWarning.removeClass("invisible");
-    }
-
-    // Set values according to previous values.
-    if (values) {
-      // Loop through all checkboxes and only check those in values.
-      $(`#${id}-modules`).find("input[type=checkbox]").each((i, cb) => {
-        if (values.includes(cb.value)) cb.checked = true;
-        else cb.checked = false;
-      })
-    }
-
-    if (enableModulesTab) {
-      $(`#${id}-modules-tab`).removeClass("disabled");
-      $(`#${id}-modules-tab`).show();
-    }
-    else {
-      $(`#${id}-modules-tab`).addClass("disabled");
-      $(`#${id}-modules-tab`).hide();
-      tabWarning.addClass("invisible");
-    }
-  }
-
-  /*
-  Util functions
-  */
-  var resetInputElement = function (element, required = true) {
-    element.html("");
-    element.val(null);
-    element.removeClass("text-muted disabled");
-    if (required) {
-      if(! element.hasClass("optional")){
-        element.attr("required", required);
-      }
-    } else {
-      element.removeAttr("required");
-    }
-  }
-
-  var updateLabConfigSelect = function (select, value, lastSelected) {
-  }
-
-  var updateLabConfigSelect2 = function (select, value, lastSelected) {
-    // For some systems, e.g. cloud, some options are not available
-    if (select.html() == "") {
-      select.append("<option disabled>Not available</option>");
-      select.addClass("text-muted").removeAttr("required");
-    }
-    // If there is only one option, we disable the dropdown
-    const numberOfOptions = select.children().length
-    if (numberOfOptions == 1) {
-      select.addClass("disabled");
-    }
-    if (value) select.val(value);
-    else {
-      // Check if the last value is contained in the new options,
-      // otherwise just select the first value.
-      var index = 0;
-      select.children().each(function (i, option) {
-        if ($(option).val() == lastSelected) {
-          index = i;
-          /* Although index should be used to set the value and
-            avoid the (index == 0) query, indices don't work directly
-            when there are optiongroups in the select. So we set
-            it via the .val() function regardless. */
-          select.val(lastSelected);
-          return;
-        }
-      })
-      if (index == 0) select.prop("selectedIndex", index);
-    }
-    select[0].dispatchEvent(new Event("change"));
-  }
-
-  var updateLabConfigInput = function (input, value, lastSelected, min, max, defaultValue, required = true) {
-    input.attr({ "min": min, "max": max });
-    if (required) input.attr("required", required);
-    else input.removeAttr("required");
-    // Set message for invalid feedback
-    input.siblings(".invalid-feedback")
-      .text(`Please choose a number between ${min} and ${max}.`);
-    if (value) {
-      input.val(value);
-    }
-    // Check if we can keep the old value
-    else if (lastSelected != "" && lastSelected >= min && lastSelected <= max) {
-      input.val(lastSelected);
-    }
-    else {
-      input.val(defaultValue);
-    }
-  }
-
-  var updateR2dType = function (id, r2dType) {
-    // const dropdownOptions = getDropdownOptions();
-    const repos = getBinderRepos().repos || [];
-
-    let select = $(`select#${id}-type-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-
-    repos.forEach((repo) => select.append(`<option value="${repo}">${repo}</option>`));
-
-    updateLabConfigSelect(select, r2dType, currentVal);
-  }
-
-  var updateR2dNotebookTypes = function(id, r2dNotebookType){
-    const notebookTypes = getBinderRepos().notebookTypes || [];
-
-    let select = $(`select#${id}-notebook_type-select`);
-    const currentVal = select.val();
-    resetInputElement(select);
-
-    notebookTypes.forEach((nbType) => select.append(`<option value="${nbType}">${nbType}</option>`))
-    updateLabConfigSelect(select, r2dNotebookType, currentVal);
-  }
-
-  var updateDropdowns = {
-    updateServices: updateServices,
-    updateSystems: updateSystems,
-    updateFlavors: updateFlavors,
-    updateAccounts: updateAccounts,
-    updateProjects: updateProjects,
-    updatePartitions: updatePartitions,
-    updateReservations: updateReservations,
-    updateResources: updateResources,
-    updateModules: updateModules,
-    updateR2dType: updateR2dType,
-    updateR2dNotebookTypes: updateR2dNotebookTypes,
-    resetInputElement: resetInputElement,
-    updateLabConfigSelect: updateLabConfigSelect,
-    updateLabConfigInput: updateLabConfigInput,
-  }
-
-  return updateDropdowns;
-
-})
diff --git a/static/js/home/handle-events.js b/static/js/home/handle-events.js
deleted file mode 100644
index 5376b14..0000000
--- a/static/js/home/handle-events.js
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
-* Callbacks related to interacting with table rows
-*/
-require(["jquery", "home/utils", "home/dropdown-options"], function (
-  $,
-  utils,
-  dropdowns
-) {
-  "use strict";
-
-  /* *************** */
-  /* TABLE UI EVENTS */
-  /* *************** */
-
-  // Toggle a labs corresponding collapsible table row 
-  // when it's summary table row is clicked.
-  $(".summary-tr").on("click", function () {
-    let id = $(this).data("server-id");
-    let accordionIcon = $(this).find(".accordion-icon");
-    let collapse = $(`.collapse[id*=${id}]`);
-    let shown = collapse.hasClass("show");
-    if (shown) accordionIcon.addClass("collapsed");
-    else accordionIcon.removeClass("collapsed");
-    new bootstrap.Collapse(collapse);
-  });
-
-  // ... but not when the action td button are clicked.
-  $(".actions-td button").on("click", function (event) {
-    event.preventDefault();
-    event.stopPropagation();
-  });
-
-  // We show warning icons when the content of tabs change.
-  // Hide those warning icons once the tab is activated.
-  $("button[role=tab]").on("click", function () {
-    let warning = $(this).find("[id$=tab-warning]");
-    warning.addClass("invisible");
-  });
-
-  // Toggle log tabs on log button or log info text click
-  $(".log-info-btn, .log-info-text").on("click", function (event) {
-    let id = $(this).parents("tr").data("server-id");
-    let collapse = $(`.collapse[id*=${id}]`);
-    let shown = collapse.hasClass("show");
-    // Prevent collapse from closing if it is  
-    // already open, but not showing the logs tab.
-    if (shown && !$(`#${id}-logs-tab`).hasClass("active")) {
-      event.preventDefault();
-      event.stopPropagation();
-    }
-    // Change to the log tab.
-    var trigger = $(`#${id}-logs-tab`);
-    var tab = new bootstrap.Tab(trigger);
-    tab.show();
-  });
-
-  // Show selected logs.
-  $("select[id*=log-select]").change(function () {
-    const id = utils.getId(this);
-    const val = $(this).val();
-    var log = $(`#${id}-log`);
-    log.html("");
-    for (const event of spawnEvents[id][val]) {
-      utils.appendToLog(log, event["html_message"]);
-    }
-  });
-
-  $("button[id*=view-password]").on("click", function (event) {
-    const id = utils.getId(this);
-    const passInput = $(`#${id}-image-private-pass-input`)[0]
-    const eye = $(`#${id}-password-eye`)[0]
-    if (passInput.type === 'password') {
-      passInput.type = 'text';
-      eye.classList.remove('fa-eye');
-      eye.classList.add('fa-eye-slash');
-    } else {
-      passInput.type = 'password';
-      eye.classList.add('fa-eye');
-      eye.classList.remove('fa-eye-slash');
-    }
-  });
-
-  /* *************** */
-  /* LAB CONFIG      */
-  /* *************** */
-
-  function _toggle_show_element(id, key, type, showInput, pattern) {
-    let element = $(`#${id}-${key}-${type}`);
-    if (showInput) {
-      $(`#${id}-${key}-${type}-div`).show();
-      if(element.hasClass("optional")){
-        element.removeAttr("required");
-      }
-      else element.attr("required", true);
-      if (pattern) element.attr("pattern", pattern);
-    } else {
-      $(`#${id}-${key}-${type}-div`).hide();
-      element.removeAttr("required pattern");
-    }
-  }
-
-  function _toggle_show_repo2Docker(id){
-    var repo2DockerInputs = ["repo", "gitref", "notebook"];
-    var repo2DockerSelects = ["type", "notebook_type"]
-
-    var values = utils.getLabConfigSelectValues(id);
-    const show = (values.service || "") == "repo2docker";
-
-    for(let key of repo2DockerInputs){
-      let element = $(`#${id}-${key}-input`);
-      dropdowns.resetInputElement(element);
-      _toggle_show_element(id, key, "input", show);
-    }
-    repo2DockerSelects.forEach(key => _toggle_show_element(id, key, "select", show));
-
-    if (show) {
-      dropdowns.updateR2dType(id, null);
-      dropdowns.updateR2dNotebookTypes(id, null);
-    }
-  }
-
-  function _toggle_show_customImage(id, userInputInfo){
-    var customDockerInputs = ["image"]
-    var customDockerInputsMounts = ["image-mount"]
-    var customDockerInputsPrivate = ["image-private-url", "image-private-user", "image-private-pass"]
-    var registryAuthsInputDivs = $(`#${id}-image-private-url-input-div,#${id}-image-private-user-input-div, #${id}-image-private-pass-input-div`)
-    var allUserInputDivs = $(`#${id}-image-input-div, #${id}-image-private-cb-input-div, #${id}-image-mount-cb-input-div, #${id}-image-mount-input-div`)
-
-    var values = utils.getLabConfigSelectValues(id);
-    const show = (values.service || "") == "custom";
-
-    for(let key of customDockerInputs){
-      let element = $(`#${id}-${key}-input`);
-      dropdowns.resetInputElement(element, show);
-      _toggle_show_element(id, key, "input", show);
-    }
-
-    // set default values for mount userdata
-    var mount_cb_checked = userInputInfo.defaultMountEnabled || true;
-
-    if (mount_cb_checked) {
-      for(let key of customDockerInputsMounts){
-        let element = $(`#${id}-${key}-input`);
-        dropdowns.resetInputElement(element, show && mount_cb_checked);
-        _toggle_show_element(id, key, "input", show && mount_cb_checked);
-      }
-    }
-
-    for(let key of customDockerInputsPrivate){
-      let element = $(`#${id}-${key}-input`);
-      dropdowns.resetInputElement(element, false);
-      _toggle_show_element(id, key, "input", false);
-    }
-
-    if (show) {
-      $(`#${id}-image-mount-cb-input`)[0].checked = mount_cb_checked;
-      $(`#${id}-image-mount-input`).val(userInputInfo.defaultMountPath || "/mnt/userdata");
-      allUserInputDivs.show();
-    } else {
-      registryAuthsInputDivs.hide();
-      allUserInputDivs.hide();
-    }
-  }
-
-  function _toggle_show_share_button(id, values, force_hide=false, force_show=false){
-    const shareInfo = getShareInfo();
-    const software = "JupyterLab";
-    const service = values.service || "";
-    const system = values.system || "";
-    if ( force_show || ( (! force_hide) && ( shareInfo[software] ) && ( (shareInfo[software][service] || []).includes(system) ) ) ) {
-      $(`#${id}-share-btn`).show();
-    } else {
-      $(`#${id}-share-btn`).hide();
-    }
-  }
-
-  $("select[id*=verfffsion]").change(function () {
-    const id = utils.getId(this);
-    const values = utils.getLabConfigSelectValues(id);
-    if (!$(this).hasClass("no-update")) {
-      try {
-        dropdowns.updateSystems(id, values.service);
-      }
-      catch (e) {
-        utils.setLabAsNA(id, "due to a JS error");
-        console.log(e);
-      }
-    }
-
-    const serviceInfo = getServiceInfo();
-    const userInputInfo = (serviceInfo.JupyterLab.options[values.service] || {}).userInput || {};
-    _toggle_show_customImage(id, userInputInfo);
-    _toggle_show_repo2Docker(id);
-  });
-
-  $("select[id*=type]").change(function () {
-    const id = utils.getId(this);
-    const values = utils.getLabConfigSelectValues(id);
-    if (!$(this).hasClass("no-update")) {
-      try {
-        dropdowns.updateSystems(id, values.service);
-      }
-      catch (e) {
-        utils.setLabAsNA(id, "due to a JS error");
-        console.log(e);
-      }
-    }
-
-    if ( ["GitHub"].includes(values.r2dtype) ){
-      let label = $(`label[for="${id}-repo-input"]`);
-      let input = $(`#${id}-repo-input`);
-      label.text("GitHub repository name or URL");
-      input.attr("placeholder", "GitHub repository name or URL");
-    }
-  });
-
-  $("select[id*=notebook_type]").change(function () {
-    const id = utils.getId(this);
-    const values = utils.getLabConfigSelectValues(id);
-    if (!$(this).hasClass("no-update")) {
-      try {
-        dropdowns.updateSystems(id, values.service);
-      }
-      catch (e) {
-        utils.setLabAsNA(id, "due to a JS error");
-        console.log(e);
-      }
-    }
-
-    if ( ["GitHub"].includes(values.r2dtype) ){
-      let label = $(`label[for="${id}-notebook-input"]`);
-      let input = $(`#${id}-notebook-input`);
-      if ( values.r2dnotebooktype == "File") {
-        label.text("Path to a notebook file (optional)");
-        input.attr("placeholder", "Path to a notebook file (optional)");
-      } else {
-        label.text("URL to open (optional)");
-        input.attr("placeholder", "URL to open (optional)");
-      }
-    }
-  });
-
-  $("input[id*=image-private-cb-input]").change(function () {
-    const id = utils.getId(this, -4);
-    const values = utils.getLabConfigSelectValues(id);
-    const showInput = this.checked;
-    _toggle_show_element(id, "image-private-url", "input", showInput);
-    _toggle_show_element(id, "image-private-user", "input", showInput);
-    _toggle_show_element(id, "image-private-pass", "input", showInput);
-
-    // If private registry is used, we disable the share button
-    _toggle_show_share_button(id, values, showInput);
-  });
-
-  $("input[id*=image-mount-cb-input]").change(function () {
-    const id = utils.getId(this, -4);
-    const pattern_check = "^\\/[A-Za-z0-9\\-\\/]+";
-    _toggle_show_element(id, "image-mount", "input", this.checked, pattern_check);
-  });
-
-  $("select[id*=system]").change(function () {
-    const id = utils.getId(this);
-    const values = utils.getLabConfigSelectValues(id);
-    if (!$(this).hasClass("no-update")) {
-      try {
-        dropdowns.updateFlavors(id, values.service, values.system);
-        dropdowns.updateAccounts(id, values.service, values.system);
-      }
-      catch (e) {
-        utils.setLabAsNA(id, "due to a JS error");
-        console.log(e);
-      }
-    }
-
-    // Check if the chosen version is deprecated for the system
-    const serviceInfo = getServiceInfo();
-    const systemInfo = getSystemInfo();
-    // First check for system specific default option, then for general one
-    var defaultOption = (((systemInfo[values.system] || {}).services || {}).JupyterLab || {}).defaultOption || serviceInfo.JupyterLab.defaultOption;
-    if (defaultOption && values.service != defaultOption) {
-      // Not using default/latest version, show a warning message
-      let reason = "<span style=\"color:darkorange;\">uses deprecated version</span>";
-      $(`#${id}-spawner-info`).show().html(reason);
-    }
-    else {
-      $(`#${id}-spawner-info`).hide().html("");
-    }
-    _toggle_show_share_button(id, values);
-  });
-
-  $("select[id*=account]").change(function () {
-    const id = utils.getId(this);
-    const values = utils.getLabConfigSelectValues(id);
-    if (!$(this).hasClass("no-update")) {
-      try {
-        dropdowns.updateProjects(id, values.service, values.system, values.account);
-      }
-      catch (e) {
-        utils.setLabAsNA(id, "due to a JS error");
-        console.log(e);
-      }
-    }
-  });
-
-  $("select[id*=project]").change(function () {
-    const id = utils.getId(this);
-    const values = utils.getLabConfigSelectValues(id);
-    if (!$(this).hasClass("no-update")) {
-      try {
-        dropdowns.updatePartitions(id, values.service, values.system, values.account, values.project);
-      }
-      catch (e) {
-        utils.setLabAsNA(id, "due to a JS error");
-        console.log(e);
-      }
-    }
-  });
-
-  $("select[id*=partition]").change(function () {
-    const id = utils.getId(this);
-    const values = utils.getLabConfigSelectValues(id);
-    if (!$(this).hasClass("no-update")) {
-      try {
-        dropdowns.updateReservations(id, values.service, values.system, values.account, values.project, values.partition);
-        dropdowns.updateResources(id, values.service, values.system, values.account, values.project, values.partition);
-        dropdowns.updateModules(id, values.service, values.system, values.account, values.project, values.partition);
-      }
-      catch (e) {
-        utils.setLabAsNA(id, "due to a JS error");
-        console.log(e);
-      }
-    }
-  });
-
-  $("input[id*=xserver-cb-input]").change(function () {
-    const id = utils.getId(this, -3);
-    _toggle_show_element(id, "xserver", "input", this.checked);
-  });
-
-  $("select[id*=reservation]").change(function () {
-    const reservationInfo = getReservationInfo();
-
-    const id = utils.getId(this);
-    const value = $(this).val();
-    if (value) {
-      if (value == "None") {
-        $(`#${id}-reservation-info-div`).hide();
-        $(`#${id}-runtime-input`).trigger("change");
-        // }
-        return;
-      }
-      const systemReservationInfo = reservationInfo[utils.getLabConfigSelectValues(id)["system"]] || [];
-      for (const reservationInfo of systemReservationInfo) {
-        if (reservationInfo.ReservationName == value) {
-          $(`#${id}-reservation-start`).html(`${reservationInfo.StartTime} (Europe/Berlin)`);
-          $(`#${id}-reservation-end`).html(`${reservationInfo.EndTime} (Europe/Berlin)`);
-          $(`#${id}-reservation-state`).html(reservationInfo.State);
-          $(`#${id}-reservation-details`).html(
-            JSON.stringify(reservationInfo, null, 2));
-        }
-      }
-      $(`#${id}-reservation-info-div`).show();
-      $(`#${id}-runtime-input`).trigger("change");
-    }
-    else {
-      $(`#${id}-reservation-info-div`).hide();
-    }
-  });
-
-  $("input[id*=runtime-input").change(function () {
-
-    function _getTimeInMinutes(startTime, endTime){
-      const elapsedTime = endTime - startTime;
-      const elapsedSeconds = elapsedTime / 1000; // Convert milliseconds to seconds
-      const elapsedMinutes = elapsedSeconds / 60; // Convert seconds to minutes
-      
-      return elapsedMinutes;
-    };
-
-    function _resetErrors(id, element) {
-
-      var resourceInfo = getResourceInfo();
-      const values = utils.getLabConfigSelectValues(id);
-      const partitionResources = ((resourceInfo[values.service] || {})[values.system] || {})[values.partition] || {};
-      if (partitionResources.runtime != undefined) {
-        let min = (partitionResources.runtime.minmax || [0, 1])[0];
-        let max = (partitionResources.runtime.minmax || [0, 1])[1];
-        element.siblings(".invalid-feedback").text(`Please choose a number between ${min} and ${max}.`);
-      }
-      tabWarning.addClass("invisible");
-      element.removeClass("is-invalid");
-    }
-
-    const id = utils.getId(this);
-    const reservationInfo = getReservationInfo();
-    const systemReservationInfo = reservationInfo[utils.getLabConfigSelectValues(id)["system"]] || [];
-    var tabWarning = $(`#${id}-resources-tab-warning`);
-    
-    if (reservationInfo) {
-      const currentReservation = $(`#${id}-reservation-select`).val();
-
-      if (currentReservation == "None") {
-        _resetErrors(id, $(this));
-        return;
-      }
-      for (const reservationInfo of systemReservationInfo) {
-        if (reservationInfo.ReservationName == currentReservation) {
-          const resStart = reservationInfo.StartTime;
-          const resEnd = reservationInfo.EndTime;
-
-          const nowString = Date().toLocaleString("en-US", {timeZone: "Europe/Berlin"});
-          const now = new Date(nowString).getTime();
-          const reservStart = new Date(resStart).getTime();
-          const startTime = (reservStart > now)? reservStart : now;
-          const endTime = new Date(resEnd).getTime();
-
-          var reservationTime = _getTimeInMinutes(startTime, endTime);
-          var currentRuntimeVal = $(this)[0].value;
-
-          if(currentRuntimeVal > reservationTime){
-            // a buffer of 10 minutes, which is used only for the error message to avoid users copy-pasting the maximum time and their job landing in the queue forever
-            let buffer = 10;
-            const timeLeft = Math.floor(reservationTime - buffer);
-            $(this).siblings(".invalid-feedback").text(`Your reservation ends on ${resEnd}. Do not set a runtime which exceeds this limit, e.g., ${timeLeft} minutes.`);
-            $(this).addClass("is-invalid");
-
-            tabWarning.removeClass("invisible");
-          }
-          else {
-            _resetErrors(id, $(this));
-          }
-        }
-      }
-    }
-  });
-
-  $("input.module-selector").click(function () {
-    const id = utils.getId(this, -3);
-    const allOrNone = $(this).attr("id").includes("select-all") ? "all" : "none";
-    var checkboxes = $(`#${id}-modules-form`).find("input[type=checkbox]");
-    if (allOrNone == "all") {
-      $(`#${id}-modules-select-none`)[0].checked = false;
-      checkboxes.each((i, cb) => { cb.checked = true; });
-    }
-    else if (allOrNone == "none") {
-      $(`#${id}-modules-select-all`)[0].checked = false;
-      checkboxes.each((i, cb) => { cb.checked = false; });
-    }
-  });
-
-})
diff --git a/static/js/home/handle-servers.js b/static/js/home/handle-servers.js
deleted file mode 100644
index 9d5055a..0000000
--- a/static/js/home/handle-servers.js
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-/*
-* This module is responsible for JupyterLab start/stop/cancel/delete etc. events. It also prepares the user options to be sent to the backend
-*/
-require(["jquery", "jhapi", "utils", "home/utils", "home/lab-configs"], function (
-  $,
-  JHAPI,
-  utils,
-  custom_utils,
-  lab
-) {
-  "use strict";
-
-  var base_url = window.jhdata.base_url;
-  var user = window.jhdata.user;
-  var api = new JHAPI(base_url);
-
-  function cancelServer() {
-    var [tr, id] = _getTrAndId(this);
-    _disableTrButtons(tr);
-    api.cancel_named_server(user, id, {
-      success: function () {
-        console.log("cancel success");
-        custom_utils.setSpawnActive(id, false);
-      },
-      error: function () {
-        console.log("cancel error");
-      }
-    });
-  }
-
-  function stopServer() {
-    var [tr, id] = _getTrAndId(this);
-    _disableTrButtons(tr);
-    custom_utils.updateProgressState(id, "stopping");
-    api.stop_named_server(user, id, {
-      success: function () {
-        console.log("stop success");
-        let running = false;
-        _enableTrButtons(tr, running);
-        // Reset progress
-        custom_utils.updateProgressState(id, "reset");
-        custom_utils.setSpawnActive(id, false);
-      },
-      error: function (xhr) {
-        console.log("stop error");
-        custom_utils.updateProgressState(id, "stop_failed");
-        tr.find(".btn-open-lab, .btn-cancel-lab").removeClass("disabled");
-        $(`#${id}-log`)
-          .append($('<div class="log-div">')
-            .html`Could not stop server. Error: ${xhr.responseText}`);
-      }
-    });
-  }
-
-  function deleteServer() {
-    var that = $(this);
-    var [collapsibleTr, id] = _getTrAndId(this);
-    _disableTrButtons(collapsibleTr);
-    api.delete_named_server(user, id, {
-      success: function () {
-        $(`tr[data-server-id=${id}]`).each(function () {
-          $(this).remove();
-        });
-        custom_utils.setSpawnActive(id, false);
-      },
-      error: function (xhr) {
-        var alert = that.siblings(".alert");
-        const displayName = _getDisplayName(collapsibleTr);
-        _showErrorAlert(alert, displayName, xhr.responseText);
-      }
-    });
-  }
-
-  function startServer() {
-    var [tr, id] = _getTrAndId(this);
-    var collapsibleTr = tr.siblings(`.collapsible-tr[data-server-id=${id}]`);
-    _disableTrButtons(tr);
-
-    // Validate the form and start spawn only after validation
-    try {
-      $(`form[id*=${id}]`).submit();
-    }
-    catch (e) {
-      let running = false;
-      _enableTrButtons(tr, running);
-      return;
-    }
-    custom_utils.updateProgressState(id, "reset");
-    $(`#${id}-log`).html("");
-
-    var options = _createDataDict(collapsibleTr);
-    // Update the summary row according to the values set in the collapsibleTr
-    _updateTr(tr, id, options);
-    // Open a new tab for spawn_pending.html
-    // Need to create it here for JS context reasons
-    var newTab = window.open("about:blank");
-    api.start_named_server(user, id, {
-      data: JSON.stringify(options),
-      success: function () {
-        // Save latest log to time stamp and empty it
-        custom_utils.updateSpawnEvents(window.spawnEvents, id);
-        window.userOptions[id] = options;
-        // Open the spawn url in the new tab
-        newTab.location.href = utils.url_path_join(base_url, "spawn", user, id);
-        // Hook up event-stream for progress
-        var evtSources = window.evtSources;
-        if (!(id in evtSources)) {
-          var progressUrl = utils.url_path_join(jhdata.base_url, "api/users", jhdata.user, "servers", id, "progress");
-          progressUrl = progressUrl + "?_xsrf=" + window.jhdata.xsrf_token;
-          evtSources[id] = new EventSource(progressUrl);
-          evtSources[id].onmessage = function (e) {
-            onEvtMessage(e, id);
-          }
-        }
-        // Successfully sent request to start the lab, enable row again
-        let running = true;
-        custom_utils.setSpawnActive(id, "pending");
-        _enableTrButtons(tr, running);
-      },
-      error: function (xhr) {
-        newTab.close();
-        // If cookie is not valid anymore, refresh the page.
-        // This should redirect the user to the login page.
-        if (xhr.status == 403) {
-          document.location.reload();
-          return;
-        }
-        custom_utils.updateProgressState(id, "failed");
-        // Update progress in log
-        let details = $("<details>")
-          .append($("<summary>")
-            .html(`Could not request spawn. Error: ${xhr.responseText}`))
-          .append($("<pre>")
-            .html(custom_utils.parseJSON(xhr.responseText)));
-        $(`#${id}-log`).append(
-          $("<div>").addClass("log-div").html(details)
-        );
-        // Spawn attempt finished, enable row again
-        let running = false;
-        _enableTrButtons(tr, running);
-      }
-    });
-  }
-
-  function startNewServer() {
-    function _uuidv4hex() {
-      return ([1e7, 1e3, 4e3, 8e3, 1e11].join('')).replace(/[018]/g, c =>
-        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
-    }
-
-    function _uuidWithLetterStart() {
-      let uuid = _uuidv4hex();
-      let char = Math.random().toString(36).match(/[a-zA-Z]/)[0];
-      return char + uuid.substring(1);
-    }
-
-    const uuid = _uuidWithLetterStart();
-    // Start button is in collapsible tr for new labs
-    var [collapsibleTr, id] = _getTrAndId(this);
-    _disableTrButtons(collapsibleTr);
-
-    // Validate the form and start spawn only after validation
-    try {
-      $(`form[id*=${id}]`).submit();
-    }
-    catch (e) {
-      collapsibleTr.find("button").removeClass("disabled");
-      return;
-    }
-
-    var options = _createDataDict(collapsibleTr);
-    // Open a new tab for spawn_pending.html
-    // Need to create it here for JS context reasons
-    var newTab = window.open("about:blank");
-    api.start_named_server(user, uuid, {
-      data: JSON.stringify(options),
-      success: function () {
-        var url = utils.url_path_join(base_url, "spawn", user, uuid);
-        newTab.location.href = url;
-        // Reload page to add spawner to table
-        location.reload();
-      },
-      error: function (xhr) {
-        newTab.close();
-        // If cookie is not valid anymore, refresh the page.
-        // This should redirect the user to the login page.
-        if (xhr.status == 403) {
-          document.location.reload();
-          return;
-        }
-        // Show information about why the start failed
-        let details = $("<details>")
-          .append($("<summary>")
-            .html(`Could not request spawn. Error: ${xhr.responseText}`))
-          .append($("<pre>")
-            .html(custom_utils.parseJSON(xhr.responseText)));
-        $(`#${id}-log`).append(
-          $("<div>").addClass("log-div").html(details)
-        );
-        collapsibleTr.find("button").removeClass("disabled");
-      }
-    });
-  }
-
-  function shareLab() {
-    // Start button is in collapsible tr for new labs
-    var [collapsibleTr, id] = _getTrAndId(this);
-    // _disableTrButtons(collapsibleTr);
-
-    var options = _createDataDict(collapsibleTr);
-
-    function showShareDialogue(url) {
-
-      $(`#${id}-copy-btn`).click(function() {
-
-        const shareUrl = $(`#${id}-share-link .modal-body a`).attr('href');
-        navigator.clipboard.writeText(shareUrl).then(function() {
-
-          $(`#${id}-copy-btn`).tooltip('dispose').attr('title', 'Copied');
-          $(`#${id}-copy-btn`).tooltip('show');
-        }, function(err) {
-          console.error('Could not copy text: ', err);
-        });
-      });
-
-      let shareableURL = url;
-
-      $(`#${id}-share-link .modal-title`).text(`Share Lab ${options["name"]}`);
-      $(`#${id}-share-link .modal-body a`).text(`${shareableURL}`);
-      try {
-        shareableURL = new URL(url);
-        $(`#${id}-share-link .modal-body a`).attr('href', shareableURL);
-      } catch (error) {}
-
-      $(`#${id}-share-link`).modal('show');
-    }
-    //---------------------------------------------------
-
-    // Open a new tab for spawn_pending.html
-    // Need to create it here for JS context reasons
-    // var newTab = window.open("about:blank");
-    // let protocol = window.location.protocol;
-    var urlStr = utils.url_path_join(window.origin, base_url, "share");
-    api.share_server({
-      data: JSON.stringify(options),
-      success: function (resp) {
-        urlStr = utils.url_path_join(window.origin, base_url, "share", "user_options", resp).replace("//", "/");
-        showShareDialogue(urlStr);
-      },
-      error: function (xhr) {
-        // newTab.close();
-        // If cookie is not valid anymore, refresh the page.
-        // This should redirect the user to the login page.
-        if (xhr.status == 403) {
-          document.location.reload();
-          return;
-        }
-
-        let err = `Failed to create a share link for this lab. Error: ${xhr.responseText}`;
-        showShareDialogue(err);
-      }
-    });
-  }
-  
-  $(".btn-start-lab").click(startServer);
-  $(".btn-start-new-lab").click(startNewServer);
-  $(".btn-cancel-lab").click(cancelServer);
-  $(".btn-stop-lab").click(stopServer);
-  $(".btn-delete-lab").click(deleteServer);
-  $(".btn-share-lab").click(shareLab);
-
-  /*
-  Validate form before starting a new lab
-  */
-  $("form").submit(function (event) {
-    event.preventDefault();
-    event.stopPropagation();
-
-    if (!$(this)[0].checkValidity()) {
-      $(this).addClass('was-validated');
-      // Show the tab where the error was thrown
-      var tab_id = $(this).attr("id").replace("-form", "-tab");
-      var tab = new bootstrap.Tab($("#" + tab_id));
-      tab.show();
-      // Open the collapsibleTr if it was hidden
-      const id = custom_utils.getId(this);
-      var tr = $(`.summary-tr[data-server-id=${id}`);
-      if (!$(`${id}-collapse`).css("display") == "none") {
-        tr.trigger("click");
-      }
-      throw {
-        name: "FormValidationError",
-        toString: function () {
-          return this.name;
-        }
-      };
-    } else {
-      $(this).removeClass('was-validated');
-    }
-  });
-
-
-  /*
-  Save and revert changes to spawner
-  */
-  function saveChanges() {
-    var [collapsibleTr, id] = _getTrAndId(this);
-    var tr = $(`.summary-tr[data-server-id=${id}]`);
-    var alert = $(this).siblings(".alert");
-
-    const displayName = _getDisplayName(collapsibleTr);
-    const options = _createDataDict(collapsibleTr);
-    api.update_named_server(user, id, {
-      data: JSON.stringify(options),
-      success: function () {
-        _updateTr(tr, id, options);
-        // Update global user options
-        window.userOptions[id] = options;
-        alert.children("span")
-          .text(`Successfully updated ${displayName}.`);
-        alert
-          .removeClass("alert-danger p-0")
-          .addClass("alert-success show p-1");
-      },
-      error: function (xhr) {
-        _showErrorAlert(alert, displayName, xhr.responseText);
-      }
-    });
-  }
-
-  function revertChanges() {
-    const id = custom_utils.getId(this);
-    var alert = $(this).siblings(".alert");
-
-    const options = window.userOptions[id];
-    const name = options.name;
-    // Do not send start_id when updating lab config
-    delete options.start_id;
-
-    api.update_named_server(user, id, {
-      data: JSON.stringify(options),
-      success: function () {
-        $(`#${id}-name-input`).val(name);
-        // Reset all user inputs to the values saved in the global user options
-        let available = lab.checkIfAvailable(id, options);
-        lab.setUserOptions(id, options, available);
-        // Remove all tab warnings since manual changes shouldn't cause warnings
-        $("[id$=tab-warning]").addClass("invisible");
-        // Show first tab after resetting values
-        var trigger = $(`#${id}-collapse`).find(".nav-link").first();
-        var tab = new bootstrap.Tab(trigger);
-        tab.show();
-        alert.children("span")
-          .text(`Successfully reverted settings for ${name}.`);
-        alert
-          .removeClass("alert-danger p-0")
-          .addClass("alert-success show p-1");
-      },
-      error: function (xhr) {
-        _showErrorAlert(alert, name, xhr.responseText);
-      }
-    });
-  }
-
-  $(".btn-save-lab").click(saveChanges);
-  $(".btn-reset-lab").click(revertChanges);
-
-  /*
-  Util functions
-  */
-  function _getDisplayName(collapsibleTr) {
-    var displayName = collapsibleTr.find("input[id*=name]").val();
-    if (displayName == "") displayName = "Unnamed JupyterLab";
-    return displayName;
-  }
-
-  function _getTrAndId(element) {
-    let tr = $(element).parents("tr");
-    let id = tr.data("server-id");
-    return [tr, id];
-  }
-
-  function _disableTrButtons(tr) {
-    // Disable buttons
-    tr.find(".btn").addClass("disabled");
-  }
-
-  function _enableTrButtons(tr, running) {
-    if (running) {
-      // Show open/cancel for starting labs
-      tr.find(".btn-na-lab, .btn-start-lab").addClass("disabled").hide();
-      tr.find(".btn-open-lab, .btn-cancel-lab").show();
-      // Disable until fitting event received from EventSource
-      tr.find(".btn-open-lab, .btn-cancel-lab").addClass("disabled");
-    }
-    else {
-      // Show start or na for non-running labs
-      var na = tr.find(".na-status").text() || 0;
-      if (na != "0") {
-        tr.find(".btn-na-lab").removeClass("disabled").show();
-        tr.find(".btn-start-lab").addClass("disabled").hide();
-      }
-      else {
-        tr.find(".btn-na-lab").addClass("disabled").hide();
-        tr.find(".btn-start-lab").removeClass("disabled").show();
-      }
-      tr.find(".btn-open-lab, .btn-cancel-lab, .btn-stop-lab")
-        .addClass("disabled").hide();
-    }
-  }
-
-  function _showErrorAlert(alert, name, text) {
-    alert.children("span")
-      .text(`Could not update ${name}. Error: ${text}`);
-    alert
-      .removeClass("alert-success p-0")
-      .addClass("alert-danger show p-1");
-  }
-
-
-  function _updateTr(tr, id, options) {
-    tr.find(".name-td").text(options.name);
-    function _updateTd(key) {
-      let configTdDiv = tr.find(`#${id}-config-td-div-${key}`);
-      if (options[key]) configTdDiv.show();
-      else configTdDiv.hide();
-      let configDiv = tr.find(`#${id}-config-td-${key}`);
-      configDiv.text(options[key]);
-    }
-    ["system", "flavor", "partition", "project",
-      "runtime", "nodes", "gpus"].forEach(key => _updateTd(key));
-  }
-
-  function _createDataDict(collapsibleTr) {
-    var options = {}
-    options.name = _getDisplayName(collapsibleTr);
-
-    function _addSelectValue(param) {
-      var select = collapsibleTr.find(`select[id*=${param}]`);
-      var value = select.val();
-      if (param == "version") {
-        param = "profile";
-        value = "JupyterLab/" + value;
-      }
-      if (value) options[param] = value;
-    }
-
-    function _addInputValue(param) {
-      var input = collapsibleTr.find(`input[id*=${param}]`).not(`[type=checkbox]`);
-      var value = input.val();
-      if (param == "xserver") {
-        if (collapsibleTr.find(`input[id*=xserver-cb-input]`).length && collapsibleTr.find(`input[id*=xserver-cb-input]`)[0] && !collapsibleTr.find(`input[id*=xserver-cb-input]`)[0].checked) return;
-      }
-      else if (param == "image-private") {
-        if (collapsibleTr.find(`input[id*=image-private-cb-input]`).length && collapsibleTr.find(`input[id*=image-private-cb-input]`)[0] && !collapsibleTr.find(`input[id*=image-private-cb-input]`)[0].checked) return;
-        param = "dockerregistry";
-       
-        let registry_url = "";
-        const credentials = {}
-
-        for(let i = 0; i < input.length; i++) {
-          let el = input[i]
-          if(el.id.indexOf("private-url") !== -1){
-            registry_url = el.value;
-          }
-          if(el.id.indexOf("user") !== -1){
-            credentials["username"] = el.value;
-          }
-          if(el.id.indexOf("pass") !== -1){
-            credentials["password"] = el.value;
-          }  
-        }
-        const auth_values = {}
-        auth_values[registry_url] = credentials
-        const auths = {"auths" : auth_values }
-        // Encode user credentials for the private docker repository in base64
-        value = btoa(JSON.stringify(auths));
-      }
-      else if (param == "image-mount") {
-        if (collapsibleTr.find(`input[id*=image-mount-cb-input]`).length && collapsibleTr.find(`input[id*=image-mount-cb-input]`)[0] && !collapsibleTr.find(`input[id*=image-mount-cb-input]`)[0].checked) return;
-        param = "userdata_path";
-      }
-      if (value) options[param] = value;
-    }
-
-    function _addCbValues(param) {
-      var checkboxes = collapsibleTr
-        .find('form[id*=modules-form]')
-        .find(`input[type=checkbox]`);
-      var values = [];
-      checkboxes.each(function () {
-        if (this.checked) values.push($(this).val());
-      });
-      options[param] = values;
-    }
-
-    ["version", "system", "flavor", "account",
-      "project", "partition", "reservation", "type", "notebook_type"].forEach(key => _addSelectValue(key));
-    ["image", "image-mount", "image-private", "nodes", "gpus", "runtime", "xserver", "repo", "gitref", "notebook"].forEach(key => _addInputValue(key));
-    _addCbValues("userModules");
-    return options;
-  }
-});
diff --git a/static/js/home/lab-configs.js b/static/js/home/lab-configs.js
deleted file mode 100644
index 6ac5161..0000000
--- a/static/js/home/lab-configs.js
+++ /dev/null
@@ -1,383 +0,0 @@
-define(["jquery", "home/utils", "home/dropdown-options"], function (
-  $,
-  utils,
-  dropdowns
-) {
-  "use strict";
-
-  var checkComputeMaintenance = function (system, partition) {
-    const systemInfo = getSystemInfo();
-    const interactivePartitions = (systemInfo[system] || {}).interactivePartitions || [];
-    if (!interactivePartitions.includes(partition)) {
-      const systemUpper = system.replace('-', '').toUpperCase();
-      if ((window.systemsHealth[systemUpper] || 0) >= (window.systemsHealth.threshold.compute || 40)) return true;
-      else return false;
-    }
-  }
-
-  var checkIfAvailable = function (id, options) {
-    var reason = "due to ";
-    var reason_broken_lab = "This lab is broken.\nPlease delete and recreate.";
-
-    // Check if system is not available due to incident
-    const systemUpper = options["system"].replace('-', '').toUpperCase();
-    if ((window.systemsHealth[systemUpper] || 0) >= (window.systemsHealth.threshold.interactive || 50)) {
-      reason += "maintenance";
-      utils.setLabAsNA(id, reason);
-      return false;
-    }
-
-    // Check if system is not available due to groups
-    const dropdownOptions = getDropdownOptions();
-    const service = getService(options);
-    const systemInfo = getSystemInfo();
-    const system = options["system"];
-    const flavor = options["flavor"];
-    const account = options["account"];
-    const project = options["project"];
-    const partition = options["partition"];
-    const reservation = options["reservation"];
-    const nodes = options["nodes"];
-    const runtime = options["runtime"];
-    const gpus = options["gpus"];
-    const xserver = options["xserver"];
-
-    if (service == undefined) {
-      utils.setLabAsNA(id, reason_broken_lab);
-      return false;
-    }
-    if (!(service in dropdownOptions)) {
-      reason += "service version";
-      utils.setLabAsNA(id, reason);
-      return false;
-    }
-    if (system !== undefined) {
-      if (dropdownOptions[service] == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      if (!(system in dropdownOptions[service])) {
-        reason += "system";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-      if (!(system in systemInfo)) {
-        reason += "system";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (flavor !== undefined) {
-      let systemFlavors = window.flavorInfo[system] || {};
-      if (!(flavor in systemFlavors)) {
-        reason += "flavor";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-      let flavorDescription = systemFlavors[flavor];
-      let spawnerState = window.spawnActive[id];
-      if (flavorDescription.max != -1 && (flavorDescription.current || 0) >= flavorDescription.max && !spawnerState) {
-        reason += "flavor limits";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (account !== undefined) {
-      if (dropdownOptions[service][system] == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      if (!(account in dropdownOptions[service][system])) {
-        reason += "account";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (project !== undefined) {
-      if (dropdownOptions[service][system][account] == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      if (!(project in dropdownOptions[service][system][account])) {
-        reason += "project";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (partition !== undefined) {
-      if (dropdownOptions[service][system][account][project] == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      if (!(partition in dropdownOptions[service][system][account][project])) {
-        reason += "partition";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-      // Only compute nodes are not available during rolling updates
-      if (checkComputeMaintenance(system, partition)) {
-        reason += "maintenance";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (reservation !== undefined && reservation != "None") {
-      if (dropdownOptions[service][system][account][project][partition] == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      let setFalse = true;
-      for (const reservation_dict of dropdownOptions[service][system][account][project][partition]) {
-        if (reservation == reservation_dict.ReservationName) {
-          if (reservation_dict.State == "ACTIVE") {
-            setFalse = false;
-            break;
-          }
-        }
-      }
-      if (setFalse) {
-        reason += "reservation";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    // Resources
-    const resourceInfo = getResourceInfo();
-    const partitionResources = ((resourceInfo[service] || {})[system] || {})[partition] || {};
-    if (nodes !== undefined) {
-      if (partitionResources.nodes == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      let min = (partitionResources.nodes.minmax || [0, 1])[0];
-      let max = (partitionResources.nodes.minmax || [0, 1])[1];
-      if (nodes < min || nodes > max) {
-        reason += "number of nodes";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (gpus !== undefined) {
-      if (partitionResources.gpus == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      let min = (partitionResources.gpus.minmax || [0, 1])[0];
-      let max = (partitionResources.gpus.minmax || [0, 1])[1];
-      if (gpus < min || gpus > max) {
-        reason += "number of GPUs";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (runtime !== undefined) {
-      if (partitionResources.runtime == undefined) {
-        utils.setLabAsNA(id, reason_broken_lab);
-        return false;
-      }
-      let min = (partitionResources.runtime.minmax || [0, 1])[0];
-      let max = (partitionResources.runtime.minmax || [0, 1])[1];
-      if (runtime < min || runtime > max) {
-        reason += "runtime";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-    if (xserver !== undefined) {
-      if (!("xserver" in partitionResources)) {
-        reason += "XServer";
-        utils.setLabAsNA(id, reason);
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  var setUserOptions = function (id, options, available) {
-    const name = options["name"];
-    const service = getService(options);
-    const system = options["system"];
-
-    // customDockerImage
-    const image = options["image"];
-    const dockerregistry = options["dockerregistry"];
-    const userdata_path = options["userdata_path"];
-
-    // default
-    const flavor = options["flavor"];
-    const account = options["account"];
-    const project = options["project"];
-    const partition = options["partition"];
-    const reservation = options["reservation"];
-    const nodes = options["nodes"];
-    const runtime = options["runtime"];
-    const gpus = options["gpus"];
-    const xserver = options["xserver"];
-    const modules = options["userModules"];
-    
-    // repo2Docker values
-    const r2dType = options["type"];
-    const r2dRepo = options["repo"];
-    const r2dGitref = options["gitref"]
-    const r2dNotebook = options["notebook"]
-    const r2dNotebookType = options["notebook_type"]
-
-    function _updateDockerRegistryFields(id, value){
-      $(`#${id}-image-private-cb-input`)[0].checked = true;
-      // Decode the value of the dockerRegistry. It comes encoded in base64 from the backend
-      let privateRegistryString = atob(value);
-      let privateRegistry = JSON.parse(privateRegistryString);
-      let auths = Object.values(privateRegistry)[0]; // returns a dictionary in the form of {"registry_url" : {"username": <username>, "password": <password>}}
-      let url = Object.keys(auths)[0];
-      $(`#${id}-image-private-url-input`).val(url);
-      $(`#${id}-image-private-user-input`).val(auths[url]["username"]);
-      $(`#${id}-image-private-pass-input`).val(auths[url]["password"]);
-    }
-
-    $(`#${id}-name-input`).val(name);
-    let registryAuthsInputDivs = $(`#${id}-image-private-url-input-div,#${id}-image-private-user-input-div, #${id}-image-private-pass-input-div`);
-    if (available) {
-      /* Set allowed values. Do not rely on change events here as without
-          passing a value explicitely, the first allowed option would be 
-          chosen regardless of the user option value. */
-      try {
-        dropdowns.updateServices("JupyterLab", id, service);
-        if (image) $(`#${id}-image-input`).val(image);
-        if (userdata_path) $(`#${id}-image-mount-input`).val(userdata_path);
-        if (dockerregistry){
-           _updateDockerRegistryFields(id, dockerregistry);
-        }
-        else {
-          registryAuthsInputDivs.hide();
-        }
-        if (r2dRepo) $(`#${id}-repo-input`).val(r2dRepo);
-        if (r2dGitref) $(`#${id}-gitref-input`).val(r2dGitref);
-        if (r2dNotebook) $(`#${id}-notebook-input`).val(r2dNotebook);
-        dropdowns.updateSystems(id, service, system);
-        dropdowns.updateFlavors(id, service, system, flavor);
-        dropdowns.updateAccounts(id, service, system, account);
-        dropdowns.updateProjects(id, service, system, account, project);
-        dropdowns.updatePartitions(id, service, system, account, project, partition);
-        dropdowns.updateReservations(id, service, system, account, project, partition, reservation);
-        dropdowns.updateResources(id, service, system, account, project, partition, nodes, gpus, runtime, xserver);
-        dropdowns.updateModules(id, service, system, account, project, partition, modules);
-        dropdowns.updateR2dType(id, r2dType);
-        dropdowns.updateR2dNotebookTypes(id, r2dNotebookType);
-      }
-      catch (e) { utils.setLabAsNA(id, "due to a JS error");
-        console.log(e)
-      }
-    }
-    else {
-      function _setSelectOption(key, value, displayValue) {
-        if (!displayValue) displayValue = value;
-        if (value) $(`#${id}-${key}-select`).append(`<option value="${value}">${displayValue}</option>`);
-        else $(`#${id}-${key}-select-div`).hide();
-        dropdowns.updateLabConfigSelect($(`#${id}-${key}-select`), value);
-      }
-
-      function _setInputValue(key, value) {
-        if (value) $(`#${id}-${key}-input`).val(value);
-        else $(`#${id}-${key}-input-div`).hide();
-      }
-
-      $(`input[id*=${id}], select[id*=${id}]`).addClass("no-update");
-
-      const serviceInfo = getServiceInfo();
-      let serviceName = (serviceInfo.JupyterLab.options[service] || {}).name || service;
-
-      // Selects which are always visible
-      $(`#${id}-version-select`).append(`<option value="${service}">${serviceName}</option>`);
-      _setSelectOption("system", system);
-      _setInputValue("image", image);
-      if (userdata_path) {
-        $(`#${id}-image-mount-cb-input-div`)[0].checked = true;
-        $(`#${id}-image-mount-cb-input-div`).show();
-      }
-      else {
-        $(`#${id}-image-mount-cb-input-div`)[0].checked = false;
-        $(`#${id}-image-mount-cb-input-div`).hide();
-      }
-      if (dockerregistry) {
-        $(`#${id}-image-private-cb-input-div`)[0].checked = true;
-        $(`#${id}-image-private-cb-input-div`).show();
-        _updateDockerRegistryFields(id, dockerregistry);
-      }
-      else {
-        $(`#${id}-image-private-cb-input-div`)[0].checked = false;
-        // $(`#${id}-image-private-cb-input-div`).hide();
-        registryAuthsInputDivs.hide();
-      }
-
-      _setInputValue("image-mount", userdata_path);
-      _setSelectOption("flavor", flavor, ((window.flavorInfo[system] || {})[flavor] || {}).display_name);
-      utils.createFlavorInfo(id, system);
-      _setSelectOption("account", account);
-      _setSelectOption("project", project);
-      let maintenance = checkComputeMaintenance(system, partition);
-      _setSelectOption("partition", maintenance ? `${partition} (in maintenance)` : partition);
-
-      // Reservation
-      var hasReservationInfo = false;
-      if (reservation) {
-        const reservationInfo = getReservationInfo();
-        const systemReservationInfo = reservationInfo[system] || [];
-        for (const info of systemReservationInfo) {
-          if (info.ReservationName == reservation) {
-            hasReservationInfo = true;
-            var inactive = (info.State == "INACTIVE");
-            if (inactive) {
-              $(`#${id}-reservation-select`).append(
-                `<option value="${reservation}">${reservation} [INACTIVE]</option>`
-              );
-            }
-            else {
-              $(`#${id}-reservation-select`).append(
-                `<option value="${reservation}">${reservation}</option>`
-              );
-            }
-            $(`#${id}-reservation-select`).trigger("change");
-          }
-        }
-        if (!hasReservationInfo)
-          $(`#${id}-reservation-select`).append(`<option value="${reservation}">${reservation}</option>`);
-      }
-      else {
-        $(`#${id}-reservation-select-div`).hide();
-        $(`#${id}-reservation-hr`).hide();
-      }
-      if (hasReservationInfo) $(`#${id}-reservation-info-div`).show()
-      else $(`#${id}-reservation-info-div`).hide();
-
-      // Resources
-      if ((nodes || runtime || gpus || xserver) !== undefined) {
-        _setInputValue("nodes", nodes);
-        _setInputValue("runtime", runtime);
-        _setInputValue("gpus", gpus);
-        // Don't have info about resources, so just never show the xserver checkbox
-        _setInputValue("xserver", xserver);
-      }
-      else {
-        $(`#${id}-resources-tab`).addClass("disabled");
-        $(`#${id}-resources-tab`).hide();
-      }
-
-      // Modules
-      dropdowns.updateModules(id, service, system, account, project, partition, modules);
-
-      // Disable all user input elements if N/A
-      $(`input[id*=${id}]`).attr("disabled", true);
-      $(`select[id*=${id}]`).not("[id*=log]").addClass("disabled");
-    }
-  }
-
-  var labConfigs = {
-    checkComputeMaintenance: checkComputeMaintenance,
-    checkIfAvailable: checkIfAvailable,
-    setUserOptions: setUserOptions,
-  }
-
-  return labConfigs;
-
-})
\ No newline at end of file
diff --git a/static/js/home/utils.js b/static/js/home/utils.js
deleted file mode 100644
index 02c3a64..0000000
--- a/static/js/home/utils.js
+++ /dev/null
@@ -1,280 +0,0 @@
-define(["jquery", "jhapi",], function (
-  $,
-  JHAPI
-) {
-  "use strict";
-  var base_url = window.jhdata.base_url;
-  var api = new JHAPI(base_url);
-
-  const progressStates = {
-    "running": {
-      "text": "running",
-      "background": "bg-success",
-      "width": 100
-    },
-    "stop_failed": {
-      "text": "running (stop failed)",
-      "background": "bg-success",
-      "width": 100
-    },
-    "cancelling": {
-      "text": "cancelling...",
-      "background": "bg-danger",
-      "width": 100
-    },
-    "stopping": {
-      "text": "stopping...",
-      "background": "bg-danger",
-      "width": 100
-    },
-    "failed": {
-      "text": "last spawn failed",
-      "background": "bg-danger",
-      "width": 100
-    },
-    "reset": {
-      "text": "",
-      "background": "",
-      "width": 0
-    }
-  }
-
-  var parseJSON = function (inputString) {
-    try {
-      return JSON.stringify(JSON.parse(inputString), null, 2);
-    } catch (e) {
-      return inputString;
-    }
-  }
-
-  var getId = function (element, slice_index = -2) {
-    let id_array = $(element).attr("id").split('-');
-    let id = id_array.slice(0, slice_index).join('-');
-    return id;
-  }
-
-  var getSpecificValuesInTab = function(id, prefix) {
-    const values = {};
-    $(`[id^="${id}"]`).filter('select, input').each(function() {
-      const id = $(this).attr('id');
-      const suffixLength = $(this).prop("tagName").length + 1;
-      const key = id.substring(prefix.length, id.length - suffixLength);
-      if ($(this).is(':checkbox')) {
-        values[key] = $(this).is(':checked'); // Checkbox value
-      } else {
-        values[key] = $(this).val(); // Standard value
-      }
-    });
-    return values;
-  }
-
-  var getLabConfigSelectValues = function (id) {
-
-    return {
-      "service": $(`select#${id}-version-select`).val(),
-      "system": $(`select#${id}-system-select`).val(),
-      "flavor": $(`select#${id}-flavor-select`).val(),
-      "account": $(`select#${id}-account-select`).val(),
-      "project": $(`select#${id}-project-select`).val(),
-      "partition": $(`select#${id}-partition-select`).val(),
-      "r2dtype": $(`select#${id}-type-select`).val(),
-      "r2dnotebooktype": $(`select#${id}-notebook_type-select`).val(),
-    }
-  }
-
-  var setLabAsNA = function (id, reason) {
-    $(`#${id}-start-btn, #${id}-open-btn, #${id}-cancel-btn, #${id}-stop-btn`).addClass("disabled").hide();
-    $(`#${id}-na-btn`).show();
-    $(`#${id}-na-status`).html(1);
-    $(`#${id}-na-info`).html(reason).show();
-  }
-
-  var setSpawnActive = function (id, active) {
-    window.spawnActive[id] = active;
-  }
-
-  var updateProgressState = function (id, state) {
-    $(`#${id}-progress-bar`)
-      .width(progressStates[state].width)
-      .removeClass("bg-success bg-danger")
-      .addClass(progressStates[state].background)
-      .html("");
-    $(`#${id}-progress-info-text`).html(progressStates[state].text);
-  }
-
-  var appendToLog = function (log, htmlMsg) {
-    try { htmlMsg = htmlMsg.replace(/&nbsp;/g, ' '); }
-    catch (e) { return; } // Not a valid htmlMsg
-    // Only append if a log message has not been appended yet
-    var exists = false;
-    log.children().each(function (i, e) {
-      let logMsg = $(e).html();
-      if (htmlMsg == logMsg) exists = true;
-    })
-    if (!exists)
-      log.append($('<div class="log-div">').html(htmlMsg));
-  }
-
-  var updateSpawnEvents = function (spawnEvents, id) {
-    if (spawnEvents[id]["latest"].length) {
-      var re = /([0-9]+(-[0-9]+)+).*[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,3})?/;
-      for (const [_, event] of spawnEvents[id]["latest"].entries()) {
-        const startMsg = event.html_message || event.message;
-        const startTimeMatch = re.exec(startMsg);
-        if (startTimeMatch) {
-          const startTime = startTimeMatch[0];
-          // Have we already created a log entry for this time?
-          let logOptions = $(`#${id}-log-select option`);
-          let logTimes = $.map(logOptions, function (option) {
-            return option.value;
-          });
-          // If yes, we do not need to do anything anymore
-          if (logTimes.includes(startTime)) return;
-          // Otherwise, save the current events to the startTime,
-          // update the log select and reset the "latest" events.
-          spawnEvents[id][startTime] = spawnEvents[id]["latest"];
-          spawnEvents[id]["latest"] = [];
-          $(`#${id}-log-select`)
-            .append(`<option value="${startTime}">${startTime}</option>`)
-            .val("latest");
-          break;
-        }
-      }
-      // We didn't manage to find a time, so update with no timestamp
-      if ((spawnEvents[id]["latest"].length)) {
-        spawnEvents[id]["previous"] = spawnEvents[id]["latest"];
-        spawnEvents[id]["latest"] = [];
-      }
-    }
-  }
-
-  var createFlavorInfo = function (id, system) {
-    $(`#${id}-flavor-info-div`).empty();
-
-    const systemFlavors = window.flavorInfo[system] || {};
-    for (const [_, description] of Object.entries(systemFlavors).sort(([, a], [, b]) => (a["weight"] || 99) < (b["weight"] || 99) ? 1 : -1)) {
-      var current = description.current || 0;
-      var maxAllowed = description.max;
-      // Flavor not valid, so skip
-      if (maxAllowed == 0 || current < 0 || maxAllowed == null || current == null) continue;
-
-      var bgColor = "bg-primary";
-      // Infinite allowed
-      if (maxAllowed == -1) {
-        var progressTooltip = `${current} used`;
-        var maxAllowedLabel = '∞';
-        if (current == 0) {
-          var currentWidth = 0;
-          var maxAllowedWidth = 100;
-        }
-        else {
-          var currentWidth = 20;
-          var maxAllowedWidth = 80;
-        }
-      }
-      else {
-        var progressTooltip = `${current} out of ${maxAllowed} used`;
-        var maxAllowedLabel = maxAllowed - current;
-        var currentWidth = current / maxAllowed * 100;
-        var maxAllowedWidth = maxAllowedLabel / maxAllowed * 100;
-
-        if (maxAllowedLabel < 0) {
-          maxAllowedLabel = 0;
-          maxAllowedWidth = 0;
-          bgColor = "bg-danger";
-        }
-      }
-
-      var diagramHtml = `
-        <div class="row align-items-center g-0 mt-4">
-          <div class="col-4">
-            <span>${description.display_name}</span>
-            <a class="lh-1 ms-3" style="padding-top: 1px;" 
-              data-bs-toggle="tooltip" data-bs-placement="right" title="${description.description}">
-              ${getInfoSvg()}
-            </a>
-          </div>
-          <div class="progress col ms-2 fw-bold" style="height: 20px;"
-            data-bs-toggle="tooltip" data-bs-placement="top" title="${progressTooltip}">
-            <div class="progress-bar ${bgColor}" role="progressbar" style="width: ${currentWidth}%">${current}</div>
-            <div class="progress-bar bg-success" role="progressbar" style="width: ${maxAllowedWidth}%">${maxAllowedLabel}</div>
-          </div>
-        </div>
-      `
-      $(`#${id}-flavor-info-div`).append(diagramHtml);
-    }
-
-    // The lab has a flavor configured or is a new lab, but we could not get any flavor information
-    if (((window.userOptions[id] || {}).flavor || id == "new-jupyterlab") && $.isEmptyObject(systemFlavors)) {
-      var noFlavorsHtml = `
-      <div class="row g-0 mt-3">
-        <div class="col-4"></div>
-        <div class="col ms-2 fw-bold text-danger">No flavors could be fetched. Try logging out and back in to fix the issue.</div>
-      </div>
-      `;
-      $(`#${id}-flavor-info-div`).append(noFlavorsHtml);
-    }
-  }
-
-  // Updates number of users in ther footer
-  var updateNumberOfUsers = function () {
-    api.api_request("usercount", {
-      success: function (data) {
-        // Get all systems from footer and track if updated
-        var systems = {};
-        $("div[id^='ampel'").each((i, e) => {
-          let system = $(e).attr("id").split('-')[1];
-          systems[system] = false;
-        })
-        // Update systems with info from request
-        for (const [system, usercount] of Object.entries(data)) {
-          switch (system) {
-            case 'jupyterhub':
-              $("#jupyter-users").html(usercount);
-              systems['jupyter'] = true;
-              break;
-            case 'JSC-Cloud':
-              $(`#jsccloud-users`).html(usercount['total']);
-              systems['jsccloud'] = true;
-              break;
-            default:
-              $(`#${system.toLowerCase()}-users`).html(usercount['total']);
-              systems[`${system.toLowerCase()}`] = true;
-              var partitionInfos = "";
-              for (const [partition, users] of Object.entries(usercount['partitions'])) {
-                partitionInfos += `\n${partition}: ${users}`;
-              }
-              $(`#${system.toLowerCase()}-users`)
-                .parents("[data-bs-toggle]")
-                .attr("data-bs-original-title", `Number of active servers${partitionInfos}`);
-          }
-        }
-        // If there was no info about a system, set running labs to 0 and reset tooltip
-        for (const [system, systemInfo] of Object.entries(systems)) {
-          if (systemInfo == false) {
-            $(`#${system}-users`).html(0);
-            $(`#${system.toLowerCase()}-users`)
-              .parents("[data-toggle]")
-              .attr("data-bs-original-title", `Number of active servers`);
-          }
-        }
-      }
-    })
-  }
-
-  var utils = {
-    parseJSON: parseJSON,
-    getId: getId,
-    getSpecificValuesInTab: getSpecificValuesInTab,
-    getLabConfigSelectValues: getLabConfigSelectValues,
-    setLabAsNA: setLabAsNA,
-    setSpawnActive: setSpawnActive,
-    updateProgressState: updateProgressState,
-    appendToLog: appendToLog,
-    updateSpawnEvents: updateSpawnEvents,
-    createFlavorInfo: createFlavorInfo,
-    updateNumberOfUsers: updateNumberOfUsers,
-  };
-
-  return utils;
-})
\ No newline at end of file
diff --git a/static/js/jhapi.js b/static/js/jhapi.js
index 23f64e6..862696c 100755
--- a/static/js/jhapi.js
+++ b/static/js/jhapi.js
@@ -103,8 +103,7 @@ define(["jquery", "utils"], function ($, utils) {
     options = update(options, { type: "POST" });
     options.data = JSON.stringify({
       failed: true,
-      progress: 100,
-      html_message: "<details><summary>Start cancelled by user.</summary>You clicked the cancel button.</details>"
+      progress: 100
     });
     this.api_request(
       utils.url_path_join("users/progress/events", user, server_name),
@@ -118,7 +117,7 @@ define(["jquery", "utils"], function ($, utils) {
     options.data = JSON.stringify({
       failed: true,
       progress: 100,
-      html_message: "<details><summary>Start cancelled by user.</summary>You clicked the cancel button.</details>"
+      html_message: "<details><summary>Start cancelled.</summary></details>"
     });
     this.api_request(
       utils.url_path_join("users/progress/events", user),
@@ -218,18 +217,6 @@ define(["jquery", "utils"], function ($, utils) {
     );
   };
 
-  JHAPI.prototype.remove_2fa = function (user, options) {
-    options = options || {};
-    options = update(options, { type: "DELETE", dataType: null });
-    this.api_request(utils.url_path_join("2FA"), options);
-  };
-
-  JHAPI.prototype.activate_2fa = function (user, options) {
-    options = options || {};
-    options = update(options, { type: "POST", dataType: null });
-    this.api_request(utils.url_path_join("2FA"), options);
-  };
-
   JHAPI.prototype.shutdown_hub = function (data, options) {
     options = options || {};
     options = update(options, { type: "POST" });
diff --git a/templates/footer.html b/templates/footer.html
index dad8e1e..931ea13 100644
--- a/templates/footer.html
+++ b/templates/footer.html
@@ -17,7 +17,7 @@
 <footer class="navbar mt-auto p-0">
   <div id="footer-top" class="container-fluid justify-content-evenly p-4">
     {#- We create a carousel to be able to show all systems in the footer #}
-    <div id="footerSystemsCarousel" class="carousel carousel-dark slide w-100" data-bs-ride="carousel" data-bs-interval="10000">
+    <div id="footerSystemsCarousel" data-sse-usercount class="carousel carousel-dark slide w-100" data-bs-ride="carousel" data-bs-interval="10000">
       <div  id="carousel-inner" class="carousel-inner">
         <!-- Carousel items will be injected here dynamically via JavaScript -->
       </div>
@@ -57,9 +57,8 @@
 
 {%- block script -%}
 <script type="text/javascript">
-require(["jquery", "home/utils"], function (
-  $, 
-  utils
+require(["jquery"], function (
+  $
 ) {
   "use strict";
 
@@ -148,13 +147,16 @@ require(["jquery", "home/utils"], function (
     }
 
     const ampelHtml = `
-      <div id="ampel-${systemLower}" class="text-center">
+      <div id="ampel-${systemLower}" class="text-center"
+          data-system=${system}
+          data-systemlower=${systemLower}
+          >
           <img class="ampel-img" src="${staticUrl}/images/footer/systems/${systemLower}.svg?v=${imgVersion}" />
           <a id="ampel-${systemLower}-tooltip" 
               href="https://status.jsc.fz-juelich.de/services/${systemId}" 
               target="_blank" 
               class="align-middle" 
-              data-bs-toggle="tooltip" 
+              data-bs-toggle="tooltip"
               data-bs-placement="top">
               ${displayName}
           </a>
@@ -259,18 +261,48 @@ require(["jquery", "home/utils"], function (
   $(document).ready(function() {
     createCarouselPages();
     updateSystemHoverTooltips();
-    utils.updateNumberOfUsers();
   })
 
-  if (!(window.location.pathname.endsWith("home") || window.location.pathname.includes("spawn-pending"))) {
-    console.log("setup SSE")
-    let userSpawnerNotificationUrl = `${jhdata.base_url}api/users/${jhdata.user}/notifications/spawners?_xsrf=${window.jhdata.xsrf_token}`;
-    evtSourcesGlobal["footer"] = new EventSource(userSpawnerNotificationUrl);
-    evtSourcesGlobal["footer"].onmessage = (e) => {
-      utils.updateNumberOfUsers();
-    };
-  }
-  
+
+  $(`[data-sse-usercount]`).on("sse", function (event, data) {
+    var systems = {};
+    $("div[id^='ampel']").each((i, e) => {
+      let system = $(e).attr("id").split('-')[1];
+      systems[system] = false;
+    })
+    // Update systems with info from request
+    for (const [system, usercount] of Object.entries(data)) {
+      switch (system) {
+        case 'jupyterhub':
+          $("#jupyter-users").html(usercount);
+          systems['jupyter'] = true;
+          break;
+        case 'JSC-Cloud':
+          $(`#jsccloud-users`).html(usercount['total']);
+          systems['jsccloud'] = true;
+          break;
+        default:
+          $(`#${system.toLowerCase()}-users`).html(usercount['total']);
+          systems[`${system.toLowerCase()}`] = true;
+          var partitionInfos = "";
+          for (const [partition, users] of Object.entries(usercount['partitions'])) {
+            partitionInfos += `\n${partition}: ${users}`;
+          }
+          $(`#${system.toLowerCase()}-users`)
+            .parents("[data-bs-toggle]")
+            .attr("data-bs-original-title", `Number of active servers${partitionInfos}`);
+      }
+    }
+    // If there was no info about a system, set running labs to 0 and reset tooltip
+    for (const [system, systemInfo] of Object.entries(systems)) {
+      if (systemInfo == false) {
+        $(`#${system}-users`).html(0);
+        $(`#${system.toLowerCase()}-users`)
+          .parents("[data-toggle]")
+          .attr("data-bs-original-title", `Number of active servers`);
+      }
+    }
+  });
 })
 </script>
 {%- endblock -%}
diff --git a/templates/header.html b/templates/header.html
index 69698b3..cd2ab61 100644
--- a/templates/header.html
+++ b/templates/header.html
@@ -34,6 +34,9 @@
   <div class="d-flex">
     {%- if user %}
     <li class="nav-item"><a id="{{prefix}}start-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}home">JupyterLab</a></li>
+    {%- if auth_state and "geant:dfn.de:fz-juelich.de:jsc:jupyter:workshop_instructors" in auth_state.get("groups", []) %}
+    <li class="nav-item"><a id="{{prefix}}workshop-manage-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}workshopmanager">Manage Workshops</a></li>
+    {%- endif -%}
     {%- if user.admin %}
     <li class="nav-item"><a id="{{prefix}}admin-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}admin">Admin</a></li>
     {%- endif -%}
diff --git a/templates/home.html b/templates/home.html
index b37808a..81eea44 100644
--- a/templates/home.html
+++ b/templates/home.html
@@ -1,499 +1,55 @@
 {%- extends "page.html" -%}
-{%- import "macros/home.jinja" as home -%}
-{%- import "macros/svgs.jinja" as svg -%}
 
 {%- block stylesheet -%}
   <link rel="stylesheet" href='{{static_url("css/home.css")}}' type="text/css"/>
 {%- endblock -%}
 
-{#- Set some convenience variables -#}
-{%- set lab_spawners = [] -%}
-{%- for s in spawners -%}
-  {%- if s.user_options -%}
-    {%- if (
-        "profile" in s.user_options 
-        and s.user_options.get("profile").startswith("JupyterLab")
-      )
-      or (
-        "service" in s.user_options
-        and s.user_options.get("service").startswith("JupyterLab")
-      )
-    -%}
-    {%- do lab_spawners.append(s) -%}
-    {%- endif -%}
-  {%- endif -%}
-{%- endfor -%}
-{%- set software_key = "JupyterLab" %}
-{%- set software_prefix = "jupyterlab" %}
-{%- set new = "new" -%}  {# id for new software entry #}
-
 {%- block main -%}
-<div class="container-fluid p-4">
-  {#- ANNOUNCEMENT #}
-  {%- if custom_config.get("announcement", {}).get("show", False) %}
-  {{ home.create_announcement(custom_config) }}
-  {%- endif -%}
-  {#- REAUTHENTICATE #}
-  {%- if auth_state and auth_state.get("reauthenticate", False) %}
-  <div class="alert bg-info alert-dismissible fade show" style="color: #023d6b;" role="alert">
-    <span class="align-middle">  Your access to the HPC-systems has been updated. <a style="text-decoration-line: underline; "href={{base_url}}logout?alldevices=false&stop=false&next=oauth_login> Please click here to reload. </a></span>
-    <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
-  </div>
-  {%- endif -%}
-
-  {#- TABLE #}
-  <p>You can configure your existing JupyterLabs by expanding the corresponding table row.</p>
-
-  <div class="table-responsive-md">
-    <table id="jupyterlabs-table" class="table table-bordered table-striped table-hover table-light align-middle">
-    {#- TABLE HEAD #}
-      <thead class="table-secondary">
-        <tr>
-          <th scope="col" width="1%"></th>
-          <th scope="col" width="20%">Name</th>
-          <th scope="col">Configuration</th>
-          <th scope="col" width="10%;">Status</th>
-          <th scope="col" width="10%;">Actions</th>
-        </tr>
-      </thead>
-      {#- TABLE BODY #}
-      <tbody>
-        {#- New JupyterLab row #}
-        <tr data-server-id="{{ software_prefix }}-{{ new }}" class="new-spawner-tr summary-tr">
-          <th scope="col" class="details-td">
-            <div class="d-flex mx-4">
-              <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-plus-lg m-auto" viewBox="0 0 16 16">
-                <path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2Z"/>
-              </svg>
-            </div>
-          </th>
-          <th scope="row" colspan="100%" class="text-center">New JupyterLab</th>
-        </tr>
-        {{ home.create_collapsible_tr(software_key, software_prefix, None, {}, custom_config, lab_id=new) }}
-        {#- Existing JupyterLab rows -#}
-        {#- By looping through lab_spawners #}
-        {# {%- for spawner in lab_spawners -%}
-          {%- set spawner_name = user.spawners[spawner.name].name -%}
-          {%- set user_options = spawner.user_options -%}
-          {{ home.create_summary_tr(software_key, software_prefix, spawner_name, user_options) }}
-          {{ home.create_collapsible_tr(software_key, software_prefix, spawner_name, user_options, custom_config) }}
-        {%- endfor %} #}
-      </tbody>
-    </table>
-  </div>  {#- table responsive #}
-</div>  {#- container fluid #}
-{%- endblock -%}
-
+{%- import "macros/table/config/home.jinja" as config %}
+{%- import "macros/svgs.jinja" as svg -%}
+{%- import "macros/table/variables.jinja" as vars with context %}
 
-{%- block script -%}
-<script>
-{#- Manually sets some cancel related variables -#}
-{%- set cancel_progress_activation = 0 -%}
-{#- Percentage when cancel should be disabled again
-    since it is already in progress -#}
-{%- set cancel_progress_deactivation = 99 %}
+{%- set pagetype = vars.pagetype_home %}
 
-{#- Save some global variables #}
-var evtSources = {};
-var userOptions = {};
-var spawnEvents = {};
+{%- set table_rows = {vars.first_row_id: {}} %}
 
-{%- for spawner in lab_spawners -%}
-  {%- set userOptions = decrypted_user_options[spawner.name] or {} -%}
-userOptions["{{spawner.name}}"] = {{ userOptions | tojson }};
-  {%- if spawner.state and spawner.state.get("events") %}
-spawnEvents["{{spawner.name}}"] = {{ spawner.state.get("events") | tojson }};
-  {%- else -%}
-  {#- We still want to show a "latest" entry for the log dropdown,
-  so we manually create an entry for spawners without events #}
-spawnEvents["{{spawner.name}}"] = {"latest": []};
-  {%- endif -%}
+{%- for spawner in user.spawners.values() %}
 {%- endfor %}
-var spawnActive = {};
-{% for spawner in user.spawners.values() -%}
-  {% if spawner.name -%}
-    {% if spawner.pending -%}
-      spawnActive["{{spawner.name}}"] = "pending";
-    {% elif spawner.ready -%}
-      spawnActive["{{spawner.name}}"] = "ready";
-    {% else -%}
-      spawnActive["{{spawner.name}}"] = false;
-    {%- endif %}
+{%- for spawner in spawners %}
+  {%- if ( spawner.name and spawner.name in user.spawners.keys() ) or 
+         ( spawner.user_options and spawner.user_options.get("name", false) ) %}
+    {%- set _ = table_rows.update({spawner.name: spawner.user_options}) %}
   {%- endif %}
 {%- endfor %}
 
-var systemsHealth = {
-threshold: {
-    interactive: {{custom_config.get("incidentCheck", {}).get("healthThreshold", {}).get("interactive", 50) | int}}, 
-    compute: {{custom_config.get("incidentCheck", {}).get("healthThreshold", {}).get("compute", 40) | int}}
-  }
-};
-{%- for system, system_info in incidents.items() %}
-systemsHealth["{{system}}"] = {{ system_info.health }};
-{%- endfor %}
-
-var flavorInfo = {{ outpostflavors | tojson }};
-</script>
-
-<script>
-/* (Mostly) Jinja dependent functions:
- * Define get funtions to enable the use of jinja variables (supplied by the backend) within the JavaScript classes (otherwise they are not reachable)
- */
-function getHostname() {
-  return {{hostname | tojson}} || {};
-}
-
-function getEntitlements() {
-  return {{auth_state.get("entitlements", []) | tojson}} || [];
-}
-
-function getMapSystems() {
-  return {{custom_config.get("mapSystems", {}) | tojson }};
-}
-
-function getDropdownOptions() {
-  return {{auth_state.get("options_form", {}).get("dropdown_list", {}) | tojson}};
-}
-
-function getService(options) {
-  if ("profile" in options)
-    return options["profile"].split('/')[1];
-  else 
-    return options["service"].split('/')[1];
-}
-
-function getServiceInfo() {
-  return {{custom_config.get("services") | tojson}} || {};
-}
-
-function getShareInfo() {
-  return {{custom_config.get("share") | tojson}} || {};
-}
-
-function getBinderRepos() {
-  return {{custom_config.get("binderRepos") | tojson}} || {};
-}
-
-
-function getBackendServiceInfo() {
-  return {{custom_config.get("backendServices") | tojson}} || {};
-}
-
-function getSystemInfo() {
-  return {{custom_config.get("systems") | tojson}} || {};
-}
-
-function getReservationInfo() {
-  return {{auth_state.get("options_form").get("reservations") | tojson}} || {};
-}
-
-function getResourceInfo() {
-  return {{auth_state.get("options_form").get("resources") | tojson}} || {};
-}
+{%- from "macros/table/table.jinja" import tables with context %}
+{%- import "macros/table/content.jinja" as functions with context %}
+<div id="toastContainer" class="position-fixed top-0 end-0 p-3"></div>
+{{ tables(
+  config.frontend_config,
+  functions.home_description,
+  functions.home_headerlayout,
+  functions.home_defaultheader,
+  functions.home_firstheader,
+  functions.row_content,
+  {
+    "stop": "workshopButtonStop",
+    "start": "workshopButtonStart",
+    "open": "homeOpen",
+    "cancel": "workshopButtonCancel",
+    "del": "homeButtonDelete"
+  },
+  functions.sse_functions
+) }}
 
-function getModuleInfo() {
-  return {{custom_config.get("userModules", {}) | tojson}} || {};
-}
 
-function getInfoSvg() {
-  return `{{ svg.info_svg | safe }}`;
-}
 
-function getLinkSvg() {
-  return `{{ svg.link_svg | safe }}`;
-}
-
-function get_4_2_system(kwargs) {
-  return ["JUSYSTEM1", "JUSYSTEM2", "JSC-Cloud"];
-}
-
-function onEvtMessage(event, id) {
-  function _updateProgress(infoText, background="", html="") {
-    $(`#${id}-progress-bar`)
-      .width(100)
-      .removeClass("bg-success bg-danger")
-      .addClass(background)
-      .html(html);
-    $(`#${id}-progress-info-text`).html(infoText);
-  }
-
-  const evt = JSON.parse(event.data);
-  spawnEvents[id]["latest"].push(evt);
-  let tr = $(`.summary-tr[data-server-id=${id}]`);
-  if (evt.progress !== undefined && evt.progress != 0) {
-    if (evt.progress == 100) {  // Spawn finished
-      evtSources[id].close();
-      delete evtSources[id];
-      if (evt.failed) {  // Spawn failed
-        spawnActive[id] = false;
-        // All other UI updates all handled by the evtSourcesGlobal["home"]
-        // so that they happend after the stop has finished in the backend
-      }
-      else if (evt.ready) {  // Spawn successful
-        spawnActive[id] = "ready";
-        _updateProgress("running", "bg-success");
-        _updateLabButtons(id, true);
-      }
-    }
-    else { // Spawn in progress
-      spawnActive[id] = "pending";
-      let collapsibleTr = $(`.collapsible-tr[data-server-id=${id}]`);
-      let collapseBtns = collapsibleTr.find("button").not(".nav-link");
-      collapseBtns.addClass("disabled");
-      if (evt.progress == {{cancel_progress_deactivation}}) {
-        _updateProgress("cancelling...", "bg-danger", `<b>${evt.progress}%</b>`)
-        tr.find(".btn-cancel-lab").addClass("disabled");
-      }
-      else {
-        _updateProgress("spawning...", "", `<b>${evt.progress}%</b>`)
-        if (evt.progress >= {{cancel_progress_activation}} 
-          && evt.progress < {{cancel_progress_deactivation}}) {
-          tr.find(".btn-cancel-lab").removeClass("disabled");
-        }
-      }
-    }    
-  }
-
-  if (evt.html_message !== undefined) {
-    var htmlMsg = evt.html_message
-  } else if (evt.message !== undefined) {
-    var htmlMsg = evt.message;
-  }
-  if (htmlMsg) {
-    // Only append if latest log is selected
-    if ($(`#${id}-log-select`).val() == "latest") {
-      // appendToLog($(`#${id}-log`), htmlMsg);
-      try { htmlMsg = htmlMsg.replace(/&nbsp;/g, ' '); }
-      catch (e) { return; } // Not a valid htmlMsg
-      // Only append if a log message has not been appended yet
-      var exists = false;
-      $(`#${id}-log`).children().each(function (i, e) {
-        let logMsg = $(e).html();
-        if (htmlMsg == logMsg) exists = true;
-      })
-      if (!exists)
-        $(`#${id}-log`).append($('<div class="log-div">').html(htmlMsg));
-    }
-  }
-}
-
-function _updateLabButtons(id, running) {
-  let tr = $(`.summary-tr[data-server-id=${id}]`);
-  let collapsibleTr = $(`.collapsible-tr[data-server-id=${id}]`);
-  let collapseBtns = collapsibleTr.find("button").not(".nav-link");
-  if (running) {
-    // Show open/cancel for starting labs
-    tr.find(".btn-na-lab, .btn-start-lab, .btn-cancel-lab")
-      .addClass("disabled")
-      .hide();
-    tr.find(".btn-open-lab, .btn-stop-lab")
-      .removeClass("disabled")
-      .show(); 
-  }
-  else {
-    // Show start or na for non-running labs
-    var na = tr.find(".na-status").text() || 0;
-    if (na != "0") {
-      tr.find(".btn-na-lab").removeClass("disabled").show();
-      tr.find(".btn-start-lab").addClass("disabled").hide();
-    }
-    else {
-      tr.find(".btn-na-lab").hide()
-      tr.find(".btn-start-lab").removeClass("disabled").show();
-    }
-    tr.find(".btn-open-lab, .btn-cancel-lab, .btn-stop-lab")
-      .addClass("disabled").hide();
-  }
-  collapseBtns.removeClass("disabled");
-}
-</script>
-
-<script>
-require(["jquery", "jhapi", "home/utils", "home/dropdown-options", "home/lab-configs"], function (
-  $,
-  JHAPI,
-  utils,
-  dropdowns,
-  lab
-) {
-  "use strict";
-
-  var base_url = window.jhdata.base_url;
-  var api = new JHAPI(base_url);
-
-  /*
-    On page load
-  */
-  $(document).ready(function() {
-    const sharedOptions = JSON.stringify({{ spawner_options_form_values | safe }});
-    if (sharedOptions) {
-      const sharedOp = JSON.parse(sharedOptions);
-      let id = "{{ server_name }}";
-      let available = lab.checkIfAvailable(id, sharedOp);
-      lab.setUserOptions(id, sharedOp, available);
-    }
-    else {
-      {# for  (const id of Object.keys(userOptions)) {
-        let available = lab.checkIfAvailable(id, userOptions[id]);
-        lab.setUserOptions(id, userOptions[id], available);
-      }
-      updateSpawnProgress(); -#}
-
-      {# Set initial value, which will trigger to fill other dropdowns #}
-      const defaultOptionTab = "{{ custom_config.get("services", {}).get(software_key, {}).get("frontend", {}).get("versionsSelect", {}).get("tab", "") }}";
-      const defaultOptionKey = "{{ custom_config.get("services", {}).get(software_key, {}).get("frontend", {}).get("versionsSelect", {}).get("key", "") }}";
-      const defaultOptionValue = "{{ custom_config.get("services", {}).get(software_key, {}).get("frontend", {}).get("versionsSelect", {}).get("defaultValue", "") }}";
-      let select = $(`select[id*=${defaultOptionTab}-${defaultOptionKey}]`);
-      {%- for versionName, versionOptions in custom_config.get("services", {}).get(software_key, {}).get("options", {}).items() %}
-        select.append(`<option value="{{versionName}}">{{versionOptions.get("name", versionName)}}</option>`);
-      {%- endfor %}
-      select.val(defaultOptionValue);
-      setTimeout(() => {
-        select.trigger("change");
-      }, 50);
-
-      {# dropdowns.updateServices("{{ software_key }}", "{{ software }}-{{ new }}"); #}
-
-      {# $("#{{ software }}-{{ new }}-log-select").prepend(`<option value="latest">latest</option>`); #}
-    }
-
-    // Remove all tab warnings since initial changes shouldn't cause warnings
-    $("[id$=tab-warning]").addClass("invisible");
-  })
-
-  // Add event source for user spawner events
-  let userSpawnerNotificationUrl = `${jhdata.base_url}api/users/${jhdata.user}/notifications/spawners?_xsrf=${window.jhdata.xsrf_token}`;
-  evtSourcesGlobal["home"] = new EventSource(userSpawnerNotificationUrl);
-  evtSourcesGlobal["home"].onmessage = (e) => {
-    const data = JSON.parse(e.data);
-    const spawning = data.spawning || [];
-    const stopped = data.stoppedall || [];
-    var spawnEvents = window.spawnEvents;
-    utils.updateNumberOfUsers();
-
-    // Create eventListeners for new labs if they don't exist
-    for (const id of spawning) {
-      utils.setSpawnActive(id, "pending");
-      if (!(id in spawnEvents)) {
-        spawnEvents[id] = { "latest": [] };
-      }
-      if (!(id in evtSources)) {
-        utils.updateSpawnEvents(spawnEvents, id);
-
-        let progressUrl = `${window.jhdata.base_url}api/users/${window.jhdata.user}/servers/${id}/progress?_xsrf=${window.jhdata.xsrf_token}`;
-        evtSources[id] = new EventSource(progressUrl);
-        evtSources[id].onmessage = function (e) {
-          onEvtMessage(e, id);
-        }
-        // Reset progress bar and log for new spawns
-        $(`#${id}-progress-bar`)
-          .width(0).html("")
-          .removeClass("bg-danger bg-success");
-        $(`#${id}-progress-info-text`).html("");
-        $(`#${id}-log`).html("");
-        // Update buttons to reflect pending state
-        let tr = $(`tr.summary-tr[data-server-id=${id}]`);
-        // _enableTrButtonsRunning
-        tr.find(".btn-na-lab, .btn-start-lab").hide();
-        tr.find(".btn-open-lab, .btn-cancel-lab").show().addClass("disabled");
-      }
-    }
-
-    for (const id of stopped) {
-      if (!id) continue; // Filter out labs with no name
-      utils.updateProgressState(id, "reset");
-      // Change buttons to start or N/A
-      _updateLabButtons(id, false);
-    }
-    // We have updated flavor information, check if we need to update any flavor UI elements
-    window.flavorInfo = data.outpostflavors || window.flavorInfo;
-    for (const id of Object.keys(userOptions)) {
-      const values = utils.getLabConfigSelectValues(id);
-      dropdowns.updateFlavors(id, values.service, values.system, values.flavor);
-    }
-
-    const sharedOptions = JSON.stringify({{ spawner_options_form_values | safe }});
-    if (sharedOptions) {
-      const sharedOp = JSON.parse(sharedOptions);
-      let id = sharedOp["name"];
-    //  const sharedValues = utils.getLabConfigSelectValues(id);
-    //  dropdowns.updateFlavors(id, sharedValues.service, sharedValues.system, sharedValues.flavor);
-    }
-    else {
-       // The jinja2 variable "new" points to the id of a new JupyterLab, e.g. "new-jupyterlab"
-      const newLabValues = utils.getLabConfigSelectValues("{{ software }}-{{ new }}");
-      dropdowns.updateFlavors("{{ software }}-{{ new }}", newLabValues.service, newLabValues.system, newLabValues.flavor);
-    }
-  };
-
-  /*
-    Jinja dependent function definitions
-  */
-  function updateSpawnProgress() {
-    {%- for spawner in lab_spawners %}
-    var id = "{{spawner.name}}";
-    var latestEvents = spawnEvents[id]["latest"] || [];
-    // Append log messages
-    for (const event of latestEvents) {
-      utils.appendToLog($(`#${id}-log`), event["html_message"]);
-    }
-    // Add options to log select and select the latest log by default
-    var logSelect = $(`#${id}-log-select`);
-    for (const log in spawnEvents[id]) {
-      if (log == "latest") logSelect.prepend(`<option value="${log}">${log}</option>`);
-      else logSelect.append(`<option value="${log}">${log}</option>`);
-    }
-    logSelect.val("latest");
-    
-    {%- set s = user.spawners[spawner.name] -%}
-    {%- if s.active -%}
-      {%- if s.ready %}
-      utils.updateProgressState(id, "running");
-      {%- elif not s._stop_pending %}
-      var tr = $(`#${id}.summary-tr`);
-      tr.find(".btn-open-lab").addClass("disabled");
-      var currentProgress = 0;
-      if (latestEvents.length > 0) {
-        let lastEvent = latestEvents.slice(-1)[0];
-        currentProgress = lastEvent.progress;
-      }
-      if (currentProgress < {{cancel_progress_activation}}
-        || currentProgress >= {{cancel_progress_deactivation}}) {
-        tr.find(".stop, .cancel").addClass("disabled");
-      }
-      // Disable the delete button during the spawn process.
-      var collapse = $(`.collapsible-tr[data-server-id=${id}]`);
-      collapse.find(".btn-delete-lab").addClass("disabled");
-      // Update progress with percentage also
-      $(`#${id}-progress-bar`)
-          .width(100)
-          .html(`<b>${currentProgress}%</b>`);
-      $(`#${id}-progress-info-text`).html("spawning...");
-      // Add an event listener to catch and display updates.
-      var progressUrl = `${jhdata.base_url}api/users/${jhdata.user}/servers/${id}/progress?_xsrf=${window.jhdata.xsrf_token}`;
-      evtSources[id] = new EventSource(progressUrl);
-      {%- endif %}
-    {%- elif s._failed or s._cancel_event_yielded %}
-    var id = "{{s.name | safe}}";
-    utils.updateProgressState(id, "failed");
-    {%- endif -%}
-
-    {%- endfor %}
-
-    for (const id in evtSources) {
-      evtSources[id].onmessage = function (e) {
-        onEvtMessage(e, id);
-      }
-    }
-  }
+{%- endblock -%}
 
-})
-</script>
 
-<script src='{{static_url("js/home/handle-events.js", include_version=True) }}' type="text/javascript" charset="utf-8"></script>
-<script src='{{static_url("js/home/handle-servers.js", include_version=True) }}' type="text/javascript" charset="utf-8"></script>
-<script>
-$("nav [id$=nav-item]").removeClass("active");
-$("#start-nav-item, #collapse-start-nav-item").addClass("active");
-</script>
-{%- endblock -%}
+{%- block script -%}
+{%- import "macros/table/variables.jinja" as vars with context %}
+{%- set pagetype = vars.pagetype_home %}
+{%- import "macros/table/config/home.jinja" as config with context %}
+{%- include "macros/table/elements_js.jinja" with context %}
+{%- endblock %}
diff --git a/templates/macros/home.jinja b/templates/macros/home.jinja
index be375fc..618800c 100644
--- a/templates/macros/home.jinja
+++ b/templates/macros/home.jinja
@@ -12,12 +12,12 @@
 </div>
 {%- endmacro -%}
 
-{%- macro create_summary_tr(software_key, software_prefix, spawner_name, user_options, lab_id="", share_structure=false) -%}
+{%- macro create_summary_tr(s, user_options, lab_id="", share_structure=false) -%}
 
 {%- set name = user_options.get("name", "") -%}
-{%- if lab_id != "" %} {%- set id = software_prefix ~ "-" ~ lab_id -%}
-{%- elif spawner_name %} {%- set id = software_prefix ~ "-" ~ spawner_name -%}
-{%- else %} {%- set id = software_prefix ~ "-new-jupyterlab" -%}
+{%- if lab_id != "" %} {%- set id = lab_id -%}
+{%- elif s %} {%- set id = s.name -%}
+{%- else %} {%- set id = "new-jupyterlab" -%}
 {%- endif -%}
 
 {%- set system = user_options.get("system", "") -%}
@@ -120,103 +120,175 @@
 </td>
 {%- endmacro -%}
 
-{%- macro create_collapsible_tr(software_key, software_prefix, spawner_name, user_options, custom_config, lab_id="", share_structure=false) -%}
+{%- macro create_collapsible_tr(s, user_options, custom_config, lab_id="", share_structure=false) -%}
 
 {%- set name = user_options.get("name", "") -%}
-{%- set new_lab_id = software_prefix ~ "-new" %}
-{%- if lab_id != "" %} {%- set id = software_prefix ~ "-" ~ lab_id -%}
-{%- elif spawner %} {%- set id = software_prefix ~ "-" ~ spawner_name -%}
-{%- else %} {%- set id = software_prefix ~ "-new" -%}
+{%- set new_lab_id = "new-jupyterlab" %}
+{%- if lab_id != "" %} {%- set id = lab_id -%}
+{%- elif s %} {%- set id = s.name -%}
+{%- else %} {%- set id = "new-jupyterlab" -%}
 {%- endif -%}
 
 <tr data-server-id="{{id}}" class="collapsible-tr" style="--bs-table-accent-bg: transparent;">
   <td colspan="100%" class="p-0">  {#- Remove padding to hide td when collapsed #}
     <div class="collapse{% if share_structure %} show {% endif %}" id="{{id}}-collapse">
       <div class="d-flex align-items-start m-3">
-
-
-
         {#- TAB NAV PILLS -#}
         {%- set nav_tab_margins = "mb-3" %}
         <div class="nav flex-column nav-pills p-3 ps-0" id="{{ id }}-tab" role="tablist">
-          {#- In the custom config we defined the required sidebar navigations for this service
-            We create a tab + button for each of them, and fill them with all required values.
-            Later, we will se what we want to show / hide.
-            This will be updated, everytime an event is triggered.
-            #}
-          {%- for navsidebar in custom_config.services.get(software_key, {}).get("frontend", {}).get("navsidebar", []) -%}
-            {%- set counter = loop.index0 -%}
-            {%- for key, options in navsidebar.items() -%}
-              <button class="nav-link {{ nav_tab_margins }} {% if counter > 0 %}d-none{% endif %}" id="{{ id }}-{{ key }}-tab" data-bs-toggle="pill" data-bs-target="#{{ id }}-{{ key }}" type="button" role="tab">
-                <span>{{ options.label }}</span>
-                  <span id="{{id}}-resources-tab-warning" class="d-flex invisible">
-                  {{ svg.warning_svg | safe }}
-                  <span class="visually-hidden">settings changed</span>
-                </span>
-              </button>
-            {%- endfor -%}
-          {%- endfor -%}
+          <button class="nav-link active {{ nav_tab_margins }}" id="{{ id }}-config-tab" data-bs-toggle="pill" data-bs-target="#{{ id }}-config" type="button" role="tab">Lab Config</button>
+          <button class="nav-link {{ nav_tab_margins }}" id="{{ id }}-resources-tab" data-bs-toggle="pill" data-bs-target="#{{ id }}-resources" type="button" role="tab">
+            <span>Resources</span>
+            <span id="{{id}}-resources-tab-warning" class="d-flex invisible">
+              {{ svg.warning_svg | safe }}
+              <span class="visually-hidden">settings changed</span>
+            </span>
+          </button>
+          <button class="nav-link {{ nav_tab_margins }}" id="{{ id }}-modules-tab" data-bs-toggle="pill" data-bs-target="#{{ id }}-modules" type="button" role="tab">
+            <span>Kernels and Extensions</span>
+            <span id="{{id}}-modules-tab-warning" class="d-flex invisible">
+              {{ svg.warning_svg | safe }}
+              <span class="visually-hidden">settings changed</span>
+            </span>
+          </button>
           {%- if id != new_lab_id %}
-            <button class="nav-link {{ nav_tab_margins }}" id="{{ id }}-logs-tab" data-bs-toggle="pill" data-bs-target="#{{ id }}-logs" type="button" role="tab">Logs</button>
+          <button class="nav-link {{ nav_tab_margins }}" id="{{ id }}-logs-tab" data-bs-toggle="pill" data-bs-target="#{{ id }}-logs" type="button" role="tab">Logs</button>
           {%- endif %}
         </div>
-
-
-
         {#- TAB NAV CONTENT -#}
-        {#- We create all elements for all tabs, but everything will be hidden.
-            It will be filled with values later via JS, same goes for display/hidden #}
+        {#- We only create empty elements here as they will be filled via JS #}
         <div class="tab-content w-100" id="{{ id }}-tabContent">
-          {# Create a block for each version of the software, always start with the general configuration of the software
-             We only add `tabs` which are also available in `navsidecar` #}
-          {%- for version_name, version_options in custom_config.services.get(software_key, {}).get("options", {}).items() %}
-            {%- for nav_item in custom_config.services.get(software_key, {}).get("frontend", {}).get("navsidebar", []) %}
-              {%- set counter = loop.index0 -%}
-              {%- for tab_key in nav_item.keys() %}
-                {%- set _id = id ~ "-" ~ version_name ~ "-" ~ tab_key %}
-                <div class="{% if counter > 0 %}d-none{% endif %} tab-pane fade show active" id="{{ _id }}" role="tabpanel">
-                  <form id="{{ _id }}-form">
-                    {# This blocks comes from the software.frontend configuration and is added to all versions #}
-                    {%- for tabOption in custom_config.services.get(software_key, {}).get("frontend", {}).get("tabs", {}).get(tab_key, []) %}
-                      {%- if tabOption.show is boolean %}
-                        {%- set show = tabOption.show %}
-                      {%- else %}
-                        {%- set show = false %}
-                      {%- endif %}
-                      {%- if tabOption.type == "inputtext" %}
-                        {{ inputs.create_text_input_2(_id, software_key, tab_key, tabOption.key, tabOption.options, tabOption.get("label", {}), show ) }}
-                      {%- elif tabOption.type == "dropdown" %}
-                        {{ inputs.create_select_2(_id, software_key, tab_key, tabOption.key, tabOption.options, tabOption.get("label", {}), true ) }}
-                      {%- elif tabOption.type == "hr" %}
-                        <hr>
-                      {%- endif %}
-                    {%- endfor %}
-                    {# Version specific #}
-                    <div id={{ _id }}-specific>
-                      {# This block is specific for each version of the software 
-                        In the end we can simply show the right div and hide the others #}
-                      {%- for tabOption in version_options.get("frontend", {}).get("tabs", {}).get(tab_key, {}).get("options", []) %}
-                        {%- if tabOption.type == "dropdown" %}
-                          {{ inputs.create_select_2(_id, software_key, tab_key, tabOption.key, tabOption.options, tabOption.label, true ) }}
-                        {%- elif tabOption.type == "flavorsummary" %}
-                          {{ create_flavor_summary(_id, software_key, tab_key, tabOption.key, tabOption.options, true ) }}
-                        {%- elif tabOption.type == "number" %}
-                          {{ inputs.create_number_input_2(_id, software_key, tab_key, tabOption.key, tabOption.options, tabOption.label, true ) }}
-                        {%- elif tabOption.type == "reservationsummary" %}
-                          {{ create_reservation_summary(_id, software_key, tab_key, tabOption.key, true) }}
-                        {%- elif tabOption.type == "multiple_checkboxes" %}
-                          {{ inputs.create_multiple_checkboxes(_id, software_key, tab_key, tabOption.key, tabOption.options, tabOption.label, custom_config, true ) }}
-                        {%- endif %}
-                      {%- endfor %}
-                    </div>
-                  </form>
-                  {{ create_lab_config_buttons_2(_id, add_save_reset_buttons=true) }}
-                  {#- {{ create_lab_config_buttons(id, id == new_lab_id or share_structure) }} #}
+          {#- Lab Config #}
+          <div class="tab-pane fade show active" id="{{ id }}-config" role="tabpanel">
+            <form id="{{id}}-lab-config-form">
+              {{ inputs.create_text_input(id, "name", placeholder="Give your lab a name") }}
+              {{ inputs.create_select(id, "version", custom_config.get("services").get("JupyterLab").get("optionsName", "Version")) }}
+              {#- Docker images #}
+              {%- call inputs.create_text_input(id, "image", 
+                placeholder="e.g. jupyter/datascience-notebook",
+                warning="Please enter a valid docker image, e.g. jupyter/datascience-notebook",
+                persistent_hover=True) %}
+                A public registry docker image starting a single-user notebook server.
+                <a href='https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html' target='_blank' style='color: white !important;'>Examples.</a>
+              {%- endcall %}
+              {#- Fields for private docker repository #}
+              {{ inputs.create_checkbox_input(id, "image-private-cb", "Private repository")}}
+              {%- call inputs.create_text_input(id, "image-private-url", "Image Repository",
+                placeholder="URL for your image registry",
+                pattern="^(([a-zA-Z0-9.\-]+)(:[0-9]+)?\/)?([a-zA-Z0-9._\-]+\/)*[a-zA-Z0-9._\-]+(:[a-zA-Z0-9._\-]+|@[A-Fa-f0-9]+(:[A-Fa-f0-9]+)*)?$",
+                warning="Please enter a valid docker repository URL") %}
+              {%- endcall %}
+              {%- call inputs.create_text_input(id, "image-private-user", "Username",
+                placeholder="Please enter your username") %}
+                Username for the private docker repository
+              {%- endcall %}
+              {{ inputs.create_password_input(id, "image-private-pass", "Password", placeholder="Please enter your password")}}
+              {#-----#}
+              {{ inputs.create_checkbox_input(id, "image-mount-cb", "Mount user data")}}
+              {%- call inputs.create_text_input(id, "image-mount", "User data path",
+                pattern="^\/[A-Za-z0-9\-\/]+",
+                warning="Please input a valid Unix-style path, e.g. /mnt/userdata") %}
+                Path to which your persistent user data will be mounted
+              {%- endcall %}
+              <hr>
+              {#- Repo2Docker fields #}
+              {{ inputs.create_select(id, key="type", label="Repository") }}
+              {{ inputs.create_text_input(id, key="repo", label="Repository URL", placeholder="GitHub repository name or URL") }}
+              {{ inputs.create_text_input(id, key="gitref", label="Git ref (branch,tag, or commit)", placeholder="HEAD") }}
+              {{ inputs.create_text_input(id, key="notebook", label="URL path to notebook (optional)", placeholder="URL path to notebook (optional)", clazz="optional") }}
+              {{ inputs.create_select(id, key="notebook_type", label="Notebook Type") }}
+
+              {#- Standard HPC system fields #}
+              {{ inputs.create_select(id, "system") }}
+              {{ inputs.create_select(id, "flavor") }}
+              <div id="{{id}}-flavor-legend-div" class="row align-items-center g-0 mt-4">
+                <span class="col-4 fw-bold">Available Flavors</span>
+                <div class="col d-flex align-items-center ms-2">
+                  {%- set box_style = "height: 15px; width: 15px; border-radius: 0.25rem;"%}
+                  <div style="{{box_style}} background-color: #198754;"></div>
+                  <span class="ms-1">= Free</span>
+                  <span class="mx-2"></span>
+                  <div style="{{box_style}} background-color: #023d6b;"></div>
+                  <span class="ms-1">= Used</span>
+                  <span class="mx-2"></span>
+                  <div style="{{box_style}} background-color: #dc3545;"></div>
+                  <span class="ms-1">= Limit exceeded</span>
+                </div>
+              </div>
+              <div id="{{id}}-flavor-info-div" class="mb-3"></div>
+              {{ inputs.create_select(id, "account") }}
+              {{ inputs.create_select(id, "project") }}
+              {{ inputs.create_select(id, "partition") }}
+              <hr id="{{id}}-reservation-hr">
+              {{ inputs.create_select(id, "reservation") }}
+              <div id="{{id}}-reservation-info-div" class="row mb-3">
+                {%- set reservation_info_classes = "col-4 fw-bold"%}
+                <div id="{{id}}-reservation-info" class="col-8 offset-4">
+                  <div class="row">
+                    <span class="{{ reservation_info_classes }}">Start Time:</span>
+                    <span id="{{id}}-reservation-start" class="col-auto"></span>
+                  </div>
+                  <div class="row">
+                    <span class="{{ reservation_info_classes }}">End Time:</span>
+                    <span id="{{id}}-reservation-end" class="col-auto"></span>
+                  </div>
+                  <div class="row">
+                    <span class="{{ reservation_info_classes }}">State:</span>
+                    <span id="{{id}}-reservation-state" class="col-auto"></span>
+                  </div>
+                  <div class="mt-1">
+                    <details>
+                      <summary class="fw-bold">Detailed reservation information:</summary>
+                      <pre id="{{id}}-reservation-details"></pre>
+                      {#- TODO: Fix horizontal width upon expanding the detail #}
+                    </details>
+                  </div>
                 </div>
-              {%- set first_navitem = false %}
+              </div>
+            </form>
+            {{ create_lab_config_buttons(id, id == new_lab_id or share_structure) }}
+          </div>
+          {#- Lab Resources #}
+          <div class="tab-pane fade" id="{{ id }}-resources" role="tabpanel">
+            <form id="{{id}}-resources-form">
+              {{ inputs.create_number_input(id, "nodes") }}
+              {{ inputs.create_number_input(id, "gpus", "GPUs") }}
+              {{ inputs.create_number_input(id, "runtime", "Runtime (minutes)") }}
+              {{ inputs.create_checkbox_input(id, "xserver-cb", "Activate XServer")}}
+              {{ inputs.create_number_input(id, "xserver", "Use XServer GPU Index") }}
+            </form>
+            {{ create_lab_config_buttons(id, id == new_lab_id or share_structure) }}
+          </div>
+          {#- User-selected Modules #}
+          <div class="tab-pane fade" id="{{ id }}-modules" role="tabpanel">
+            <form id="{{id}}-modules-form">
+              {%- for module_set in custom_config.get("userModules", {}).keys() %}
+              <div id="{{id}}-{{module_set}}-div">
+                <h4>{{ module_set | title}}</h4>
+                <div id="{{id}}-{{module_set}}-checkboxes-div" class="row g-0"></div>
+              </div>
               {%- endfor %}
-            {%- endfor %}
-          {%- endfor %}
+            </form>
+            <hr>
+            <div id="{{id}}-modules-selector-div" class="row g-0">
+              {%- set module_cols = "col-sm-6 col-md-4 col-lg-3" %}
+              <div class="form-check {{module_cols}}">
+                <input class="form-check-input module-selector" type="checkbox" id="{{id}}-modules-select-all">
+                <label class="form-check-label" for="{{id}}-modules-select-all">Select all</label>
+              </div>
+              <div class="form-check {{module_cols}}">
+                <input class="form-check-input module-selector" type="checkbox" id="{{id}}-modules-select-none">
+                <label class="form-check-label" for="{{id}}-modules-select-none">Deselect all</label>
+              </div>
+            </div>
+            {{ create_lab_config_buttons(id, id == new_lab_id or share_structure) }}
+          </div>
+          {#- Lab Logs #}
+          <div class="tab-pane fade" id="{{ id }}-logs" role="tabpanel">
+              {{ inputs.create_select(id, "log") }}
+              <div id="{{id}}-log" class="card card-body"></div>
+              {{ create_lab_config_buttons(id, id == new_lab_id or share_structure) }}
+          </div>
         </div> {#- End of tab content #}
       </div> {#- End of d-flex #}
     </div> {#- End of collapse #}
@@ -224,100 +296,6 @@
 </tr>
 {%- endmacro -%}
 
-{%- macro create_share_modal(id) %}
-<!-- Modal -->
-<div class="modal fade" id="{{ id }}-share-link" role="dialog" tabindex="-1">
-  <div class="modal-dialog modal-dialog-centered">
-
-    <!-- Modal content-->
-    <div class="modal-content">
-      <div class="modal-header">
-        <h4 class="modal-title">Share Lab</h4>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
-      </div>
-      <div class="modal-body">
-        <p>Share your lab via URL</p>
-        <a href=""></a>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-default" data-bs-dismiss="modal">Close</button>
-        <button type="button" id="{{id}}-copy-btn" class="btn btn-outline-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="Copy to clipboard">Copy</button>
-      </div>
-    </div>
-
-  </div>
-</div>
-{%- endmacro %}
-
-{%- macro create_reservation_summary(id, software_key, tab_key, input_key, show) %}
-<div id="{{id}}-{{input_key}}-reservation-info-div" class="row mb-3{% if not show %} d-none{% endif %}">
-  {%- set reservation_info_classes = "col-4 fw-bold"%}
-  <div id="{{id}}-{{input_key}}-reservation-info" class="col-8 offset-4">
-    <div class="row">
-      <span class="{{ reservation_info_classes }}">Start Time:</span>
-      <span id="{{id}}-{{input_key}}-reservation-start" class="col-auto"></span>
-    </div>
-    <div class="row">
-      <span class="{{ reservation_info_classes }}">End Time:</span>
-      <span id="{{id}}-{{input_key}}-reservation-end" class="col-auto"></span>
-    </div>
-    <div class="row">
-      <span class="{{ reservation_info_classes }}">State:</span>
-      <span id="{{id}}-{{input_key}}-reservation-state" class="col-auto"></span>
-    </div>
-    <div class="mt-1">
-      <details>
-        <summary class="fw-bold">Detailed reservation information:</summary>
-        <pre id="{{id}}-{{input_key}}-reservation-details"></pre>
-        {#- TODO: Fix horizontal width upon expanding the detail #}
-      </details>
-    </div>
-  </div>
-</div>
-{%- endmacro %}
-
-{%- macro create_flavor_summary(id, software_key, tab_key, input_key, options, show) -%}
-<div id="{{id}}-{{input_key}}-flavor-legend-div" class="row align-items-center g-0 mt-4{% if not show %} d-none{% endif %}">
-  <span class="col-4 fw-bold">{{ options.text }}</span>
-  <div class="col d-flex align-items-center ms-2">
-    {%- set box_style = "height: 15px; width: 15px; border-radius: 0.25rem;"%}
-    <div style="{{box_style}} background-color: #198754;"></div>
-    <span class="ms-1">= Free</span>
-    <span class="mx-2"></span>
-    <div style="{{box_style}} background-color: #023d6b;"></div>
-    <span class="ms-1">= Used</span>
-    <span class="mx-2"></span>
-    <div style="{{box_style}} background-color: #dc3545;"></div>
-    <span class="ms-1">= Limit exceeded</span>
-  </div>
-</div>
-<div id="{{id}}-{{input_key}}-flavor-info-div" class="mb-3"></div>
-{%- endmacro %}
-
-{%- macro create_lab_config_buttons_2(id, add_save_reset_buttons=true) -%}
-<hr>
-<div class="d-flex">
-  {# everyone gets a share button, we decide later if we would like to show it #}
-  <button type="button" id="{{id}}-share-btn" class="btn btn-share-lab d-none" data-toggle="modal" data-target="#{{ id }}-share-link">{{ svg.share_svg | safe }} Share </button>
-
-  {%- if add_save_reset_buttons %}
-    <button type="button" id="{{ id }}-save-btn" class="btn btn-success btn-save-lab me-2">{{ svg.save_svg | safe }} Save </button>
-    <button type="button" id="{{ id }}-reset-btn" class="btn btn-danger btn-reset-lab me-2">{{ svg.reset_svg | safe }} Reset</button>
-  {%- endif %}
-
-  {# If Lab is N/A we will use this div to show information later #}
-  <button type="button" id="{{id}}-na-btn" class="btn btn-secondary btn-na-lab disabled ms-auto me-2" style="display: none;">
-      {{ svg.na_svg | safe }} N/A
-  </button>
-  <div id="{{id}}-na-info" class="text-muted my-auto" style="display: none; font-size: smaller;"></div>
-
-  
-  <button type="button" id="{{id}}-delete-btn" class="btn btn-danger btn-delete-lab ms-auto"> {{ svg.delete_svg | safe }} Delete</button>
-
-  {{ create_share_modal(id) }}
-</div>
-{%- endmacro -%}
-
 {%- macro create_lab_config_buttons(id, start_button_only=false) -%}
 <hr>
 <div class="d-flex">
diff --git a/templates/macros/svgs.jinja b/templates/macros/svgs.jinja
index 0663de1..c32638c 100644
--- a/templates/macros/svgs.jinja
+++ b/templates/macros/svgs.jinja
@@ -2,6 +2,11 @@
   <path d="M8 0c-.176 0-.35.006-.523.017l.064.998a7.117 7.117 0 0 1 .918 0l.064-.998A8.113 8.113 0 0 0 8 0zM6.44.152c-.346.069-.684.16-1.012.27l.321.948c.287-.098.582-.177.884-.237L6.44.153zm4.132.271a7.946 7.946 0 0 0-1.011-.27l-.194.98c.302.06.597.14.884.237l.321-.947zm1.873.925a8 8 0 0 0-.906-.524l-.443.896c.275.136.54.29.793.459l.556-.831zM4.46.824c-.314.155-.616.33-.905.524l.556.83a7.07 7.07 0 0 1 .793-.458L4.46.824zM2.725 1.985c-.262.23-.51.478-.74.74l.752.66c.202-.23.418-.446.648-.648l-.66-.752zm11.29.74a8.058 8.058 0 0 0-.74-.74l-.66.752c.23.202.447.418.648.648l.752-.66zm1.161 1.735a7.98 7.98 0 0 0-.524-.905l-.83.556c.169.253.322.518.458.793l.896-.443zM1.348 3.555c-.194.289-.37.591-.524.906l.896.443c.136-.275.29-.54.459-.793l-.831-.556zM.423 5.428a7.945 7.945 0 0 0-.27 1.011l.98.194c.06-.302.14-.597.237-.884l-.947-.321zM15.848 6.44a7.943 7.943 0 0 0-.27-1.012l-.948.321c.098.287.177.582.237.884l.98-.194zM.017 7.477a8.113 8.113 0 0 0 0 1.046l.998-.064a7.117 7.117 0 0 1 0-.918l-.998-.064zM16 8a8.1 8.1 0 0 0-.017-.523l-.998.064a7.11 7.11 0 0 1 0 .918l.998.064A8.1 8.1 0 0 0 16 8zM.152 9.56c.069.346.16.684.27 1.012l.948-.321a6.944 6.944 0 0 1-.237-.884l-.98.194zm15.425 1.012c.112-.328.202-.666.27-1.011l-.98-.194c-.06.302-.14.597-.237.884l.947.321zM.824 11.54a8 8 0 0 0 .524.905l.83-.556a6.999 6.999 0 0 1-.458-.793l-.896.443zm13.828.905c.194-.289.37-.591.524-.906l-.896-.443c-.136.275-.29.54-.459.793l.831.556zm-12.667.83c.23.262.478.51.74.74l.66-.752a7.047 7.047 0 0 1-.648-.648l-.752.66zm11.29.74c.262-.23.51-.478.74-.74l-.752-.66c-.201.23-.418.447-.648.648l.66.752zm-1.735 1.161c.314-.155.616-.33.905-.524l-.556-.83a7.07 7.07 0 0 1-.793.458l.443.896zm-7.985-.524c.289.194.591.37.906.524l.443-.896a6.998 6.998 0 0 1-.793-.459l-.556.831zm1.873.925c.328.112.666.202 1.011.27l.194-.98a6.953 6.953 0 0 1-.884-.237l-.321.947zm4.132.271a7.944 7.944 0 0 0 1.012-.27l-.321-.948a6.954 6.954 0 0 1-.884.237l.194.98zm-2.083.135a8.1 8.1 0 0 0 1.046 0l-.064-.998a7.11 7.11 0 0 1-.918 0l-.064.998zM4.5 7.5a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1h-7z"/>
 </svg>'-%}
 
+{%- set plus_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-plus-lg m-auto" viewBox="0 0 16 16">
+  <path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2Z"></path>
+</svg>'
+-%}
+
 {%- set start_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play-fill" viewBox="0 0 16 16">
   <path d="m11.596 8.697-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z"></path>
 </svg>'-%}
diff --git a/templates/macros/table/config/home.jinja b/templates/macros/table/config/home.jinja
new file mode 100644
index 0000000..7526f81
--- /dev/null
+++ b/templates/macros/table/config/home.jinja
@@ -0,0 +1,722 @@
+{%- set frontend_config = {
+  "services": {
+    "default": "jupyterlab",
+    "options": {
+      "jupyterlab": {
+        "fillingOrder": ["option", "system", "account", "project", "partition"],
+        "navbar": {
+          "labconfig": {
+            "show": true,
+            "displayName": "Lab Config"
+          },
+          "modules": {
+            "displayName": "Kernels and Extensions",
+            "dependency": {
+              "option": [
+                "lmod"
+              ]
+            }
+          },
+          "resources": {
+            "show": false,
+            "displayName": "Resources",
+            "trigger": {
+              "partition": "resourceButton"
+            },
+            "dependency": {
+              "system": [
+                "unicore"
+              ]
+            }
+          },
+          "logs": {
+            "show": true,
+            "firstRow": false,
+            "displayName": "Logs"
+          }
+        },
+        "tabs": {
+          "labconfig": {
+            "center": {
+              "name": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "collect": true,
+                    "enabled": true,
+                    "show": true,
+                    "placeholder": "Give your lab a name"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "width": 4,
+                  "value": "Name"
+                },
+              },
+              "option": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "collect": true,
+                    "show": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Select Version"
+                },
+                "trigger": {
+                  "init": "workshopManagerFillOptions"
+                }
+              },
+              "hr1": {
+                "input": {
+                  "type": "hr"
+                }
+              },
+              "system": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "collect": true,
+                    "show": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Systems"
+                },
+                "trigger": {
+                  "init": "workshopManagerUpdateSystem",
+                  "option": "workshopManagerUpdateSystem"
+                }
+              },
+              "lrzcb": {
+                "input": {
+                  "type": "checkbox",
+                  "options": {
+                    "enabled": true,
+                    "default": false
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Some Checkbox"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ],
+                  "system": [
+                    "kube"
+                  ]
+                }
+              },
+              "repotype": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Repository Type"
+                },
+                "trigger": {
+                  "init": "setR2DType"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repourl": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": "show",
+                    "placeholder": "GitHub repository name or URL",
+                    "patternDisabled": "^([a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+(\\.git)?|https?:\\/\\/[a-zA-Z0-9._-]+(\\.[a-z]{2,})?(:\\d+)?\\/[a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+(\\.git)?)(\\/)?$"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Repository name or URL"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "reporef": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": true,
+                    "placeholder": "HEAD",
+                    "patternDisabled": "^([a-zA-Z0-9._-]+|([a-f0-9]{7,40})|([a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+)|([a-zA-Z0-9._-]+@~\\d+)|@~\\d+)$"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Git ref (branch, tag, or commit)"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repopath": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "Path to a notebook file (optional)",
+                    "patternDisabled": "^(\\/?[a-zA-Z0-9/_-]+(?:\\.[a-zA-Z0-9]+)?(?:\\/[a-zA-Z0-9/_-]+(?:\\.[a-zA-Z0-9]+)?)*|[a-zA-Z0-9/_-]+)$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Open notebook or path (optional)",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repopathtype": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": false,
+                    "show": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Notebook Type",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "init": "setR2DPathType",
+                  "repopath": "workshopManagerRepoPathType"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "image": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "value": "jupyter/datascience-notebook",
+                    "placeholder": "jupyter/datascience-notebook",
+                    "patternDisabled": "^(([a-zA-Z0-9.\\-]+)(:[0-9]+)?\\/)?([a-zA-Z0-9._\\-]+\\/)*[a-zA-Z0-9._\\-]+(:[a-zA-Z0-9._\\-]+|@[A-Fa-f0-9]{64})?$"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Image"
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "privaterepo": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "myregistry.com:5000/myuser/myrepo",
+                    "patternDisabled": "^([a-zA-Z0-9.\\-]+(:[0-9]+)?\\/)?[a-zA-Z0-9._\\-]+\\/[a-zA-Z0-9._\\-]+$"
+                  }
+                },
+                "label": {
+                  "type": "texticoncheckbox",
+                  "value": "Private image registry",
+                  "icontext": "Use private images from your own registry",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "privaterepousername": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "show": false,
+                    "placeholder": "Enter your username"
+                  }
+                },
+                "label": {
+                  "type": "texticon",
+                  "value": "Username",
+                  "icontext": "Username for the private registry",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "privaterepo": "toggleExternalCB"
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "privaterepopassword": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "secret": true,
+                    "show": false,
+                    "placeholder": "Enter your password"
+                  }
+                },
+                "label": {
+                  "type": "texticon",
+                  "value": "Password",
+                  "icontext": "Password for the private registry",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "privaterepo": "toggleExternalCB"
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "mountuserdata": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": true,
+                    "placeholder": "/home/jovyan/work",
+                    "value": "/home/jovyan/work",
+                    "pattern": "^\\/(?:[^\\/\\0]+\\/)*[^\\/\\0]*$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Mount user data",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "custom",
+                    "repo2docker"
+                  ]
+                }
+              },
+              "account": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true,
+                    "group": "hpc"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Account"
+                },
+                "trigger": {
+                  "system": "workshopUpdateAccount"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "project": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true,
+                    "group": "hpc"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Project"
+                },
+                "trigger": {
+                  "account": "workshopManagerUpdateProject"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "partition": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true,
+                    "group": "hpc"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Partition"
+                },
+                "trigger": {
+                  "project": "workshopManagerUpdatePartition",
+                  "system": "workshopManagerUpdatePartition"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "reservation": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": false,
+                    "group": "hpc"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Reservation"
+                },
+                "trigger": {
+                  "partition": "workshopManagerUpdateReservation",
+                  "project": "workshopManagerUpdateReservation",
+                  "system": "workshopManagerUpdateReservation"
+                },
+                "triggerOnChange": "workshopManagerUpdateReservation"
+              },
+              "reservationinfo": {
+                "input": {
+                  "type": "reservationinfo",
+                  "options": {
+                    "show": false
+                  }
+                },
+                "triggerSuffix": "input-div",
+                "trigger": {
+                  "reservation": "updateReservationInfo"
+                }
+              },
+              "flavor": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Flavor"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateFlavor"
+                },
+                "dependency": {
+                  "system": [
+                    "kube"
+                  ]
+                }
+              },
+              "flavorlegend": {
+                "input": {
+                  "type": "flavorlegend"
+                },
+                "dependency": {
+                  "system": [
+                    "kube"
+                  ]
+                },            
+                "triggerSuffix": "input-div"
+              },
+              "flavorinfo": {
+                "input": {
+                  "type": "flavorinfo"
+                },
+                "triggerSuffix": "input-div",
+                "trigger": {
+                  "system": "updateFlavorInfo"
+                },
+                "dependency": {
+                  "system": [
+                    "kube"
+                  ]
+                }
+              }
+            },
+          },
+          "modules": {
+            "center": {
+              "extensions": {
+                "input": {
+                  "type": "multiple_checkboxes"
+                },
+                "label": {
+                  "type": "header",
+                  "value": "Extensions"
+                },
+                "options": {
+                  "group": "modules",
+                  "setName": "extensionSet"
+                },
+                "triggerSuffix": "checkboxes-div",
+                "trigger": {
+                  "option": "updateMultipleCheckboxes"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "kernels": {
+                "input": {
+                  "type": "multiple_checkboxes"
+                },
+                "options": {
+                  "group": "modules",
+                  "setName": "kernelSet"
+                },
+                "label": {
+                  "type": "header",
+                  "value": "Kernels"
+                },
+                "triggerSuffix": "checkboxes-div",
+                "trigger": {
+                  "option": "updateMultipleCheckboxes"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "proxies": {
+                "input": {
+                  "type": "multiple_checkboxes"
+                },
+                "options": {
+                  "group": "modules",
+                  "setName": "proxySet"
+                },
+                "label": {
+                  "type": "header",
+                  "value": "Proxies"
+                },
+                "triggerSuffix": "checkboxes-div",
+                "trigger": {
+                  "option": "updateMultipleCheckboxes"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "selecthelper": {
+                "input": {
+                  "type": "selecthelper"
+                },
+                "triggerSuffix": "input-div"
+              }
+            },
+          },
+          "resources": {
+            "center": {
+              "nodes": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Nodes"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "runtime": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Runtime"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "gpus": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "GPUs"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "xserver": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Use XServer GPU index",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              }
+            },
+          },
+          "logs": {
+            "center": {
+              "logcontainer": {
+                "input": {
+                  "type": "logcontainer"
+                }
+              }
+            },
+          },
+          "buttonrow": {
+            "center": {
+              "buttonrow": {
+                "input": {
+                  "type": "buttons",
+                  "options": {
+                    "buttons": [
+                      "share",
+                      "save",
+                      "reset",
+                      "delete",
+                      "startgreen"
+                    ],
+                    "share": {
+                      "text": "Share",
+                      "trigger": "workshopManagerShowLink",
+                      "dependency": {
+                        "option": [
+                          "repo2docker",
+                          "custom"
+                        ]
+                      }
+                    },
+                    "startgreen": {
+                      "text": "Start",
+                      "trigger": "homeButtonNew",
+                      "defaultRow": false,
+                      "alignRight": true
+                    },
+                    "save": {
+                      "trigger": "workshopManagerButtonSave",
+                      "firstRow": false
+                    },
+                    "reset": {
+                      "firstRow": false,
+                      "trigger": "workshopManagerButtonReset"
+                    },
+                    "delete": {
+                      "firstRow": false,
+                      "trigger": "homeButtonDelete",
+                      "alignRight": true
+                    }
+                  }
+                }
+              }
+            }
+          }
+        },
+        "default": {
+          "tab": "labconfig",
+          "options": {
+            "option": "4.2",
+            "system": "JUWELS"
+          }
+        }
+      }
+    }
+  }
+}%}
\ No newline at end of file
diff --git a/templates/macros/table/config/workshop.jinja b/templates/macros/table/config/workshop.jinja
new file mode 100644
index 0000000..f6a4c76
--- /dev/null
+++ b/templates/macros/table/config/workshop.jinja
@@ -0,0 +1,667 @@
+{%- set frontend_config = {
+  "services": {
+    "default": "jupyterlab",
+    "options": {      
+      "jupyterlab": {
+        "navbar": {
+          "labconfig": {
+            "show": true,
+            "displayName": "Lab Config"
+          },
+          "modules": {
+            "displayName": "Kernels and Extensions",
+            "dependency": {
+              "option": [
+                "lmod"
+              ]
+            }
+          },
+          "resources": {
+            "show": false,
+            "displayName": "Resources",
+            "trigger": {
+              "partition": "resourceButton"
+            },
+            "dependency": {
+              "system": [
+                "unicore"
+              ]
+            }
+          },
+          "logs": {
+            "show": true,
+            "displayName": "Logs"
+          }
+        },
+        "tabs": {
+          "labconfig": {
+            "center": {
+              "name": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "collect": true,
+                    "enabled": true,
+                    "show": true,
+                    "placeholder": "Give your lab a name"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "width": 4,
+                  "value": "Name"
+                },
+                "trigger": {
+                  "init": "workshopLabName"
+                }
+              },
+              "option": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "collect": true,
+                    "show": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Select Version"
+                },
+                "trigger": {
+                  "init": "workshopManagerFillOptions"
+                }
+              },
+              "hr1": {
+                "input": {
+                  "type": "hr"
+                }
+              },
+              "system": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "collect": true,
+                    "show": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Systems"
+                },
+                "trigger": {
+                  "init": "workshopManagerUpdateSystem",
+                  "option": "workshopManagerUpdateSystem"
+                }
+              },
+              "repotype": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Repository Type"
+                },
+                "trigger": {
+                  "init": "setR2DType"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repourl": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": "show",
+                    "placeholder": "GitHub repository name or URL",
+                    "patternDisabled": "^([a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+(\\.git)?|https?:\\/\\/[a-zA-Z0-9._-]+(\\.[a-z]{2,})?(:\\d+)?\\/[a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+(\\.git)?)(\\/)?$"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Repository name or URL"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "reporef": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": true,
+                    "placeholder": "HEAD",
+                    "patternDisabled": "^([a-zA-Z0-9._-]+|([a-f0-9]{7,40})|([a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+)|([a-zA-Z0-9._-]+@~\\d+)|@~\\d+)$"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Git ref (branch, tag, or commit)"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repopath": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "Path to a notebook file (optional)",
+                    "patternDisabled": "^(\\/?[a-zA-Z0-9/_-]+(?:\\.[a-zA-Z0-9]+)?(?:\\/[a-zA-Z0-9/_-]+(?:\\.[a-zA-Z0-9]+)?)*|[a-zA-Z0-9/_-]+)$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Open notebook or path (optional)",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repopathtype": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": false,
+                    "show": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Notebook Type",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "init": "setR2DPathType",
+                  "repopath": "workshopManagerRepoPathType"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "image": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "value": "jupyter/datascience-notebook",
+                    "placeholder": "jupyter/datascience-notebook",
+                    "patternDisabled": "^(([a-zA-Z0-9.\\-]+)(:[0-9]+)?\\/)?([a-zA-Z0-9._\\-]+\\/)*[a-zA-Z0-9._\\-]+(:[a-zA-Z0-9._\\-]+|@[A-Fa-f0-9]{64})?$"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Image"
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "privaterepo": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "myregistry.com:5000/myuser/myrepo",
+                    "patternDisabled": "^([a-zA-Z0-9.\\-]+(:[0-9]+)?\\/)?[a-zA-Z0-9._\\-]+\\/[a-zA-Z0-9._\\-]+$"
+                  }
+                },
+                "label": {
+                  "type": "texticoncheckbox",
+                  "value": "Private image registry",
+                  "icontext": "Use private images from your own registry",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "privaterepousername": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "show": false,
+                    "placeholder": "Enter your username"
+                  }
+                },
+                "label": {
+                  "type": "texticon",
+                  "value": "Username",
+                  "icontext": "Username for the private registry",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "privaterepo": "toggleExternalCB"
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "privaterepopassword": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "show": false,
+                    "placeholder": "Enter your password"
+                  }
+                },
+                "label": {
+                  "type": "texticon",
+                  "value": "Password",
+                  "icontext": "Password for the private registry",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "privaterepo": "toggleExternalCB"
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "mountuserdata": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": true,
+                    "placeholder": "/home/jovyan/work",
+                    "value": "/home/jovyan/work",
+                    "pattern": "^\\/(?:[^\\/\\0]+\\/)*[^\\/\\0]*$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Mount user data",
+                  "options": {
+                    "default": true
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "account": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Account"
+                },
+                "trigger": {
+                  "system": "workshopUpdateAccount"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "project": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Project"
+                },
+                "trigger": {
+                  "account": "workshopManagerUpdateProject"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "partition": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Partition"
+                },
+                "trigger": {
+                  "project": "workshopManagerUpdatePartition",
+                  "system": "workshopManagerUpdatePartition"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "reservation": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": false
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Reservation"
+                },
+                "trigger": {
+                  "partition": "workshopManagerUpdateReservation",
+                  "project": "workshopManagerUpdateReservation",
+                  "system": "workshopManagerUpdateReservation"
+                },
+                "triggerOnChange": "workshopManagerUpdateReservation"
+              },
+              "reservationinfo": {
+                "input": {
+                  "type": "reservationinfo",
+                  "options": {
+                    "show": false
+                  }
+                },
+                "triggerSuffix": "input-div",
+                "trigger": {
+                  "reservation": "updateReservationInfo"
+                }
+              },
+              "flavor": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Flavor"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateFlavor"
+                },
+                "dependency": {
+                  "system": [
+                    "kube"
+                  ]
+                }
+              },
+              "flavorlegend": {
+                "input": {
+                  "type": "flavorlegend"
+                },
+                "dependency": {
+                  "system": [
+                    "kube"
+                  ]
+                },            
+                "triggerSuffix": "input-div"
+              },
+              "flavorinfo": {
+                "input": {
+                  "type": "flavorinfo"
+                },
+                "triggerSuffix": "input-div",
+                "trigger": {
+                  "system": "updateFlavorInfo"
+                },
+                "dependency": {
+                  "system": [
+                    "kube"
+                  ]
+                }
+              }
+            },
+          },
+          "modules": {
+            "center": {
+              "extensions": {
+                "input": {
+                  "type": "multiple_checkboxes"
+                },
+                "label": {
+                  "type": "header",
+                  "value": "Extensions"
+                },
+                "options": {
+                  "group": "modules",
+                  "setName": "extensionSet"
+                },
+                "triggerSuffix": "checkboxes-div",
+                "trigger": {
+                  "option": "updateMultipleCheckboxes"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "kernels": {
+                "input": {
+                  "type": "multiple_checkboxes"
+                },
+                "options": {
+                  "group": "modules",
+                  "setName": "kernelSet"
+                },
+                "label": {
+                  "type": "header",
+                  "value": "Kernels"
+                },
+                "triggerSuffix": "checkboxes-div",
+                "trigger": {
+                  "option": "updateMultipleCheckboxes"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "proxies": {
+                "input": {
+                  "type": "multiple_checkboxes"
+                },
+                "options": {
+                  "group": "modules",
+                  "setName": "proxySet"
+                },
+                "label": {
+                  "type": "header",
+                  "value": "Proxies"
+                },
+                "triggerSuffix": "checkboxes-div",
+                "trigger": {
+                  "option": "updateMultipleCheckboxes"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "selecthelper": {
+                "input": {
+                  "type": "selecthelper"
+                },
+                "triggerSuffix": "input-div"
+              }
+            },
+          },
+          "resources": {
+            "center": {
+              "nodes": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Nodes"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "runtime": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "Runtime"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "gpus": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "value": "GPUs"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "xserver": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "collectstatic": true
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Use XServer GPU index",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              }
+            },
+          },
+          "logs": {
+            "center": {
+              "logcontainer": {
+                "input": {
+                  "type": "logcontainer"
+                }
+              }
+            },
+          },
+          "buttonrow": {
+            "center": {
+              "buttonrow": {
+                "input": {
+                  "type": "buttons",
+                  "options": {
+                    "buttons": [
+                      "reset"
+                    ],
+                    "reset": {
+                      "firstRow": false,
+                      "trigger": "workshopManagerButtonReset"
+                    }
+                  }
+                }
+              }
+            }
+          }
+        },
+        "default": {
+          "tab": "labconfig",
+          "options": {
+            "option": "4.2",
+            "system": "JUWELS"
+          }
+        }
+      }
+    }
+  }
+}%}
\ No newline at end of file
diff --git a/templates/macros/table/config/workshop_manager.jinja b/templates/macros/table/config/workshop_manager.jinja
new file mode 100644
index 0000000..c74a320
--- /dev/null
+++ b/templates/macros/table/config/workshop_manager.jinja
@@ -0,0 +1,775 @@
+{% set frontend_config = {
+  "services": {
+    "default": "jupyterlab",
+    "options": {
+      "jupyterlab": {
+        "navbar": {},
+        "tabs": {
+          "default": {
+            "left": {
+              "workshopid": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "collect": true,
+                    "alwaysDisabled": true,
+                    "enabled": false,
+                    "show": true,
+                    "placeholder": "An ID will be generated for you",
+                    "placeholderInstructor": "Choose a descriptive ID",
+                    "pattern": "[a-z][a-z0-9_\\-]*",
+                    "warning": "Allowed chars: a-z 0-9 _ - . Must start with a lowercase latter ([a-z][a-z0-9_-]*)",
+                    "group": "none"
+                  }
+                },
+                "trigger": {
+                  "init": "workshopManagerWorkshopId"
+                },
+                "label": {
+                  "type": "texticonclick",
+                  "width": 6,
+                  "value": "Workshop ID:",
+                  "icontext": "For more information check out <a href='https://jupyterjsc.pages.jsc.fz-juelich.de/docs/jupyterjsc/users/jupyterlab/4.2/' target='_blank'>documentation</a>"
+                }
+              },
+              "description": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "collect": true,
+                    "show": true,
+                    "required": true,
+                    "group": "none",
+                    "warning": "A description of your workshop is required. This will be displayed to users to help them select the appropriate workshop."
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "width": 6,
+                  "value": "Description:"
+                }
+              },
+              "enddate": {
+                "input": {
+                  "type": "date",
+                  "options": {
+                    "show": true,
+                    "enabled": false,
+                    "group": "none",
+                    "instructor": "enabled"
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "width": 6,
+                  "value": "Available until:",
+                  "options": {
+                    "name": "public"
+                  }
+                }
+              },
+              "public": {
+                "input": {
+                  "type": "checkbox",
+                  "options": {
+                    "group": "none",
+                    "instructor": "show",
+                    "show": false,
+                    "default": false,
+                    "enabled": true
+                  }
+                },
+                "label": {
+                  "type": "text",
+                  "width": 6,
+                  "value": "List workshop at /hub/workshops:"
+                }
+              },
+              "expertmode": {
+                "input": {
+                  "type": "checkbox",
+                  "options": {
+                    "default": false,
+                    "group": "none",
+                    "instructor": "show",
+                    "enabled": true
+                  }
+                },
+                "trigger": {
+                  "init": "workshopManagerToggleExpertMode"
+                },
+                "triggerOnChange": "workshopManagerToggleExpertMode",
+                "label": {
+                  "type": "texticon",
+                  "icontext": "Expert Mode allows you to select multiple Options + Systems",
+                  "width": 6,
+                  "value": "Enable expert mode"
+                }
+              },
+              "buttons": {
+                "input": {
+                  "type": "buttons",
+                  "options": {
+                    "summaryButtons": [
+                      "new",
+                      "open"
+                    ],
+                    "buttons": [
+                      "reset",
+                      "delete",
+                      "share",
+                      "save",
+                      "new"
+                    ],
+                    "share": {
+                      "text": "Show Link",
+                      "trigger": "workshopManagerShowLink",
+                      "align-right": true,
+                      "firstRow": false
+                    },
+                    "save": {
+                      "trigger": "workshopManagerButtonSave",
+                      "firstRow": false
+                    },
+                    "new": {
+                      "trigger": "workshopManagerButtonNew",
+                      "align-right": true,
+                      "text": "Create Workshop",
+                      "textFirst": true,
+                      "firstRow": true
+                    },
+                    "reset": {
+                      "firstRow": false,
+                      "trigger": "workshopManagerButtonReset"
+                    },
+                    "delete": {
+                      "firstRow": false,
+                      "trigger": "workshopManagerButtonDelete"
+                    }
+                  }
+                }
+              }
+            },
+            "right": {
+              "option": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": true,
+                    "enabled": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Select Version",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "init": "workshopManagerFillOptions"
+                }
+              },
+              "system": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": true,
+                    "enabled": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Systems",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "init": "workshopManagerUpdateSystem",
+                  "option": "workshopManagerUpdateSystem"
+                }
+              },
+              "repotype": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Repository Type",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "init": "setR2DType"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repourl": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "GitHub repository name or URL",
+                    "patternDisabled": "^([a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+(\\.git)?|https?:\\/\\/[a-zA-Z0-9._-]+(\\.[a-z]{2,})?(:\\d+)?\\/[a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+(\\.git)?)(\\/)?$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Repository name or URL",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "reporef": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "HEAD",
+                    "patternDisabled": "^([a-zA-Z0-9._-]+|([a-f0-9]{7,40})|([a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+)|([a-zA-Z0-9._-]+@~\\d+)|@~\\d+)$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Git ref (branch, tag, or commit)",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repopath": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "Path to a notebook file (optional)",
+                    "patternDisabled": "^(\\/?[a-zA-Z0-9/_-]+(?:\\.[a-zA-Z0-9]+)?(?:\\/[a-zA-Z0-9/_-]+(?:\\.[a-zA-Z0-9]+)?)*|[a-zA-Z0-9/_-]+)$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Open notebook or path (optional)",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "repopathtype": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": false,
+                    "show": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Notebook Type",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "init": "setR2DPathType",
+                  "repopath": "workshopManagerRepoPathType"
+                },
+                "dependency": {
+                  "option": [
+                    "repo2docker"
+                  ]
+                }
+              },
+              "image": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "value": "jupyter/datascience-notebook",
+                    "placeholder": "jupyter/datascience-notebook",
+                    "patternDisabled": "^(([a-zA-Z0-9.\\-]+)(:[0-9]+)?\\/)?([a-zA-Z0-9._\\-]+\\/)*[a-zA-Z0-9._\\-]+(:[a-zA-Z0-9._\\-]+|@[A-Fa-f0-9]{64})?$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Image",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "privaterepo": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "myregistry.com:5000/myuser/myrepo",
+                    "patternDisabled": "^([a-zA-Z0-9.\\-]+(:[0-9]+)?\\/)?[a-zA-Z0-9._\\-]+\\/[a-zA-Z0-9._\\-]+$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Private image repository",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "mountuserdata": {
+                "input": {
+                  "type": "text",
+                  "options": {
+                    "enabled": false,
+                    "placeholder": "/home/jovyan/work",
+                    "value": "/home/jovyan/work",
+                    "pattern": "^\\/(?:[^\\/\\0]+\\/)*[^\\/\\0]*$"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Mount user data",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "dependency": {
+                  "option": [
+                    "custom"
+                  ]
+                }
+              },
+              "extensions": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "group": "modules",
+                    "enabled": false,
+                    "size": 4,
+                    "multiple": true,
+                    "setName": "extensionSet"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Extensions",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "option": "workshopManagerUpdateModuleWorkshop"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "kernels": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "group": "modules",
+                    "enabled": false,
+                    "size": 4,
+                    "multiple": true,
+                    "setName": "kernelSet"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Kernels",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "option": "workshopManagerUpdateModuleWorkshop"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "proxies": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "group": "modules",
+                    "enabled": false,
+                    "size": 4,
+                    "multiple": true,
+                    "setName": "proxySet"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Proxies",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "option": "workshopManagerUpdateModuleWorkshop"
+                },
+                "dependency": {
+                  "option": [
+                    "lmod"
+                  ]
+                }
+              },
+              "project": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": false,
+                    "multiple": true,
+                    "size": 4
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "options": {
+                    "default": false
+                  },
+                  "value": "Project"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateProject"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "defaultvaluesproject": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": false,
+                    "collect": false,
+                    "enabled": false,
+                    "parent": "project",
+                    "group": "defaultvalues"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "options": {
+                    "default": false
+                  },
+                  "value": "Specify default project"
+                },
+                "trigger": {
+                  "project": "defaultValue"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "partition": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": false,
+                    "multiple": true,
+                    "size": 4
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Partition",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "project": "workshopManagerUpdatePartition",
+                  "system": "workshopManagerUpdatePartition"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "defaultvaluespartition": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": false,
+                    "collect": false,
+                    "enabled": false,
+                    "parent": "partition",
+                    "group": "defaultvalues"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "options": {
+                    "default": false
+                  },
+                  "value": "Specify default partition"
+                },
+                "trigger": {
+                  "partition": "defaultValue"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "reservation": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": false,
+                    "collectstatic": true,
+                    "enabled": false,
+                    "multiple": true,
+                    "size": 4
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "options": {
+                    "default": false
+                  },
+                  "triggerOnChange": "toggleCollectCB",
+                  "value": "Reservation"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateReservation",
+                  "partition": "workshopManagerUpdateReservation",
+                  "project": "workshopManagerUpdateReservation"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "defaultvaluesreservation": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "show": false,
+                    "collect": false,
+                    "enabled": false,
+                    "parent": "reservation",
+                    "group": "defaultvalues"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "options": {
+                    "default": false
+                  },
+                  "value": "Specify default reservation"
+                },
+                "trigger": {
+                  "reservation": "defaultValue"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "nodes": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources",
+                    "enabled": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Nodes",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "runtime": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Runtime",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "gpus": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "enabled": false,
+                    "group": "resources"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "GPUs",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "xserver": {
+                "input": {
+                  "type": "number",
+                  "options": {
+                    "show": false,
+                    "group": "resources"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Use XServer GPU index",
+                  "options": {
+                    "default": false
+                  }
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateResourcesElementTrigger",
+                  "partition": "workshopManagerUpdateResourcesElementTrigger"
+                },
+                "dependency": {
+                  "system": [
+                    "unicore"
+                  ]
+                }
+              },
+              "flavor": {
+                "input": {
+                  "type": "select",
+                  "options": {
+                    "enabled": false
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "options": {
+                    "default": false
+                  },
+                  "value": "Flavor"
+                },
+                "trigger": {
+                  "system": "workshopManagerUpdateFlavor"
+                },
+                "dependency": {
+                  "system": [
+                    "kube"
+                  ]
+                }
+              },
+              "envvariables": {
+                "input": {
+                  "type": "textgrower",
+                  "options": {
+                    "enabled": false,
+                    "required": true,
+                    "show": true,
+                    "pattern": "^[A-Za-z_][A-Za-z0-9_]*=[^\\s]+$",
+                    "placeholder": "KEY=VALUE"
+                  }
+                },
+                "label": {
+                  "type": "textcheckbox",
+                  "value": "Add environment variables",
+                  "options": {
+                    "default": false
+                  }
+                }
+              }
+            }
+          }
+        },
+        "default": {
+          "tab": "default",
+          "options": {
+            "option": "4.2",
+            "system": "JUWELS"
+          }
+        }
+      }
+    }
+  }
+} %}
\ No newline at end of file
diff --git a/templates/macros/table/content.jinja b/templates/macros/table/content.jinja
new file mode 100644
index 0000000..b97b59f
--- /dev/null
+++ b/templates/macros/table/content.jinja
@@ -0,0 +1,362 @@
+{%- import "macros/table/elements.jinja" as table_elements with context %}
+{%- import "macros/svgs.jinja" as svg -%}
+
+{% macro workshopmanager_description() %}
+  <p>{{ db_workshops }}</p>
+  <h2>Workshop Manager</h2>
+  <p>Select the options users might be able to use during your workshop.</p>
+  <p>Use shift or ctrl to select multiple items. <a style="color:#fff" href="https://jupyterjsc.pages.jsc.fz-juelich.de/docs/jupyterjsc/" target="_">Click here for more information.</a></p>
+{% endmacro %}
+
+{% macro workshopmanager_headerlayout() %}
+  <th scope="col" width="1%"></th>
+  <th scope="col" width="20%">Name</th>
+  <th scope="col">Description</th>
+  <th scope="col" class="text-center" width="10%">Action</th>
+{% endmacro %}
+
+{% macro workshopmanager_defaultheader(service_id, row_id, row_options) %}
+  <th scope="row" class="name-td">{{ row_id }}</th>
+  <th scope="row" class="description-td">{{ row_options.get("user_options", {}).get("description", "") }}</th>
+  <th scope="row" class="url-td text-center">
+    <button type="button" id="{{ service_id }}-{{row_id}}-open-workshop-btn" class="btn btn-success open-workshop-btn" data-target="#{{ row_id }}-workshop-link" onclick="window.open('https://{{ hostname }}{{ base_url }}workshops/{{ row_id }}');">{{ svg.open_svg | safe }} Open</button>
+  </th>
+{% endmacro %}
+
+{% macro workshopmanager_firstheader(service_id, row_id, row_options) %}
+  <th scope="row" class="name-td">New Workshop</th>
+  <th scope="row" class="description-td">Design a simplified set of options for your workshop to make it more accessible for your students.</th>
+  <th scope="row" class="url-td text-center">
+    <button type="button" data-service="{{ service_id }}" data-row="{{ row_id }}" id="{{ service_id }}-header-{{row_id}}-new-btn" class="btn btn-primary" data-target="#{{ row_id }}-workshop-link">{{ svg.plus_svg | safe }} Create</button>
+  </th>
+{% endmacro %}
+
+{% macro workshopmanager_row_content(service_id, service_options, row_id, tab_id) %}
+  {%- for side in service_options.get("tabs", {}).get(tab_id, {}).keys() %}
+    <div class="col-6">
+      {%- for element_id, element_options in service_options.get("tabs", {}).get(tab_id, {}).get(side, {}).items() %}
+        {{ table_elements.create_element(service_id, row_id, tab_id, element_id, element_options) }}
+      {%- endfor %}
+    </div>
+  {%- endfor %}
+{% endmacro %}
+
+{% macro workshop_headerlayout() %}
+  <th scope="col" width="1%"></th>
+  <th scope="col" width="20%">Name</th>
+  <th scope="col">Description</th>
+  <th scope="col" class="text-center" width="10%">Status</th>
+  <th scope="col" class="text-center" width="10%">Action</th>
+{% endmacro %}
+
+{% macro workshop_firstheader(service_id, row_id, row_options) %}
+  <th scope="row" class="name-td">Workshop {{ workshop_id }}</th>
+  <th scope="row" class="description-td">{{ db_workshops.get(row_id, {}).get("user_options", {}).get("description") }}</th>
+  <th scope="row" class="status-td">
+    <div class="d-flex justify-content-center">
+      <div class="d-flex flex-column">
+        <div class="d-flex justify-content-center progress" style="background-color: #d3e4f4; height: 20px; min-width: 100px;">
+          <div id="{{ service_id }}-{{ row_id }}-progress-bar" data-service="{{ service_id }}"  data-row="{{ row_id }}" data-sse-progress class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0px; margin-right: auto;"></div>
+          <span id="{{ service_id }}-{{ row_id }}-progress-text" style="position: absolute; width: 100px; text-align: center; line-height: 20px; color: black">0%</span>
+        </div>
+        <span id="{{ service_id }}-{{ row_id }}-progress-info-text" class="progress-info-text text-center text-muted" style="font-size: smaller;"></span>
+      </div>
+    </div>
+  </th>
+  <th scope="row" class="url-td text-center" style="white-space: nowrap">
+    <button type="button"
+      id="{{ service_id }}-{{row_id}}-open-btn-header"
+      class="btn btn-success"
+      data-service="{{ service_id }}"
+      data-row="{{ row_id }}"
+      data-element="open"
+      {%- if not spawner.active %}
+      style="display: none"
+      {%- endif %}
+      >
+      {{ svg.open_svg | safe }} Open
+    </button>
+    <button type="button"
+      id="{{ service_id }}-{{row_id}}-stop-btn-header"
+      class="btn btn-danger"
+      data-service="{{ service_id }}"
+      data-row="{{ row_id }}"
+      data-element="stop"
+      {%- if not spawner.ready %}
+      style="display: none"
+      {%- endif %}
+      >
+      {{ svg.stop_svg | safe }} Stop
+    </button>
+    <button type="button"
+      id="{{ service_id }}-{{row_id}}-cancel-btn-header"
+      class="btn btn-danger"
+      data-service="{{ service_id }}"
+      data-row="{{ row_id }}"
+      data-element="cancel"
+      {%- if spawner.ready or not spawner.active %}
+      style="display: none"
+      {%- endif %}
+      >
+      {{ svg.stop_svg | safe }} Cancel
+    </button>
+    <button type="button"
+      id="{{ service_id }}-{{row_id}}-start-btn-header"
+      class="btn btn-primary"
+      data-service="{{ service_id }}"
+      data-row="{{ row_id }}"
+      data-element="start"
+      {%- if spawner.active %}
+      style="display: none"
+      {%- endif %}
+      >
+      {{ svg.start_svg | safe }} Start
+    </button>
+  </th>
+{% endmacro %}
+
+
+{% macro sse_functions() %}
+  $(`[data-sse-progress][id$='-tabContent-div']`).on("sse", function (event, data) {
+    const $this = $(this);
+    const serviceId = $this.attr("data-service");
+    const rowId = $this.attr("data-row");
+    if ( Object.keys(data).includes(rowId) ){
+      const ready = data[rowId]?.ready ?? false;
+      const failed = data[rowId]?.failed ?? false;
+      const progress = data[rowId]?.progress ?? 10;
+      if ( ready ) {
+        updateHeaderButtons(serviceId, rowId, "waiting");
+        const url = data[rowId]?.url ?? "{{ url }}";
+        checkAndOpenUrl(serviceId, rowId, url);
+      } else if ( failed ) {
+        updateHeaderButtons(serviceId, rowId, "stopped");
+        $(`button[id^='${serviceId}-${rowId}-'][id$='-btn']`).prop("disabled", false);
+      } else if ( progress == 99 ) {
+        updateHeaderButtons(serviceId, rowId, "cancelling");
+        $(`button[id^='${serviceId}-${rowId}-'][id$='-btn']`).prop("disabled", true);
+      } else {
+        updateHeaderButtons(serviceId, rowId, "starting");
+        $(`button[id^='${serviceId}-${rowId}-'][id$='-btn']`).prop("disabled", true);
+      }
+      appendToLog(serviceId, rowId, data[rowId]);
+    }
+  });
+
+  $(`[data-sse-progress].progress-bar`).on("sse", function (event, data) {
+    const $this = $(this);
+    const rowId = $this.attr("data-row");
+    const serviceId = $this.attr("data-service");
+    if ( Object.keys(data).includes(rowId) ){
+      const ready = data[rowId]?.ready ?? false;
+      const failed = data[rowId]?.failed ?? false;
+      const progress = data[rowId]?.progress ?? 10;
+      let status = "starting";
+      if ( ready ) status = "connecting";
+      else if ( failed ) status = "stopped";
+      else if ( progress == 99 ) status = "cancelling";
+      else if ( progress == 0 ) status = "";
+      progressBarUpdate(serviceId, rowId, status, progress);
+    }
+  });
+{% endmacro %}
+
+{% macro workshop_description() %}
+  <p>{{ db_workshops }}</p>
+{% endmacro %}
+
+{% macro home_description() %}
+  <p>You can configure your existing JupyterLabs by expanding the corresponding table row.</p>
+{% endmacro %}
+
+
+{% macro home_headerlayout() %}
+  <th scope="col" width="1%"></th>
+  <th scope="col" width="20%">Name</th>
+  <th scope="col">Configuration</th>
+  <th scope="col" class="text-center" width="10%">Status</th>
+  <th scope="col" class="text-center" width="10%">Action</th>
+{% endmacro %}
+
+{% macro home_firstheader(service_id, row_id, row_options) %}
+  <th scope="row" colspan="100%" class="text-center">New JupyterLab</th>
+{% endmacro %}
+
+
+{% macro home_defaultheader(service_id, row_id, row_options) %}
+  {%- for s in spawners %}
+    {%- if s.name == row_id %}
+      {%- set spawner = user.spawners.get(s.name, s) %}
+      {%- set ready = spawner.ready %}
+      {%- set active = spawner.active %}
+      {%- set failed = spawner.failed %}
+      {%- set progress = 0 %}
+      {%- if ready %}
+        {%- set progress = 100 %}
+      {%- elif active %}
+        {%- set progress = (spawner.events | last | default({}, true)).get("progress", 0) %}
+      {%- elif spawner.events %}
+        {%- set progress = 0 %}
+      {%- endif %}
+      
+      <th scope="row" class="name-td">{{ spawner.user_options.get("name", "") }}</th>
+      <td scope="row" class="config-td">
+        <div style="max-height: 152px; overflow: auto;">
+          <div class="row mx-3 mb-1 justify-content-between">
+            <div id="{{ service_id }}-{{ row_id }}-config-td-div" class="row col-12 col-md-6 col-lg-12 d-flex align-items-center">
+              <div id="{{ service_id }}-{{ row_id }}-config-td-option-div" class="col text-lg-center col-12 col-lg-3">
+                <span class="text-muted" style="font-size: smaller;">Option</span><br>
+                <span id="{{ service_id }}-{{ row_id }}-config-td-option">{{ spawner.user_options.get("option", false) }}</span>
+              </div>
+              <div id="{{ service_id }}-{{ row_id }}-config-td-system-div" class="col text-lg-start col-12 col-lg-3">
+                <span class="text-muted" style="font-size: smaller;">System</span><br>
+                <span id="{{ service_id }}-{{ row_id }}-config-td-system">{{ spawner.user_options.get("system", false) }}</span>
+              </div>
+              {%- if spawner.user_options.get("project", false) %}
+              <div id="{{ service_id }}-{{ row_id }}-config-td-project-div" class="col text-lg-start col-12 col-lg-3">
+                <span class="text-muted" style="font-size: smaller;">Project</span><br>
+                <span id="{{ service_id }}-{{ row_id }}-config-td-project">{{ spawner.user_options.get("project", "") }}</span>
+              </div>
+              {%- endif %}
+              {%- if spawner.user_options.get("partition", false) %}
+              <div id="{{ service_id }}-{{ row_id }}-config-td-partition-div" class="col text-lg-start col-12 col-lg-3">
+                <span class="text-muted" style="font-size: smaller;">Partition</span><br>
+                <span id="{{ service_id }}-{{ row_id }}-config-td-partition">{{ spawner.user_options.get("partition", "") }}</span>
+              </div>
+              {%- endif %}
+            </div>
+          </div>
+        </div>
+      </td>
+
+      <th scope="row" class="status-td">
+        <div class="d-flex justify-content-center">
+          <div class="d-flex flex-column">
+            <div class="d-flex justify-content-center progress" style="background-color: #d3e4f4; height: 20px; min-width: 100px;">
+              <div id="{{ service_id }}-{{ row_id }}-progress-bar"
+                data-service="{{ service_id }}"
+                data-row="{{ row_id }}"
+                data-sse-progress
+                class="
+                {%- if ready %}
+                bg-success
+                {%- endif %}
+                progress-bar progress-bar-striped progress-bar-animated
+                "
+                role="progressbar"
+                style="width: {{ progress }}px; margin-right: auto;"
+              ></div>
+              <span id="{{ service_id }}-{{ row_id }}-progress-text"
+                style="position: absolute;
+                  width: 100px;
+                  text-align: center;
+                  line-height: 20px;
+                  {% if progress >= 60 %}
+                  color: white
+                  {% else %}
+                  color: black
+                  {% endif -%}
+                  "
+              >{{ progress }}%</span>
+            </div>
+            <span id="{{ service_id }}-{{ row_id }}-progress-info-text" class="progress-info-text text-center text-muted" style="font-size: smaller;">
+              {%- if ready %}
+              running
+              {%- elif active %}
+              starting
+              {%- elif progress == 99 %}
+              cancelling
+              {%- endif %}
+            </span>
+          </div>
+        </div>
+      </th>
+      <th scope="row" class="url-td text-center" style="white-space: nowrap">
+        <button type="button"
+          id="{{ service_id }}-{{row_id}}-open-btn-header"
+          class="btn btn-success"
+          data-service="{{ service_id }}"
+          data-row="{{ row_id }}"
+          data-element="open"
+          {%- if not spawner.active %}
+          style="display: none"
+          {%- endif %}>
+          {{ svg.open_svg | safe }} Open
+        </button>
+        <button type="button"
+          id="{{ service_id }}-{{row_id}}-stop-btn-header"
+          class="btn btn-danger"
+          data-service="{{ service_id }}"
+          data-row="{{ row_id }}"
+          data-element="stop"
+          {%- if not spawner.ready %}
+          style="display: none"
+          {%- endif %}
+          >
+          {{ svg.stop_svg | safe }} Stop
+        </button>
+        <button type="button"
+          id="{{ service_id }}-{{row_id}}-cancel-btn-header"
+          class="btn btn-danger"
+          data-service="{{ service_id }}"
+          data-row="{{ row_id }}"
+          data-element="cancel"
+          {%- if spawner.ready or not spawner.active %}
+          style="display: none"
+          {%- endif %}
+          >
+          {{ svg.stop_svg | safe }} Cancel
+        </button>
+        <button type="button"
+          id="{{ service_id }}-{{row_id}}-start-btn-header"
+          class="btn btn-primary"
+          data-service="{{ service_id }}"
+          data-row="{{ row_id }}"
+          data-element="start"
+          {%- if spawner.active %}
+          style="display: none"
+          {%- endif %}
+          >
+          {{ svg.start_svg | safe }} Start
+        </button>
+        <button type="button"
+          id="{{ service_id }}-{{row_id}}-na-btn-header"
+          class="btn btn-secondary btn-na-lab disabled"
+          data-service="{{ service_id }}"
+          data-row="{{ row_id }}"
+          data-element="na"
+          style="display: none"
+          >
+          {{ svg.na_svg | safe }} N/A
+        </button>
+        <button type="button"
+          id="{{ service_id }}-{{row_id}}-del-btn-header"
+          class="btn btn-danger"
+          data-service="{{ service_id }}"
+          data-row="{{ row_id }}"
+          data-element="del"
+          style="display: none"
+          >
+          {{ svg.delete_svg | safe }}
+        </button>
+      </th>
+      
+    {%- endif %}
+  {%- endfor %}
+{%- endmacro %}
+
+{% macro workshop_user_not_ready() %}
+  <h1 class="user-documentation-info" style="text-align: center; color: red">Account not ready yet!</h1>
+  <div class="user-documentation-info">
+  Your account is not ready for {{ db_workshops.get(workshop_id, {}).get("user_options", {}) }}.
+  </div>
+{% endmacro %}
+
+
+{% macro row_content(service_id, service_options, row_id, tab_id) %}
+  <div class="col-12">
+    {%- for element_id, element_options in service_options.get("tabs", {}).get(tab_id, {}).get("center", {}).items() %}
+      {{ table_elements.create_element(service_id, row_id, tab_id, element_id, element_options) }}
+    {%- endfor %}
+  </div>
+{% endmacro %}
diff --git a/templates/macros/table/elements.jinja b/templates/macros/table/elements.jinja
new file mode 100644
index 0000000..ab94ddc
--- /dev/null
+++ b/templates/macros/table/elements.jinja
@@ -0,0 +1,836 @@
+{%- import "macros/svgs.jinja" as svg -%}
+{%- include "macros/table/table_js.jinja" %}
+
+
+{%- macro create_button(
+  service_id,
+  row_id,
+  button,
+  button_options
+)%}
+  {%- set clazz = "" %}
+  {%- set svgicon = "" %}
+  {%- set buttontext = "" %}
+  {%- if button == "share" %}
+    {%- set clazz = "" %}
+    {%- set svgicon = svg.share_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Share") %}
+  {%- elif button == "reset" %}
+    {%- set clazz = "btn-danger" %}
+    {%- set svgicon = svg.reset_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Reset") %}
+  {%- elif button == "delete" %}
+    {%- set clazz = "btn-danger" %}
+    {%- set svgicon = svg.delete_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Delete") %}
+  {%- elif button == "save" %}
+    {%- set clazz = "btn-success" %}
+    {%- set svgicon = svg.save_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Save") %}
+  {%- elif button == "create" %}
+    {%- set clazz = "btn-primary" %}
+    {%- set svgicon = svg.plus_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Create") %}
+  {%- elif button == "start" %}
+    {%- set clazz = "btn-success" %}
+    {%- set svgicon = svg.start_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Start") %}
+  {%- elif button == "startblue" %}
+    {%- set clazz = "btn-primary" %}
+    {%- set svgicon = svg.start_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Start") %}
+  {%- elif button == "startgreen" %}
+    {%- set clazz = "btn-success" %}
+    {%- set svgicon = svg.start_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Start") %}
+  {%- elif button == "new" %}
+    {%- set clazz = "btn-primary" %}
+    {%- set svgicon = svg.plus_svg | safe %}
+    {%- set buttontext = button_options.get("text", "New") %}
+  {%- elif button == "open" %}
+    {%- set clazz = "btn-success" %}
+    {%- set svgicon = svg.open_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Open") %}
+  {%- elif button == "retry" %}
+    {%- set clazz = "btn-success" %}
+    {%- set svgicon = svg.retry_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Retry") %}
+  {%- elif button == "cancel" %}
+    {%- set clazz = "btn-danger" %}
+    {%- set svgicon = svg.stop_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Cancel") %}
+  {%- elif button == "stop" %}
+    {%- set clazz = "btn-success" %}
+    {%- set svgicon = svg.stop_svg | safe %}
+    {%- set buttontext = button_options.get("text", "Stop") %}
+  {%- endif %}
+    <button 
+      type="button"       
+      data-service="{{ service_id }}"
+      data-row="{{ row_id }}"
+      id="{{ service_id }}-{{ row_id }}-{{ button }}-btn" 
+      class="btn {{ clazz }}
+      {% if button_options.get("alignRight", false) -%} ms-auto {%- else -%} me-2 {%- endif %}"
+      {%- for specific_key, specific_values in button_options.get("dependency", {}).items() %}
+        data-dependency-{{ specific_key }}="true"
+        {%- for specific_value in specific_values %}
+          data-dependency-{{ specific_key }}-{{ specific_value }}="true"
+        {%- endfor %}
+      {%- endfor %}
+    >
+      {%- if button_options.get("textFirst", false ) %}
+        {{ buttontext }}
+        {{ svgicon | safe }}
+      {%- else %}
+        {{ svgicon | safe }}
+        {{ buttontext }}
+      {%- endif %}
+    </button>
+{%- endmacro %}
+
+
+
+{%- macro create_workshop_modal(
+  service_id,
+  row_id,
+  workshop_id)
+%}
+  <div class="modal fade" id="{{ service_id }}-{{ row_id }}-workshop-modal" role="dialog" tabindex="-1">
+    <div class="modal-dialog modal-dialog-centered">
+
+      <!-- Modal content-->
+      <div class="modal-content">
+        <div class="modal-header">
+          <h4 class="modal-title" style="color: black">Share Workshop</h4>
+          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
+        </div>
+        <div class="modal-body">
+          <p style="color: black">Share your workshop via URL</p>
+          <a href="" target="_blank"></a>
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-default" data-bs-dismiss="modal">Close</button>
+          <button type="button" data-service="{{ service_id }}" data-row="{{ row_id }}" id="{{ service_id }}-{{ row_id }}-workshop-modal-copy-btn" class="btn btn-outline-primary" data-bs-toggle="tooltip" data-service="{{ service_id }}" data-row="{{ row_id }}" data-bs-placement="top" title="Copy to clipboard">Copy</button>
+        </div>
+      </div>
+    </div>
+  </div>
+{%- endmacro %}
+
+{%- macro create_buttons(
+  service_id, 
+  row_id,
+  element_options
+)%}
+  <hr>
+  <div class="d-flex" id="{{ service_id }}-{{ row_id }}-buttons-div" role="dialog" tabindex="-1">
+    {%- for button in element_options.get("input", {}).get("options", {}).get("buttons",[] ) %}
+      {%- set button_options = element_options.get("input", {}).get("options", {}).get(button, {}) %}
+      {%- if ( row_id == vars.first_row_id and button_options.get("firstRow", true) ) or 
+          ( row_id != vars.first_row_id and button_options.get("defaultRow", true) ) %}
+        {{ create_button(service_id, row_id, button, button_options) }}
+      {%- endif %}
+    {%- endfor %}
+  </div>
+  {%- if pagetype == vars.pagetype_workshopmanager %}
+    {{ create_workshop_modal(service_id, row_id) }}
+  {%- endif %}
+{%- endmacro %}
+
+{%- macro create_trigger(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options,
+  full_id
+) %}
+{%- endmacro %}
+
+{%- macro create_label(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+)%}
+  {#
+    <label class="col-{{ label.get("width", "4") }} col-form-label" for="{{ id_prefix }}-{{ element_id }}-input">
+  #}
+  {%- set label = element_options.get("label", {}) %}
+  <div class="col-{{ label.get("width", "4") }} col-form-label d-flex align-items-start justify-content-between"> 
+    <label for="{{ id_prefix }}-{{ element_id }}-input" class="d-flex align-items-center w-100"> 
+      {%- if label.type in ["text", "texticon", "texticonclick", "texticonclickcheckbox", "textcheckbox", "texticoncheckbox"] %}
+        {%- if label.value is string %}
+          {{ label.value }}
+        {%- endif %}
+      {%- endif %}
+      {%- if label.type in ["texticon", "texticoncheckbox"] %}
+        <a class="lh-1 ms-3" style="padding-top: 1px;" 
+          data-bs-toggle="tooltip" data-bs-placement="right" data-bs-html="true"
+          title="{{ label.icontext }}">
+          {{ svg.info_svg | safe }}
+        </a>
+      {%- endif %}
+      {%- if label.type == "texticonclick" %}
+        <button type="button" class="btn"
+          data-bs-toggle="tooltip" data-bs-placement="right" data-bs-html="true"
+          title="{{ label.icontext }}">
+          {{ svg.info_svg | safe }}
+          <span class="text-muted" style="font-size: smaller">(click me)</span>
+        </button>
+      {%- endif %}
+      {%- if label.type == "textdropdown" %}
+      {%- endif %}
+      {%- if label.type in ["textcheckbox", "texticoncheckbox", "texticonclickcheckbox"] %}
+        <input type="checkbox" 
+          {%- if label.get('options', {}).get("align-right", true ) %}
+          style="margin-left: auto;"
+          {%- else %}
+          style="margin-left: .5em;"
+          {%- endif %}
+          class="form-check-input"
+          id="{{ id_prefix }}-{{ element_id }}-input-cb"
+          data-service="{{ service_id }}"
+          data-row="{{ row_id }}"
+          data-tab="{{ tab_id }}"
+          data-element="{{ element_id }}"
+          {%- for specific_key, specific_values in element_options.get("dependency", {}).items() %}
+            data-dependency-{{ specific_key }}="true"
+            {%- for specific_value in specific_values %}
+              data-dependency-{{ specific_key }}-{{ specific_value }}="true"
+            {%- endfor %}
+          {%- endfor %}
+
+          {%- set ignore_keys = ["name", "value", "show", "align-right", "placeholder", "pattern", "warning", "required"] %}
+          {%- for key, value in label.get('options', {}).items() %}
+            {%- if key not in ignore_keys %}
+              {%- if value is string or value is boolean %}
+                data-{{key}}="{{ value | lower }}"
+              {%- endif %}
+            {%- endif %}
+          {%- endfor %}
+
+          {# add default group #}
+          {%- if "group" not in label.get('options', {}).keys() %}
+            data-group="default"
+          {%- endif %}
+
+          {%- set checked = label.get('options', {}).get('default', false) %}
+          data-enabled="{{ label.get('options', {}).get('enabled', true) | lower }}"
+          {%- if not label.get('options', {}).get('enabled', true) %}
+          disabled="true"
+          {%- endif %}
+          data-label-input="true"
+          data-checked={{ checked | lower }}
+          {%- if checked %}
+            checked
+          {%- endif -%}
+          {%- if label.get('options', {}).get('name', false) %}
+          name="{{ label.get('options', {}).get('name', false) }}"
+          {%- endif %}
+          />
+      {%- endif %}
+      {%- if label.type == "dropdown" %}
+      {%- endif %}
+      {%- if label.type == "function" %}
+      {%- endif %}
+      {%- if label.type == "header" %}
+        <h4>{{ label.value }}</h4>
+      {%- endif %}
+    </label>
+  </div>
+  {# 
+  #}
+{%- endmacro %}
+
+
+{%- macro create_multiple_checkboxes(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) -%}
+  {#- User-selected Modules #}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+    <div id="{{ id_prefix }}-{{ element_id }}-checkboxes-div" class="row g-0"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+    >
+    </div>
+  </div>
+  {# create_trigger suffix: checkboxes-div #}
+{%- endmacro %}
+
+{%- macro create_label_input(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div"
+    class="row mb-1"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+  </div>
+{%- endmacro %}
+
+
+{%- macro element_parameters(
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options,
+  define_show=false,
+  collect=true
+) %}
+  {# data parameter for all elements #}
+  data-service="{{ service_id }}"
+  data-row="{{ row_id }}"
+  data-tab="{{ tab_id }}"
+  data-type="{{ element_options.get('input', {}).get('type', 'default') }}"
+  data-element="{{ element_id }}"
+
+  {%- set ignore_keys = ["name", "value", "show", "align-right", "placeholder", "pattern", "warning", "required", "collect-static"] %}
+  {%- for key, value in element_options.get('input', {}).get('options', {}).items() %}
+    {%- if key not in ignore_keys %}
+      {%- if value is string or value is boolean %}
+        data-{{key}}="{{ value | lower }}"
+      {%- endif %}
+    {%- endif %}
+  {%- endfor %}
+
+  {# add default group #}
+  {%- if "group" not in element_options.get('input', {}).get('options', {}).keys() %}
+    data-group="default"
+  {%- endif %}
+  {%- if collect %}
+    {%- if "collect" not in element_options.get('input', {}).get('options', {}).keys() %}
+      data-collect=false
+    {%- endif %}
+  {%- endif %}
+  {%- if element_options.get('input', {}).get('options', {}).get('collectstatic', false) %}
+    data-collect-static
+  {%- endif %}
+    
+
+  {# data parameter for input elements #}
+  {%- if element_options.get("input", {}).get("options", {}).get("size", false) %} 
+    size={{ element_options.get("input", {}).get("options", {}).get("size", 1) }} 
+  {%- endif %}
+  {%- if element_options.get("input", {}).get("options", {}).get("multiple", false) %} 
+    multiple 
+  {%- endif %}
+  {%- if not element_options.get('input', {}).get('options', {}).get('enabled', true) and 
+      not ( is_instructor and element_options.get("input", {}).get("options", {}).get("instructor", "") == "enabled" )
+  %}
+    disabled
+  {%- endif %}
+  {%- if element_options.get("input", {}).get("options", {}).get("required", false) %}
+    required
+  {%- endif %}
+  {%- if element_options.get("input", {}).get("options", {}).get("pattern", "") %}
+    pattern="{{ element_options.get("input", {}).get("options", {}).get("pattern", "") }}"
+  {%- endif %}
+  {%- if element_options.get("input", {}).get("options", {}).get("placeholder", "") %}
+    placeholder="{{ element_options.get("input", {}).get("options", {}).get("placeholder", "") }}"
+  {%- endif %}
+  {%- if element_options.get("input", {}).get("options", {}).get("value", "") %}
+    value="{{ element_options.get("input", {}).get("options", {}).get("value", "") }}"
+  {%- endif %}
+
+  {# If it's only available in a specific environment, hide it always by default #}
+  
+  {%- for specific_key, specific_values in element_options.get("dependency", {}).items() %}
+    data-dependency-{{ specific_key }}="true"
+    {%- for specific_value in specific_values %}
+      data-dependency-{{ specific_key }}-{{ specific_value }}="true"
+    {%- endfor %}
+  {%- endfor %}
+  {%- if define_show %}
+    {%- if element_options.get("input", {}).get("options", {}).get("show", true) or 
+        ( is_instructor and element_options.get("input", {}).get("options", {}).get("instructor", "") == "show" )
+    %}
+      data-show="true"
+    {%- else %}      
+      data-show="false"
+    {%- endif %}
+    {%- if not element_options.get("input", {}).get("options", {}).get("show", false) and
+        not ( is_instructor and element_options.get("input", {}).get("options", {}).get("instructor", "") == "show" )
+    %}
+      style="display: none"
+    {%- endif %}
+  {%- endif %}
+{%- endmacro %}
+
+{%- macro create_text_input(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row mb-1"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+    <div class="col-{{ 12 - element_options.get("label", {}).get("width", "4") | int }} d-flex flex-column justify-content-center">
+      {%- if element_options.get("input", {}).get("options", {}).get("secret", false) %}
+        <div class="input-group">
+      {%- endif %}
+      <input type="{%- if element_options.get("input", {}).get("options", {}).get("secret", false) -%}password{%- else -%}text{%- endif -%}" 
+        class="form-control"
+        {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+        name="{{ element_options.get('input', {}).get('options', {}).get('name', element_id) }}"
+        id="{{ id_prefix }}-{{ element_id }}-input"
+      />
+      {%- if element_options.get("input", {}).get("options", {}).get("secret", false) %}
+        <span class="input-group-append">
+          <button class="btn btn-light" type="button" 
+            data-service="{{ service_id }}"
+            data-row="{{ row_id }}"
+            data-element="{{ element_id }}"
+            id="{{ id_prefix }}-{{ element_id }}-view-password"
+          >
+            <i id="{{ id_prefix }}-{{ element_id }}-password-eye" class="fa fa-eye" aria-hidden="true"></i>
+          </button>
+        </span>
+      {%- endif %}
+      <div class="invalid-feedback">{{ element_options.get("input", {}).get("options", {}).get("warning", "") }}</div>
+      {%- if element_options.get("input", {}).get("options", {}).get("secret", false) %}
+        </div>
+      {%- endif %}
+    </div>
+  </div>
+{%- endmacro %}
+
+{%- macro create_textgrower_input(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row mb-1"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+    <div data-count=1 class="container col-{{ 12 - element_options.get("label", {}).get("width", "4") | int }} d-flex flex-column justify-content-center">
+      
+      <div class="input-group" style="display: flex; align-items: center; margin-bottom: 10px;">
+        <input id="{{ id_prefix }}-1-{{ element_id }}-input" type="{%- if element_options.get("input", {}).get("options", {}).get("secret", false) -%}password{%- else -%}text{%- endif -%}" 
+          class="form-control"
+          {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+          name="{{ element_options.get('input', {}).get('options', {}).get('name', element_id) }}"          
+        />
+        <button data-service="{{ service_id }}" data-row="{{ row_id }}" data-tab="{{ tab_id }}" data-collect-static data-element="{{ element_id }}" data-textgrower-btn-type="add" data-collect="false" {% if not element_options.get('input', {}).get('options', {}).get('enabled', true) -%} disabled {% endif -%} type="button" id="{{ id_prefix }}-1-addbtn-{{ element_id }}-input" data-btn-type="add" style="margin-left: 8px;" class="btn btn-primary">{{ svg.plus_svg | safe }}</button>
+      </div>
+      <div class="invalid-feedback">{{ element_options.get("input", {}).get("options", {}).get("warning", "") }}</div>
+    </div>
+  </div>
+{%- endmacro %}
+
+{%- macro create_date_input(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div"
+    class="row mb-1"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+    <div class="col-{{ 12 - element_options.get("label", {}).get("width", "4") | int }} d-flex flex-column justify-content-center">
+      <input type="date" 
+        {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+        class="form-control"
+        name="{{ element_options.get('input', {}).get('options', {}).get('name', element_id) }}"
+        id="{{ id_prefix }}-{{ element_id }}-input"
+        value="{{ today_plus_half_year }}"
+        min="{{ today }}"
+        max="{{ today_plus_one_year }}"
+      />
+      <div class="invalid-feedback">{{ element_options.get("input", {}).get("options", {}).get("warning", "") }}</div>
+    </div>
+  </div>
+{%- endmacro %}
+
+
+{%- macro create_number_input(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  {% set name_ = element_options.get('input', {}).get('options', {}).get('name', element_id) %}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row mb-2"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+    <div class="col-{{ 12 - element_options.get("label", {}).get("width", "4") | int }} d-flex flex-column justify-content-center">
+      <input type="number"
+        {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+        name="{{ name_ }}"
+        class="form-control"
+        id="{{ id_prefix }}-{{ element_id }}-input"
+        {%- if element_options.get("input", {}).get("options", {}).get("required", false) %}
+        required
+        {%- endif %}
+        {%- if element_options.get("input", {}).get("options", {}).get("pattern", "") %}
+        pattern="{{ element_options.get("input", {}).get("options", {}).get("pattern", "") }}"
+        {%- endif %}
+        {%- if element_options.get("input", {}).get("options", {}).get("placeholder", "") %}
+        placeholder="{{ element_options.get("input", {}).get("options", {}).get("placeholder", "") }}"
+        {%- endif %}
+        {%- if element_options.get("input", {}).get("options", {}).get("value", "") %}
+        value="{{ element_options.get("input", {}).get("options", {}).get("value", "") }}"
+        {%- endif %}
+        {%- if not element_options.get("input", {}).get("options", {}).get("enabled", true) %}
+        disabled
+        {%- endif %}
+      />
+      <div class="invalid-feedback">{{ element_options.get("input", {}).get("options", {}).get("warning", "") }}</div>
+    </div>
+  </div>
+{%- endmacro %}
+
+{%- macro create_checkbox_input(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row mb-2"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+    <div class="col-{{ 12 - element_options.get("label", {}).get("width", "4") | int }} d-flex flex-column justify-content-center">
+      <input type="checkbox"
+        name="{{ element_options.get('input', {}).get('options', {}).get('name', element_id) }}"
+        {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+        class="form-check-input"
+        id="{{ id_prefix }}-{{ element_id }}-input"
+        {%- if element_options.get("input", {}).get("options", {}).get("required", false) %}
+        required
+        {%- endif %}
+        {%- if element_options.get("input", {}).get("options", {}).get("pattern", "") %}
+        pattern="{{ element_options.get("input", {}).get("options", {}).get("pattern", "") }}"
+        {%- endif %}
+        {%- if element_options.get("input", {}).get("options", {}).get("placeholder", "") %}
+        placeholder="{{ element_options.get("input", {}).get("options", {}).get("placeholder", "") }}"
+        {%- endif %}
+        {%- if element_options.get("input", {}).get("options", {}).get("value", "") %}
+        value="{{ element_options.get("input", {}).get("options", {}).get("value", "") }}"
+        {%- endif %}
+        {%- if not element_options.get("input", {}).get("options", {}).get("enabled", true) %}
+        disabled
+        {%- endif %}
+        {% if element_options.get('input', {}).get('options', {}).get('default', false) %}
+        checked
+        {%- endif %}
+      />
+      <div class="invalid-feedback">{{ element_options.get("input", {}).get("options", {}).get("warning", "") }}</div>
+    </div>
+  </div>
+{%- endmacro %}
+
+{%- macro create_select_input(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  {# Versions #}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row mb-1"
+  {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {{ create_label(id_prefix, service_id, row_id, tab_id, element_id, element_options) }}
+    <div class="col-{{ 12 - element_options.get("label", {}).get("width", "4") | int }} d-flex flex-column justify-content-center">
+      <select 
+        name="{{ element_options.get('input', {}).get('options', {}).get('name', element_id) }}"
+        id="{{ id_prefix }}-{{ element_id }}-input"
+        class="form-select"
+        {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+      >
+      </select>
+      <div class="invalid-feedback">{{ element_options.get("input", {}).get("options", {}).get("warning", "You have to select at least one item.") }}</div>
+    </div>
+  </div>
+{%- endmacro %}
+
+{%- macro create_reservation_info(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+)%}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row mb-3"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    {%- set reservation_info_classes = "col-4 fw-bold"%}
+    <div id="{{ id_prefix }}-{{ element_id }}-info" class="col-8 offset-4">
+      <div class="row">
+        <span class="{{ reservation_info_classes }}">Start Time:</span>
+        <span id="{{ id_prefix }}-{{ element_id }}-start" class="col-auto"></span>
+      </div>
+      <div class="row">
+        <span class="{{ reservation_info_classes }}">End Time:</span>
+        <span id="{{ id_prefix }}-{{ element_id }}-end" class="col-auto"></span>
+      </div>
+      <div class="row">
+        <span class="{{ reservation_info_classes }}">State:</span>
+        <span id="{{ id_prefix }}-{{ element_id }}-state" class="col-auto"></span>
+      </div>
+      <div class="mt-1">
+        <details>
+          <summary class="fw-bold">Detailed reservation information:</summary>
+          <pre id="{{ id_prefix }}-{{ element_id }}-details"></pre>
+        </details>
+      </div>
+    </div>
+  </div>
+  {# create_trigger suffix: input-div #}
+{%- endmacro %}
+
+{%- macro create_flavor_legend(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+)%}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row align-items-center g-0 mt-4"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}    
+  >
+    <span class="col-4 fw-bold">Available Flavors</span>
+    <div class="col d-flex align-items-center ms-2">
+      {%- set box_style = "height: 15px; width: 15px; border-radius: 0.25rem;"%}
+      <div style="{{box_style}} background-color: #198754;"></div>
+      <span class="ms-1">= Free</span>
+      <span class="mx-2"></span>
+      <div style="{{box_style}} background-color: #023d6b;"></div>
+      <span class="ms-1">= Used</span>
+      <span class="mx-2"></span>
+      <div style="{{box_style}} background-color: #dc3545;"></div>
+      <span class="ms-1">= Limit exceeded</span>
+    </div>
+  </div>
+  {# create_trigger suffix: input-div #}
+{%- endmacro %}
+
+{%- macro create_flavor_info(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+)%}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" data-sse-flavors class="mb-3"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+    ></div>
+{# create_trigger suffix: input-div #}
+{%- endmacro %}
+
+{%- macro create_selecthelper(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+)%}
+  <div id="{{ id_prefix }}-{{ element_id }}-input-div" class="row g-0"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options, define_show=true) }}
+  >
+    <hr>
+    <div class="form-check col-sm-6 col-md-4 col-lg-3">
+      <input class="form-check-input data-service="{{ service_id }}" data-row="{{ row_id }}" data-tab="{{ tab_id }}" module-selector" type="checkbox" id="{{ id_prefix }}-{{ element_id }}-select-all">
+      <label class="form-check-label" for="{{ id_prefix }}-{{ element_id }}-select-all">Select all</label>
+    </div>
+    <div class="form-check col-sm-6 col-md-4 col-lg-3">
+      <input class="form-check-input data-service="{{ service_id }}" data-row="{{ row_id }}" data-tab="{{ tab_id }}" module-selector" type="checkbox" id="{{ id_prefix }}-{{ element_id }}-select-none">
+      <label class="form-check-label" for="{{ id_prefix }}-{{ element_id }}-select-none">Deselect all</label>
+    </div>
+  </div>
+{# create_trigger suffix: input-div #}
+{%- endmacro %}
+
+{%- macro create_logcontainer(
+  id_prefix,
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+)%}
+  <div id="{{ id_prefix }}-{{ element_id }}-input" class="card card-body text-black row g-0"
+    {{ element_parameters(service_id, row_id, tab_id, element_id, element_options) }}
+  >
+    <div class="log-div">
+      Logs collected during the Start process will be shown here.
+    </div>
+  </div>
+{# create_trigger suffix: input-div #}
+{%- endmacro %}
+
+{%- macro create_element(
+  service_id,
+  row_id,
+  tab_id,
+  element_id,
+  element_options
+) %}
+  {% set id_prefix = service_id ~ '-' ~ row_id ~ '-' ~ tab_id %}
+  {%- if element_options.get("input", {}).get("type", "") == "text" %}
+    {{ create_text_input(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "textgrower" %}
+    {{ create_textgrower_input(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "label" %}
+    {{ create_label_input(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}  
+  {%- elif element_options.get("input", {}).get("type", "") == "date" %}
+    {{ create_date_input(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "number" %}
+    {{ create_number_input(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "checkbox" %}
+    {{ create_checkbox_input(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "buttons" %}
+    {{ create_buttons(
+      service_id, 
+      row_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "select" %}
+    {{ create_select_input(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "reservationinfo" %}
+    {{ create_reservation_info(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "flavorlegend" %}
+    {{ create_flavor_legend(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "flavorinfo" %}
+    {{ create_flavor_info(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "multiple_checkboxes" %}
+    {{ create_multiple_checkboxes(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "selecthelper" %}
+    {{ create_selecthelper(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "logcontainer" %}
+    {{ create_logcontainer(
+      id_prefix,
+      service_id,
+      row_id,
+      tab_id,
+      element_id,
+      element_options
+    )}}
+  {%- elif element_options.get("input", {}).get("type", "") == "hr" %}
+  <hr>
+  {%- endif %}
+{%- endmacro %}
+
diff --git a/templates/macros/table/elements_js.jinja b/templates/macros/table/elements_js.jinja
new file mode 100644
index 0000000..7f3865c
--- /dev/null
+++ b/templates/macros/table/elements_js.jinja
@@ -0,0 +1,646 @@
+{%- import "macros/svgs.jinja" as svg -%}
+{%- include "macros/table/table_js.jinja" %}
+{%- import "macros/table/variables.jinja" as vars with context %}
+
+<script>
+  $(document).ready(function() {
+    require(["jquery", "jhapi", "utils"], function (
+      $,
+      JHAPI,
+      utils
+    ) {
+      var base_url = window.jhdata.base_url;
+      var api = new JHAPI(base_url);
+      var user = window.jhdata.user;
+      const logDebug = false;
+
+      let optionElement;
+
+      {%- for service_id, service_options in config.frontend_config.get("services", {}).get("options", {}).items() %}
+        // Configure element specific elements:
+        {%- for tab_id, tab_options in service_options.get("tabs", {}).items() %}
+          {%- for side in tab_options.keys() %}
+            {%- for element_id, element_options in tab_options.get(side, {}).items() %}
+              {%- if element_options.get("input", {}).get("type", "") == "buttons" %}
+                {%- for button in element_options.get("input", {}).get("options", {}).get("buttons", []) %}
+                  {% set trigger = element_options.get("input", {}).get("options", {}).get(button, {}).get("trigger", false) %}
+                  {%- if trigger %}
+                    {%- set button_options = element_options.get("input", {}).get("options", {}).get(button, {}) %}
+                    $(`[id^='{{ service_id }}-'][id$='-{{ button }}-btn']`).on("click", function() {
+                      logDebug && console.log("Button click {{ button }}");
+                      const $this = $(this);
+                      const serviceId = $this.attr("data-service");
+                      const rowId = $this.attr("data-row");
+                      {{ button_options.get("trigger", "") }}(serviceId, rowId, "{{ button }}", {{ button_options | tojson }}, user, api, base_url, utils);
+                      logDebug && console.log("Button click {{ button }} done");
+                    });
+                  {%- endif %}
+                {%- endfor %}
+              {%- else %}
+                {%- set trigger_suffix = element_options.get("triggerSuffix", "input") %}
+                {%- for trigger_key, trigger_func in element_options.get("trigger", {}).items() %}
+                  $(`[id^='{{ service_id }}-'][id$='-{{ element_id }}-{{ trigger_suffix}}']`).on("trigger_{{ trigger_key }}", function (event) {
+                    if (event.target !== this) {
+                      return; // Ignore events bubbling up from child elements
+                    }
+                    logDebug && console.log("update {{ element_id }}. Triggered by: ({{ trigger_key }})");
+                    const $this = $(this);
+                    const serviceId = $this.attr("data-service");
+                    const rowId = $this.attr("data-row");
+                    const preValue = $this.val();
+                    const dependencies = {{ element_options.get("dependency", {}) | tojson }};
+                    let trigger = true;
+                    {%- if trigger_key != "init" %}
+                      for (const [key, allowedValues] of Object.entries(dependencies)) {
+                        const currentValues = val(getInputElement(serviceId, rowId, key));
+                        trigger = currentValues.some(value => {
+                          const mappedValue = mappingDict?.[serviceId]?.[key]?.[value] ?? value;
+                          return allowedValues.includes(mappedValue);
+                        });
+                        if ( !trigger ) {
+                          break;
+                        }
+                      }
+                    {%- endif %}
+                    if ( trigger ) {
+                      {{ trigger_func }}("{{ trigger_key }}", serviceId, rowId, "{{ tab_id }}", "{{ element_id }}", {{ element_options | tojson }});
+                      $this.trigger("change");
+                      logDebug && console.log("update {{ element_id }}. Triggered by: ({{ trigger_key }}) done");
+                    } else {
+                      logDebug && console.log("update {{ element_id }}. Triggered by: ({{ trigger_key }}) no function call");
+                    }
+                  });
+                {%- endfor %}
+                {%- if element_options.get("triggerOnChange", "") %}
+                  $(`[id^='{{ service_id }}-'][id$='-{{ tab_id }}-{{ element_id }}-{{ trigger_suffix}}']`).on("change", function () {
+                    const $this = $(this);
+                    const serviceId = $this.attr("data-service");
+                    const rowId = $this.attr("data-row");
+                    {{ element_options["triggerOnChange"] }}("onChange", serviceId, rowId, "{{ tab_id }}", "{{ element_id }}", {{ element_options | tojson }});
+                  });
+                {%- endif %}
+                {%- set label_options = element_options.get("label", {}) %}
+                {%- if label_options.get("type", "text") in ["textcheckbox", "texticoncheckbox", "texticonclickcheckbox"] %}
+                  {%- for trigger_key, trigger_func in label_options.get("trigger", {}).items() %}
+                    $(`[id^='{{ service_id }}-'][id$='-{{ tab_id }}-{{ element_id }}-input-cb']`).on("trigger_{{ trigger_key }}"), function (event) {
+                      if (event.target !== this) {
+                        return; // Ignore events bubbling up from child elements
+                      }
+                      const $this = $(this);
+                      const serviceId = $this.attr("data-service");
+                      const rowId = $this.attr("data-row");
+                      logDebug && console.log("update {{ element_id }}. Triggered by: ({{ trigger_key }})");
+                      {{ trigger_func }}("{{ trigger_key }}", serviceId, rowId, "{{ tab_id }}", "{{ element_id }}", {{ label_options.get("options", {}) | tojson }});
+                      logDebug && console.log("update {{ element_id }}. Triggered by: ({{ trigger_key }}) done");
+                    });
+                  {%- endfor %}
+                  $(`[id^='{{ service_id }}-'][id$='-{{ tab_id }}-{{ element_id }}-input-cb']`).on("change", function() {
+                    const $this = $(this);
+                    const serviceId = $this.attr("data-service");
+                    const rowId = $this.attr("data-row");
+                    const checked = $this.prop("checked");
+                    $(`[id^='${serviceId}-${rowId}-'][id$='-{{ element_id }}-input']`).prop("disabled", !checked);
+                    $(`[id^='${serviceId}-${rowId}-'][id$='-{{ element_id }}-input']:not([data-collect-static])`).attr("data-collect", checked);
+                    if ( !checked ) {
+                      $(`[id^='${serviceId}-${rowId}-'][id$='-{{ element_id }}-input']`).removeClass("is-invalid");
+                    }
+                    
+                    {%- if label_options.get("triggerOnChange", "") %}
+                      {{ label_options["triggerOnChange"] }}("change", serviceId, rowId, "{{ tab_id }}", "{{ element_id }}", {{ label_options.get("options", {}) | tojson }});
+                    {%- endif %}
+                    $(`[id^='${serviceId}-${rowId}-']`).trigger(`trigger_{{ element_id }}`);
+                    logDebug && console.log("update {{ element_id }}. Trigger Change by: {{ trigger_key }}");
+                    $(`[id^='${serviceId}-${rowId}-'][id$='-{{ element_id }}-input']`).trigger("change");
+                    logDebug && console.log("update {{ element_id }}. Trigger Change by: {{ trigger_key }} done");
+                  });
+                {%- endif %}
+              {%- endif %}
+            {%- endfor %}
+          {%- endfor %}
+        {%- endfor %}
+        {%- for button_id, button_options in service_options.navbar.items() %}
+          $(`button[id^='{{ service_id }}-'][id$='-{{ button_id }}-navbar-button']`).on("show", function (event) {
+            const $this = $(this);
+            const rowId = $this.attr("data-row");
+            const serviceId = $this.attr("data-service");
+            let show = true;
+            if ( !$this.data('show') ) {
+              const dependencies = {{ button_options.get("dependency", {}) | tojson }};
+              for (const [key, allowedValues] of Object.entries(dependencies)) {
+                const currentValues = val(getInputElement(serviceId, rowId, key));
+                show = currentValues.some(value => {
+                  const mappedValue = mappingDict[serviceId]?.[key]?.[value] ?? value;
+                  return allowedValues.includes(mappedValue);
+                });
+                if ( !show ) {
+                  break;
+                }
+              }
+            }
+            if ( show ) {
+              $this.addClass("show");
+              $this.attr("style", "");
+              $this.show();
+              $(`#${serviceId}-${rowId}-{{ button_id }}-tab-input-warning`).addClass("invisible");
+            }
+          });
+          $(`button[id^='{{ service_id }}-'][id$='-{{ button_id }}-navbar-button']`).on("hide", function (event) {
+            const $this = $(this);
+            const rowId = $this.attr("data-row");
+            const serviceId = $this.attr("data-service");
+            $this.removeClass("show");
+            $this.attr("style", "{{ style_hide }}");
+            $this.hide();
+            $(`[id^='${serviceId}-'][id$='-${rowId}-{{ button_id }}-tab-input-warning']`).addClass("invisible");
+          });
+          $(`button[id^='{{ service_id }}-'][id$='-{{ button_id }}-navbar-button']`).on("activate", function (event) {
+            const $this = $(this);
+            const rowId = $this.attr("data-row");
+            const serviceId = $this.attr("data-service");
+            $(`div[id^='${serviceId}-${rowId}-'][id$='-{{ button_id }}-contenttab-div']`).addClass("show");
+            $(`div[id^='${serviceId}-${rowId}-'][id$='-{{ button_id }}-contenttab-div']`).show();
+            $(`[id^='${serviceId}-${rowId}-'][id$='-{{ button_id }}-tab-input-warning']`).addClass("invisible");
+          });
+          $(`button[id^='{{ service_id }}-'][id$='-{{ button_id }}-navbar-button']`).on("deactivate", function (event) {
+            const $this = $(this);
+            const rowId = $this.attr("data-row");
+            const serviceId = $this.attr("data-service");
+            $(`div[id^='${serviceId}-${rowId}-'][id$='-{{ button_id }}-contenttab-div']`).removeClass("show");
+            $(`div[id^='${serviceId}-${rowId}-'][id$='-{{ button_id }}-contenttab-div']`).hide();
+          });
+          $(`button[id^='{{ service_id }}-'][id$='-{{ button_id }}-navbar-button']`).on("click", function (event) {
+            $this = $(this);
+            const rowId = $this.attr("data-row");
+            const serviceId = $this.attr("data-service");
+            $(`button[id^='${serviceId}-${rowId}-'][id$='-navbar-button']:not([data-tab='{{ button_id }}'])`).trigger("deactivate");
+            $this.trigger("activate");
+          });
+          {%- for trigger_key, trigger_func in button_options.get("trigger", {}).items() %}
+            $(`button[id^='{{ service_id }}-'][id$='-{{ button_id }}-navbar-button']`).on("trigger_{{ trigger_key }}", function (event) {
+              if (event.target !== this) {
+                return; // Ignore events bubbling up from child elements
+              }
+              $this = $(this);
+              const rowId = $this.attr("data-row");
+              const serviceId = $this.attr("data-service");
+              let trigger = true;
+              const dependencies = {{ button_options.get("dependency", {}) | tojson }};
+              for (const [key, allowedValues] of Object.entries(dependencies)) {
+                const currentValues = val(getInputElement(serviceId, rowId, key));
+                trigger = currentValues.some(value => {
+                  const mappedValue = mappingDict[serviceId]?.[key]?.[value] ?? value;
+                  return allowedValues.includes(mappedValue);
+                });
+                if ( !trigger ) {
+                  break;
+                }
+              }
+              if ( trigger ) {
+                {{ trigger_func }}("{{ button_id }}", serviceId, rowId);
+              }
+            })
+          {%- endfor %}
+
+        {%- endfor %}
+        {%- if pagetype == vars.pagetype_workshopmanager %}
+          let modalWasVisible = false;
+          new IntersectionObserver((entries) => {
+            entries.forEach(entry => {
+              if (entry.isIntersecting) {
+                modalWasVisible = true;
+              } else if (modalWasVisible) {
+                let serviceId = $('#service-input').val();
+                let workshopId = $(`input[data-row='{{ vars.first_row_id }}'][id$='-workshopid-input']`).val();
+                if ( !Array.isArray(workshopId) ){
+                  workshopId = [workshopId];
+                }
+                window.location.href = window.location.origin + window.location.pathname + "?service=" + serviceId + "&row=" + workshopId + "&v" + new Date().getTime();
+              }
+            });
+          }).observe(document.getElementById('{{ service_id }}-{{ vars.first_row_id }}-workshop-modal'));
+        {%- endif %}
+      {%- endfor %}
+      // show / hide dependent elements
+      $(`select[id$='-input']`).change(function (event) {
+        const $this = $(this);
+        const serviceId = $this.attr("data-service");
+        const rowId = $this.attr("data-row");
+        const elementId = $this.attr("data-element");
+        logDebug && console.log(`${elementId} changed ... `);
+        $(`[id^='${serviceId}-${rowId}-']`).trigger(`trigger_${elementId}`);
+
+        const isDisabled = $this.prop("disabled");
+        let newValues = $this.val();
+        if ( !isDisabled && !(!newValues || (Array.isArray(newValues) && newValues.length === 0)) ) {
+          if ( !Array.isArray(newValues) ){
+            newValues = [newValues];
+          }
+          // const mappedValues = newValues.map(newValue => mappingDict[serviceId]?.[elementId]?.[newValue] ?? newValue);
+          const mappedValues = [...new Set(newValues.map(newValue => mappingDict[serviceId]?.[elementId]?.[newValue] ?? newValue))];
+          const excludes = `:not(${mappedValues.map(value => `[data-dependency-${elementId}-${value}]`).join(',')})`;
+          let prefixSelector = "";
+          let selector = "";
+
+          // Show + set to Active (add collect)
+          prefixSelector = `div[id^='${serviceId}-${rowId}-'][id$='-input-div'][data-show='true']`;
+          selector = mappedValues.map(value => `${prefixSelector}[data-dependency-${elementId}-${value}]`).join(',');
+          $(`${selector}`).show();
+          
+          prefixSelector = `[id^='${serviceId}-${rowId}-'][id$='-input']:not([data-collect-static])`;
+          selector = mappedValues.map(value => `${prefixSelector}[data-dependency-${elementId}-${value}]`).join(',');
+          $(`${selector}`).attr("data-collect", true);
+          
+          // trigger all new activated label cb, to ensure normally hidden inputs are shown
+          prefixSelector = `[id^='${serviceId}-${rowId}-'][id$='-input-cb']`;
+          selector = mappedValues.map(value => `${prefixSelector}[data-dependency-${elementId}-${value}]`).join(',');
+          $(`${selector}`).trigger("change");
+
+          // show navbar buttons
+          prefixSelector = `button[id^='${serviceId}-${rowId}-'][id$='-navbar-button'][data-show="true"]`;
+          selector = mappedValues.map(value => `${prefixSelector}[data-dependency-${elementId}-${value}]`).join(',');
+          $(`${selector}`).trigger("show");
+          $(`${selector}`).trigger("change");
+
+          // show buttons
+          prefixSelector = `button[id^='${serviceId}-${rowId}-'][id$='-btn']`;
+          selector = mappedValues.map(value => `${prefixSelector}[data-dependency-${elementId}-${value}]`).join(',');
+          $(`${selector}`).show();
+
+        {# Show / Hide dependency values #}
+          // hide + ignore
+          $(`div[id^='${serviceId}-${rowId}-'][id$='input-div'][data-dependency-${elementId}]${excludes}`).hide();
+          $(`[id^='${serviceId}-${rowId}-'][id$='-input'][data-dependency-${elementId}]${excludes}`).attr("data-collect", false);
+
+          // hide navbar buttons
+          selector = `button[id^='${serviceId}-${rowId}-'][id$='-navbar-button'][data-dependency-${elementId}]${excludes}`;
+          $(`${selector}`).trigger("hide");
+
+          // hide buttons
+          selector = `button[id^='${serviceId}-${rowId}-'][id$='-btn'][data-dependency-${elementId}]${excludes}`;
+          $(`${selector}`).hide();
+        } else {
+          // hide + ignore all specific inputs
+          $(`div[id^='${serviceId}-${rowId}-'][id$='input-div'][data-dependency-${elementId}]`).hide();
+          $(`[id^='${serviceId}-${rowId}-'][id$='input'][data-dependency-${elementId}]`).attr("data-collect", false);
+        }
+      });
+
+
+      {%- if pagetype == vars.pagetype_workshopmanager %}
+        $(`[id$='-workshop-modal-copy-btn']`).on("click", function (){
+          const $this = $(this);
+          const serviceId = $this.attr("data-service");
+          const rowId = $this.attr("data-row");
+          const workshopUrl = $(`#${serviceId}-${rowId}-workshop-modal .modal-body a`).attr('href');
+          navigator.clipboard.writeText(workshopUrl).then(function() {
+            $(`#${serviceId}-${rowId}-workshop-modal-copy-btn`).tooltip('dispose').attr('title', 'Copied');
+            $(`#${serviceId}-${rowId}-workshop-modal-copy-btn`).tooltip('show');
+          }, function(err) {
+            console.error('Could not copy text: ', err);
+          });
+        });
+
+        window.workshopManagerShowModal = function (serviceId, rowId, workshopId) {
+          let workshopUrl = new URL(utils.url_path_join(window.origin, base_url, "workshops", workshopId).replace("//", "/"));
+          $(`#${serviceId}-${rowId}-workshop-modal .modal-title`).text(`Share Workshop ${workshopId}`);
+          $(`#${serviceId}-${rowId}-workshop-modal .modal-body a`).text(`${workshopUrl}`);
+          $(`#${serviceId}-${rowId}-workshop-modal .modal-body a`).attr('href', workshopUrl);
+          $(`#${serviceId}-${rowId}-workshop-modal`).modal('show');
+        }
+      {%- endif %}
+
+      // secret input text fields -->
+        $(`button[id$='-view-password']`).on("click", function (event) {
+          const $this = $(this);
+          const serviceId = $this.attr("data-service");
+          const rowId = $this.attr("data-row");
+          const elementId = $this.attr("data-element");
+          const passInput = $(`input[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input']`);
+          const eye = $(`i[id^='${serviceId}-${rowId}-'][id$='-${elementId}-password-eye']`);
+          {#
+          const passInput = $('input[id*={{ id_prefix }}-{{ element_id }}-input]')[0];
+          const eye = $('i[id*={{ id_prefix }}-{{ element_id }}-password-eye]')[0];
+          #}
+          if (passInput.prop("type") === "password") {
+            passInput.prop("type", "text");
+            eye.removeClass("fa-eye");
+            eye.addClass("fa-eye-slash");
+          } else {
+            passInput.prop("type", "password");
+            eye.addClass("fa-eye");
+            eye.removeClass("fa-eye-slash");
+          }
+        });
+      // <-- secret input text fields
+
+      $(document).on("click", `button[data-textgrower-btn-type='add'][id$='-input']`, function (event) {
+        const $this = $(this);
+        const serviceId = $this.attr("data-service");
+        const rowId = $this.attr("data-row");
+        const tabId = $this.attr("data-tab");
+        const elementId = $this.attr("data-element");
+        
+        const parentContainer = $this.closest('.container');
+        const countElements = parseInt(parentContainer.attr("data-count")) + 1;
+        parentContainer.attr("data-count", countElements);
+        const firstInputElement = $(`[id^='${serviceId}-${rowId}-${tabId}'][id$='-1-${elementId}-input']`);
+        const dataType = firstInputElement.attr("data-type");
+        const group = firstInputElement.attr("data-group") ?? "default";
+        const name = firstInputElement.attr("name") ?? elementId;
+        const type = firstInputElement.attr("type") ?? "text";
+        let pattern = firstInputElement.attr("pattern");
+        if ( !pattern ) {
+          pattern = "";
+        }
+        let placeholder = firstInputElement.attr("placeholder");
+        if ( !placeholder ) {
+          placeholder = "";
+        }
+
+        const newInputGroup = `
+          <div class="input-group" style="display: flex; align-items: center; margin-bottom: 10px;">
+          <input id="${serviceId}-${rowId}-${tabId}-${countElements}-${elementId}-input" type="${type}"
+            class="form-control"
+            data-service="${serviceId}"
+            data-row="${rowId}"
+            data-tab="${tabId}"
+            data-type="${dataType}"
+            data-element="${elementId}"
+            data-group="${group}"
+            data-collect="true"
+            data-collect-static
+            name="${name}"
+            type="${type}"
+            pattern="${pattern}"
+            placeholder="${placeholder}"
+          />
+          <button data-collect-static data-textgrower-btn-type="del" data-element="${elementId}" data-service="${serviceId}" data-row="${rowId}" data-tab="${tabId}" data-collect="false" type="button" id="${serviceId}-${rowId}-${tabId}-${countElements}-delbtn-${elementId}-input" style="margin-left: 8px;" class="btn btn-danger">{{ svg.delete_svg | safe }}</button>
+          <button data-collect-static data-textgrower-btn-type="add" data-element="${elementId}" data-service="${serviceId}" data-row="${rowId}" data-tab="${tabId}" data-collect="false" type="button" id="${serviceId}-${rowId}-${tabId}-${countElements}-addbtn-${elementId}-input" style="margin-left: 8px;" class="btn btn-primary">{{ svg.plus_svg | safe }}</button>
+        </div>
+        `;
+        parentContainer.append(newInputGroup);
+      });
+      $(document).on("click", `button[data-textgrower-btn-type='del'][id$='-input']`, function (event) {
+        $(this).closest('.input-group').remove();              
+      });
+
+
+      $(`[data-sse-flavors]`).on("sse", function (event, data) { 
+        const $this = $(this);
+        const serviceId = $this.attr("data-service");
+        const rowId = $this.attr("data-row");
+        for ( const [system, systemFlavors] of Object.entries(data) ) {
+          kubeOutpostFlavors[system] = systemFlavors;
+        }
+        const currentSystem = $(`[id^='${serviceId}-${rowId}-'][id$='-system-input']`);
+        if ( currentSystem.length && currentSystem.attr("data-collect") == "true" ) {
+          if ( Object.keys(data).includes(currentSystem.val()) ){
+            setFlavorInfo(serviceId, rowId, currentSystem.val(), kubeOutpostFlavors[currentSystem.val()]);
+          }
+        }
+      });
+
+      $(`input[id$='-select-all']`).on("click", function () {
+        const $this = $(this);
+        const serviceId = $this.attr("data-service");
+        const rowId = $this.attr("data-row");
+        const tabId = $this.attr("data-tab");
+        if ( $this.prop("checked") ) {
+          $(`input[id^='${serviceId}-${rowId}-${tabId}-'][id$='-input']`).prop("checked", true);
+          $(`[id^='${serviceId}-${rowId}-${tabId}-'][id$='-select-none']`).prop("checked", false);
+        }
+      })
+      $(`input[id$='-select-none']`).on("click", function () {
+        const $this = $(this);
+        const serviceId = $this.attr("data-service");
+        const rowId = $this.attr("data-row");
+        const tabId = $this.attr("data-tab");
+        if ( $this.prop("checked") ) {
+          $(`input[id^='${serviceId}-${rowId}-${tabId}-'][id$='-input']`).prop("checked", false);
+          $(`[id^='${serviceId}-${rowId}-${tabId}-'][id$='-select-all']`).prop("checked", false);
+        }
+      })
+
+      $(".summary-tr").on("click", function (event) {
+        if (![event.target, event.target.parentElement, event.target.parentElement?.parentElement]
+          .some(el => el?.tagName === "BUTTON")) {
+          const $this = $(this);
+          const id = $this.data("server-id");
+          let accordionIcon = $(this).find(".accordion-icon");
+          let collapse = $(`.collapse[id^=${id}]`);
+          if ( collapse.length > 0 ) {
+            let shown = collapse.hasClass("show");
+            if (shown) accordionIcon.addClass("collapsed");
+            else accordionIcon.removeClass("collapsed");
+            new bootstrap.Collapse(collapse);
+          }
+        }
+      });
+
+
+      logDebug && console.log(`Fill elements ...`);
+      $(`[id$='-input']`).trigger("trigger_init");
+      logDebug && console.log(`Fill elements ... done`);
+
+      // Set Defaults, as configured in config file
+      {%- for service_id, service_options in config.frontend_config.get("services", {}).get("options", {}).items() %}
+        logDebug && console.log("Set default values ( {{ service_id }} ) ...");
+        {%- set default_tab_id = service_options.get("default", {}).get("tab", "default") %}
+        {%- for option_key, option_value in service_options.get("default", {}).get("options", {}).items() %}
+          optionElement = $(`[id^='{{ service_id }}-'][id$='-{{ default_tab_id }}-{{ option_key }}-input']`);
+          if ( optionElement.is("select") && optionElement.find(`option[value="{{ option_value }}"]:not(:disabled)`).length ){
+            optionElement.val("{{ option_value }}");
+            optionElement.trigger("change");
+          } else if ( optionElement.is("input") ){
+            optionElement.val("{{ option_value }}");
+            optionElement.trigger("change");
+          }
+        {%- endfor %}
+        {%- if pagetype == vars.pagetype_workshopmanager %}
+          {%- for row_id, values in db_workshops.items() %}
+            workshopManagerFillExistingRow("{{ service_id }}", "{{ row_id }}", {{ values | tojson }});
+          {%- endfor %}
+        {%- elif pagetype == vars.pagetype_workshop %}
+          workshopManagerFillExistingRow("{{ service_id }}", "{{ spawner.name }}", {{ db_workshops.get(spawner.name, {}) | tojson }});
+        {%- elif pagetype == vars.pagetype_home %}
+          // homeFillExistingRow
+          {%- for s in spawners %}
+            // console.log( {{ s }});
+            // console.log( {{ user.spawners.get(s.name, s) }});
+            {%- set spawner = user.spawners.get(s.name, s) %}
+            // console.log( {{ spawner.name }});
+            // console.log( {{ spawner.events }});
+            {%- if spawner.events %}
+            // console.log("y");
+            {%- endif %}
+            {%- if spawner.user_options and spawner.user_options.get("name", false) %}
+              homeFillExistingRow("{{ service_id }}", "{{ spawner.name }}", {{ spawner.user_options | tojson }}, {{ service_options.get("fillingOrder", []) | tojson }});
+              {%- if spawner.events %}
+              {%- for event in spawner.events %}
+                appendToLog("{{ service_id }}", "{{ spawner.name }}", {{ event | tojson }});
+              {%- endfor %}
+              {%- endif %}
+            {%- endif %}
+          {%- endfor %}
+        {%- endif %}
+        logDebug && console.log("Set default values ( {{ service_id }} ) done");
+        
+      {%- endfor %}
+
+      {%- if pagetype == vars.pagetype_workshop %}
+        let service = "";
+        let name = "";
+        let lastEvent = false;
+        let updateProgressBar = false;
+        {# iterate through all spawners #}
+        service = "{{ spawner.user_options.get("service", "jupyterlab") | lower }}";
+        name = "{{ spawner.name }}";
+        events = [];
+        {%- if spawner and spawner.events %}            
+        events = {{ spawner.events | tojson }};
+        {%- endif %}
+        lastEvent = events.length > 0 ? events[events.length - 1] : false;
+        clearLogs(service, name);
+        if ( lastEvent ) {
+          {%- if spawner.cancel_pending or spawner.active %}
+          updateProgressBar = true;
+          {%- else %}
+          updateProgressBar = lastEvent.progress != 100;
+          {%- endif %}
+        }
+        events.forEach( event => {
+          if ( updateProgressBar ) {
+            let ready = event.ready ?? false;
+            let failed = event.failed ?? false;
+            let progress = event.progress ?? 0;
+            let status = "starting";
+            if ( ready ) status = "running";
+            else if ( failed ) status = "stopped";
+            else if ( progress == 99 ) status = "cancelling";
+            else if ( progress == 0 ) status = "";
+            progressBarUpdate(serviceId, rowId, status, progress);
+          }
+          appendToLog(service, name, event);
+        });
+        if ( updateProgressBar ) {
+          $(`#${service}-${name}-logs-navbar-button`).trigger("click");
+        }
+        {# Set Buttons in correct state #}
+        // status: ["running", "starting", "na", "stopping", "cancelling", "stopped"]
+        let status = "stopped";
+        {%- if spawner.cancel_pending %}
+        status = "cancelling";
+        {%- elif not spawner.ready and spawner.active %}
+        status = "starting";
+        {%- elif spawner.ready %}
+        status = "running";
+        {% endif %}
+        updateHeaderButtons(service, name, status);   
+
+        const workshopValues = {{ db_workshops | tojson }}?.['{{ spawner.name }}']?.user_options || {};
+        const serviceId = "{{ spawner.user_options.get("service", "jupyterlab") | lower }}";
+        
+
+        $(`input[id^='${serviceId}-{{ spawner.name }}-'][id$='-input']`).each( function () {
+          const $this = $(this);
+          const dataGroup = $this.attr("data-group");
+          const key = $this.attr("data-element");
+          let keys = [];
+          let newValue = "";
+          if ( ["none", "default"].includes(dataGroup) ) {
+            keys = Object.keys(workshopValues);
+            if ( keys.includes(key) ) {
+              newValue = workshopValues[key];
+            }
+          } else {
+            keys = Object.keys(workshopValues?.[dataGroup] || {});
+            if ( keys.includes(key) ) {
+              newValue = workshopValues[dataGroup][key];
+            }
+          }
+          if ( newValue ) {
+            $this.attr("data-alwaysdisabled", "true");
+            $this.val(newValue);
+            $this.attr("value", newValue);
+            $this.prop("disabled", true);
+
+            const labelElement = $(`#${$this.prop('id')}-cb`);
+            if ( labelElement ) {
+              labelElement.prop("checked", "true");
+              labelElement.prop("disabled", "true");
+              labelElement.trigger("change");
+            }
+          }
+        });
+
+        
+        $(`select[id^='${serviceId}-{{ spawner.name }}-'][id$='-input']`).each( function () {
+          const $this = $(this);          
+          const dataGroup = $this.attr("data-group");
+          const key = $this.attr("data-element");
+          let keys = [];
+          let newValue = "";
+          if ( ["none", "default"].includes(dataGroup) ) {
+            keys = Object.keys(workshopValues);
+            if ( keys.includes(key) ) {
+              newValue = workshopValues[key];
+            }
+          } else {
+            keys = Object.keys(workshopValues?.[dataGroup] || {});
+            if ( keys.includes(key) ) {
+              newValue = workshopValues[dataGroup][key];
+            }
+          }
+          if ( newValue ) {
+            $this.val(newValue);
+            $this.attr("value", newValue);
+
+            const labelElement = $(`#${$this.prop('id')}-cb`);
+            if ( labelElement ) {
+              labelElement.prop("checked", "true");
+              labelElement.prop("disabled", "true");
+              labelElement.trigger("change");
+            }
+          }
+        });
+        for ( const [key, value] of Object.entries(workshopValues?.defaultvalues || {}) ) {
+          const inputElement = $(`[id^='${serviceId}-{{ spawner.name }}-'][id$='-${key}-input']`);
+          inputElement.val(value);
+          inputElement.trigger("change");
+        }
+
+        {%- if spawner and spawner.events %}
+          fillLogContainer(serviceId, "{{ spawner.name }}", {{ spawner.events | tojson }});
+        {%- else %}
+          defaultLogs(serviceId, "{{ spawner.name }}");
+        {%- endif %}
+      {%- endif %}
+
+      const queryString = window.location.search;
+      const urlParams = new URLSearchParams(queryString);
+      if (urlParams.has('row') && urlParams.has('service')) {
+
+        // Get the value of the "row" parameter
+        const serviceValue = urlParams.get('service');
+        const rowValue = urlParams.get('row');
+        
+        $(`div[id$='-table-div']:not([id^='${serviceValue}-'])`).hide();
+        $(`div[id$='-table-div'][id^='${serviceValue}-']`).show();
+
+        $(`div[id$='-collapse']:not([id^='${serviceValue}-${rowValue}-collapse'])`).removeClass("show");
+        $(`div[id^='${serviceValue}-${rowValue}-collapse']`).addClass("show");
+        let x = document.getElementById(`${serviceValue}-${rowValue}-summary-tr`)
+        if ( x ) x.scrollIntoView();
+        if ( urlParams.has('showlogs') ) $(`[id^='${serviceValue}-${rowValue}-'][id$='-logs-navbar-button']`).trigger("click");
+      }
+      {%- if pagetype == vars.pagetype_workshop %}
+        logDebug && console.log(`Fill elements ...`);
+        $(`[id$='-input']`).trigger("trigger_init");
+        logDebug && console.log(`Fill elements ... done`);
+      {%- endif %}
+      
+      {%- if pagetype == vars.pagetype_workshop %} 
+      {%- endif %}
+    });
+  });
+</script>
diff --git a/templates/macros/table/helpers/options_js.jinja b/templates/macros/table/helpers/options_js.jinja
new file mode 100644
index 0000000..44f526a
--- /dev/null
+++ b/templates/macros/table/helpers/options_js.jinja
@@ -0,0 +1,88 @@
+{# lmod --> #}
+  function getModuleValues(serviceId, rowId, name, setName) {
+    const options = val(getInputElement(serviceId, rowId, "option"));
+    let values = [];
+    let keys = new Set();
+    options.forEach(option => {
+      if (getServiceConfig(serviceId)?.options?.[option]?.[setName]) {
+        const nameSet = getServiceConfig(serviceId)?.options[option]?.[setName];
+        Object.entries(userModulesConfig[name])
+          .filter(([key, value]) => value.sets && value.sets.includes(nameSet))
+          .forEach( ([key, value]) => {
+            if ( !keys.has(key) ) {
+              keys.add(key);
+              values.push([
+                key,
+                value.displayName,
+                typeof value.default === 'object' && value.default !== null ? value.default.default : value.default,
+                value.href
+              ]);
+            }
+          });
+      }
+    });
+    return values;
+  }
+
+
+  function updateModule(serviceId, rowId, tabId, elementId, elementOptions, name, setName) {
+    const containerDiv = $(`div[id^='${serviceId}-${rowId}-${modulesTabName}-'][id$='${elementId}-checkboxes-div']`);
+    const inputDiv = $(`div[id^='${serviceId}-${rowId}-${modulesTabName}-'][id$='${elementId}-input-div']`);
+    let values = getModuleValues(serviceId, rowId, name, setName);
+
+    // for workshops we will disable all checkboxes, so users cannot change the selection
+    let workshopPreset = false;
+    let workshopPresetChecked = [];
+    {%- if pagetype == vars.pagetype_workshop and db_workshops %}
+      const workshopValues = {{ db_workshops | tojson }}.user_options || {};
+      if ( Object.keys(workshopValues).includes("userModules") && Object.keys(workshopValues.userModules).includes(name) ){
+        workshopPreset = true;
+        const modules = workshopValues.userModules[name];
+        if ( modules.length > 0 ) {
+          workshopPresetChecked = modules;
+        }
+      }
+    {%- endif %}
+
+    // Ensure the container exists
+    if (containerDiv.length > 0 && values.length > 0) {
+      const idPrefix = containerDiv.attr('id').replace(/-checkboxes-div$/, "");
+      containerDiv.html('');
+      values.forEach(function (item) {
+        let isChecked = '';
+        let isDisabled = '';
+        if ( workshopPreset ) {
+          if ( workshopPresetChecked.includes(item[0]) ){
+            isChecked = 'checked';
+          }
+          isDisabled = 'disabled="true"';
+        } else {
+          isChecked = item[2] ? 'checked' : '';
+        }
+        // Create the new div block
+        const newDiv = $(`
+          <div id="${idPrefix}-${item[0]}-input-div" class="form-check col-sm-6 col-md-4 col-lg-3">
+            <input type="checkbox" name="${item[0]}" class="form-check-input" id="${idPrefix}-${item[0]}-input" value="${item[0]}" ${isChecked} ${isDisabled}/>
+            <label class="form-check-label" for="${idPrefix}-${item[0]}-input">
+              <span class="align-middle">${item[1]}</span>
+              <a href="${item[3]}" target="_blank" class="module-info text-muted ms-3">
+                <span>{{ svg.info_svg | safe }}</span>
+                <div class="module-info-link-div d-inline-block">
+                  <span class="module-info-link" id="nbdev-info-link"> {{ svg.link_svg | safe }}</span>
+                </div>
+              </a>
+            </label>
+          </div>
+        `);
+        // Append the new div to the container
+        containerDiv.append(newDiv);
+        // Add toggle function to each checkbox
+        $(`#${idPrefix}-${item[0]}-input`).on("click", function (event) {
+          $(`input[id^='${serviceId}-${rowId}-${modulesTabName}-'][id$='-select-all']`).prop("checked", false);
+          $(`input[id^='${serviceId}-${rowId}-${modulesTabName}-'][id$='-select-none']`).prop("checked", false);
+        });
+      });
+    }
+    inputDiv.show();
+  }
+{# <-- lmod #}
\ No newline at end of file
diff --git a/templates/macros/table/helpers/systems_js.jinja b/templates/macros/table/helpers/systems_js.jinja
new file mode 100644
index 0000000..8f884ec
--- /dev/null
+++ b/templates/macros/table/helpers/systems_js.jinja
@@ -0,0 +1,630 @@
+{# Kube Systems --> #}
+  const kubeOutpostFlavors = {{ auth_state.outpost_flavors | tojson }};
+  function _getKubeSystems() {
+    return Object.keys(systemConfig).filter(system => {
+      const backendService = systemConfig[system].backendService;
+      // Check if the backend service type is "kube"
+      return backendServicesConfig[backendService]?.type === "kube";
+    });
+  }
+
+  const kubeSystems = _getKubeSystems();
+
+  function getAvailableKubeFlavorsS(systems) {
+    let ret = [];
+
+    systems.forEach(system => {
+      const allFlavors = kubeOutpostFlavors[system];
+      if ( allFlavors ) {
+        ret.push(...Object.keys(allFlavors)
+          .filter(key => allFlavors[key].max != 0) // do not use flavor.max == 0
+          .filter(key => allFlavors[key].current < allFlavors[key].max || allFlavors[key].max == -1 ) // must be room for new jupyterlabs
+          .sort((a, b) => allFlavors[a].weight - allFlavors[b].weight) // sort by weight
+          .map(key => [key, allFlavors[key].display_name])); // get keyname + displayname
+      }
+    });
+    return ret;
+  }
+
+  function getUnavailableKubeFlavorsS(systems) {
+    let ret = [];
+
+    systems.forEach(system => {
+      const allFlavors = kubeOutpostFlavors[system];
+
+      if ( allFlavors ) {
+        ret.push(...Object.keys(allFlavors)
+          .filter(key => allFlavors[key].max != 0) // do not use flavor.max == 0
+          .filter(key => allFlavors[key].current >= allFlavors[key].max && allFlavors[key].max != -1)
+          .sort((a, b) => allFlavors[a].weight - allFlavors[b].weight)
+          .map(key => [key, allFlavors[key].display_name]));
+      }
+    });
+    return ret;
+  }
+{# <-- Kube Systems #}
+
+{# Unicore Systems --> #}
+  {# 
+    JavaScript functions to get user specific information for the HPC systems which support UNICORE.
+  #}
+
+  const resPattern = /^urn:(?<namespace>.+?(?=:res:)):res:(?<systempartition>[^:]+):(?<project>[^:]+):act:(?<account>[^:]+):(?<accounttype>[^:]+)$/;
+  const unicoreEntitlements = {{ auth_state.entitlements | list | tojson }};
+  const unicorePreferredUsername = {{ auth_state.preferred_username | tojson }};
+  const unicoreReservations = {{ reservations | tojson }};
+  const unicoreMapSystems = {{ custom_config.mapSystems | tojson }};
+  const unicoreMapPartitions = {{ custom_config.mapPartitions | tojson }};
+  const unicoreDefaultPartitions = {{ custom_config.defaultPartitions | tojson }};
+
+  function extractEntitlementResources(entitlement) {
+    const match = resPattern.exec(entitlement);
+    if (match) {
+      // Access named capture groups using match.groups
+      let system_ = unicoreMapSystems[match.groups.systempartition.toLowerCase()];
+      let partition_ = unicoreMapPartitions[match.groups.systempartition.toLowerCase()];
+      if ( Object.keys(resourcesConfig[system_] ?? {}).includes(partition_) ){
+        return {
+          systempartition: match.groups.systempartition,
+          project: match.groups.project,
+          account: match.groups.account,
+          accounttype: match.groups.accounttype
+        };
+      }
+    }
+    return null; // Return null if no match is found
+  }
+
+  function _getUnicoreAccountType() {
+    for (let entitlement of unicoreEntitlements) {
+      const entitlementInfo = extractEntitlementResources(entitlement);
+
+      if (entitlementInfo && entitlementInfo.account === unicorePreferredUsername) {
+        return entitlementInfo.accounttype;
+      }
+    }
+    return null;
+  }
+
+  const unicoreAccountType = _getUnicoreAccountType();
+
+  function _getUnicoreSystemPartitions() {
+    const systemPartitions = unicoreEntitlements
+      .map(extractEntitlementResources)
+      .filter(Boolean)
+      .map(tmp => tmp.systempartition);
+
+    if (unicoreAccountType === "normal") {
+      return [...new Set(systemPartitions)];
+    }
+
+    if (unicoreAccountType === "secondary") {
+      return [...new Set(
+        systemPartitions.filter(systempartition => {
+          return unicoreEntitlements
+            .map(extractEntitlementResources) // Extract entitlement resources
+            .filter(Boolean)
+            .some(tmp => tmp.systempartition === systempartition && tmp.account === unicorePreferredUsername);
+        })
+      )];
+    }
+
+    return [];
+  }
+
+  const unicoreSystemPartitions = _getUnicoreSystemPartitions();
+
+  function _getUnicoreSystems() {
+    // Get all systems corresponding to the system partitions
+    let systems = unicoreSystemPartitions
+      .map(key => unicoreMapSystems[key.toLowerCase()]) // Map system partitions to their respective systems
+      .filter(system => system); // Remove falsy values (null, undefined, etc.)
+
+    // If the unicoreAccountType is "normal", return all systems (no filtering)
+    if (unicoreAccountType === "normal") {
+      return [...new Set(systems)]; // Remove duplicates using Set
+    }
+
+    // If the unicoreAccountType is "secondary", filter systems based on unicorePreferredUsername
+    if (unicoreAccountType === "secondary") {
+      return [...new Set(
+        systems.filter(system => {
+          // Filter systems where the system matches the unicorePreferredUsername in unicoreEntitlements
+          return unicoreEntitlements
+            .map(extractEntitlementResources) // Extract entitlement resources
+            .filter(Boolean) // Remove falsy values (null, undefined, etc.)
+            .some(tmp => tmp.systempartition && unicoreMapSystems[tmp.systempartition.toLowerCase()] === system && tmp.account === unicorePreferredUsername);
+        })
+      )]; // Remove duplicates using Set
+    }
+
+    // Return an empty array if unicoreAccountType is neither "normal" nor "secondary"
+    return [];
+  }
+
+  const unicoreSystems = _getUnicoreSystems();
+
+  function _getAllUnicoreAccountsBySystemPartition() {
+    const accountsBySystemPartition = {};  // The output dictionary where key is systempartition and value is list of accounts
+
+    // Initialize accounts list for each systempartition
+    unicoreSystemPartitions.forEach(function(systempartition) {
+      accountsBySystemPartition[systempartition] = new Set();  // Using Set to store unique accounts for each systempartition
+    });
+
+    // Iterate through all unicoreEntitlements and populate the accounts for the relevant unicoreSystemPartitions
+    unicoreEntitlements.forEach(function(entitlement) {
+      const entitlementInfo = extractEntitlementResources(entitlement);
+
+      if (entitlementInfo && unicoreSystemPartitions.includes(entitlementInfo.systempartition)) {
+        accountsBySystemPartition[entitlementInfo.systempartition].add(entitlementInfo.account);
+      }
+    });
+
+    // Filter accounts based on unicoreAccountType
+    Object.keys(accountsBySystemPartition).forEach(function(systempartition) {
+      // If the unicoreAccountType is "secondary", only keep accounts that match unicorePreferredUsername
+      if (unicoreAccountType === "secondary") {
+        accountsBySystemPartition[systempartition] = [...accountsBySystemPartition[systempartition]]
+          .filter(account => account === unicorePreferredUsername);
+      } else {
+        // For "normal" account type, return all accounts
+        accountsBySystemPartition[systempartition] = [...accountsBySystemPartition[systempartition]];
+      }
+    });
+    return accountsBySystemPartition;
+  }
+
+  const unicoreAccountsBySystemPartition = _getAllUnicoreAccountsBySystemPartition();
+
+  function getUnicoreProjectsBySystemPartition() {
+    const projectsBySystemPartition = {};  // Output dictionary where key is systempartition and value is list of projects
+
+    // Initialize projects list for each systempartition
+    unicoreSystemPartitions.forEach(function(systempartition) {
+      projectsBySystemPartition[systempartition] = new Set();  // Using Set to store unique projects
+    });
+
+    // Iterate through all unicoreEntitlements and populate the projects for the relevant unicoreSystemPartitions
+    unicoreEntitlements.forEach(function(entitlement) {
+      const entitlementInfo = extractEntitlementResources(entitlement);
+
+      // Check if entitlement has valid info and if it matches the system partitions list
+      if (entitlementInfo && unicoreSystemPartitions.includes(entitlementInfo.systempartition)) {
+        // Only add project if account matches the unicorePreferredUsername when unicoreAccountType is secondary
+        if (unicoreAccountType === "normal" || entitlementInfo.account === unicorePreferredUsername) {
+          projectsBySystemPartition[entitlementInfo.systempartition].add(entitlementInfo.project);
+        }
+      }
+    });
+
+    // Convert Set to Array for each systempartition in the output dictionary
+    Object.keys(projectsBySystemPartition).forEach(function(systempartition) {
+      projectsBySystemPartition[systempartition] = [...projectsBySystemPartition[systempartition]];
+    });
+
+    return projectsBySystemPartition;
+  }
+
+  function getUnicorePartitions() {
+    let partitions = new Set();
+
+    // Iterate over unicoreSystemPartitions and add the corresponding partition names to the set
+    unicoreSystemPartitions.forEach((partition) => {
+      const partitionName = unicoreMapPartitions[partition.toLowerCase()];
+      if (partitionName) {
+        partitions.add(partitionName);
+      }
+    });
+
+    // Add default partitions to the set
+    Object.keys(unicoreDefaultPartitions).forEach((partition) => {
+      unicoreDefaultPartitions[partition].forEach((defaultPartition) => {
+        partitions.add(defaultPartition);
+      });
+    });
+
+    // If the unicoreAccountType is "normal", return all partitions (no filtering)
+    if (unicoreAccountType === "normal") {
+      return [...partitions]; // Convert Set to Array (removes duplicates)
+    }
+
+    // If the unicoreAccountType is "secondary", filter the partitions based on unicorePreferredUsername
+    if (unicoreAccountType === "secondary") {
+      return [...new Set(
+        [...partitions].filter(partition => {
+          // Check if the partition matches the preferred username from unicoreEntitlements
+          return unicoreEntitlements
+            .map(extractEntitlementResources) // Extract entitlement resources
+            .filter(Boolean) // Remove falsy values (null, undefined, etc.)
+            .some(tmp => tmp.systempartition && unicoreMapPartitions[tmp.systempartition.toLowerCase()] === partition && tmp.account === unicorePreferredUsername);
+        })
+      )]; // Remove duplicates using Set
+    }
+
+    // Return an empty array if unicoreAccountType is neither "normal" nor "secondary"
+    return [];
+  }
+
+  function getUnicoreAccountsS(systems) {
+    const accounts = new Set();  // A Set to ensure accounts are unique
+
+    // Iterate over the unicoreEntitlements to collect accounts related to the system
+    systems.forEach(system => {
+      unicoreEntitlements.forEach(function(entitlement) {
+        const entitlementInfo = extractEntitlementResources(entitlement);
+
+        // Check if the entitlement is for the provided system
+        if (entitlementInfo && unicoreMapSystems[entitlementInfo.systempartition.toLowerCase()] === system) {
+          if (unicoreAccountType === "normal") {
+            // If unicoreAccountType is "normal", add all accounts for the system
+            accounts.add(entitlementInfo.account);
+          } else if (unicoreAccountType === "secondary") {
+            // If unicoreAccountType is "secondary", only add the account if it matches unicorePreferredUsername
+            if (entitlementInfo.account === unicorePreferredUsername) {
+              accounts.add(entitlementInfo.account);
+            }
+          }
+        }
+      });
+    });
+
+    // Return the accounts as an array, since we're using a Set to avoid duplicates
+    return [...accounts];
+  }
+
+  function getUnicoreProjectsSA(systems, accounts) {
+    const projects = [];  // Initialize an empty array to store the list of projects
+
+    // Iterate through entitlements to find all projects for the system and account
+    systems.forEach(system => {
+      accounts.forEach(account => {
+        unicoreEntitlements.forEach(function(entitlement) {
+          const entitlementInfo = extractEntitlementResources(entitlement);
+
+          // Check if entitlement matches the provided system
+          if (entitlementInfo) {
+            const mappedSystem = unicoreMapSystems[entitlementInfo.systempartition.toLowerCase()];
+            if (mappedSystem === system) {
+              if (unicoreAccountType === "normal") {
+                // If unicoreAccountType is "normal", we check if the account matches
+                if (entitlementInfo.account === account) {
+                  projects.push(entitlementInfo.project);  // Add project to the list
+                }
+              } else if (unicoreAccountType === "secondary") {
+                // If unicoreAccountType is "secondary", only consider the entitlement if the account matches the preferred username
+                if (entitlementInfo.account === unicorePreferredUsername) {
+                  if (entitlementInfo.account === account) {
+                    projects.push(entitlementInfo.project);  // Add project to the list
+                  }
+                }
+              }
+            }
+          }
+        });
+      });
+    });
+    return [...new Set(projects)];
+  }
+
+  function getUnicoreProjectsS(systems) {
+    const projects = [];  // Initialize an empty array to store the list of projects
+
+    // Iterate through entitlements to find all projects for the system and account
+    systems.forEach(system => {
+      unicoreEntitlements.forEach(function(entitlement) {
+        const entitlementInfo = extractEntitlementResources(entitlement);
+
+        // Check if entitlement matches the provided system
+        if (entitlementInfo) {
+          const mappedSystem = unicoreMapSystems[entitlementInfo.systempartition.toLowerCase()];
+          if (mappedSystem === system) {
+            projects.push(entitlementInfo.project);
+          }
+        }
+      });
+    });
+    return [...new Set(projects)];
+  }
+
+  function getUnicorePartitionsSAP(systems, accounts=[], projects=[]) {
+    // Initialize the result list of partitions
+    let partitions = [];
+    let interactivePartitions = [];
+    let allPartitions = [];
+    systems.forEach(system => {
+      accounts.forEach(account => {
+        projects.forEach(project => {
+          // 1. Add interactive partitions for the given system (if any)
+
+          // 2. Get the system partitions for the given system and account/project (with entitlement checking)
+          const allPartitions_ = new Set(); // Using Set to ensure unique entries
+
+          let interactiveAdded = false;
+
+          // Iterate over the entitlements to get partitions for the specified system, account, and project
+          unicoreEntitlements.forEach(function(entitlement) {
+            const entitlementInfo = extractEntitlementResources(entitlement);
+            if (entitlementInfo && unicoreMapSystems[entitlementInfo.systempartition.toLowerCase()] === system && (entitlementInfo.project === project || project === "_all_")) {
+              // Apply unicoreAccountType logic
+              if (unicoreAccountType === "normal" || account === "_all_") {
+                if ( !interactiveAdded ){
+                  interactiveAdded = true;
+                  const interactivePartitions_ = systemConfig[system]?.interactivePartitions || [];
+                  interactivePartitions = [...new Set([...interactivePartitions, ...interactivePartitions_])]; // Start with interactive partitions
+                }
+                // For normal accounts, match the exact account
+                if (entitlementInfo.account === account || account === "_all_") {
+                  allPartitions_.add(unicoreMapPartitions[entitlementInfo.systempartition.toLowerCase()]);
+                }
+              } else if (unicoreAccountType === "secondary") {
+                // For secondary accounts, only match if the account is the preferred username
+                if ( !interactiveAdded ){
+                  interactiveAdded = true;
+                  const interactivePartitions_ = systemConfig[system]?.interactivePartitions || [];
+                  interactivePartitions = [...new Set([...interactivePartitions, ...interactivePartitions_])]; // Start with interactive partitions
+                }
+                if (entitlementInfo.account === unicorePreferredUsername && entitlementInfo.account === account) {
+                  allPartitions_.add(unicoreMapPartitions[entitlementInfo.systempartition.toLowerCase()]);
+                }
+              }
+            }
+            // 3. Add the partitions from entitlements to the list (remove duplicates automatically due to Set)
+            allPartitions = [...new Set([...allPartitions, ...allPartitions_])];
+          });
+
+          // 4. Add default partitions for the given system
+
+          Object.keys(unicoreDefaultPartitions).forEach(function(systempartition) {
+            let system_ = unicoreMapSystems[systempartition];
+            if ( system_ === system ) {
+              // Check if the systempartition matches
+              if (unicoreDefaultPartitions[systempartition]) {
+                // Add the corresponding partition from the unicoreMapPartitions object
+                if (allPartitions.includes(unicoreMapPartitions[systempartition])) {
+                  unicoreDefaultPartitions[systempartition].forEach(function(defaultPartition) {
+                    allPartitions.push(unicoreMapPartitions[defaultPartition.toLowerCase()]);
+                  });
+                }
+              }
+            }
+          });
+        });
+      });
+    });
+
+    // 5. Return the list of partitions (interactive first, then others, with defaults added)
+    return [...new Set([...interactivePartitions, ...allPartitions])];
+  }
+
+  function getAllUnicoreReservations() {
+    // Initialize an empty array to store reservation names
+    let reservations = [];
+
+    // Iterate over each system in the reservations object
+    Object.keys(unicoreReservations).forEach(system => {
+      // For each system, iterate over the reservations array
+      unicoreReservations[system].forEach(reservation => {
+        // Add the entire reservation object to the list (instead of just ReservationName)
+        reservations.push(reservation);
+      });
+    });
+
+    // Return the list of all reservations
+    return reservations;
+  }
+
+  function getUnicoreReservationsS(systems) {
+    // Check if the system exists in the reservations object
+    let reservations = [];
+    systems.forEach(system => {
+      if (unicoreReservations[system]) {
+        // Map the reservations for the system and return an array of ReservationNames
+        reservations.push(unicoreReservations[system].filter(reservation => reservation).map(reservation => reservation));
+      }
+    });
+    return reservations;
+  }
+
+  function getUnicoreReservationsSAPP(systems, accounts, projects, partitions) {
+    // Check if the system exists in the reservations object
+    let reservations = [];
+
+    systems.forEach(system => {
+      accounts.forEach(account => {
+        projects.forEach(project => {
+          partitions.forEach(partition => {
+            if (!unicoreReservations[system]) {
+              return;
+            }
+
+            // Check if the partition is interactive for the given system
+            const isInteractivePartition = systemConfig[system] && systemConfig[system].interactivePartitions.includes(partition);
+
+            // If the partition is interactive, do not return any reservations for it
+            if (isInteractivePartition) {
+              return;
+            }
+
+            // Filter the reservations for the given system based on the provided account, project, and partition
+            reservations.push(
+              ...unicoreReservations[system].filter(reservation => {
+                const partitionMatches = (reservation.PartitionName === "" || reservation.PartitionName === partition || partition === "_all_");
+                const usersMatch = (reservation.Users === "" || reservation.Users.split(",").includes(account) || account === "_all_");
+                const accountsMatch = (reservation.Accounts === "" || reservation.Accounts === project || project === "_all_");
+                return partitionMatches && usersMatch && accountsMatch;
+              })
+            );
+          });
+        });
+      });
+    });
+    return [...new Set(reservations)];
+  }
+
+
+  function getUnicoreValues(serviceId, rowId, elementId) {
+    const inputElement = getInputElement(serviceId, rowId, elementId);
+    const labelElementCB = getLabelCBElement(serviceId, rowId, elementId);
+      //if (inputElement.length == 0 || inputElement.attr("data-collect") === "false" ) {
+      if (inputElement.length == 0 || inputElement.is("[disabled]") ) {
+        // Input does not exist, or is disabled. Use the keyword _all_ instead.
+        return ["_all_"];
+      } else {
+        return val(inputElement);
+      }
+   
+  }
+
+  function getAccountOptions(serviceId, rowId) {
+    const systems = val(getInputElement(serviceId, rowId, "system"));
+    const accounts = getUnicoreAccountsS(systems);
+    if (accounts.includes(unicorePreferredUsername)) {
+      accounts.sort(account => account === unicorePreferredUsername ? -1 : 1);
+    }
+    return accounts.map(item => [item, item]);
+  }
+
+  function getProjectOptions(serviceId, rowId) {
+    const systems = val(getInputElement(serviceId, rowId, "system"));
+    let projects = [];
+    const accountInput = getInputElement(serviceId, rowId, "account");
+    const accounts = val(accountInput);
+    if ( accountInput.length > 0 && accounts.length > 0 && accounts[0] ){
+      // Account Option exists, let's take it into account
+      const accounts = val(accountInput);
+      projects = getUnicoreProjectsSA(systems, accounts);
+    } else {
+      // Acount selection does not exists (e.g. in workshopManager)
+      projects = getUnicoreProjectsS(systems);
+    }
+    return projects.map(item => [item, item]);
+  }
+
+  function getPartitionOptions(serviceId, rowId) {
+    const systems = val(getInputElement(serviceId, rowId, "system"));
+    const accounts = getUnicoreValues(serviceId, rowId, "account");
+    const projects = getUnicoreValues(serviceId, rowId, "project");
+    let partitions = getUnicorePartitionsSAP(systems, accounts, projects);
+    
+    return partitions.map(item => [item, item]);
+  }
+
+  function getPartitionAndInteractivePartition(serviceId, rowId) {
+    const systems = val(getInputElement(serviceId, rowId, "system"));
+    const partitions = getPartitionOptions(serviceId, rowId);
+    let interactivePartitionsLength = 0;
+    let interactivePartitionAdded = [];
+    partitions.forEach(partition => {
+      let partition_ = partition[0];
+      systems.forEach(system => {
+        if ( (systemConfig[system]?.interactivePartitions || []).includes(partition_) ) {
+          if ( !interactivePartitionAdded.includes(partition_) ) {
+            interactivePartitionsLength += 1;
+            interactivePartitionAdded.push(partition_);
+          }
+        }
+      });
+    });
+    return [partitions, interactivePartitionsLength];
+  }
+
+  function getReservationOptions(serviceId, rowId) {
+    const systems = val(getInputElement(serviceId, rowId, "system"));
+    const accounts = getUnicoreValues(serviceId, rowId, "account");
+    const projects = getUnicoreValues(serviceId, rowId, "project");
+    const partitions = getUnicoreValues(serviceId, rowId, "partition");
+
+    return getUnicoreReservationsSAPP(systems, accounts, projects, partitions);
+  }
+{# <-- Unicore Systems #}
+
+{# All Systems --> #}
+  function _getAllSystems() {
+    // Combine both lists and remove duplicates using a Set
+    let allSystems = [...new Set([...unicoreSystems, ...kubeSystems])];
+
+    {%- if pagetype == vars.pagetype_workshop %}
+    const db_workshops = {{ db_workshops | tojson }};
+    let allowedSystems = Object.values(db_workshops)[0]?.user_options?.system ?? false;
+    if ( allowedSystems ) {
+      allSystems = allSystems.filter(system => allowedSystems.includes(system));
+    }
+    {%- endif %}
+    
+    return allSystems;
+  }
+
+  const allSystems = _getAllSystems();
+
+  function getAvailableSystemOptions(serviceId, options) {
+    let ret = [];
+    options.forEach(option => {
+      if (getServiceConfig(serviceId)?.options) {
+        const subSystems1 = getServiceConfig(serviceId).options[option].allowedLists.systems;
+        ret.push(...allSystems.filter(system => subSystems1.includes(system)));
+      } else {
+        // return all systems, if it's not reduced by the option
+        ret.push(...allSystems);
+      }
+    });
+    
+    const uniqueSystems = [...new Set(ret)];
+    uniqueSystems.sort((a, b) => (systemConfig[a].weight || 0) - (systemConfig[b].weight || 0));
+
+    return uniqueSystems.map(item => [item, item]);
+  }
+
+  function getMissingSystemOptions(serviceId, rowId, options) {
+    let availableSystems = getAvailableSystemOptions(serviceId, options);
+    let missingSystems = allSystems.filter(system => !availableSystems.map(([key, value]) => key).includes(system));
+
+    {%- if pagetype == vars.pagetype_workshop %}
+    const db_workshops = {{ db_workshops | tojson }};
+    let allowedSystems = db_workshops[rowId]?.user_options?.system ?? false;
+    if ( allowedSystems ) {
+      missingSystems = missingSystems.filter(system => allowedSystems.includes(system));
+    }
+    {%- endif %}
+    return missingSystems.map(item => [item, item]);
+  }
+
+
+  function getSystemValues(serviceId, rowId, element) {
+    let systems = val(getInputElement(serviceId, rowId, "system"));
+    let values = [];
+    if ( element === "system" ){
+      values = systems;
+    } else {
+      let systemTypesChecked = [];
+      systems.forEach(system => {
+        const backendService = systemConfig[system]?.backendService;
+        const systemType = backendServicesConfig[backendService]?.type;
+        if ( !systemTypesChecked.includes(systemType) ) {
+          systemTypesChecked.push(systemType);
+          let value = $(`[id^='${serviceId}-${rowId}-'][id$='-${element}-input']`).val();
+          if ( value ) {
+            if (!Array.isArray(value)) {
+              value = [value];
+            }
+            values.push(...value);
+          }
+        }
+      });
+    }
+    return values;
+  }
+
+
+  function getSystemTypes(serviceId, rowId) {
+    const systems = getSystemValues(serviceId, rowId, "system");
+    let systemTypes = [];
+    systems.forEach(system => {
+      const systemType = mappingDict[serviceId]?.["system"]?.[system] ?? system;
+      if ( !systemTypes.includes(systemType) ){
+        systemTypes.push(systemType);
+      }
+    });
+    return systemTypes;
+  }
+{# <-- All Systems #}
\ No newline at end of file
diff --git a/templates/macros/table/table.jinja b/templates/macros/table/table.jinja
new file mode 100644
index 0000000..ec408b5
--- /dev/null
+++ b/templates/macros/table/table.jinja
@@ -0,0 +1,149 @@
+{%- macro tables(
+  frontend_config,
+  macro_description,
+  macro_headerlayout,
+  macro_defaultheader,
+  macro_firstheader,
+  macro_row_content,
+  header_button_functions={},
+  sse_functions=false
+)%}
+  <div id="global-content-div" class="container-fluid p-4">
+    <input id="service-input" class="form-control" data-collect="true" data-group="default" data-type="input" name="service" data-element="service" value="{{ frontend_config.get("services", {}).get("default", "jupyterlab") }}" style="display: none"/>
+    {#- TABLE #}
+    {%- for service_id, service_options in frontend_config.get("services", {}).get("options", {}).items() %}
+      {%- set is_first_service = loop.first %}
+      <div id="{{ service_id }}-table-div" class="table-responsive-md">
+        {%- if macro_description %}
+          {{ macro_description() }}
+        {%- endif %}
+        <table id="{{ service_id }}-table" class="table table-bordered table-striped table-hover table-light align-middle">
+        {#- TABLE HEAD #}
+          <thead class="table-secondary">
+            <tr>
+              {%- if macro_headerlayout %}
+                {{ macro_headerlayout() }}
+              {%- endif %}
+            </tr>
+          </thead>
+          {#- TABLE BODY #}
+          <tbody>
+            {# - List existing workshops #}
+            {%- for row_id, row_options in table_rows.items() %}
+              {%- set is_first_row = loop.first %}
+              <!-- summary of row -->
+              <tr id="{{ service_id }}-{{ row_id }}-summary-tr" data-server-id="{{ service_id }}-{{ row_id }}" class="summary-tr">
+                <td class="details-td" data-bs-target="#{{ row_id }}-collapse">
+                  {%- if loop.first %}
+                    <div class="d-flex mx-4">
+                      {{ svg.plus_svg | safe }}
+                    </div>
+                  {%- else %}
+                    <div class="d-flex mx-auto accordion-icon collapsed mx-4"></div>
+                  {%- endif %}
+                </td>
+                {%- if loop.index0 and macro_defaultheader %}
+                  {{ macro_defaultheader(service_id, row_id, row_options) }}
+                {%- else %}
+                  {%- if macro_firstheader %}
+                    {{ macro_firstheader(service_id, row_id, row_options) }}
+                  {%- endif %}
+                {%- endif %}
+              </tr>
+
+              <!-- collapsible row -->
+              <tr data-server-id="{{ service_id }}-{{ row_id }}" class="collapsible-tr" style="--bs-table-accent-bg: transparent;">
+                <td colspan="100%" class="p-0">
+                  <div class="collapse {%- if loop.first and (table_rows | length == 1) %} show {%- endif -%}" id="{{ service_id }}-{{row_id}}-collapse">                  
+                    <div class="d-flex align-items-start m-3">
+                      {%- if service_options.navbar | length > 0 %}
+                        <div class="nav flex-column nav-pills p-3 ps-0" style="min-width: 15% !important" id="{{ service_id }}-{{ row_id }}-tab-button-div" role="tablist">
+                          {%- for button_id, button_options in service_options.navbar.items() %}
+                            {%- if ( is_first_row and button_options.get("firstRow", true) ) or 
+                                   ( (not is_first_row) and button_options.get("defaultRow", true) )
+                            %}
+                              {%- set style_hide = 'height: 0 !important; overflow: hidden !important; padding-top: 0 !important; padding-bottom: 0 !important; border: none !important; margin: 0 !important;' %}
+                              <button
+                                class="nav-link {{ 'active' if show else '' }} {{ button_options.get("margins", "mb-3") }} {%- if loop.index0 == 0 %} active {%- endif -%}" 
+                                id="{{ service_id }}-{{ row_id }}-{{ button_id }}-navbar-button"
+                                {%- if not button_options.get("show", false) %}
+                                  {#
+                                    Instead of just .hide() it, we want to keep the width of the buttons, 
+                                    so the interface does not wabble around when showing / hiding buttons.
+                                  #}
+                                  style="{{ style_hide }}"
+                                {%- endif %}
+                                name="{{ button_id }}"
+                                data-tab="{{ button_id }}"
+                                data-service="{{ service_id }}"
+                                data-row="{{ row_id }}"
+                                data-bs-toggle="pill" 
+                                data-bs-target="#{{ service_id }}-{{ row_id }}-{{ button_id }}"
+                                {%- if button_options.get("show", true) %}
+                                  data-show="true"
+                                {%- endif %}
+                                type="button"
+                                {%- for specific_key, specific_values in button_options.get("dependency", {}).items() %}
+                                  data-dependency-{{ specific_key }}="true"
+                                  {%- for specific_value in specific_values %}
+                                    data-dependency-{{ specific_key }}-{{ specific_value }}="true"
+                                  {%- endfor %}
+                                {%- endfor %}
+                                role="tab">
+                                <span>{{ button_options.get("displayName", "Unknown Button") }}</span>
+                                <span id="{{ service_id }}-{{ row_id }}-{{ button_id }}-tab-input-warning" class="d-flex invisible">
+                                  {{ svg.warning_svg | safe }}
+                                  <span class="visually-hidden">settings changed</span>
+                                </span>
+                              </button>
+                            {%- endif %}
+                          {%- endfor %}
+                        </div>
+                      {%- endif %}
+                      <div class="tab-content w-100" data-row="{{ row_id }}" data-service="{{ service_id }}" data-sse-progress id="{{ service_id }}-{{ row_id }}-tabContent-div">
+                        <form id="{{ service_id }}-{{ row_id }}-form">
+                          {%- for tab_id, tab_options in service_options.get("tabs", {}).items() %}
+                            <div class="tab-pane fade {%- if loop.first or tab_id == "buttonrow" %} show active"{%- else -%}" style="display: none" {%- endif %} id="{{ service_id }}-{{ row_id }}-{{ tab_id }}-contenttab-div" role="tabpanel">
+                              <div class="row">
+                                {{ macro_row_content(service_id, service_options, row_id, tab_id) }}
+                              </div>
+                            </div>
+                          {%- endfor %}
+                        </form>
+                      </div>
+                    </div>
+                  </div>
+                </td>
+              </tr>
+            {%- endfor %}
+          </tbody>
+        </table>
+      </div>  {#- table responsive #}
+    {%- endfor %}
+  </div>  {#- container fluid #}
+  <script>
+    require(["jquery", "jhapi", "utils"], function (
+      $,      
+      JHAPI,
+      utils
+    ) {
+      "use strict";
+
+      var base_url = window.jhdata.base_url;
+      var user = window.jhdata.user;
+      var api = new JHAPI(base_url);
+
+      
+      
+      {%- for button_key, button_func in header_button_functions.items() %}
+        $(`button[id$='-{{ button_key }}-btn-header']`).on("click", function() {
+          const $this = $(this);
+          {{ button_func }}($this.attr('data-service'), $this.attr('data-row'), $this.attr('data-element'), {}, user, api, base_url, utils)
+        });
+      {%- endfor %}
+      {%- if sse_functions %}
+      {{ sse_functions() }}
+      {%- endif %}
+    });
+  </script>
+{%- endmacro %}
diff --git a/templates/macros/table/table_js.jinja b/templates/macros/table/table_js.jinja
new file mode 100644
index 0000000..f71eec2
--- /dev/null
+++ b/templates/macros/table/table_js.jinja
@@ -0,0 +1,1884 @@
+{# 
+  Different sites may use the functions slighty different
+#}
+
+{%- import "macros/table/variables.jinja" as vars with context %}
+{%- import "macros/svgs.jinja" as svg -%}
+
+<script type="text/javascript">
+
+
+
+  // table_js_start
+  
+
+  // Define the regex pattern with named capture groups
+  const serviceConfig = {{ custom_config.services | tojson }};
+  const userModulesConfig = {{ custom_config.userModules | tojson }};
+  const systemConfig = {{ custom_config.systems | tojson }};
+  const resourcesConfig = {{ custom_config.resources | tojson }};
+  const backendServicesConfig = {{ custom_config.backendServices | tojson }};
+
+  const mappingDict = {}
+
+  {% include 'macros/table/helpers/systems_js.jinja' with context %}
+
+  Object.entries(serviceConfig)
+    .forEach(([key, value]) => {
+      const serviceId = value.serviceId ?? key;
+      if ( !Object.keys(mappingDict).includes(serviceId) ){
+        mappingDict[serviceId] = {
+          "serviceKey": key,
+          "system": {},
+          "option": {}
+        };
+      }
+      Object.entries(value.options).forEach(([optionKey, optionValue]) => {
+        mappingDict[serviceId]["option"][optionKey] = optionValue.type ?? optionKey;
+      });
+      allSystems.forEach(system => {
+        const backendService = systemConfig[system].backendService;
+        const systemType = backendServicesConfig[backendService]?.type ?? system;
+        if (!Object.keys(mappingDict[serviceId]["system"]).includes(systemType)) {
+          mappingDict[serviceId]["system"][system] = systemType;
+        }
+      });
+    });
+
+  function getServiceConfig(serviceId) {
+    const key = mappingDict[serviceId]["serviceKey"];
+    return serviceConfig[key];
+  }
+
+  function val(obj) {
+    let ret = "";
+    if ( obj.is("input[type='checkbox']") ) {
+      ret = obj.prop('checked');
+    } else if ( obj.is("select") ) {
+      ret = obj.val();
+      if ( !Array.isArray(ret) ){
+        ret = [ret];
+      }
+    } else {
+      ret = obj.val();
+    }
+    return ret;
+  }
+
+  function getInputElement(serviceId, rowId, elementId) {
+    return $(`[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input']`);
+  }
+
+  function getLabelCBElement(serviceId, rowId, elementId) {
+    return $(`input[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input-cb']`);
+  }
+
+  function getInputDiv(serviceId, rowId, elementId) {
+    return $(`div[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input-div']`);
+  }
+
+  function getLabel(inputElement) {
+    return $(`label[for='${inputElement.prop("id")}']`);
+  }
+
+  function getInvalidFeedback(inputDiv) {
+    return inputDiv.find(".invalid-feedback");
+  }
+
+  function getOptionTypes(serviceId, rowId) {
+    const options = val(getInputElement(serviceId, rowId, "option"));
+    let ret = [];
+    options.forEach(option => {
+      ret.push(mappingDict[serviceId]?.["option"]?.[option] ?? option);
+    });
+    return ret;
+  }
+
+
+
+
+  {# Fill Input elements -> #}
+
+    function fillSelect(elementId, select, values_, groups = {}, inactive_values = [], inactive_text = "N/A") {
+      let values = values_;
+      {%- if pagetype == vars.pagetype_workshop and db_workshops %}
+        const key = select.attr("name");
+        const rowId = select.attr("data-row");
+        const workshopValues = {{ db_workshops | tojson }}?.[rowId]?.user_options || {};
+        if ( Object.keys(workshopValues).includes(key) ) {
+          let valueKeys = workshopValues[key];
+          if ( !Array.isArray(valueKeys) ){
+            valueKeys = [valueKeys];
+          }
+          values = [];
+          values_.forEach( item => {
+            if ( valueKeys.includes(item[0]) ){
+              values.push(item);
+            }
+          });
+          groups = {};
+        }
+      {%- endif %}
+      const labelElement = $(`label[for='${select.attr("id")}']`);
+      const checkBox = labelElement.find("input[type='checkbox']");
+      let preValue = select.val();
+      select.html("");
+      let valueIndex = 0;
+
+      for (const groupLabel in groups) {
+        if (groups.hasOwnProperty(groupLabel)) {
+          const groupSize = groups[groupLabel];
+          select.append(`<optgroup label="${groupLabel}">`);        
+          for (let i = 0; i < groupSize; i++) {
+              if (valueIndex < values.length) {
+                  select.append(`<option value="${values[valueIndex][0]}">${values[valueIndex][1]}</option>`);
+                  valueIndex++;
+              }
+          }
+          select.append(`</optgroup>`);
+        }
+      }
+
+      while (valueIndex < values.length) {
+        select.append(`<option value="${values[valueIndex][0]}">${values[valueIndex][1]}</option>`);
+        valueIndex++;
+      }
+
+      // Add a horizontal line if there are inactive options
+      if (inactive_values.length > 0) {
+          select.append('<hr>');
+      }
+
+      // Add inactive options at the end of the dropdown
+      inactive_values.forEach(([key, value]) => {
+        select.append(`<option value="${key}" disabled>${value} (${inactive_text})</option>`);
+      });
+
+      if ( preValue && select.find(`option[value="${preValue}"]:not(:disabled)`).length) {
+        select.val(preValue);
+      } else {
+        if ( select.prop("multiple") ) {
+          select.val(null);
+        } else {
+          if (values.length > 0){
+            select.val(values[0][0]);
+          } else {
+            console.error(`Could not fill object. Check configuration.`);
+            
+            {%- if pagetype == vars.pagetype_workshop %}
+            workshopNotUsable(select);
+            {%- endif %}
+          }
+        }
+      } 
+    }
+
+  {# <- Fill Input elements #}
+  {%- if pagetype == vars.pagetype_workshop %}
+    function workshopNotUsable(element) {
+      const helpDiv = $('#workshopnotusable');
+      if ( helpDiv.children().length === 0 ) {
+        const serviceId = element.attr("data-service");
+        const rowId = element.attr("data-row");
+        const elementName = element.attr("data-element");
+        const workshop = {{ db_workshops | tojson }}?.[rowId]?.user_options || {};
+        const workshopId = workshop.workshopid;
+        
+        const workshopSystems = workshop?.system || [];
+        let workshopProject = workshop?.project || [];
+        if ( !Array.isArray(workshopProject) ){
+          workshopProject = [workshopProject];
+        }
+        let workshopPartition = workshop?.partition || [];
+        if ( !Array.isArray(workshopPartition) ){
+          workshopPartition = [workshopPartition];
+        }
+
+        var partitionLinkText = "";
+        var partitionLinkText2 = "";
+        var projectInviteText = "";
+        if ( workshopProject.length === 0 ) {
+          projectInviteText = `
+            <li style="color: #333;">Enter the Project id, that was handed out during the workshop invivation. If in doubt, ask the workshop instructor for the project id.</li>
+          `
+          partitionLinkText = `
+            <li style="color: #333;">Visit <a href="https://judoor.fz-juelich.de" target="_blank">JuDoor</a> and sign in with the credentials you've used to log into here.</li>
+            <li style="color: #333;">Click on the project of this workshop.</li>
+            <li style="color: #333;">Click on "Request access for resources".</li>
+            <img src="{{ static_url("images/workshop/partition_01.png") }}" alt="Login Procedure" style="width: 100%; max-width: 400px; margin-top: 10px; border: 1px solid #ddd; border-radius: 5px;">
+          `
+        } else {
+          workshopProject.forEach(project => {
+            projectInviteText += `
+              <li style="color: #333;">Enter "${project}" into Project id, add some additional information and clickon "Join project".</li>
+            `
+          })
+          if ( workshopProject.length === 1 ) {
+            partitionLinkText = `
+              <li style="color: #333;">Visit <a href="https://judoor.fz-juelich.de/projects/${workshopProject[0]}/request" target="_blank">JuDoor</a> and sign in with the credentials you've used to log into here.</li>
+              
+            `
+          } else {
+            partitionLinkText = `
+              <li style="color: #333;">Visit <a href="https://judoor.fz-juelich.de/" target="_blank">JuDoor</a> and sign in with the credentials you've used to log into here.</li>
+              <li style="color: #333;">Click on the projects of this workshop ( ${workshopProject} ). Repeat the "request access for resources" for each project.</li>
+              <li style="color: #333;">Click on "Request access for resources".</li>
+              <img src="{{ static_url("images/workshop/partition_01.png") }}" alt="Login Procedure" style="width: 100%; max-width: 400px; margin-top: 10px; border: 1px solid #ddd; border-radius: 5px;">
+            `
+          }
+        }
+
+        if ( workshopPartition.length === 0 ) {
+          partitionLinkText2 = `
+            <li style="color: #333;">Select all partitions.</li>
+          `
+        } else {
+          partitionLinkText2 = `
+            <li style="color: #333;">Select these partitions: ${workshopPartition}.</li>
+          `
+        }
+        var missingSystems = allSystems.filter(key => workshopSystems.includes(key));
+        var stepLogin = "";
+        var stepSystem = "";
+        var stepProject = "";
+        var stepPartition = "";
+          // User doesn't have a access to a single system in the workshop
+          // Maybe we can check this in the feature via auth_state entitlements
+          stepLogin = `
+            <details style="margin-bottom: 15px;">
+              <summary style="font-weight: bold; margin-left: 10px; font-size: 16px; color: #0056b3; cursor: pointer;">
+                  - Use the correct AAI during the Login process (click here for more information)
+              </summary>
+              <div style="margin-left: 20px; margin-top: 10px;">
+                <p style="color: #333;">When using HPC resources, you have to use the JSC Account during the login process.</p>
+                <ul>
+                  <li style="color: #333;">Click on <a href="https://{{ hostname }}{{ base_url }}logout" target="_blank">Logout</a></li>
+                  <li style="color: #333;">Click on <a href="https://{{ hostname }}{{ base_url }}login?next=%2Fhub%2Fworkshops%2F${workshopId}" target="_blank">Login</a> (make sure to come back to this page ("/workshops/${workshopId}") after logging in).</li>
+                  <ul>
+                    <li style="color: #333;">Click on "Sign In"</li>
+                    <li style="color: #333;">Click on "Show other sign in options"</li>
+                      <img src="{{ static_url("images/workshop/login_01.png") }}" alt="Login Procedure" style="width: 100%; max-width: 400px; margin-top: 10px; border: 1px solid #ddd; border-radius: 5px;">
+                    <li style="color: #333;">Click on "Sign in with JSC Account"</li>
+                    <li style="color: #333;">Enter your JSC Account credentials and click on Login. Don't have an account yet? Click on register and follow the process. For more information look into the <a href="https://www.fz-juelich.de/en/ias/jsc/services/user-support/how-to-get-access-to-systems/judoor" target="_blank"> JuDoor documentation</a>.</li>
+                  </ul>
+                </ul>
+              </div>
+            </details>
+          `
+          stepProject = `
+            <details style="margin-bottom: 15px;">
+              <summary style="font-weight: bold; margin-left: 10px; font-size: 16px; color: #0056b3; cursor: pointer;">
+                  - Join Projects
+              </summary>
+              <div style="margin-left: 20px; margin-top: 10px;">
+                <p style="color: #333;">When using HPC resources, you have to join a project, before you're allowed to use resources.</p>
+                <ul>
+                  <li style="color: #333;">Visit <a href="https://judoor.fz-juelich.de" target="_blank">JuDoor</a> and sign in with the credentials you've used to log into here.</li>
+                  <li style="color: #333;">Click on "Join a project"</li>
+                  <img src="{{ static_url("images/workshop/project_01.png") }}" alt="Join Project" style="width: 100%; max-width: 400px; margin-top: 10px; border: 1px solid #ddd; border-radius: 5px;">
+                  ${projectInviteText}
+                  <li style="color: #333;">You will receive an email. Follow the steps in this mail.</li>
+                  <li style="color: #333;">For more information about joining projects look into the <a href="https://www.fz-juelich.de/en/ias/jsc/services/user-support/how-to-get-access-to-systems/judoor" target="_blank">JuDoor documentation</a></li>
+                </ul>                
+              </div>
+            </details>
+          `
+        
+        stepSystem = `
+            <details style="margin-bottom: 15px; ">
+              <summary style="font-weight: bold; margin-left: 10px; font-size: 16px; color: #0056b3; cursor: pointer;">
+                  - Accept System Usage Policy
+              </summary>
+              <div style="margin-left: 20px; margin-top: 10px;">
+                <p style="color: #333;">When using HPC resources, you have to accept the usage policy of a system, before you're allowed to use resources.</p>
+                <ul>
+                  <li style="color: #333;">Visit <a href="https://judoor.fz-juelich.de" target="_blank">JuDoor</a> and sign in with the credentials you've used to log into here.</li>
+                  <li style="color: #333;">You have to "sign the usage agreement" for the systems you want to use.</li>                  
+                  <li style="color: #333;">It may take up to 30 minutes for your account to be fully updated and ready on the system after completing the steps.</li>
+                  <li style="color: #333;">For more information look into the <a href="https://www.fz-juelich.de/en/ias/jsc/services/user-support/how-to-get-access-to-systems/judoor" target="_blank">JuDoor documentation</a></li>
+                </ul>                
+              </div>
+            </details>
+          `
+        stepPartition = `
+            <details style="margin-bottom: 15px; ">
+              <summary style="font-weight: bold; margin-left: 10px; font-size: 16px; color: #0056b3; cursor: pointer;">
+                  - Request access for resources
+              </summary>
+              <div style="margin-left: 20px; margin-top: 10px;">
+                <p style="color: #333;">When using HPC resources, you have to accept the usage policy of a system, before you're allowed to use resources.</p>
+                <ul>
+                  <li style="color: #333;">Visit <a href="https://judoor.fz-juelich.de" target="_blank">JuDoor</a> and sign in with the credentials you've used to log into here.</li>
+                  ${partitionLinkText}
+                  ${partitionLinkText2}
+                  <li style="color: #333;">Click on "Inform PIs and PAs about your request.</li>
+                  <li style="color: #333;">The PI or PA has to accept your request.</li>
+                  <li style="color: #333;">It may take up to 30 minutes for your account to be fully updated and ready on the system after completing the steps.</li>
+                  <li style="color: #333;">For more information look into the <a href="https://www.fz-juelich.de/en/ias/jsc/services/user-support/how-to-get-access-to-systems/judoor" target="_blank">JuDoor documentation</a></li>
+                </ul>                
+              </div>
+            </details>
+          `
+        
+        
+        var genericHtml = `
+          <div style="width: 80%; margin: auto; margin-top: 20px; margin-bottom: 20px; padding: 20px; border: 1px solid #ccc; border-radius: 10px; background-color: #f9f9f9;">
+            <h2 style="text-align: center; color: #333;">Workshop "${workshop.workshopid}" not available for you</h2>            
+            <p style="text-align: center; color: #666;">Your account is not yet ready to access this workshop. Please complete the steps below to proceed.</p>
+            
+            <div style="margin-top: 20px;">
+                ${stepLogin}
+                ${stepProject}
+                ${stepSystem}
+                ${stepPartition}
+            </div>
+            <p style="text-align: center; color: darkorange;">It may take up to 60 minutes for the systems to fully process account updates. Any start attempts during this time might fail.</p>
+        </div>
+        `
+        helpDiv.append(genericHtml);
+        $(`#global-content-div`).hide();
+      }
+    }
+  {%- endif %}
+
+  {# Button Helper functions --> #}
+
+    function dictHasKey(obj, key) {
+      // Check if the key exists at the current level
+      if (Object.hasOwn(obj, key)) {
+        return true;
+      }
+
+      // Traverse through nested objects or arrays
+      for (const k in obj) {
+        if (typeof obj[k] === "object" && obj[k] !== null) {
+          if (dictHasKey(obj[k], key)) {
+            return true;
+          }
+        }
+      }
+
+      // If the key is not found
+      return false;
+    }
+
+    function validateInput(inputElement) {
+      const labelElement = $(`label[for='${inputElement.attr("id")}']`);
+      const checkBox = labelElement.find("input[type='checkbox']");
+      if ( checkBox.length > 0 && !checkBox.prop("checked") ) {
+        return true;
+      } else if( !inputElement[0].checkValidity() ) {
+        inputElement.addClass('is-invalid');
+        inputElement.siblings('.invalid-feedback').show();
+        return false;
+      } else {
+        inputElement.removeClass('is-invalid');
+        inputElement.siblings('.invalid-feedback').hide();
+        return true;
+      }
+    }
+
+    function validateSelect(selectElement) {
+      const labelElement = $(`label[for='${selectElement.attr("id")}']`);
+      const checkBox = labelElement.find("input[type='checkbox']");
+      if ( checkBox.length > 0 && !checkBox.prop("checked") ) {
+        return true;
+      } else if (selectElement.val() === ""       
+        || selectElement.val() === undefined)
+      {
+        selectElement.addClass('is-invalid');
+        selectElement.siblings('.invalid-feedback').show();
+        return false;
+      } else {
+        selectElement.removeClass('is-invalid');
+        selectElement.siblings('.invalid-feedback').hide();
+        return true;
+      }
+    }
+
+    function validateForm(serviceId, rowId) {
+      const form = $(`form[id='${serviceId}-${rowId}-form']`);
+      let ret = true;
+      form.find(`[id$='-input']:not(:disabled):not([data-collect="false"])`).each(function () {
+        let $this = $(this);
+        const valid = $this.is("input") ? validateInput($this) : $this.is("select") ? validateSelect($this) : false;
+        if ( !valid ) {
+          console.error("The following element is invalid: ");
+          console.log($this);
+          // If the user is looking at a different tab, we should highlight the button in the navbar
+          const buttonDiv = $(`#${serviceId}-${rowId}-tab-button-div`);
+          const activeTab = buttonDiv.find('.active').attr('name');
+          const inputTab = $this.attr('data-tab');
+          if ( inputTab !== activeTab ){
+            buttonDiv.find(`button[data-tab='${inputTab}']`).click();
+          }
+          ret = false;
+        }
+      });
+      if ( ret ) {
+        form.find(`[id$='-input'].is-invalid`).removeClass('is-invalid');
+        form.find(`[id$='-input'].invalid-feedback`).hide();
+      }
+      return ret;
+    }  
+
+    function homeFillExistingRow(serviceId, rowId, user_options, fillingOrder) {
+      const excludes = `:not(${fillingOrder.map(value => `[data-element='${value}']`).join(',')})`
+      let available = true;
+      let availableDescription = "";
+      // It's important to fill the user options in the right order
+      fillingOrder.forEach(key => {
+        if ( available ) {
+          const inputElement = $(`[id^='${serviceId}-${rowId}-'][id$='-${key}-input']`);
+          const dataGroup = inputElement.attr("data-group");
+          const dataType = inputElement.attr("data-type");
+          let newValue = "";
+          if ( ["none", "default"].includes(dataGroup) ) {
+            newValue = user_options?.[key] ?? "";
+          } else {
+            newValue = user_options?.[dataGroup]?.[key] ?? "";
+          }
+          if ( newValue ) {
+            if ( dataType == "select" ){
+              if (inputElement.find(`option[value="${newValue}"]`).length > 0) {
+                inputElement.val(newValue);
+                inputElement.trigger("change");
+              } else {
+                available = false;
+                availableDescription = `${key} ${newValue} is not available for your account. Please try re-logging in.`;
+                console.log(`${key} ${newValue} currently not available`);
+              }
+            } else if (dataType == "number" ) {
+              const min = inputElement.attr("min");
+              const max = inputElement.attr("max");
+              if (newValue && newValue >= min && newValue <= max) {
+                inputElement.val(newValue);
+                inputElement.trigger("change");
+              } else {
+                available = false;
+                availableDescription = `${key} ${newValue} is not in allowed range [${min}, ${max}].`;
+                console.log(`${key} ${newValue} currently not available`);
+              }
+            } else {
+              inputElement.val(newValue);
+              inputElement.trigger("change");
+            }
+          } else if (inputElement.is("input[type='checkbox']") ) {
+            inputElement.prop("checked", false);
+            inputElement.trigger("change");
+          }
+        }
+      });
+
+      const unorderedElements = $(`[id^='${serviceId}-${rowId}-'][id$='-input']${excludes}`);
+      unorderedElements.each(function () {
+        if ( available ) {
+          const inputElement = $(this);
+          const key = inputElement.attr("data-element");
+          const dataGroup = inputElement.attr("data-group");
+          
+          let newValue = "";
+          if ( ["none", "default"].includes(dataGroup) ) {
+            newValue = user_options?.[key] ?? "";
+          } else {
+            newValue = user_options?.[dataGroup]?.[key] ?? "";
+          }
+          if (inputElement.is("input[type='checkbox']") ) {
+            if ( newValue ) {
+              inputElement.prop("checked", true);
+              inputElement.trigger("change");
+            } else {
+              inputElement.prop("checked", false);
+              inputElement.trigger("change");
+            }
+          } else if ( newValue ) {
+            inputElement.val(newValue);
+            inputElement.trigger("change");
+          } 
+        }
+      });
+      if ( !available ) {
+        console.log(`tr.collapsible-tr[data-server-id='${serviceId}-${rowId}']`);
+        $(`tr.collapsible-tr[data-server-id='${serviceId}-${rowId}']`).remove();
+        console.log("Header NA");
+        updateHeaderButtons(serviceId, rowId, "na");
+        let description = `
+          <div id="${serviceId}-${rowId}-config-td-nadescription-div" class="col text-lg-center col-12 col-lg-12">
+            <span id="${serviceId}-${rowId}-config-td-nadescription">${availableDescription}</span>
+          </div>
+        `;
+        const headerDescription = $(`#${serviceId}-${rowId}-config-td-div`);
+        headerDescription.addClass("justify-content-center");
+        $(`#${serviceId}-${rowId}-config-td-div`).html(description);
+      }
+    }
+
+    function workshopManagerFillExistingRow(serviceId, rowId, workshopDict) {    
+      const form = $(`form[id='${serviceId}-${rowId}-form']`);
+
+      // We must run through the data groups in the correct order, to allow correct trigger behavior
+      const selectors = [
+        "[id$='-input'][data-group='none']",
+        "[id$='-input'][data-group='default']",
+        "[id$='-input']:not([data-group='none']):not([data-group='default']):not([data-group='defaultvalues'])",
+        "[id$='-input'][data-group='defaultvalues']",
+      ]
+      selectors.forEach( selector => {
+        form.find(`${selector}`).each(function () {
+          const $this = $(this);
+          const id = $this.prop('id');
+          let key = $this.attr('data-element');
+          key = $this.attr('data-parent') || key;
+          const dataGroup = $this.attr('data-group');
+          if ( dataGroup === "defaultvalues" ) {
+            $this.trigger(`trigger_${key}`);
+          }
+          let keys = "";
+          let newValue = "";
+          if ( ["none", "default"].includes(dataGroup) ) {
+            keys = Object.keys(workshopDict?.["user_options"]);
+            if ( keys.includes(key) ) {
+              newValue = workshopDict["user_options"][key];
+            }
+          }
+          else {
+            keys = Object.keys(workshopDict?.["user_options"]?.[dataGroup] || {});
+            if ( keys.includes(key) ) {
+              newValue = workshopDict["user_options"][dataGroup][key];
+            }
+          }
+
+          const parentInputDiv = $(`#${id}-div`);
+          const labelInput = $(`#${id}-cb`);
+          if ( newValue ) {
+            $this.attr("data-collect", true);
+            if ( $this.is("input[type='checkbox']") ) {
+              $this.prop('checked', !!newValue);
+            } else {
+              $this.val(newValue);
+            }
+            // enable, since it's part of the stored user_options
+            const alwaysDisabled = $this.attr('data-alwaysdisabled') || false;
+            if ( !alwaysDisabled ) {
+              $this.prop("disabled", false);
+            } 
+            if ( labelInput && labelInput.length > 0 ) {
+              labelInput.prop("disable", false);
+              labelInput.prop("checked", "checked");
+            }
+            parentInputDiv.show();
+          } else {
+            // Set to default values
+            if ( $this.is("input[type='checkbox']") ) {
+              const checked = $this.attr("data-default");
+              $this.prop('checked', !!$this.attr('data-checked'));
+            }
+            if ( $this.attr('data-enabled') != undefined ) {
+              if ( $this.attr('data-enabled') === "true" ) {
+                $this.prop('disabled', false);
+              } else {
+                $this.prop('disabled', true);
+              }
+            }
+            if ( labelInput && labelInput.length > 0 ) {
+              const labelInputEnable = labelInput.attr('data-enabled') === "true";
+              const labelInputCheck = labelInput.attr('data-checked') === "true";
+              labelInput.prop("disable", !labelInputEnable);
+              labelInput.prop("checked", labelInputCheck);
+            }
+          }
+          $this.trigger("change");
+        });
+      });
+
+      if ( !isWorkshopInstructor() ) {
+        console.log("No Instructor");
+        // double check to hide / disable the instructor elements.
+        form.find(`input[data-instructor]`).prop("disabled", true);
+        form.find(`div[data-instructor="show"][id$="-input-div"]`).hide();
+      }
+    }
+
+    function collectWorkshopOptions(serviceId, rowId) {
+      const form = $(`form[id='${serviceId}-${rowId}-form']`);
+      const options = {};
+      form.find(`input[data-group="none"][id$='-input'], input[data-group="none"][id$='-cb-input']`).each(function () {
+        const $this = $(this);
+        let value = "";
+        if ( !$this.prop("disabled") || $this.attr('data-group') === "none" ) {
+          if ( $this.is("input[type='checkbox']") ){
+            value = $this.prop('checked');
+          } else {
+            if ( Array.isArray(value) && values.length == 1 ) {          
+              value = value[0];
+            }
+            value = $this.val();
+          }
+          options[$this.attr('name')] = value;
+        }
+      });
+      return options;
+    }
+
+    function collectSelectedOptions(serviceId, rowId, allCheckboxes=false) {
+      const form = $(`form[id='${serviceId}-${rowId}-form']`);
+      let ret = {};
+      // collect all inputs in default group
+      form.find(`[id^='${serviceId}-${rowId}-'][id$='-input'][data-collect="true"]:not([data-group="none"])`).each(function () {
+        let $this = $(this).first();
+        let dataGroupValue = $this.attr('data-group');
+        let value = "";
+        let addValue = true;
+        let id = $this.prop("id");
+        let labelInput = $(`#${id}-cb`);
+        let parent = $this.attr("data-parent");
+        let name = parent || $this.attr("name");
+        if ( parent ) {
+          let parentElement = $(`[id^='${serviceId}-${rowId}-'][id$='-${parent}-input']`);
+          addValue = parentElement.attr("data-collect") === "true";
+        }
+        if ( addValue ) {
+          if ( labelInput.length > 0 && !labelInput.prop('checked') ) {
+            addValue = false;
+          } else {
+            if ( $this.is("input[type='checkbox']") ){
+              value = $this.prop('checked');
+              if ( !value && !allCheckboxes ) {
+                addValue = false;
+              }
+            } else {
+              if ( Array.isArray(value) && values.length == 1 ) {          
+                value = value[0];
+              }
+              value = $this.val();
+            }
+          }
+        }
+
+        if ( addValue ) {
+          if ( dataGroupValue === "default" ) {
+            ret[$this.attr('name')] = value;
+          } else if ( dataGroupValue != "none" ) {
+            if (!Object.keys(ret).includes(dataGroupValue)) {
+              ret[dataGroupValue] = {}
+            }
+            ret[dataGroupValue][name] = value;
+          }
+        }
+      });
+      let profile = "";
+      if ( Object.keys(ret).includes("option") ) profile = ret.option;
+      else profile = serviceId;
+      ret["profile"] = profile;
+      ret["service"] = serviceId;
+
+      if ( !Object.keys(ret).includes("name") || !ret?.name ) {
+        ret["name"] = `Unnamed ${serviceId}`;
+      }
+      
+      console.log("Collected Options in frontend:");
+      console.log(ret);
+      return ret;
+    }
+
+  {# <-- Button Helper functions #}
+
+  {# Workshop Manager --> #}
+    {# WorkshopManager.helper --> #}
+    function isWorkshopInstructor() {
+      {%- if is_instructor %}
+        return true;
+      {%- else %}
+        return false;
+      {%- endif %}
+    }
+
+    function isFirstRow(rowId) {
+      return rowId === "{{ vars.first_row_id }}";
+    }
+    {# <-- WorkshopManager.helper #}
+
+    {# WorkshopManager.none.workshopid --> #}
+      function workshopManagerWorkshopId(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+          const $this = $(`input[id^="${serviceId}-${rowId}-"][id$="-${elementId}-input"]`);
+          if ( !isFirstRow(rowId) ){
+            $this.val(rowId);        
+          } else {
+            if ( isWorkshopInstructor() ) {
+              $this.prop("disabled", false);
+              $this.prop("placeholder", elementOptions?.["input"]?.["options"]?.["placeholderInstructor"] || "W");
+            }
+          }
+      }
+    {# <-- WorkshopManager.none.workshopid #}
+
+    {# WorkshopManager.default.option --> #}
+      function workshopManagerFillOptions(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        {# I think that's not needed 
+        let valueKeys = [];
+        if (getServiceConfig(serviceId)?.options) {
+          valueKeys = Object.keys(getServiceConfig(serviceId).options);        
+        }
+        let values = Object.entries(getServiceConfig(serviceId).options)
+          .filter(([key, value]) => valueKeys.includes(key))
+          .map(([key, value]) => [key, value.name]);
+        #}
+        let values = getServiceConfig(serviceId).options;
+        
+        {%- if pagetype == vars.pagetype_workshop %}
+          const db_workshops = {{ db_workshops | tojson }};
+          {# Only allow options, which are available for the selected systems #}
+          let allowedSystems = db_workshops[rowId]?.user_options?.system ?? false;
+          if ( allowedSystems ) {
+            if ( !Array.isArray(allowedSystems) ){
+              allowedSystems = [allowedSystems];
+            }
+            let allowedOptions = {};
+            for ( const [key, valueInformation] of Object.entries(values) ) {
+              allowedSystems.forEach(system => {
+                const systemsPerOption = getServiceConfig(serviceId)?.options?.[key]?.allowedLists?.systems ?? [];
+                if ( systemsPerOption.includes(system) && !allowedOptions.hasOwnProperty(key) ) {
+                  allowedOptions[key] = valueInformation;
+                }
+              });
+            }
+            values = allowedOptions;
+          }
+        {%- endif %}
+
+        const optionInput = $(`#${serviceId}-${rowId}-${tabId}-option-input`);
+
+        fillSelect("init", optionInput, Object.entries(values).map(([key, value]) => [key, value.name]), {}, [], "N/A");
+      }
+    {# <-- WorkshopManager.default.option #}
+
+    {# WorkshopManager.default.system --> #}
+      function workshopManagerUpdateSystem(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const optionInput = $(`#${serviceId}-${rowId}-${tabId}-option-input`);
+        const systemInput = $(`#${serviceId}-${rowId}-${tabId}-system-input`);
+
+        const options = val(optionInput);
+
+        if ( optionInput.prop("disabled") ){
+          // If option is disabled -> make all systems available
+          fillSelect(elementId, systemInput, allSystems.map(item => [item, item]));
+        } else {
+          // Update available systems
+          let inactiveText = "N/A"
+          let displayNames = [];
+          options.forEach(option => {
+            if (getServiceConfig(serviceId)?.options) {
+              displayNames.push(getServiceConfig(serviceId).options[option].name);
+            }
+          })
+          let displayName = displayNames.join(", ");
+          inactiveText = `N/A for ${displayName}`
+
+          fillSelect(elementId, systemInput, getAvailableSystemOptions(serviceId, options), {}, getMissingSystemOptions(serviceId, rowId, options), inactiveText);
+        }
+      }
+
+    {# <-- WorkshopManager.default.system #}
+
+    {# WorkshopManager.default.unicore.project --> #}
+      function workshopManagerUpdateProject(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const values = getProjectOptions(serviceId, rowId);
+        const inputElement = getInputElement(serviceId, rowId, "project");
+        fillSelect(elementId, inputElement, values);
+        // inputElement.trigger("change");
+      }
+    {# WorkshopManager.default.unicore.project --> #}
+
+    {# WorkshopManager.default.unicore.partition --> #}
+      function workshopManagerUpdatePartition(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const [partitions, interactivePartitionsLength] = getPartitionAndInteractivePartition(serviceId, rowId);
+        const inputElement = getInputElement(serviceId, rowId, "partition");
+        fillSelect(elementId, inputElement, partitions, {"Login Nodes": interactivePartitionsLength, "Compute Nodes": -1});
+        // inputElement.trigger("change");
+      }
+    {# <-- WorkshopManager.default.unicore.partition #}
+
+    {# WorkshopManager.default.unicore.reservation --> #}
+      function toggleCollectCB(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const labelChecked = val(getLabelCBElement(serviceId, rowId, elementId));
+        const inputDiv = getInputDiv(serviceId, rowId, elementId);
+        const inputElement = getInputElement(serviceId, rowId, elementId);
+        if ( !inputElement.is(":visible") ) {
+          inputElement.attr("data-collect", false);
+        } else {
+          if ( labelChecked ) {
+            inputElement.attr("data-collect", true);
+          } else {
+            inputElement.attr("data-collect", false);
+          }
+        }
+      }
+      function workshopManagerUpdateReservation(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        
+        const systemInput = getInputElement(serviceId, rowId, "system");
+        const elementDiv = getInputDiv(serviceId, rowId, elementId);
+        const reservationInput = getInputElement(serviceId, rowId, elementId);
+        
+        let reservations = getReservationOptions(serviceId, rowId);
+        
+        {%- if pagetype == vars.pagetype_workshop and db_workshops %}
+          const db_workshops = {{ db_workshops | tojson }};
+          {# Only allow options, which are available for the selected systems #}
+          let allowedReservations = db_workshops[rowId]?.user_options?.reservation ?? false;
+          if ( allowedReservations ) {
+            if ( !Array.isArray(allowedReservations) ){
+              allowedReservations = [allowedReservations];
+            }
+            let forcedreservations = [];
+            const currentSystem = val(getInputElement(serviceId, rowId, "system"));
+            if ( currentSystem.length === 1 && currentSystem[0] && unicoreReservations.hasOwnProperty(currentSystem[0]) ) {
+              allowedReservations.forEach(singleWorkshopReservation => {
+                let singleWorkshopToAdd = unicoreReservations[currentSystem[0]].filter(item => item.ReservationName == singleWorkshopReservation);
+                if ( singleWorkshopToAdd.length === 1 ) {
+                  forcedreservations.push(singleWorkshopToAdd[0]);
+                }
+              });
+            }
+            reservations = forcedreservations;
+            reservationInput.attr("data-collect", true);
+          }
+        {%- endif %}
+        if ( !systemInput.prop("disabled") && reservations.length > 0 ) {
+          
+          activeReservationNames = reservations
+            .filter(item => item.State === "ACTIVE")
+            .map(item => [item.ReservationName, item.ReservationName]);
+          inactiveReservationNames = reservations
+            .filter(item => item.State === "INACTIVE")
+            .map(item => [item.ReservationName, item.ReservationName]);
+          const allReservationsSorted = [
+            ["None", "None"],
+            ...activeReservationNames,
+            ...inactiveReservationNames
+          ];
+          
+          let groups = {
+            "No reservation": 1
+          }
+          if ( activeReservationNames.length > 0 ) {
+            groups["Active"] = activeReservationNames.length;
+          }
+          if ( inactiveReservationNames.length > 0 ) {
+            groups["Inactive"] = inactiveReservationNames.length;
+          }
+          fillSelect(elementId, reservationInput, allReservationsSorted, groups);
+          const labelCB = getLabelCBElement(serviceId, rowId, "reservation");
+          if ( labelCB.length ) {
+            if ( labelCB.prop("checked") ) {
+              reservationInput.attr("data-collect", true);
+            } else {
+              reservationInput.attr("data-collect", false);
+            }
+          } else {
+            reservationInput.attr("data-collect", true);
+          }
+          if ( val(reservationInput)[0] == "None" ) {
+            reservationInput.attr("data-collect", false);
+          }
+          elementDiv.show();
+        } else {
+          reservationInput.attr("data-collect", false);
+          elementDiv.hide();
+          $(`div[id^='${serviceId}-${rowId}-'][id$='-reservationinfo-input-div']`).hide();        
+        }
+      }
+
+      function defaultValue(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const dependentElement = elementOptions?.input?.options?.parent || "";
+        if ( !dependentElement ) {
+          console.log(`Custom Config not configured correctly for ${elementId}. Add "parent" to elementOptions.`);
+        }
+
+        const selectedParentValues = $(`select[id^='${serviceId}-${rowId}-'][id$='-${dependentElement}-input']`).val();
+        const parentLabelCB = $(`input[id^='${serviceId}-${rowId}-'][id$='-${dependentElement}-input-cb']`);
+        const inputParentElement = $(`select[id^='${serviceId}-${rowId}-'][id$='-${dependentElement}-input']`);
+
+        const inputElement = $(`select[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input']`);
+        const labelCB = $(`input[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input-cb']`);
+        const inputDiv = $(`div[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input-div']`);
+
+        if ( parentLabelCB.prop("checked") && inputParentElement.attr("data-collect") && selectedParentValues.length > 1 ) {
+          fillSelect(elementId, inputElement, selectedParentValues.map(item => [item, item]));
+          inputDiv.show();
+          if ( labelCB.prop("checked") && inputParentElement.attr("data-collect") === "true") {
+            inputElement.attr("data-collect", true);
+          } else {
+            inputElement.attr("data-collect", false);
+          }
+        } else {
+          inputDiv.hide();
+          inputElement.attr("data-collect", false);
+        }
+      }
+
+      function updateReservationInfo(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const reservation_values = val(getInputElement(serviceId, rowId, "reservation"));
+        let reservation = "None";
+        if ( reservation_values.length > 0 ){
+          reservation = reservation_values[0];
+        }
+        const reservationInfoDiv = $(`[id^='${serviceId}-${rowId}-'][id$='-reservationinfo-input-div']`);
+        if ( !reservation || reservation === "None" ) {
+          reservationInfoDiv.hide();
+        } else {          
+          const currentSystem = val(getInputElement(serviceId, rowId, "system"));
+          if ( currentSystem.length === 1 && currentSystem[0] && unicoreReservations.hasOwnProperty(currentSystem[0])) {
+            const reservations = unicoreReservations[currentSystem[0]].filter(item => item.ReservationName == reservation);
+            for (const reservationInfo of reservations) {
+              if (reservationInfo.ReservationName == reservation) {
+                reservationInfoDiv.find(`span[id$="-start"]`).html(`${reservationInfo.StartTime} (Europe/Berlin)`);
+                reservationInfoDiv.find(`span[id$="-end"]`).html(`${reservationInfo.EndTime} (Europe/Berlin)`);
+                reservationInfoDiv.find(`span[id$="-state"]`).html(reservationInfo.State);
+                reservationInfoDiv.find(`pre[id$="-details"]`).html(JSON.stringify(reservationInfo, null, 2));
+              }
+            }
+            reservationInfoDiv.show();
+          } else {
+            reservationInfoDiv.hide();
+          }
+        }
+      }
+    {# <-- WorkshopManager.default.unicore.reservation #}
+
+
+    {# WorkshopManager.default.unicore.nodesRuntimeGPUXservers --> #}
+      function workshopManagerUpdateResourcesElementTrigger(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const systems = getUnicoreValues(serviceId, rowId, "system");
+        const partitions = getUnicoreValues(serviceId, rowId, "partition");
+        let _partitions = [];
+
+        const labelOptions = elementOptions.label ?? {};
+
+        const inputDiv = getInputDiv(serviceId, rowId, elementId);
+        const inputElement = getInputElement(serviceId, rowId, elementId);      
+        const labelElement = getLabel(inputElement);
+        const labelElementCBValue = val(getLabelCBElement(serviceId, rowId, elementId));
+        const invalidFeedback = getInvalidFeedback(inputDiv);
+
+        let minmaxavail = false;
+        let min = -1;
+        let max = -1;
+        let label = (labelOptions.value === undefined || labelOptions.value === null) ? "No Label" : labelOptions.value;
+        let show = false;
+        let defaultValue = 1;
+        let collectInformation = true;
+
+        if ( collectInformation ){
+          systems.forEach(system => {
+            if (partitions.length === 1 && partitions[0] === "_all_") {
+              _partitions = Object.keys(resourcesConfig[system] ?? {});
+            } else {
+              _partitions = partitions;
+            }
+            _partitions.forEach(partition => {
+              const elementOptions = resourcesConfig[system]?.[partition]?.[elementId] ?? {};
+              if (Object.keys(elementOptions).length !== 0 ) {
+                show = true;
+                const minmax = elementOptions.minmax || false;
+                defaultValue = (elementOptions["default"] === undefined || elementOptions["default"] === null) ? defaultValue : elementOptions["default"];                
+                if ( minmax ) {
+                  if ( !minmaxavail ) {
+                    minmaxavail = true;
+                    min = minmax[0];
+                    max = minmax[1];
+                  } else {
+                    if ( minmax[0] < min ){
+                      min = minmax[0];
+                    }
+                    if ( minmax[1] > max ){
+                      max = minmax[1];
+                    }
+                  }
+                }
+              }
+            });
+          });
+        }
+        if ( show ) {
+          if ( !collectInformation ) {
+            label = `${label} [${defaultValue}]`;
+            invalidFeedback.html(`Value ${defaultValue} was chosen by workshop instructor.`)
+            inputElement.attr("min", min);
+            inputElement.attr("max", max);
+          } else if ( minmaxavail ){
+            label = `${label} [${min}, ${max}]`;
+            invalidFeedback.html(`Please choose a number between ${min} and ${max}.`);
+            inputElement.attr("min", min);
+            inputElement.attr("max", max);
+          } else {
+            invalidFeedback.html("Please choose a valid number.");
+            inputElement.removeAttr("min");
+            inputElement.removeAttr("max");
+          }
+          if ( inputElement.attr("data-alwaysdisabled") != "true" ) {
+            inputElement.attr("value", defaultValue);
+          }
+
+          labelElement.contents().filter(function () {
+            return this.nodeType === Node.TEXT_NODE;
+          }).first().replaceWith(label);
+
+          // Checkbox logic
+          const checkBoxElement = labelElement.find("input[type='checkbox']");
+          if ( checkBoxElement.length !== 0 ) {
+            const checkBoxDefault = labelOptions?.options?.default ?? false;
+            checkBoxElement.prop("checked", checkBoxDefault);
+            inputElement.prop("disabled", !checkBoxDefault);
+          } else {
+            if ( inputElement.attr("data-alwaysdisabled") != "true" ) {
+              inputElement.prop("disabled", false);
+            }
+          }
+          inputDiv.show();
+          if ( labelElementCBValue !== undefined ) {
+            inputElement.attr("data-collect", labelElementCBValue);
+          } else {
+            inputElement.attr("data-collect", true);
+          }
+          {%- if pagetype == vars.pagetype_workshop %}
+          
+            const workshops = {{ db_workshops | tojson }} || {};
+            const workshopValues = workshops?.[rowId]?.user_options;
+            if ( Object.keys(workshopValues).includes(elementId) ){
+              console.log(`Yeah - ${elementId} is defined`);
+            } 
+          {%- endif %}
+        } else {
+          inputDiv.hide();
+          inputElement.attr("data-collect", false);
+        }
+      }
+    {# <-- WorkshopManager.default.unicore.nodesRuntimeGPUXservers #}
+
+    
+    {# WorkshopManager.default.kube.flavor --> #}
+      function workshopManagerUpdateFlavor(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const systems = val(getInputElement(serviceId, rowId, "system"));
+        const systemTypes = getSystemTypes(serviceId, rowId);
+        if ( systemTypes.includes("kube") ){
+          const selectInput = getInputElement(serviceId, rowId, "flavor");
+          fillSelect(elementId, selectInput, getAvailableKubeFlavorsS(systems), {}, getUnavailableKubeFlavorsS(systems), "maximum reached");
+          // selectInput.trigger("change");        
+        }
+      }
+    {# <-- WorkshopManager.default.kube.flavor #}
+
+    
+    {# Workshop.labconfig.flavorinfo --> #}
+      function setFlavorInfo(serviceId, rowId, system, flavors={}) {
+        const inputDiv = $(`div[id^='${serviceId}-${rowId}-'][id$='-flavorinfo-input-div']`);
+        inputDiv.empty();
+        if ( system ) {
+          let allFlavors = flavors;
+          if ( allFlavors != undefined ) {
+            allFlavors = kubeOutpostFlavors[system];
+          }
+          if ( allFlavors ){
+            for (const [_, description] of Object.entries(allFlavors)
+              .filter(([key, value]) => value.max != 0)
+              .sort(([, a], [, b]) => {
+                const weightA = a["weight"] || 99;
+                const weightB = b["weight"] || 99;
+                return weightA > weightB ? 1 : -1;
+              })) {
+              var current = description.current || 0;
+              var maxAllowed = description.max;
+              // Flavor not valid, so skip
+              if (maxAllowed == 0 || current < 0 || maxAllowed == null || current == null) continue;
+
+              var bgColor = "bg-primary";
+              // Infinite allowed
+              if (maxAllowed == -1) {
+                var progressTooltip = `${current} used`;
+                var maxAllowedLabel = '∞';
+                if (current == 0) {
+                  var currentWidth = 0;
+                  var maxAllowedWidth = 100;
+                }
+                else {
+                  var currentWidth = 20;
+                  var maxAllowedWidth = 80;
+                }
+              }
+              else {
+                var progressTooltip = `${current} out of ${maxAllowed} used`;
+                var maxAllowedLabel = maxAllowed - current;
+                var currentWidth = current / maxAllowed * 100;
+                var maxAllowedWidth = maxAllowedLabel / maxAllowed * 100;
+
+                if (maxAllowedLabel < 0) {
+                  maxAllowedLabel = 0;
+                  maxAllowedWidth = 0;
+                  bgColor = "bg-danger";
+                }
+              }
+
+              var diagramHtml = `
+                <div class="row align-items-center g-0 mt-4">
+                  <div class="col-4">
+                    <span>${description.display_name}</span>
+                    <a class="lh-1 ms-3" style="padding-top: 1px;" 
+                      data-bs-toggle="tooltip" data-bs-placement="right" title="${description.description}">
+                      {{ svg.info_svg | safe }}
+                    </a>
+                  </div>
+                  <div class="progress col ms-2 fw-bold" style="height: 20px;"
+                    data-bs-toggle="tooltip" data-bs-placement="top" title="${progressTooltip}">
+                    <div class="progress-bar ${bgColor}" role="progressbar" style="width: ${currentWidth}%">${current}</div>
+                    <div class="progress-bar bg-success" role="progressbar" style="width: ${maxAllowedWidth}%">${maxAllowedLabel}</div>
+                  </div>
+                </div>
+              `
+              inputDiv.append(diagramHtml);
+            }
+          }
+        }
+
+        // The lab has a flavor configured or is a new lab, but we could not get any flavor information
+        {#
+          if (((window.userOptions[id] || {}).flavor || id == "new-jupyterlab") && $.isEmptyObject(systemFlavors)) {
+          var noFlavorsHtml = `
+          <div class="row g-0 mt-3">
+            <div class="col-4"></div>
+            <div class="col ms-2 fw-bold text-danger">No flavors could be fetched. Try logging out and back in to fix the issue.</div>
+          </div>
+          `;
+          $(`#${serviceId}-${rowId}-${tabId}-systemtype-kube-flavorinfo-info-div`).append(noFlavorsHtml);
+        }
+        #}
+      }
+
+      function updateFlavorInfo(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const systems = val(getInputElement(serviceId, rowId, "system"));
+        const systemTypes = getSystemTypes(serviceId, rowId);      
+        if ( systemTypes.includes("kube") && systems.length == 1 ){
+          setFlavorInfo(serviceId, rowId, systems[0]);
+          // $(`[id^='${serviceId}-${rowId}-'][id$='-flavorinfo-info-div']`).show();
+        }
+      }
+    {# <-- Workshop.labconfig.flavorinfo #}
+
+    {# WorkshopManager.default.lmod.modules --> #}
+      function workshopManagerUpdateModuleWorkshop(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const optiontypes = getOptionTypes(serviceId, rowId);
+        if ( optiontypes.includes("lmod") ) {
+          const values = getModuleValues(serviceId, rowId, elementId, elementOptions.input.options.setName);
+          const elementSelect = $(`select[id^='${serviceId}-${rowId}-'][id$='-${elementId}-input']`);
+          fillSelect(elementId, elementSelect, values);
+          const activeValues = values.filter(item => item[2]).map(item => item[0]);
+          // elementSelect.val(activeValues).trigger("change");
+        }
+      }
+    {# <-- WorkshopManager.default.lmod.modules #}
+
+    {# WorkshopManager.default.repo2docker.repopathtype --> #}
+      function R2DgetRepoPathType(serviceId, rowId, tabId, elementId) {
+        return {{ custom_config.get("binderRepos", {}).get("notebookTypes", ["File", "URL"]) | tojson }}.map(item => [item, item]);
+      }
+
+      function setR2DPathType(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const inputElement = getInputElement(serviceId, rowId, "repopathtype");
+        fillSelect(elementId, inputElement, R2DgetRepoPathType());
+      }
+
+      function workshopManagerRepoPathType(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const repoPathChecked = val(getLabelCBElement(serviceId, rowId, "repopath"));
+
+        const repoPathTypeDiv = getInputDiv(serviceId, rowId, "repopathtype");
+        const repoPathTypeInput = getInputElement(serviceId, rowId, "repopathtype");
+        const repoPathTypeLabel = getLabelCBElement(serviceId, rowId, "repopathtype");
+        if ( !repoPathChecked ) {
+          repoPathTypeInput.prop("disabled", true);
+          repoPathTypeLabel.prop("checked", false);
+          repoPathTypeLabel.prop("disabled", true);
+          repoPathTypeDiv.hide();
+        } else {
+          repoPathTypeDiv.show();
+          repoPathTypeLabel.prop("disabled", false);
+          const repoPathTypeChecked = repoPathTypeLabel.prop("checked");
+          repoPathTypeInput.prop("disabled", !repoPathTypeChecked);
+        }
+      }
+    {# <-- WorkshopManager.default.repo2docker.repopathtype #}
+
+    {# WorkshopManager.default.repo2docker.repotype --> #}  
+      function R2DgetRepoType() {
+        return {{ custom_config.get("binderRepos", {}).get("repos", ["GitHub"]) | tojson }}.map(item => [item, item]);
+      }
+
+      function setR2DType(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const repo2dockerSelect = $(`[id^="${serviceId}-${rowId}-"][id$="-${elementId}-input"]`);
+        fillSelect(elementId, repo2dockerSelect, R2DgetRepoType());
+      }
+    {# <-- WorkshopManager.default.repo2docker.repotype #}
+
+    {# WorkshopManager.default.expertmode --> #}
+      function workshopManagerToggleExpertMode(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const optionInput = $(`[id^="${serviceId}-${rowId}-"][id$="-option-input"]`);
+        const systemInput = $(`[id^="${serviceId}-${rowId}-"][id$="-system-input"]`);
+
+        if ( val(getInputElement(serviceId, rowId, elementId)) ){
+          // if checked: set systems + options to multiple
+          [optionInput, systemInput].forEach(input => {
+            input.prop("size", 4);
+            input.prop("multiple", true);
+          })
+        } else {
+          [optionInput, systemInput].forEach(input => {
+            input.prop("size", 1);
+            input.prop("multiple", false);
+          })
+        }
+      }
+    {# <-- WorkshopManager.default.expertmode #}
+    
+    {# WorkshopManager.button.helper --> #}
+
+      function showToast(message, type = "danger") {
+        const toast = $(`
+          <div class="toast align-items-center text-white bg-${type} border-0" role="alert" aria-live="assertive" style="opacity: 0.9 !important" aria-atomic="true">
+            <div class="d-flex">
+              <div class="toast-body">
+                  ${message}
+              </div>
+              <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
+            </div>
+          </div>
+        `);
+        $("#toastContainer").append(toast);
+        const bsToast = new bootstrap.Toast(toast[0]);
+        bsToast.show();
+      }
+
+      function getAPIOptions() {
+        return {
+          dataType: null,
+          tryCount: 5,
+          error: function (jqXHR, textStatus, errorThrown) {
+            if (jqXHR.status == 503) {
+                this.tryCount--;
+                if (this.tryCount >= 0) {
+                  $.ajax(this);
+                  return;
+                }
+                return;
+              }
+              if (jqXHR.status == 403) {                
+                return;
+              }
+              showToast("Request to Server failed. Try refreshing website");
+              console.error("API Request failed:", textStatus, errorThrown);
+            }
+        }
+      }
+
+      function getWorkshopManagerAPIUrl(serviceId, rowId, utils, base_url) {
+        if ( isFirstRow(rowId) ) {
+          const workshopId = $(`input[id^='${serviceId}-${rowId}-'][id$='-workshopid-input']`).val();
+          if ( workshopId ) {
+            return utils.url_path_join("workshops", workshopId);
+          } else {
+            return "workshops";
+          }
+        } else {
+          return utils.url_path_join("workshops", rowId);
+        }
+      }
+    {# <-- WorkshopManager.button.helper #}
+
+    {# WorkshopManager.button.new --> #}
+      function workshopManagerButtonNewSave(serviceId, rowId, buttonId, button_options, user, api, base_url, utils, show_modal=false) {
+        const options = getAPIOptions();
+        const form = $(`form[id^='${serviceId}-${rowId}-form']`);
+        const valid = validateForm(serviceId, rowId);
+        if ( !valid ) {
+          console.log(`Invalid Form for ${serviceId}-${rowId}`);
+          return;
+        }
+        let userOptions = collectSelectedOptions(serviceId, rowId, allCheckboxes=true);
+        let workshopData = collectWorkshopOptions(serviceId, rowId);
+
+        options["data"] = JSON.stringify({
+          ...userOptions,
+          ...workshopData
+        });
+        options["success"] = function (resp) {
+          if ( show_modal ) {
+            workshopManagerShowModal(serviceId, rowId, resp);
+          }
+        };
+        options["type"] = "POST";
+
+        api.api_request(
+          getWorkshopManagerAPIUrl(serviceId, rowId, utils, base_url),
+          options
+        );
+      }
+      function workshopManagerButtonNew(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        workshopManagerButtonNewSave(serviceId, rowId, buttonId, button_options, user, api, base_url, utils, true);
+      }
+    {# <-- WorkshopManager.button.new #}
+
+    {# WorkshopManager.button.reset --> #}
+      function workshopManagerButtonReset(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        const options = getAPIOptions();
+        options["type"] = "GET";
+        options["success"] = function (resp) {
+          workshopManagerFillExistingRow(serviceId, rowId, resp);
+        }
+        api.api_request(
+          getWorkshopManagerAPIUrl(serviceId, rowId, utils, base_url),
+          options
+        );
+      }
+    {# <-- WorkshopManager.button.reset #}
+
+    {# WorkshopManager.button.share --> #}
+      function workshopManagerShowLink(serviceId, rowId, tabId, buttonId, button_options, user, api, base_url, utils) {
+        workshopManagerShowModal($this.attr("data-service"), $this.attr("data-row"), rowId);
+      }
+    {# <-- WorkshopManager.button.share #}
+
+    {# WorkshopManager.button.delete --> #}
+      function workshopManagerButtonDelete(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        const options = getAPIOptions();
+        options["type"] = "DELETE";
+        options["success"] = function () {
+          $(`tr[data-server-id=${serviceId}-${rowId}]`).each(function () {
+            $(this).remove();
+          });
+          console.log(`Delete of ${serviceId}-${rowId} successful`);
+        };
+        api.api_request(
+          getWorkshopManagerAPIUrl(serviceId, rowId, utils, base_url),
+          options
+        );
+      }
+    {# <-- WorkshopManager.button.delete #}
+
+    {# WorkshopManager.button.stop --> #}
+      function updateHeaderButtons(serviceId, rowId, status) {
+        // status: ["running", "starting", "na", "stopping", "cancelling", "stopped", "waiting"]
+        let toShow = [];
+        let toDisable = [];
+        if ( status == "running" ) {
+          toShow = ["open", "stop"];
+        } else if ( status == "waiting" ) {
+          toShow = ["open", "stop"];
+          toDisable = ["open"];
+        } else if ( status == "starting" ) {
+          toShow = ["cancel"];
+        } else if ( status == "na" ) {
+          toShow = ["na", "del"];
+          toDisable = ["na"];
+        } else if ( status == "stopping" ) {
+          toShow = ["open", "stop"];
+          toDisable = ["open", "stop"];
+        } else if ( status == "cancelling" ) {
+          toShow = ["cancel"];
+          toDisable = ["cancel"];
+        } else if ( status == "stopped" ) {
+          toShow = ["start"];
+          toDisable = [];
+        } else if ( status == "disable" ) {
+          toDisable = ["open", "stop", "cancel", "start", "del"];
+        }
+        const baseSelector = `button[id^="${serviceId}-${rowId}"][id$="-btn-header"]`;
+        
+        // Enable buttons
+        const toDisableExcludeSelector = toDisable
+          .map(item => `:not([id$="-${item}-btn-header"])`)
+          .join("");
+        $(`${baseSelector}${toDisableExcludeSelector}`).prop("disabled", false);
+
+        // Disable buttons
+        toDisable.forEach(item => {
+          $(`button[id^="${serviceId}-${rowId}"][id$="-${item}-btn-header"]`).prop("disabled", true);
+        });
+
+        if ( status != "disable" ) {
+          // Hide buttons
+          const toShowExcludeSelector = toShow
+            .map(item => `:not([id$="-${item}-btn-header"])`)
+            .join("");
+          $(`${baseSelector}${toShowExcludeSelector}`).hide();
+
+          // Show buttons
+          toShow.forEach(item => {
+            $(`button[id^="${serviceId}-${rowId}"][id$="-${item}-btn-header"]`).show();
+          });
+        }
+      }
+
+      function getCurrentTimestamp() {
+          const now = new Date();
+
+          const berlinTime = new Date(
+              now.toLocaleString('en-US', { timeZone: 'Europe/Berlin' })
+          );
+
+          const year = berlinTime.getFullYear();
+          const month = String(berlinTime.getMonth() + 1).padStart(2, '0');
+          const day = String(berlinTime.getDate()).padStart(2, '0');
+          const hours = String(berlinTime.getHours()).padStart(2, '0');
+          const minutes = String(berlinTime.getMinutes()).padStart(2, '0');
+          const seconds = String(berlinTime.getSeconds()).padStart(2, '0');
+          const milliseconds = String(now.getMilliseconds()).padStart(3, '0');
+
+          return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
+      }
+
+      function getStopEvent(buttonId) {
+        const event = {
+          "progress": 100,
+          "failed": true,
+          "ready": false,
+          "html_message": `<details><summary>${getCurrentTimestamp()}: Start cancelled by user.</summary>${buttonId} button was triggered.</details>`
+        }
+        return event;
+      }
+
+      function workshopButtonStop(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        const options = getAPIOptions();
+        options["success"] = function (data, textStatus, jqXHR) {
+          updateHeaderButtons(serviceId, rowId, "stopped");
+          progressBarUpdate(serviceId, rowId, "", 0);
+          appendToLog(serviceId, rowId, getStopEvent(buttonId));
+        }
+        updateHeaderButtons(serviceId, rowId, "stopping");
+        progressBarUpdate(serviceId, rowId, "stopping", 100);
+        api.stop_named_server(user, rowId, options);
+      }
+    {# <-- WorkshopManager.button.stop #}
+    {# WorkshopManager.button.cancel --> #}
+      function workshopButtonCancel(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        const options = getAPIOptions();
+        options["success"] = function (data, textStatus, jqXHR) {
+          console.log("Stopped");
+          console.log(serviceId);
+          console.log(rowId);
+          updateHeaderButtons(serviceId, rowId, "stopped");
+          progressBarUpdate(serviceId, rowId, "", 0);
+          appendToLog(serviceId, rowId, getStopEvent(buttonId));
+        }
+        updateHeaderButtons(serviceId, rowId, "cancelling");
+        progressBarUpdate(serviceId, rowId, "cancelling", 99);
+        api.cancel_named_server(user, rowId, options);
+      }
+    {# <-- WorkshopManager.button.cancel #}
+
+    {# WorkshopManager.button.start --> #}
+      function workshopButtonStart(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        homeButtonStart(serviceId, rowId, buttonId, button_options, user, api, base_url, utils);
+      }
+    {# <-- WorkshopManager.button.start #}
+
+    {# WorkshopManager.button.open --> #}
+      async function checkAndOpenUrl(serviceId, rowId, url, retries = 50, delay = 500) {
+        // wait for 3 successful responses
+        let successCounter = 0;
+        for (let attempt = 1; attempt <= retries; attempt++) {
+          try {
+            const response = await fetch(`${url}/api`, {
+              method: 'GET',
+              mode: 'no-cors',
+            });
+            if (response.ok || response.status == 405) {
+              successCounter += 1;
+              if ( successCounter > 8 ) {
+                window.open(url, "_blank");
+                updateHeaderButtons(serviceId, rowId, "running");
+                progressBarUpdate(serviceId, rowId, "running", 100);
+                $(`button[id^='${serviceId}-${rowId}-'][id$='-btn']`).prop("disabled", false);
+                return;
+              }
+            } 
+          } catch (error) {
+            showToast(`Exception while sending request to ${url}.`, type="warning");
+            console.error(`Attempt ${attempt}: Network error or invalid URL -`, error);
+          }
+
+          if (attempt < retries) {
+            // Wait for the specified delay before retrying
+            await new Promise(resolve => setTimeout(resolve, delay));
+          } else {
+            updateHeaderButtons(serviceId, rowId, "running");
+            progressBarUpdate(serviceId, rowId, "running", 100);
+            showToast(`Cannot connect to started Server. Try to open manually. If this does not work try restarting the Server.`);
+            console.error("Maximum retries reached. Unable to access the website.");
+          }
+        }
+      }
+
+      function homeOpen(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        window.open(`/user/{{ user.name}}/${rowId}`, "_blank");
+      }
+
+      function workshopButtonOpen(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        window.open("{{ url }}", "_blank");
+      }
+    {# <-- WorkshopManager.button.open #}
+    
+
+    {# WorkshopManager.button.save --> #}
+      function workshopManagerButtonSave(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+        workshopManagerButtonNewSave(serviceId, rowId, buttonId, button_options, user, api, base_url, utils, false);
+      }
+    {# <-- WorkshopManager.button.save #}
+
+  {# <-- Workshop Manager #}
+
+  {# Workshop --> #}
+    {# Workshop.labconfig.custom.username --> #}
+      function toggleExternalCB(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const labelChecked = val(getLabelCBElement(serviceId, rowId, trigger));
+        const inputDiv = getInputDiv(serviceId, rowId, elementId);
+        const inputElement = getInputElement(serviceId, rowId, elementId);
+        if ( labelChecked ) {
+          inputDiv.show();
+          inputElement.attr("data-collect", true);
+        } else {
+          inputDiv.hide();
+          inputElement.attr("data-collect", false);
+        }
+      }
+    {# <-- Workshop.labconfig.custom.username #}
+
+    {# Workshop.labconfig.unicore.account --> #}
+      function workshopUpdateAccount(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        const values = getAccountOptions(serviceId, rowId);
+        const inputElement = getInputElement(serviceId, rowId, "account");
+        fillSelect(elementId, inputElement, values);
+        // inputElement.trigger("change");
+      }
+    {# Workshop.labconfig.unicore.account --> #}
+
+    {# Workshop.modules --> #}
+      function getModuleValues(serviceId, rowId, name, setName) {
+        const options = val(getInputElement(serviceId, rowId, "option"));
+        let values = [];
+        let keys = new Set();
+        options.forEach(option => {
+          if (getServiceConfig(serviceId)?.options?.[option]?.[setName]) {
+            const nameSet = getServiceConfig(serviceId)?.options[option]?.[setName];
+            Object.entries(userModulesConfig[name])
+              .filter(([key, value]) => value.sets && value.sets.includes(nameSet))
+              .forEach( ([key, value]) => {
+                if ( !keys.has(key) ) {
+                  keys.add(key);
+                  values.push([
+                    key,
+                    value.displayName,
+                    typeof value.default === 'object' && value.default !== null ? value.default.default : value.default,
+                    value.href
+                  ]);
+                }
+              });
+          }
+        });
+        return values;
+      }
+
+      function updateMultipleCheckboxes(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+        $(`input[id^='${serviceId}-${rowId}-${tabId}-'][id$='-select-all']`).prop("checked", false);
+        $(`input[id^='${serviceId}-${rowId}-${tabId}-'][id$='-select-none']`).prop("checked", false);
+
+        const containerDiv = $(`div[id^='${serviceId}-${rowId}-'][id$='${elementId}-checkboxes-div']`);
+        const inputDiv = $(`div[id^='${serviceId}-${rowId}-'][id$='${elementId}-input-div']`);
+        const values = getModuleValues(serviceId, rowId, elementId, elementOptions.options.setName);
+        
+        let workshopPreset = false;
+        let workshopPresetChecked = [];
+        const group = elementOptions.options.group || tabId;
+        const name = elementOptions.options.name || elementId;
+        {%- if pagetype == vars.pagetype_workshop and db_workshops %}
+          const workshops = {{ db_workshops | tojson }} || {};
+          const workshopValues = workshops?.[rowId]?.user_options;
+          if ( Object.keys(workshopValues).includes(group) && Object.keys(workshopValues[group]).includes(name) ){
+            workshopPreset = true;
+            const modules = workshopValues[group][name];
+            if ( modules.length > 0 ) {
+              workshopPresetChecked = modules;
+            }
+          }
+        {%- endif %}
+        // Ensure the container exists
+        if (containerDiv.length > 0 && values.length > 0) {
+          const idPrefix = containerDiv.attr('id').replace(/-checkboxes-div$/, "");
+          containerDiv.html('');
+          values.forEach(function (item) {
+            let isChecked = '';
+            let isDisabled = '';
+            if ( workshopPreset ) {
+              if ( workshopPresetChecked.includes(item[0]) ){
+                isChecked = 'checked';
+              }
+              isDisabled = 'disabled="true"';
+            } else {
+              isChecked = item[2] ? 'checked' : '';
+            }
+            let dependencies = '';
+            if ( elementOptions.dependency ){
+              for (const [specificKey, specificValues] of Object.entries(elementOptions.dependency)) {
+                dependencies += ` data-dependency-${specificKey}="true"`;
+                specificValues.forEach(specificValue => {
+                  dependencies += ` data-dependency-${specificKey}-${specificValue}="true"`;
+                });
+              }
+            }
+            
+            // Create the new div block
+            const newDiv = $(`
+              <div id="${idPrefix}-${item[0]}-input-div" class="form-check col-sm-6 col-md-4 col-lg-3">
+                <input type="checkbox" name="${item[0]}" data-collect="true" ${dependencies}                
+                  data-checked="${isChecked}" data-group="${group}" data-element="${item[0]}" data-type="checkbox" data-row="${rowId}" data-tab="${tabId}" class="form-check-input" id="${idPrefix}-${item[0]}-input" value="${item[0]}" ${isChecked} ${isDisabled}/>
+                <label class="form-check-label" for="${idPrefix}-${item[0]}-input">
+                  <span class="align-middle">${item[1]}</span>
+                  <a href="${item[3]}" target="_blank" class="module-info text-muted ms-3">
+                    <span>{{ svg.info_svg | safe }}</span>
+                    <div class="module-info-link-div d-inline-block">
+                      <span class="module-info-link" id="nbdev-info-link"> {{ svg.link_svg | safe }}</span>
+                    </div>
+                  </a>
+                </label>
+              </div>
+            `);
+            // Append the new div to the container
+            containerDiv.append(newDiv);
+            // Add toggle function to each checkbox
+            $(`#${idPrefix}-${item[0]}-input`).on("click", function (event) {
+              $(`input[id^='${serviceId}-${rowId}-'][id$='-select-all']`).prop("checked", false);
+              $(`input[id^='${serviceId}-${rowId}-'][id$='-select-none']`).prop("checked", false);
+            });
+          });
+        }
+        inputDiv.show();
+      }
+    {# <-- Workshop.modules #}
+    {# Workshop.navbar.resources --> #}
+      function resourceButton(trigger, serviceId, rowId) {
+        const systems = getUnicoreValues(serviceId, rowId, "system");
+        const partitions = getUnicoreValues(serviceId, rowId, "partition");
+        let showResources = false;      
+        systems.forEach( (system) => {
+          if ( !showResources ) {
+            partitions.forEach( (partition) => {
+              if ( !showResources && (Object.keys(resourcesConfig[system])).includes(partition) ) {
+                if ( !(systemConfig[system]?.interactivePartitions || []).includes(partition) ) {
+                  showResources = true;
+                }
+              }
+            });
+          }
+        });
+        if ( showResources ) {
+          $(`button[id^="${serviceId}-${rowId}-${trigger}-navbar-button"]`).trigger("show");
+        } else {
+          $(`button[id^="${serviceId}-${rowId}-${trigger}-navbar-button"]`).trigger("hide");
+        }
+      }
+    {# <-- Workshop.navbar.resources #}
+
+    {# Workshop.labconfig.name --> #}
+      {%- if pagetype == vars.pagetype_workshop %}
+        function workshopLabName(trigger, serviceId, rowId, tabId, elementId, elementOptions) {
+          const inputName = getInputElement(serviceId, rowId, elementId);
+          const user_options = {{ spawner.user_options | tojson }} || {};
+          const displayName = user_options.name || "Workshop {{ workshop_id }}";
+          inputName.val(displayName);
+        }
+      {%- endif %}
+    {# <-- Workshop.labconfig.name #}
+
+    {# Workshop.logs.logcontainer --> #}
+
+      function fillLogContainer(serviceId, rowId, events) {
+        clearLogs(serviceId, rowId);
+        events.forEach(event => {
+          appendToLog(serviceId, rowId, event);
+        })
+      }
+
+      function clearLogs(serviceId, rowId) {
+        const logInputElement = $(`[id^='${serviceId}-${rowId}-logs'][id$='-logcontainer-input']`);
+        logInputElement.html("");
+      }
+
+      function defaultLogs(serviceId, rowId) {
+        const logInputElement = $(`[id^='${serviceId}-${rowId}-logs'][id$='-logcontainer-input']`);
+        logInputElement.html("Logs collected during the Start process will be shown here.");
+      }
+    
+      function appendToLog(serviceId, rowId, event) {    
+        const logInputElement = $(`[id^='${serviceId}-${rowId}-logs'][id$='-logcontainer-input']`);
+        let htmlMsg = "";
+        if (event.html_message !== undefined) {
+          htmlMsg = event.html_message
+        } else if (event.message !== undefined) {
+          htmlMsg = event.message;
+        }
+        if ( !htmlMsg && event.failed ) {
+          htmlMsg = "Server stopped";
+        }
+        if ( htmlMsg ) {
+          try { 
+            htmlMsg = htmlMsg.replace(/&nbsp;/g, ' ');
+          } catch (e) { 
+            console.log("Could not append Log Message");
+            console.log(e);
+            return;
+          }
+          let exists = false;
+          const childCount = logInputElement.children().length;
+          logInputElement.children().each(function (i, e) {
+            let logMsg = $(e).html();
+            if (htmlMsg == logMsg) exists = true;
+          })
+          if (!exists)
+            logInputElement.append($(`<div id="${serviceId}-${rowId}-logs-logcontainer-element${childCount}" class="log-div">`).html(htmlMsg));
+            let element = $(`#${serviceId}-${rowId}-logs-logcontainer-element${childCount}`);
+            
+            if ( event.progress === 100 && element.find("details") ) {
+              element.find("details").attr("open", true);
+            }
+
+        }
+      }
+    {# <-- Workshop.logs.logcontainer #}
+
+    {# Workshop.header.progressBar --> #}
+      function progressBarUpdate(serviceId, rowId, status, progress) {
+        const progressBarElement = $(`#${serviceId}-${rowId}-progress-bar`);
+        const progressTextElement = $(`#${serviceId}-${rowId}-progress-text`);
+        const progressTextInfoElement = $(`#${serviceId}-${rowId}-progress-info-text`);
+        let background = "";
+        let text = "";
+        let color = "black";
+        if ( progress >= 60 ) {
+          color = "white";
+        }
+        if ( status == "connecting" ) {
+          text = "connecting";
+          background = "bg-success";
+        } else if ( status == "running" ) {
+          text = "running";
+          background = "bg-success";
+        } else if ( status == "stopped" ) {
+          text = "stopped";
+          background = "bg-danger";
+        } else if ( status == "cancelling" ) {
+          text = "cancelling";
+          background = "bg-danger";
+        } else if ( status == "stopping" ) {
+          text = "stopping";
+          background = "bg-danger";
+        } else if ( status == "starting" ) {
+          text = "starting";
+        } else if ( progress == 0 ){
+          text = "";
+        }
+        progressBarElement.width(progress).removeClass("bg-success bg-danger bg-primary").addClass(background).html("");
+        progressTextElement.css('color', color);
+        progressTextElement.html(`${progress}%`);
+        progressTextInfoElement.html(text);
+      }
+    {# <-- Workshop.header.progressBar #}
+
+  {# <-- Workshop #}
+
+  {# Home --> #}
+    function _uuidv4hex() {
+      return ([1e7, 1e3, 4e3, 8e3, 1e11].join('')).replace(/[018]/g, c =>
+        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
+    }
+    function _uuidWithLetterStart() {
+      let uuid = _uuidv4hex();
+      let char = Math.random().toString(36).match(/[a-zA-Z]/)[0];
+      return char + uuid.substring(1);
+    }
+
+    function homeButtonNew(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+      const newId = _uuidWithLetterStart();
+      const options = getAPIOptions();      
+
+      const form = $(`form[id^='${serviceId}-${rowId}-form']`);
+      const valid = validateForm(serviceId, rowId);
+      if ( !valid ) {
+        console.log(`Invalid Form for ${serviceId}-${rowId}`);
+        return;
+      }
+
+      let userOptions = collectSelectedOptions(serviceId, rowId);
+      options["data"] = JSON.stringify(userOptions);
+
+      options["success"] = function (data, textStatus, jqXHR) {
+        updateHeaderButtons(serviceId, rowId, "starting");
+        
+        const url = new URL(window.location.href);
+        url.searchParams.set('service', serviceId);
+        url.searchParams.set('row', newId);
+        url.searchParams.set('showlogs', true);
+        window.location.href = url.toString();
+      }
+      api.start_named_server(user, newId, options);
+    }
+
+    function homeButtonStart(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+      const options = getAPIOptions();
+
+      const form = $(`form[id^='${serviceId}-${rowId}-form']`);
+      const valid = validateForm(serviceId, rowId);
+      if ( !valid ) {
+        console.log(`Invalid Form for ${serviceId}-${rowId}`);
+        return;
+      }
+
+      let userOptions = collectSelectedOptions(serviceId, rowId);
+      options["data"] = JSON.stringify(userOptions);
+      // Ensure SSE is connected to receive all status updates
+      // sseInit();
+      clearLogs(serviceId, rowId);
+
+      options["success"] = function (data, textStatus, jqXHR) {
+        updateHeaderButtons(serviceId, rowId, "starting");        
+      }
+      api.start_named_server(user, rowId, options);
+            
+      const toView = document.getElementById(`${serviceId}-${rowId}-summary-tr`)
+      if ( toView ) toView.scrollIntoView();
+
+      // show summary-tr
+      const summaryTr = $(`tr[id^='${serviceId}-${rowId}-summary-tr']`);
+      const accordionIcon = summaryTr.find(".accordion-icon");
+      const collapse = $(`.collapse[id^='${serviceId}-${rowId}-collapse']`);
+      const shown = collapse.hasClass("show");
+      if ( ! shown ) {
+        accordionIcon.removeClass("collapsed");
+        new bootstrap.Collapse(collapse);
+      }
+
+      const navbarLogsButton = $(`[id^='${serviceId}-${rowId}-'][id$='-logs-navbar-button']`);
+      if ( navbarLogsButton ) {
+        navbarLogsButton.trigger("click");
+      }
+    }
+
+    function homeButtonDelete(serviceId, rowId, buttonId, button_options, user, api, base_url, utils) {
+      updateHeaderButtons(serviceId, rowId, "disable");
+      const options = getAPIOptions();
+      options["success"] = function () {
+        $(`tr[data-server-id='${serviceId}-${rowId}']`).each(function () {
+          $(this).remove();
+        });
+        console.log(`Delete of ${serviceId}-${rowId} successful`);
+      }
+      api.delete_named_server(user, rowId, options);
+    }
+  {# <-- Home #}
+
+</script>
diff --git a/templates/macros/table/variables.jinja b/templates/macros/table/variables.jinja
new file mode 100644
index 0000000..fc476df
--- /dev/null
+++ b/templates/macros/table/variables.jinja
@@ -0,0 +1,5 @@
+{%- set first_row_id = "__new__" %}
+{%- set pagetype_workshop = "workshop" %}
+{%- set pagetype_workshopmanager = "workshopmanager" %}
+{%- set pagetype_home = "home" %}
+{%- set pagetype_share = "share" %}
\ No newline at end of file
diff --git a/templates/page.html b/templates/page.html
index 93eb3a0..6a3a412 100644
--- a/templates/page.html
+++ b/templates/page.html
@@ -36,7 +36,36 @@
   {% block scripts -%}
   {%- endblock %}
   <script>
-    var evtSourcesGlobal = {};
+    var evtSource = undefined;
+    var testCounter = 0;
+
+    function sseInit() {
+      let sseUrl = `${jhdata.base_url}api/sse`
+      if ( jhdata.user ) {
+          sseUrl = `${jhdata.base_url}api/sse/${jhdata.user}?_xsrf=${window.jhdata.xsrf_token}`;
+      }
+      if ( evtSource ) {
+        evtSource.close();
+      }
+      evtSource = new EventSource(sseUrl);
+      evtSource.onmessage = (e) => {
+        try {
+            const jsonData = JSON.parse(event.data);
+            console.log(jsonData);
+            for (const [key, value] of Object.entries(jsonData)) {
+                console.log(`Trigger ${key}`);
+                $(`[data-sse-${key}]`).trigger("sse", value);
+            }
+        } catch (error) {
+            console.error("Failed to parse SSE data:", error);
+        }
+      };
+      evtSource.onerror = (e) => {
+        console.log("Reconnect EventSource");
+        // Reconnect
+      }
+    }
+
     require.config({
       {%- if version_hash -%}
       urlArgs: "v={{version_hash}}",
@@ -123,11 +152,12 @@
   {% block script -%}
   {%- endblock %}
   <script>
+  $(document).ready(function() {
+    sseInit();
+  });
   window.onbeforeunload = function() {
-    if (typeof evtSourcesGlobal !== 'undefined') {
-        for (const [key, value] of Object.entries(evtSourcesGlobal)) {
-            value.close();
-        }
+    if (typeof evtSource !== 'undefined') {
+        evtSource.close();
     }
   }
   </script>
diff --git a/templates/spawn_pending.html b/templates/spawn_pending.html
index 3d0bb64..7dce663 100644
--- a/templates/spawn_pending.html
+++ b/templates/spawn_pending.html
@@ -1,310 +1,8 @@
 {%- extends "page.html" -%}
-{%- import "macros/svgs.jinja" as svg -%}
 
-{%- block stylesheet -%}
-  <link rel="stylesheet" href='{{ static_url("css/home.css", include_version=True) }}' type="text/css"/>
-  <link rel="stylesheet" href='{{ static_url("css/spawn.css", include_version=True) }}' type="text/css"/>
-{%- endblock -%}
+{%- block meta -%}
+{% set service = spawner.user_options.get("service", "jupyterlab")
+<meta http-equiv="refresh" content="0; url=https://{{hostname}}{{ base_url }}home?service={{ service }}&row={{ spawner.name }}&showlogs" />
+{%- endblock %}
 
-{%- macro create_text_input(label, value) -%}
-{%- if value -%}
-{%- set key = label.lower() %}
-<div id="{{key}}-input-div"  class="row mb-3">
-  <label for="{{ key }}-input" class="col-4 col-form-label">{{ label }}</label>
-  <div class="col-8">
-    <input type="text" class="form-control" id="{{ key }}-input" value="{{value}}" disabled>
-  </div>
-</div>
-{%- endif -%}
-{%- endmacro -%}
-
-{%- macro create_number_input(label, value) -%}
-{%- set key = label.lower() -%}
-<div id="{{key}}-input-div" class="row mb-3"> 
-  <label for="{{key}}-input" class="col-4 col-form-label">{{ label }}</label>
-  <div class="col-8">
-    <input type="number" id="{{key}}-input" class="form-control" value="{{value}}" disabled>
-  </div>
-</div>
-{%- endmacro -%}
-
-{%- macro create_checkbox_input(label, checked) -%}
-{%- set key = label.lower() -%}
-<div id="{{key}}-input-div" class="row mb-3 align-items-center">
-  <label for="{{key}}-input" class="col-4 col-form-label">{{ label }}</label>
-  <div class="col-8">
-    <input type="checkbox" class="form-check-input" id="{{key}}-input" {%- if checked %} checked {%- endif %} disabled>
-  </div>
-</div>
-{%- endmacro -%}
-
-
-{%- set user_options = spawner.user_options -%}
-{%- set name = user_options.get("name") -%}
-{%- if "profile" in user_options -%}
-{%- set service = user_options.get("profile", "JupyterLab/3.6").split('/')[0] -%}
-{%- set option = user_options.get("profile", "JupyterLab/3.6").split('/')[1] -%}
-{%- else -%}
-{%- set service = user_options.get("service", "JupyterLab/3.6").split('/')[0] -%}
-{%- set option = user_options.get("service", "JupyterLab/3.6").split('/')[1] -%}
-{%- endif -%}
-{%- set service_name = custom_config.get("services").get(service).get("options").get(option).get("name") -%}
-{%- set version = user_options.get("options", "JupyterLab") -%}
-{%- set system = user_options.get("system", None) -%}
-{%- set image = user_options.get("image", None) -%}
-{%- set flavor = user_options.get("flavor", None) -%}
-{%- set account = user_options.get("account", None) -%}
-{%- set project = user_options.get("project", None) -%}
-{%- set partition = user_options.get("partition", None) -%}
-{%- set reservation = user_options.get("reservation", None) -%}
-{%- set nodes = user_options.get("nodes", None) -%}
-{%- set runtime = user_options.get("runtime", None) -%}
-{%- set xserver = user_options.get("xserver", None) -%}
-{%- set gpus = user_options.get("gpus", None) -%}
-{%- set userModules = user_options.get("userModules", {}) -%}
-
-{#- Check if we should disable any tabs -#}
-{%- set no_resources = True -%}
-{%- if nodes != None or gpus != None or runtime != None or xserver != None -%}
-  {%- set no_resources = False -%}
-{%- endif -%}
-
-
-{%- block main -%}
-<div class="container-fluid p-4">
-  <h1>Your server is starting up...</h1>
-  <p>You will be redirected automatically when it's ready for you.</p>
-
-  <div class="accordion" id="labInfoAccordion">
-    <div class="accordion-item" style="border-bottom-right-radius: .25rem;border-bottom-left-radius: .25rem;">
-      <h2 class="accordion-header" id="labInfo">
-        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#labInfoCollapse">
-          Lab Info (click to expand)
-        </button>
-      </h2>
-      <div id="labInfoCollapse" class="accordion-collapse collapse" data-bs-parent="#labInfoAccordion">
-        <div class="accordion-body text-black">
-          <div class="d-flex align-items-start m-3">
-            {#- TAB NAV PILLS -#}
-            {%- set nav_tab_margins = "mb-3" %}
-            <div class="nav flex-column nav-pills p-3 ps-0" id="tab" role="tablist">
-              <button class="nav-link active {{ nav_tab_margins }}" id="config-info-tab" data-bs-toggle="pill" data-bs-target="#config-info" type="button" role="tab">Lab Config</button>
-              <button class="nav-link {{ nav_tab_margins }} {%- if no_resources %} disabled {%- endif %}" id="resources-info-tab" data-bs-toggle="pill" data-bs-target="#resources-info" type="button" role="tab" >Resources</button>
-              <button class="nav-link {{ nav_tab_margins }} {%- if not userModules %} disabled {%- endif %}" id="modules-info-tab" data-bs-toggle="pill" data-bs-target="#modules-info" type="button" role="tab" >Kernels and Extensions</span></button>
-            </div>
-            {#- TAB NAV CONTENT -#}
-            <div class="tab-content w-100" id="tabContent">
-              <div class="tab-pane fade show active" id="config-info" role="tabpanel">
-                {{ create_text_input("Name", name) }}
-                {{ create_text_input("Version", service_name) }}
-                {{ create_text_input("Image", image) }}
-                <hr>
-                {{ create_text_input("System", system) }}
-                {{ create_text_input("Flavor", flavor) }}
-                {{ create_text_input("Account", account) }}
-                {{ create_text_input("Project", project) }}
-                {{ create_text_input("Partition", partition) }}
-                {%- if reservation != None %}
-                <hr id="reservation-hr">
-                {{ create_text_input("Reservation", reservation) }}
-                {%- endif %}
-              </div>
-              <div class="tab-pane fade" id="resources-info" role="tabpanel">
-                {%- if not no_resources -%}
-                  {%- if nodes -%} {{ create_number_input("Nodes", nodes) }} {%- endif %}
-                  {%- if gpus -%} {{ create_number_input("GPUs", gpus) }} {%- endif %}
-                  {%- if runtime -%} {{ create_number_input("Runtime", (runtime)|int) }} {%- endif %}
-                  {%- set resources = auth_state.get("options_form", {}).get('resources', {}) -%}
-                  {%- set xserver_options = resources.get(option, {}).get(system, {}).get(partition, {}).get("xserver", {}) -%}
-                  {%- set show_checkbox = xserver_options.get("checkbox", False) -%}
-                  {%- if show_checkbox -%}
-                    {%- set cb_label = xserver_options.get("checkbox_label", "XServer") %}
-                    {{ create_checkbox_input(cb_label, xserver) }}
-                  {%- endif %}
-                  {%- if xserver -%}
-                  {%- set label = xserver_options.get("label", "XServer") %}
-                  {{ create_number_input(label, xserver) }}
-                  {%- endif %}
-                  
-                {%- endif %}
-              </div>
-              <div class="tab-pane fade" id="modules-info" role="tabpanel">
-              {%- if userModules -%}
-                {%- set module_sets = custom_config.get("userModules", {}) %}
-                {%- for set, modules in module_sets.items() -%}
-                  {% set ns = namespace(first = true) -%}
-                  {%- for module, module_info in modules.items() -%}
-                    {%- if ns.first %}
-                    <h4>{{ set | title}}</h4>
-                    <div class="row g-0">
-                    {%- endif %}
-                      <div class="form-check col-sm-6 col-md-4 col-lg-3">
-                        <input type="checkbox" class="form-check-input" id="{{ module }}-check" disabled {%- if module in userModules %} checked {%- endif %}>
-                          <label class="form-check-label" for="{{ module }}-check">
-                            <span class="align-middle">{{ module_info['displayName'] }}</span>
-                            <a href="{{ module_info['href'] }}" target="_blank" class="text-muted">{{ svg.info_svg | safe }}</a>
-                          </label>
-                        </input>
-                      </div>
-                    {%- set ns.first = false -%}
-                  {%- endfor -%}
-                    </div>
-                {%- endfor -%}
-              {%- endif %}
-              </div>
-            </div> {#- tab content #}
-          </div> {#- flex div #}
-        </div> {#- accordion body #}
-      </div> {#- accordion collapse #}
-    </div>  {#- accordion item #}
-  </div>  {#- accordion #}
-
-  <div class="card mt-4">
-    <div class="card-header d-flex">
-      <div class="flex-grow-1">
-        <div class="progress" style="height: 20px;">
-          <div id="progress-bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 100%;"></div>
-        </div>
-        <div id="progress-info-text" class="text-center text-muted my-auto w-100" style="font-size: smaller;">spawning...</div>
-      </div>
-      <button id="cancel" type="button" class="btn btn-danger ms-4" disabled>{{ svg.stop_svg | safe }} Cancel </button>
-      <button id="retry" type="button" class="btn btn-primary ms-4" style="display: none;" disabled>{{ svg.retry_svg | safe }} Retry </button>
-    </div>
-    <div class="card-body text-black">
-      <div id="log"></div>
-    </div>
-  </div>
-
-</div>
-{%- endblock -%}
-
-{%- block script -%}
-{%- set cancel_progress_refresh_rate = 1000 -%}
-{%- set cancel_progress_activation = 0 -%}
-{%- set cancel_progress_deactivation = 99 -%}
-
-<script>
-require(["jquery", "jhapi", "home/utils"], function (
-  $,
-  JHAPI,
-  utils
-) {
-  var base_url = window.jhdata.base_url;
-  var user = window.jhdata.user;
-  var api = new JHAPI(base_url);
-  var timeout;
-
-  // Cancel server spawn on click
-  $("#cancel").click(function (event) {
-    $("#cancel").attr("disabled", true);
-    api.cancel_named_server(user, "{{spawner.name}}");
-    clearTimeout(timeout);
-  });
-
-  // Retry server spawn on click
-  $("#retry").click(function (event) {
-    $("#retry").attr("disabled", true);
-
-    api.start_named_server(user, "{{spawner.name}}", {
-      data: JSON.stringify({{spawner.user_options | safe}}),
-      success: function () {
-        $("#retry").hide();
-        $("#cancel").attr("disabled", true).show();
-        $("#progress-bar").removeClass("bg-danger");
-        $("#progress-info-text").html("spawning...");
-        $("#log").html("");
-        updateStatus();
-      },
-      error: function (xhr, textStatus, errorThrown) {
-        $("#progress-bar").addClass("bg-danger");
-        $("#progress-info-text").html("last spawn failed");
-        let details = $("<details>")
-          .append($("<summary>").html(`Could not request spawn. Error: ${xhr.status} ${errorThrown}`))
-          .append($("<pre>").html(JSON.stringify(JSON.parse(xhr.responseText), null, 2)));
-        let div = $("<div>").addClass("log-div").html(details);
-        $("#log").html("").append(div);
-        $("#retry").removeAttr("disabled");
-      }
-    })
-  });
-
-  function updateStatus() {
-    let id = "{{ spawner.name }}";
-    let progressUrl = `${window.jhdata.base_url}api/users/${window.jhdata.user}/servers/${id}/progress?_xsrf=${window.jhdata.xsrf_token}`;
-    let evtSource = new EventSource(progressUrl);
-    evtSource.onmessage = (e) => {
-      const evt = JSON.parse(e.data);
-      if (evt.progress !== undefined && evt.progress != 0) {
-        if (evt.progress == 100) {
-          evtSource.close();
-          delete evtSource;
-          
-          if (evt.failed) {
-            // Update UI via spawnStatusChangedEvtSource so that 
-            // it happens after the stop has finished in the backend
-            clearTimeout(timeout);
-          }
-          else {
-            $(`#progress-bar`).removeClass("bg-danger").addClass("bg-success");
-            $("#progress-info-text").html("redirecting...");
-            window.location.reload();
-          }
-        }
-        else {
-          $("#progress-bar").html('<b>' + evt.progress + '%</b>');
-          if (evt.progress >= {{ cancel_progress_activation }}) {
-            $("#cancel").removeAttr("disabled");
-          }
-          if (evt.progress == {{ cancel_progress_deactivation }}) {
-            $("#cancel").attr("disabled", true);
-            $(`#progress-bar`).addClass("bg-danger");
-            $("#progress-info-text").html("cancelling...");
-          }
-          if (evt.progress == 95) {
-            // Refresh if stuck on 95%
-            timeout = setTimeout(() => window.location.reload(), 120000);
-          }
-        }
-      }
-
-      if (evt.html_message !== undefined) {
-        var htmlMsg = evt.html_message
-      } else if (evt.message !== undefined) {
-        var htmlMsg = evt.message;
-      }
-      if (htmlMsg) {
-        try { htmlMsg = htmlMsg.replace(/&nbsp;/g, ' '); }
-        catch (e) { return; }
-        // Only append if a log message has not been appended yet
-        var exists = false;
-        $("#log").children().each(function (i, e) {
-          let logMsg = $(e).html();
-          if (htmlMsg == logMsg) exists = true;
-        })
-        if (!exists)
-          $("#log").append($('<div class="log-div">').html(htmlMsg));
-        }
-    }
-  }
-
-  $( document ).ready(function() {
-    updateStatus();
-    
-    let userSpawnerNotificationUrl = `${jhdata.base_url}api/users/${jhdata.user}/notifications/spawners?_xsrf=${window.jhdata.xsrf_token}`;
-    evtSourcesGlobal["pending"] = new EventSource(userSpawnerNotificationUrl);
-    evtSourcesGlobal["pending"].onmessage = (e) => {
-      const data = JSON.parse(e.data);
-      utils.updateNumberOfUsers();
-      for (const id of data.stopped || []) {
-        if (id == "{{spawner.name}}") {
-          $(`#progress-bar`).html("").addClass("bg-danger");
-          $("#progress-info-text").html("last spawn failed");
-          $("#retry").removeAttr("disabled").show();
-          $("#cancel").hide();
-        }
-      }
-    }
-  });
-});
-</script>
-{%- endblock -%}
+{%- block title -%}Jupyter-JSC redirect{%- endblock %}
diff --git a/templates/spawn_pending_prev.html b/templates/spawn_pending_prev.html
new file mode 100644
index 0000000..3d0bb64
--- /dev/null
+++ b/templates/spawn_pending_prev.html
@@ -0,0 +1,310 @@
+{%- extends "page.html" -%}
+{%- import "macros/svgs.jinja" as svg -%}
+
+{%- block stylesheet -%}
+  <link rel="stylesheet" href='{{ static_url("css/home.css", include_version=True) }}' type="text/css"/>
+  <link rel="stylesheet" href='{{ static_url("css/spawn.css", include_version=True) }}' type="text/css"/>
+{%- endblock -%}
+
+{%- macro create_text_input(label, value) -%}
+{%- if value -%}
+{%- set key = label.lower() %}
+<div id="{{key}}-input-div"  class="row mb-3">
+  <label for="{{ key }}-input" class="col-4 col-form-label">{{ label }}</label>
+  <div class="col-8">
+    <input type="text" class="form-control" id="{{ key }}-input" value="{{value}}" disabled>
+  </div>
+</div>
+{%- endif -%}
+{%- endmacro -%}
+
+{%- macro create_number_input(label, value) -%}
+{%- set key = label.lower() -%}
+<div id="{{key}}-input-div" class="row mb-3"> 
+  <label for="{{key}}-input" class="col-4 col-form-label">{{ label }}</label>
+  <div class="col-8">
+    <input type="number" id="{{key}}-input" class="form-control" value="{{value}}" disabled>
+  </div>
+</div>
+{%- endmacro -%}
+
+{%- macro create_checkbox_input(label, checked) -%}
+{%- set key = label.lower() -%}
+<div id="{{key}}-input-div" class="row mb-3 align-items-center">
+  <label for="{{key}}-input" class="col-4 col-form-label">{{ label }}</label>
+  <div class="col-8">
+    <input type="checkbox" class="form-check-input" id="{{key}}-input" {%- if checked %} checked {%- endif %} disabled>
+  </div>
+</div>
+{%- endmacro -%}
+
+
+{%- set user_options = spawner.user_options -%}
+{%- set name = user_options.get("name") -%}
+{%- if "profile" in user_options -%}
+{%- set service = user_options.get("profile", "JupyterLab/3.6").split('/')[0] -%}
+{%- set option = user_options.get("profile", "JupyterLab/3.6").split('/')[1] -%}
+{%- else -%}
+{%- set service = user_options.get("service", "JupyterLab/3.6").split('/')[0] -%}
+{%- set option = user_options.get("service", "JupyterLab/3.6").split('/')[1] -%}
+{%- endif -%}
+{%- set service_name = custom_config.get("services").get(service).get("options").get(option).get("name") -%}
+{%- set version = user_options.get("options", "JupyterLab") -%}
+{%- set system = user_options.get("system", None) -%}
+{%- set image = user_options.get("image", None) -%}
+{%- set flavor = user_options.get("flavor", None) -%}
+{%- set account = user_options.get("account", None) -%}
+{%- set project = user_options.get("project", None) -%}
+{%- set partition = user_options.get("partition", None) -%}
+{%- set reservation = user_options.get("reservation", None) -%}
+{%- set nodes = user_options.get("nodes", None) -%}
+{%- set runtime = user_options.get("runtime", None) -%}
+{%- set xserver = user_options.get("xserver", None) -%}
+{%- set gpus = user_options.get("gpus", None) -%}
+{%- set userModules = user_options.get("userModules", {}) -%}
+
+{#- Check if we should disable any tabs -#}
+{%- set no_resources = True -%}
+{%- if nodes != None or gpus != None or runtime != None or xserver != None -%}
+  {%- set no_resources = False -%}
+{%- endif -%}
+
+
+{%- block main -%}
+<div class="container-fluid p-4">
+  <h1>Your server is starting up...</h1>
+  <p>You will be redirected automatically when it's ready for you.</p>
+
+  <div class="accordion" id="labInfoAccordion">
+    <div class="accordion-item" style="border-bottom-right-radius: .25rem;border-bottom-left-radius: .25rem;">
+      <h2 class="accordion-header" id="labInfo">
+        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#labInfoCollapse">
+          Lab Info (click to expand)
+        </button>
+      </h2>
+      <div id="labInfoCollapse" class="accordion-collapse collapse" data-bs-parent="#labInfoAccordion">
+        <div class="accordion-body text-black">
+          <div class="d-flex align-items-start m-3">
+            {#- TAB NAV PILLS -#}
+            {%- set nav_tab_margins = "mb-3" %}
+            <div class="nav flex-column nav-pills p-3 ps-0" id="tab" role="tablist">
+              <button class="nav-link active {{ nav_tab_margins }}" id="config-info-tab" data-bs-toggle="pill" data-bs-target="#config-info" type="button" role="tab">Lab Config</button>
+              <button class="nav-link {{ nav_tab_margins }} {%- if no_resources %} disabled {%- endif %}" id="resources-info-tab" data-bs-toggle="pill" data-bs-target="#resources-info" type="button" role="tab" >Resources</button>
+              <button class="nav-link {{ nav_tab_margins }} {%- if not userModules %} disabled {%- endif %}" id="modules-info-tab" data-bs-toggle="pill" data-bs-target="#modules-info" type="button" role="tab" >Kernels and Extensions</span></button>
+            </div>
+            {#- TAB NAV CONTENT -#}
+            <div class="tab-content w-100" id="tabContent">
+              <div class="tab-pane fade show active" id="config-info" role="tabpanel">
+                {{ create_text_input("Name", name) }}
+                {{ create_text_input("Version", service_name) }}
+                {{ create_text_input("Image", image) }}
+                <hr>
+                {{ create_text_input("System", system) }}
+                {{ create_text_input("Flavor", flavor) }}
+                {{ create_text_input("Account", account) }}
+                {{ create_text_input("Project", project) }}
+                {{ create_text_input("Partition", partition) }}
+                {%- if reservation != None %}
+                <hr id="reservation-hr">
+                {{ create_text_input("Reservation", reservation) }}
+                {%- endif %}
+              </div>
+              <div class="tab-pane fade" id="resources-info" role="tabpanel">
+                {%- if not no_resources -%}
+                  {%- if nodes -%} {{ create_number_input("Nodes", nodes) }} {%- endif %}
+                  {%- if gpus -%} {{ create_number_input("GPUs", gpus) }} {%- endif %}
+                  {%- if runtime -%} {{ create_number_input("Runtime", (runtime)|int) }} {%- endif %}
+                  {%- set resources = auth_state.get("options_form", {}).get('resources', {}) -%}
+                  {%- set xserver_options = resources.get(option, {}).get(system, {}).get(partition, {}).get("xserver", {}) -%}
+                  {%- set show_checkbox = xserver_options.get("checkbox", False) -%}
+                  {%- if show_checkbox -%}
+                    {%- set cb_label = xserver_options.get("checkbox_label", "XServer") %}
+                    {{ create_checkbox_input(cb_label, xserver) }}
+                  {%- endif %}
+                  {%- if xserver -%}
+                  {%- set label = xserver_options.get("label", "XServer") %}
+                  {{ create_number_input(label, xserver) }}
+                  {%- endif %}
+                  
+                {%- endif %}
+              </div>
+              <div class="tab-pane fade" id="modules-info" role="tabpanel">
+              {%- if userModules -%}
+                {%- set module_sets = custom_config.get("userModules", {}) %}
+                {%- for set, modules in module_sets.items() -%}
+                  {% set ns = namespace(first = true) -%}
+                  {%- for module, module_info in modules.items() -%}
+                    {%- if ns.first %}
+                    <h4>{{ set | title}}</h4>
+                    <div class="row g-0">
+                    {%- endif %}
+                      <div class="form-check col-sm-6 col-md-4 col-lg-3">
+                        <input type="checkbox" class="form-check-input" id="{{ module }}-check" disabled {%- if module in userModules %} checked {%- endif %}>
+                          <label class="form-check-label" for="{{ module }}-check">
+                            <span class="align-middle">{{ module_info['displayName'] }}</span>
+                            <a href="{{ module_info['href'] }}" target="_blank" class="text-muted">{{ svg.info_svg | safe }}</a>
+                          </label>
+                        </input>
+                      </div>
+                    {%- set ns.first = false -%}
+                  {%- endfor -%}
+                    </div>
+                {%- endfor -%}
+              {%- endif %}
+              </div>
+            </div> {#- tab content #}
+          </div> {#- flex div #}
+        </div> {#- accordion body #}
+      </div> {#- accordion collapse #}
+    </div>  {#- accordion item #}
+  </div>  {#- accordion #}
+
+  <div class="card mt-4">
+    <div class="card-header d-flex">
+      <div class="flex-grow-1">
+        <div class="progress" style="height: 20px;">
+          <div id="progress-bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 100%;"></div>
+        </div>
+        <div id="progress-info-text" class="text-center text-muted my-auto w-100" style="font-size: smaller;">spawning...</div>
+      </div>
+      <button id="cancel" type="button" class="btn btn-danger ms-4" disabled>{{ svg.stop_svg | safe }} Cancel </button>
+      <button id="retry" type="button" class="btn btn-primary ms-4" style="display: none;" disabled>{{ svg.retry_svg | safe }} Retry </button>
+    </div>
+    <div class="card-body text-black">
+      <div id="log"></div>
+    </div>
+  </div>
+
+</div>
+{%- endblock -%}
+
+{%- block script -%}
+{%- set cancel_progress_refresh_rate = 1000 -%}
+{%- set cancel_progress_activation = 0 -%}
+{%- set cancel_progress_deactivation = 99 -%}
+
+<script>
+require(["jquery", "jhapi", "home/utils"], function (
+  $,
+  JHAPI,
+  utils
+) {
+  var base_url = window.jhdata.base_url;
+  var user = window.jhdata.user;
+  var api = new JHAPI(base_url);
+  var timeout;
+
+  // Cancel server spawn on click
+  $("#cancel").click(function (event) {
+    $("#cancel").attr("disabled", true);
+    api.cancel_named_server(user, "{{spawner.name}}");
+    clearTimeout(timeout);
+  });
+
+  // Retry server spawn on click
+  $("#retry").click(function (event) {
+    $("#retry").attr("disabled", true);
+
+    api.start_named_server(user, "{{spawner.name}}", {
+      data: JSON.stringify({{spawner.user_options | safe}}),
+      success: function () {
+        $("#retry").hide();
+        $("#cancel").attr("disabled", true).show();
+        $("#progress-bar").removeClass("bg-danger");
+        $("#progress-info-text").html("spawning...");
+        $("#log").html("");
+        updateStatus();
+      },
+      error: function (xhr, textStatus, errorThrown) {
+        $("#progress-bar").addClass("bg-danger");
+        $("#progress-info-text").html("last spawn failed");
+        let details = $("<details>")
+          .append($("<summary>").html(`Could not request spawn. Error: ${xhr.status} ${errorThrown}`))
+          .append($("<pre>").html(JSON.stringify(JSON.parse(xhr.responseText), null, 2)));
+        let div = $("<div>").addClass("log-div").html(details);
+        $("#log").html("").append(div);
+        $("#retry").removeAttr("disabled");
+      }
+    })
+  });
+
+  function updateStatus() {
+    let id = "{{ spawner.name }}";
+    let progressUrl = `${window.jhdata.base_url}api/users/${window.jhdata.user}/servers/${id}/progress?_xsrf=${window.jhdata.xsrf_token}`;
+    let evtSource = new EventSource(progressUrl);
+    evtSource.onmessage = (e) => {
+      const evt = JSON.parse(e.data);
+      if (evt.progress !== undefined && evt.progress != 0) {
+        if (evt.progress == 100) {
+          evtSource.close();
+          delete evtSource;
+          
+          if (evt.failed) {
+            // Update UI via spawnStatusChangedEvtSource so that 
+            // it happens after the stop has finished in the backend
+            clearTimeout(timeout);
+          }
+          else {
+            $(`#progress-bar`).removeClass("bg-danger").addClass("bg-success");
+            $("#progress-info-text").html("redirecting...");
+            window.location.reload();
+          }
+        }
+        else {
+          $("#progress-bar").html('<b>' + evt.progress + '%</b>');
+          if (evt.progress >= {{ cancel_progress_activation }}) {
+            $("#cancel").removeAttr("disabled");
+          }
+          if (evt.progress == {{ cancel_progress_deactivation }}) {
+            $("#cancel").attr("disabled", true);
+            $(`#progress-bar`).addClass("bg-danger");
+            $("#progress-info-text").html("cancelling...");
+          }
+          if (evt.progress == 95) {
+            // Refresh if stuck on 95%
+            timeout = setTimeout(() => window.location.reload(), 120000);
+          }
+        }
+      }
+
+      if (evt.html_message !== undefined) {
+        var htmlMsg = evt.html_message
+      } else if (evt.message !== undefined) {
+        var htmlMsg = evt.message;
+      }
+      if (htmlMsg) {
+        try { htmlMsg = htmlMsg.replace(/&nbsp;/g, ' '); }
+        catch (e) { return; }
+        // Only append if a log message has not been appended yet
+        var exists = false;
+        $("#log").children().each(function (i, e) {
+          let logMsg = $(e).html();
+          if (htmlMsg == logMsg) exists = true;
+        })
+        if (!exists)
+          $("#log").append($('<div class="log-div">').html(htmlMsg));
+        }
+    }
+  }
+
+  $( document ).ready(function() {
+    updateStatus();
+    
+    let userSpawnerNotificationUrl = `${jhdata.base_url}api/users/${jhdata.user}/notifications/spawners?_xsrf=${window.jhdata.xsrf_token}`;
+    evtSourcesGlobal["pending"] = new EventSource(userSpawnerNotificationUrl);
+    evtSourcesGlobal["pending"].onmessage = (e) => {
+      const data = JSON.parse(e.data);
+      utils.updateNumberOfUsers();
+      for (const id of data.stopped || []) {
+        if (id == "{{spawner.name}}") {
+          $(`#progress-bar`).html("").addClass("bg-danger");
+          $("#progress-info-text").html("last spawn failed");
+          $("#retry").removeAttr("disabled").show();
+          $("#cancel").hide();
+        }
+      }
+    }
+  });
+});
+</script>
+{%- endblock -%}
diff --git a/templates/token.html b/templates/token.html
index 736ab47..fcf01d1 100644
--- a/templates/token.html
+++ b/templates/token.html
@@ -1,3 +1,4 @@
+
 {%- extends "page.html" -%}
 
 
diff --git a/templates/workshop.html b/templates/workshop.html
new file mode 100644
index 0000000..7ca70f1
--- /dev/null
+++ b/templates/workshop.html
@@ -0,0 +1,44 @@
+{%- extends "page.html" -%}
+
+{%- block stylesheet -%}
+  <link rel="stylesheet" href='{{static_url("css/home.css")}}' type="text/css"/>
+{%- endblock -%}
+
+{%- block main -%}
+{%- import "macros/table/config/workshop.jinja" as config %}
+{%- import "macros/svgs.jinja" as svg -%}
+{%- import "macros/table/variables.jinja" as vars with context %}
+
+{%- set pagetype = vars.pagetype_workshop %}
+
+{%- set table_rows = db_workshops %}
+
+{%- from "macros/table/table.jinja" import tables with context %}
+{%- import "macros/table/content.jinja" as functions with context %}
+
+<div id="workshopnotusable"></div>
+{{ tables(
+  config.frontend_config,
+  functions.workshop_description,
+  functions.workshop_headerlayout,
+  false,
+  functions.workshop_firstheader,
+  functions.row_content,
+  {
+    "stop": "workshopButtonStop",
+    "start": "workshopButtonStart",
+    "open": "workshopButtonOpen",
+    "cancel": "workshopButtonCancel"
+  },
+  functions.sse_functions
+) }}
+
+{%- endblock -%}
+
+
+{%- block script -%}
+{%- import "macros/table/variables.jinja" as vars with context %}
+{%- set pagetype = vars.pagetype_workshop %}
+{%- import "macros/table/config/workshop.jinja" as config with context %}
+{%- include "macros/table/elements_js.jinja" with context %}
+{%- endblock %}
diff --git a/templates/workshop_list.html b/templates/workshop_list.html
new file mode 100644
index 0000000..a6946a9
--- /dev/null
+++ b/templates/workshop_list.html
@@ -0,0 +1,239 @@
+{%- extends "home.html" -%}
+{%- import "macros/home.jinja" as home -%}
+{%- import "macros/svgs.jinja" as svg -%}
+
+
+{% block main %}
+
+{%- macro _create_button(workshop_id, key, btn_class, btn_svg, btn_text, type, align_right=false) %}
+  <button type="button" id="{{ workshop_id }}-{{ key }}-workshop-btn" class="btn btn-{{ key }}-workshop {{ btn_class }} {% if align_right -%} ms-auto {%- else -%} me-2 {%- endif %}">{{ btn_svg }} {{ btn_text }}</button>
+  <script>
+    {#
+    $(document).ready(function() {
+    #}
+      require(["jquery", "jhapi", "utils"], function (
+        $,
+        JHAPI,
+        utils
+      ) {
+        "use strict";
+
+        var base_url = window.jhdata.base_url;
+        var api = new JHAPI(base_url);
+        
+        $("#{{ workshop_id }}-{{ key }}-workshop-btn").click(function() {
+          var options = {
+          }
+          {%- if key == "reset" %}
+            {{ fill_row(workshop_id, db_workshops[workshop_id]) }}
+          {%- elif key == "delete" %}
+            options["type"] = "DELETE";
+            console.log("Delete of {{ workshop_id }} initiated");
+            options["success"] = function () {
+              $("tr[data-server-id={{ workshop_id }}]").each(function () {
+                $(this).remove();
+              });
+              console.log("Delete of {{ workshop_id }} successful");
+            };
+            options["error"] = function (jqXHR, textStatus, errorThrown) {
+
+              console.error("API Request failed:", textStatus, errorThrown);
+            };
+            api.api_request(
+              utils.url_path_join("workshops", "{{ workshop_id }}"),
+              options
+            )
+          {%- elif key in ["create", "save"] %}
+            var form = $("#{{ workshop_id }}-form");
+            var valid = validateFormNow(form);
+            if ( !valid ) {
+              console.error("Form {{ workshop_id }} is not valid");
+              return;
+            }
+
+            options["type"] = "POST";
+            var options_data = {};
+            var keywords = {{ options | tojson }};
+            var value_names;
+            var value_displayname;
+            var select_element;
+            var option_element;
+            Object.entries(keywords.select).forEach(function([key, value]) {
+              if ( $(`#{{ workshop_id }}-${key}-workshop-cb-input`).prop('checked') ) {
+                select_element = $(`#{{ workshop_id }}-${key}-workshop-select`);
+                options_data[key] = {};
+                value_names = select_element.val();
+                if (!Array.isArray(value_names)) {
+                  value_names = [value_names];
+                }
+                value_names.forEach(function(value_name) {
+                  option_element = select_element.find(`option[value="${value_name}"]`);                
+                  value_displayname = option_element.html();
+                  options_data[key][value_name] = value_displayname;
+                });
+              }
+            });
+            keywords.input.forEach(function(key) {              
+              if ( $(`#{{ workshop_id }}-${key}-workshop-cb-input`).prop('checked') ) {
+                options_data[key] = $(`#{{ workshop_id }}-${key}-workshop-input`).val();
+              }
+            });
+            var workshop_id = $("#{{ workshop_id }}-{{ keyname_id }}-workshop-input").val();
+            options_data["{{ keyname_description }}"] = $("#{{ workshop_id }}-{{ keyname_description }}-workshop-input").val();
+            options_data["{{ keyname_show_public }}"] = $("#{{ workshop_id }}-{{ keyname_show_public }}-workshop-cb-input").prop('checked');
+            options_data["{{ keyname_enddate }}"] = $("#{{ workshop_id }}-{{ keyname_enddate }}-workshop-input").val();
+            options["data"] = JSON.stringify(options_data);
+            options["success"] = function () {
+              form.submit();
+              {%- if key == "create" %}
+              {%- endif %}
+            };
+            options["error"] = function (jqXHR, textStatus, errorThrown) {
+              console.error("API Request failed:", textStatus, errorThrown);
+            };
+            api.api_request(
+              utils.url_path_join("workshops", workshop_id),
+              options
+            )
+          {%- endif %}
+        });
+      });
+    {#
+    });
+    #}
+  </script>
+{%- endmacro %}
+
+{%- macro create_buttons(workshop_id, new_workshop_row) %}
+
+  <div class="d-flex">
+    {%- if new_workshop_row %}
+      {{ _create_button(workshop_id, "create", "btn-primary", svg.plus_svg | safe, "Create") }}
+    {%- else %}
+      {{ create_modal(workshop_id) }}
+      {# Create JavaScript function for Share Button to update + show modal for this workshop_id #}
+      <script>
+        require(["jquery", "jhapi", "utils"], function (
+          $,
+          JHAPI,
+          utils
+        ) {
+          "use strict";
+
+          var base_url = window.jhdata.base_url;
+          var api = new JHAPI(base_url);
+          {# Show Modal with workshop URL #}
+          {%- set sanitizedShareId = workshop_id.replace("-", "_") %}
+          function showShareDialogue{{ sanitizedShareId }}() {
+            $("#{{ workshop_id }}-share-workshop-copy-btn").click(function() {
+              const shareUrl = $("#{{ workshop_id }}-share-workshop-link .modal-body a").attr('href');
+              navigator.clipboard.writeText(shareUrl).then(function() {
+                $("#{{ workshop_id }}-share-workshop-copy-btn").tooltip('dispose').attr('title', 'Copied');
+                $("#{{ workshop_id }}-share-workshop-copy-btn").tooltip('show');
+              }, function(err) {
+                console.error('Could not copy text: ', err);
+              });
+            });
+
+            let workshop_url = utils.url_path_join(window.origin, base_url, "workshops", "{{ workshop_id }}").replace("//", "/");
+            $("#{{ workshop_id }}-share-workshop-link .modal-title").text("Share Workshop {{ workshop_id }}");
+            $("#{{ workshop_id }}-share-workshop-link .modal-body a").text(`${workshop_url}`);      
+
+            let shareableURL = new URL(workshop_url);
+            $("#{{ workshop_id }}-share-workshop-link .modal-body a").attr('href', shareableURL);
+            try {
+              shareableURL = new URL(workshop_url);
+              $("#{{ workshop_id }}-share-workshop-link .modal-body a").attr('href', shareableURL);
+            } catch (error) {console.log("no");}
+
+            $("#{{ workshop_id }}-share-workshop-link").modal('show');
+          }
+          $("#{{ workshop_id }}-share-workshop-btn").click(function (event) {
+            showShareDialogue{{ workshop_id }}();
+          });
+        });
+      </script>
+      {# Share Button does not need the script logic from _create_button macro, therefore we create it in here #}
+      <button type="button" id="{{ workshop_id }}-share-workshop-btn" class="btn btn-share-workshop" data-toggle="modal" data-target="#{{ workshop_id }}-share-workshop-link">{{ svg.share_svg | safe }} Share </button>
+
+      
+      {{ _create_button(workshop_id, "save", "btn-success", svg.save_svg | safe, "Save") }}
+      {{ _create_button(workshop_id, "reset", "btn-danger", svg.reset_svg | safe, "Reset") }}
+      {{ _create_button(workshop_id, "delete", "btn-danger", svg.delete_svg | safe, "Delete", align_right=true) }}
+    {%- endif %}
+  </div>
+{%- endmacro %}
+
+
+
+<div class="container-fluid p-4">
+  {#- TABLE #}
+
+  <div class="table-responsive-md">
+    <h2>Workshop Manager</h2>
+    <p>Select the options users might be able to use during your workshop.</p>
+    <p>Use shift or ctrl to select multiple items. <a style="color:#fff" href="https://jupyterjsc.pages.jsc.fz-juelich.de/docs/jupyterjsc/" target="_">Click here for more information.</a></p>
+    
+    <table id="jupyterlabs-table" class="table table-bordered table-striped table-hover table-light align-middle">
+    {#- TABLE HEAD #}
+      <thead class="table-secondary">
+        <tr>
+          <th scope="col" width="1%"></th>
+          <th scope="col" width="20%">Name</th>
+          <th scope="col">Configuration</th>
+          <th scope="col" class="text-center" width="10%">Link</th>
+        </tr>
+      </thead>
+      {#- TABLE BODY #}
+
+
+
+      <tbody>
+        {# - List existing workshops #}
+        {%- for workshop_id, workshop_info in db_workshops.items() %}
+        
+        <!-- summary of row -->
+        <tr data-server-id="{{ workshop_id }}" class="summary-tr">
+          <td class="details-td" data-bs-target="#{{ workshop_id }}-collapse">
+              <div class="d-flex mx-4">
+              </div>
+          </td>
+          
+          <th scope="row" class="name-td">{{ workshop_id }}</th>
+          <th scope="row" class="description-td">{{ workshop_info.user_options.description }}</th>
+          <th scope="row" class="url-td text-center">
+            <button type="button" id="{{workshop_id}}-link-workshop-btn" class="btn btn-primary link-workshop-btn" data-toggle="modal" data-target="#{{ id }}-share-link" onclick="window.location.href='https://{{ hostname }}{{ base_url }}workshops/{{ workshop_id }}';">{{ svg.plus_svg | safe }} Join </button>
+          </th>
+        </tr>        
+        {%- endfor %}
+      </tbody>
+    </table>
+  </div>  {#- table responsive #}
+</div>  {#- container fluid #}
+
+
+{%- endblock -%}
+
+
+{%- block script -%}
+<script>
+require(["jquery", "jhapi", "utils"], function (
+  $,
+  JHAPI,
+  utils
+) {
+  "use strict";
+
+  var base_url = window.jhdata.base_url;
+  var api = new JHAPI(base_url);
+
+  
+  /*
+    On page load
+  */
+  $(document).ready(function() {
+    $("nav [id$=nav-item]").removeClass("active");
+  })
+})
+</script>
+{%- endblock %}
\ No newline at end of file
diff --git a/templates/workshop_manager.html b/templates/workshop_manager.html
new file mode 100644
index 0000000..dd68441
--- /dev/null
+++ b/templates/workshop_manager.html
@@ -0,0 +1,38 @@
+{%- extends "page.html" -%}
+
+{%- block stylesheet -%}
+  <link rel="stylesheet" href='{{static_url("css/home.css")}}' type="text/css"/>
+{%- endblock -%}
+
+{%- block main -%}
+{%- import "macros/table/config/workshop_manager.jinja" as config %}
+{%- import "macros/svgs.jinja" as svg %}
+{%- import "macros/table/variables.jinja" as vars with context %}
+
+{%- set pagetype = vars.pagetype_workshopmanager %}
+
+{%- set table_rows = {vars.first_row_id: {}} %}
+{%- set _ = table_rows.update(db_workshops) %}
+
+
+{%- from "macros/table/table.jinja" import tables with context %}
+{%- import "macros/table/content.jinja" as functions with context %}
+
+{{ tables(
+  config.frontend_config,
+  functions.workshopmanager_description,
+  functions.workshopmanager_headerlayout,
+  functions.workshopmanager_defaultheader,
+  functions.workshopmanager_firstheader,
+  functions.workshopmanager_row_content
+) }}
+
+{%- endblock -%}
+
+
+{%- block script -%}
+{%- import "macros/table/variables.jinja" as vars with context %}
+{%- set pagetype = vars.pagetype_workshopmanager %}
+{%- import "macros/table/config/workshop_manager.jinja" as config with context %}
+{%- include "macros/table/elements_js.jinja" with context %}
+{%- endblock %}
-- 
GitLab