Skip to content
Snippets Groups Projects
Commit 092d5552 authored by Tim Kreuzer's avatar Tim Kreuzer
Browse files

update jupyter4nfdi frontend to new frontend version

parent 1d1e1fb2
No related branches found
No related tags found
No related merge requests found
...@@ -316,19 +316,77 @@ require(["jquery", "home/utils"], function ( ...@@ -316,19 +316,77 @@ require(["jquery", "home/utils"], function (
$(document).ready(function() { $(document).ready(function() {
createCarouselPages(); createCarouselPages();
updateSystemHoverTooltips(); });
utils.updateNumberOfUsers();
})
if (!(window.location.pathname.endsWith("home") || window.location.pathname.includes("spawn-pending"))) { const incidentsThresholdInteractiveFooter = {{ custom_config.get("incidentCheck", {}).get("healthThreshold", {}).get("interactive", 50) | tojson }};
console.log("setup SSE")
let userSpawnerNotificationUrl = `${jhdata.base_url}api/users/${jhdata.user}/notifications/spawners?_xsrf=${window.jhdata.xsrf_token}`; $(`[data-sse-incidents]`).on("sse", function (event, incidents) {
evtSourcesGlobal["footer"] = new EventSource(userSpawnerNotificationUrl); $(`[id^='ampel-'][id$='-tooltip']`).tooltip("dispose");
evtSourcesGlobal["footer"].onmessage = (e) => { let newMaintenanceList = [];
utils.updateNumberOfUsers(); for (const [system, systemInfo] of Object.entries(incidents)) {
}; if (systemInfo.incident) {
$(`#ampel-${system.toLowerCase()}-tooltip`)
.attr('data-bs-original-title', systemInfo.incident);
if ( systemInfo.health > incidentsThresholdInteractiveFooter ) {
const _system = incidentsmapping[system] ?? system;
if ( !newMaintenanceList.includes(_system) ) {
newMaintenanceList.push(_system);
}
}
} }
}
globalMaintenanceSystems = newMaintenanceList;
$(`[id$='-option-input']`).trigger("option");
$(`[id^='ampel-'][id$='-tooltip']`).tooltip();
reorderSystems(incidents);
});
$(`[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;
})
$(`[id^='ampel-'][id$='-tooltip']`).tooltip("dispose");
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-toggle]").tooltip("dispose");
$(`#${system.toLowerCase()}-users`)
.parents("[data-bs-toggle]")
.attr("data-bs-original-title", `Number of active servers${partitionInfos}`);
$(`#${system.toLowerCase()}-users`)
.parents("[data-toggle]").tooltip();
}
}
// 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.toLowerCase()}-users`)
.parents("[data-toggle]").tooltip("dispose");
$(`#${system.toLowerCase()}-users`).html(0);
$(`#${system.toLowerCase()}-users`)
.parents("[data-toggle]")
.attr("data-bs-original-title", `Number of active servers`);
$(`#${system.toLowerCase()}-users`)
}
}
});
}) })
</script> </script>
{%- endblock -%} {%- endblock -%}
{%- macro create_user_widget() -%} {%- macro create_user_widget() -%}
{%- if user %} {%- if user %}
<div class="dropdown"> <div class="dropdown">
<button class="btn btn-outline-primary dropdown-toggle mb-2" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside">{{ user.name }}</button> {%- if auth_state %}
{%- set display_name = auth_state.get("oauth_user", {}).get("name", user.name) %}
{%- else %}
{%- set display_name = user.name %}
{%- endif %}
<button class="btn btn-outline-primary dropdown-toggle mb-2" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside">{{ display_name }}</button>
<ul class="dropdown-menu dropdown-menu-end w-100"> <ul class="dropdown-menu dropdown-menu-end w-100">
{%- if auth_state and auth_state.get("last_login", False) %}
<li><h6 class="dropdown-header">Last login</h6></li>
<li><a class="dropdown-item disabled text-black">{{ auth_state.get("last_login") }}</a></li>
<li><hr class="dropdown-divider"></li>
{%- endif -%}
<li> <li>
<button id="logout" class="dropdown-item"> <button id="logout" class="dropdown-item">
<svg class="align-middle" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16"> <svg class="align-middle" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16">
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
<div class="d-flex"> <div class="d-flex">
{%- if user %} {%- 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> <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 %} {%- 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> <li class="nav-item"><a id="{{prefix}}admin-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}admin">Admin</a></li>
{%- endif -%} {%- endif -%}
......
...@@ -36,7 +36,35 @@ ...@@ -36,7 +36,35 @@
{% block scripts -%} {% block scripts -%}
{%- endblock %} {%- endblock %}
<script> <script>
var evtSourcesGlobal = {}; var evtSource = undefined;
var testCounter = 0;
let globalMaintenanceSystems = [];
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);
for (const [key, value] of Object.entries(jsonData)) {
$(`[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({ require.config({
{%- if version_hash -%} {%- if version_hash -%}
urlArgs: "v={{version_hash}}", urlArgs: "v={{version_hash}}",
...@@ -123,11 +151,12 @@ ...@@ -123,11 +151,12 @@
{% block script -%} {% block script -%}
{%- endblock %} {%- endblock %}
<script> <script>
$(document).ready(function() {
sseInit();
});
window.onbeforeunload = function() { window.onbeforeunload = function() {
if (typeof evtSourcesGlobal !== 'undefined') { if (typeof evtSourcesGlobal !== 'undefined') {
for (const [key, value] of Object.entries(evtSourcesGlobal)) { evtSource.close();
value.close();
}
} }
} }
</script> </script>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment