From 8120e1164d6660985381855da60fde3d6272430d Mon Sep 17 00:00:00 2001
From: Maria Petrova <m.petrova@fz-juelich.de>
Date: Sun, 3 Nov 2024 14:25:32 +0100
Subject: [PATCH] Adjust the footerto make the systems responsive to the sceen
 size

---
 templates/footer.html | 168 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 148 insertions(+), 20 deletions(-)

diff --git a/templates/footer.html b/templates/footer.html
index 5481d5c..26fc5e2 100644
--- a/templates/footer.html
+++ b/templates/footer.html
@@ -73,20 +73,10 @@
 {%- block footer -%}
 <footer class="navbar mt-auto p-0">
   <div id="footer-top" class="container-fluid justify-content-evenly p-4">
-    {%- if systems_default_order | length > 5 -%} 
     {#- 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 class="carousel-inner">
-        <div class="carousel-item active">
-          <div id="systems-page-1" class="d-flex justify-content-evenly">
-            {{ create_carousel_systems(0, 4) }}
-          </div>
-        </div>
-        <div class="carousel-item">
-          <div id="systems-page-2" class="d-flex justify-content-evenly">
-            {{ create_carousel_systems(4, 4) }}
-          </div>
-        </div>
+      <div  id="carousel-inner" class="carousel-inner">
+        <!-- Carousel items will be injected here dynamically via JavaScript -->
       </div>
       <button class="carousel-control-prev" type="button" data-bs-target="#footerSystemsCarousel" data-bs-slide="prev" style="width: unset;">
         <span class="carousel-control-prev-icon"></span>
@@ -97,14 +87,6 @@
         <span class="visually-hidden">Next</span>
       </button>
     </div>
-    {%- else -%}
-    {#- We only have a few systems and do not need a carousel to display them #}
-    <div id="systems-page-1" class="d-flex justify-content-evenly w-100">
-      {%- for system_config in systems_default_order %}
-        {{ ampel(system_config[0], system_config[1]) }}
-      {%- endfor %}
-    </div>
-    {%- endif %}
   </div>
   <div id="footer-bottom" class="container-fluid justify-content-center">
     {%- set logo_width = "220px" -%}
@@ -138,6 +120,146 @@ require(["jquery", "home/utils"], function (
 ) {
   "use strict";
 
+
+
+  const carouselInner = $('#carousel-inner');
+
+    // Define how many items per screen size
+  const breakpoints = {
+      xl: 5, // Extra-large screens (≥1200px)
+      lg: 4, // Large screens (≥992px)
+      md: 3, // Medium screens (≥768px)
+      sm: 2, // Small screens (≥576px)
+      xs: 1  // Extra-small screens (<576px)
+  };
+
+  // Function to get the number of items per page based on window width
+  function getItemsPerPage() {
+    const width = $(window).width();
+    if (width >= 1200) return breakpoints.xl;
+    if (width >= 992) return breakpoints.lg;
+    if (width >= 768) return breakpoints.md;
+    if (width >= 576) return breakpoints.sm;
+    return breakpoints.xs;
+  }
+
+  function randomInt(len) {
+    let result = '';
+    for (let i = 0; i < len; i++) {
+        result += Math.floor(Math.random() * 10);
+    }
+    return result;
+  }
+
+  function numberOfUsers(system) {
+    let systemSvg, urlSuffix, tooltipTitle;
+
+    const usersSvg = `{{ svg.users_svg | safe }}`;
+    const serversSvg = `{{ svg.servers_svg | safe }}`;
+    const linkSvg = `{{ svg.link_svg | safe }}`;
+
+    if (system === "jupyter") {
+        systemSvg = usersSvg;
+        urlSuffix = "";
+        tooltipTitle = "Number of active users in the last 24 hours";
+    } else if (system === "jsccloud") {
+        systemSvg = serversSvg;
+        urlSuffix = "var-system=JSC-Cloud";
+        tooltipTitle = "Number of active servers";
+    } else {
+        systemSvg = linkSvg;
+        urlSuffix = `var-system=${system.toUpperCase()}`;
+        tooltipTitle = "Number of active servers";
+    }
+
+    const anchorElement = `
+        <a class="system-users d-inline-block text-muted ms-1" 
+           data-bs-toggle="tooltip" data-bs-placement="top" 
+           title="${tooltipTitle}" 
+           href="https://{{hostname | safe}}/grafana/?${urlSuffix}" 
+           target="_blank">
+           <span id="${system}-users">0</span>
+           <span>${systemSvg}</span>
+           <div class="system-users-link-div d-inline-block">
+               <span class="system-users-link" id="${system}-users-link">
+                   {{ svg.linkSvg | safe }}
+               </span>
+           </div>
+        </a>`;
+    
+    return anchorElement;
+  }
+
+  function ampel(system, systemId) {
+    const systemLower = system.toLowerCase();
+    const imgVersion = randomInt(10);
+
+    var base_url = window.jhdata.base_url;
+    const staticUrl = base_url + "static";
+
+    let displayName;
+    if (system === "JUPYTER") {
+        displayName = {{ jupyter_name | tojson | safe }};
+    } else if (system === "JSCCLOUD") {
+        displayName = "JSC-Cloud";
+    } else {
+        displayName = system;
+    }
+
+    const ampelHtml = `
+      <div id="ampel-${systemLower}" class="text-center">
+          <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-placement="top">
+              ${displayName}
+          </a>
+          ${numberOfUsers(systemLower)}
+      </div>`;
+
+    return ampelHtml;
+  }
+
+  function create_carousel_systems(start, numElements) { 
+    let carouselSystem = '';
+    const end_index = start + numElements;
+    let order = {{ systems_default_order | tojson | safe  }};
+
+    for (let i = start; i < start + numElements; i++) {
+      let system_config = order[i];
+      carouselSystem += ampel(system_config[0], system_config[1]);
+    }
+    return carouselSystem;
+  }
+
+  // Function to dynamically create carousel pages
+  function createCarouselPages() {
+    carouselInner.empty(); // Clear existing carousel items
+    const itemsPerPage = getItemsPerPage(); 
+    const totalSystems = {{ systems_default_order | length }}; // Total number of systems
+    let pageNum = 1;
+
+    for (let i = 0; i < totalSystems; i += itemsPerPage) {
+        let carouselItem = $('<div>').addClass('carousel-item');
+        if (i === 0) carouselItem.addClass('active'); // First item is active by default
+
+        let systemPage = $('<div>').addClass('d-flex justify-content-evenly');
+        systemPage.attr('id', "systems-page-" + pageNum);
+
+        // Create systems for this page
+        const systemsDiv = create_carousel_systems(i, Math.min(totalSystems - i, itemsPerPage));
+
+        // Append systems to page and page to carousel
+        $(systemPage).append(systemsDiv);
+        $(carouselItem).append(systemPage);
+        carouselInner.append(carouselItem);
+        pageNum++;
+    }
+  }
+
   function reorderSystems(incidentsData) {
     const systemsDefaultOrder = {{ systems_default_order | tojson}};
     // Create copy of data and filter it
@@ -187,7 +309,13 @@ require(["jquery", "home/utils"], function (
     reorderSystems(incidents);
   }
 
+  // Update the carousel when the window is resized
+  $(window).resize(function () {
+    createCarouselPages();
+  });
+  
   $(document).ready(function() {
+    createCarouselPages();
     updateSystemHoverTooltips();
     utils.updateNumberOfUsers();
   })
-- 
GitLab