From 61398a3899c2cb3f5a5d46ca8e6df3ac9701a088 Mon Sep 17 00:00:00 2001
From: Bjarke Madsen <bjarke@nordu.net>
Date: Fri, 16 May 2025 11:50:28 +0200
Subject: [PATCH] Add JS fix to scrolling with more than one fixed header

---
 .../src/pages/Network/Automation.tsx           | 16 ++++++++++++++--
 .../Network/NetworkFunctionVirtualisation.tsx  | 18 ++++++++++++++++--
 .../src/scss/layout/_components.scss           |  4 ++--
 3 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/compendium-frontend/src/pages/Network/Automation.tsx b/compendium-frontend/src/pages/Network/Automation.tsx
index ecccbfe8..b8fbf804 100644
--- a/compendium-frontend/src/pages/Network/Automation.tsx
+++ b/compendium-frontend/src/pages/Network/Automation.tsx
@@ -1,4 +1,4 @@
-import React, { useContext } from "react";
+import React, { useContext, useEffect, useRef } from "react";
 import { Table } from "react-bootstrap";
 
 import { NetworkAutomation } from "compendium/Schema";
@@ -15,6 +15,7 @@ import titles from "compendium/titles";
 function AutomationPage(): React.ReactElement {
     const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext);
     const { data: pertTeamData, years, nrens } = useData<NetworkAutomation>('/api/network-automation', setFilterSelection);
+    const headerRef = useRef<HTMLTableRowElement>(null);
 
     const selectedData = (pertTeamData).filter(data =>
         filterSelection.selectedYears.includes(data.year) && filterSelection.selectedNrens.includes(data.nren)
@@ -31,6 +32,17 @@ function AutomationPage(): React.ReactElement {
 
     const showYears = [...filterSelection.selectedYears.filter(year => years.has(year))].sort();
 
+    useEffect(() => {
+        const ref = headerRef.current;
+        if (ref) {
+            const height = Math.round(ref.getBoundingClientRect().height) - 2; // -2 to account for things being visible through the border
+            const nextRow = ref.nextElementSibling as HTMLTableRowElement;
+            if (nextRow) {
+                nextRow.style.setProperty('--header-height', `${height}px`);
+            };
+        }
+    }, [headerRef]);
+
     return (
         <DataPage title={titles["network-automation"]}
             description="The table below shows which NRENs have, or plan to, automate their 
@@ -53,7 +65,7 @@ function AutomationPage(): React.ReactElement {
                         <col span={2} style={{ width: "12%" }} />
                     </colgroup>
                     <thead>
-                        <tr>
+                        <tr ref={headerRef}>
                             <th></th>
                             <th colSpan={2}>Device Provisioning</th>
                             <th colSpan={2}>Data Collection</th>
diff --git a/compendium-frontend/src/pages/Network/NetworkFunctionVirtualisation.tsx b/compendium-frontend/src/pages/Network/NetworkFunctionVirtualisation.tsx
index 82f09fc1..46c4feed 100644
--- a/compendium-frontend/src/pages/Network/NetworkFunctionVirtualisation.tsx
+++ b/compendium-frontend/src/pages/Network/NetworkFunctionVirtualisation.tsx
@@ -1,4 +1,4 @@
-import React, { useContext } from "react";
+import React, { useContext, useEffect, useRef } from "react";
 import { Table } from "react-bootstrap";
 
 import { NetworkFunctionVirtualisation } from "compendium/Schema";
@@ -15,6 +15,7 @@ import titles from "compendium/titles";
 function NetworkFunctionVirtualisationPage(): React.ReactElement {
     const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext);
     const { data, years, nrens } = useData<NetworkFunctionVirtualisation>('/api/nfv', setFilterSelection);
+    const headerRef = useRef<HTMLTableRowElement>(null);
 
     const selectedData = data.filter(data =>
         filterSelection.selectedYears.includes(data.year) && filterSelection.selectedNrens.includes(data.nren)
@@ -31,6 +32,19 @@ function NetworkFunctionVirtualisationPage(): React.ReactElement {
 
     const showYears = [...filterSelection.selectedYears.filter(year => years.has(year))].sort();
 
+    useEffect(() => {
+            const ref = headerRef.current;
+            if (ref) {
+                const height = Math.round(ref.getBoundingClientRect().height) - 2; // -2 to account for things being visible through the border
+                const nextRow = ref.nextElementSibling as HTMLTableRowElement;
+                if (nextRow) {
+                    console.log(nextRow);
+                    console.log(height);
+                    nextRow.style.setProperty('--header-height', `${height}px`);
+                };
+            }
+        }, [headerRef]);
+
     return (
         <DataPage title={titles.nfv}
             description="The table below shows the kinds of Network Function Virtualisation (NFV) used by NRENs."
@@ -47,7 +61,7 @@ function NetworkFunctionVirtualisationPage(): React.ReactElement {
                         <col span={2} style={{ width: "16%" }} />
                     </colgroup>
                     <thead>
-                        <tr>
+                        <tr ref={headerRef}>
                             <th></th>
                             <th colSpan={2}>Routers/switches</th>
                             <th colSpan={2}>Firewalls</th>
diff --git a/compendium-frontend/src/scss/layout/_components.scss b/compendium-frontend/src/scss/layout/_components.scss
index ee1e1959..3ba8379b 100644
--- a/compendium-frontend/src/scss/layout/_components.scss
+++ b/compendium-frontend/src/scss/layout/_components.scss
@@ -324,9 +324,9 @@ $service-check-colors: (
   z-index: 1;
 }
 
-.charging-struct-table thead tr:not(:first-child) th {
+.charging-struct-table thead tr:nth-child(2) th {
   position: sticky;
-  top: 50px;
+  top: var(--header-height, 50px);
   background-color: white;
   z-index: 1;
 }
-- 
GitLab