From a0daeee09ade6ccabf696bca1cfa7871be894949 Mon Sep 17 00:00:00 2001 From: Dan Webb Date: Thu, 22 Jan 2026 16:01:03 +0000 Subject: [PATCH 1/2] feat: add HTMX boosting for SPA-like navigation - Enable hx-boost on body for automatic AJAX navigation - Add main-content ID and HTMX target/select attributes for partial page updates - Add sidebar-nav-link class to navigation items - Implement client-side active state management on navigation - Disable boost on logout link to preserve full page reload - Format HTML with consistent indentation and spacing --- views/layouts/base.html | 120 ++++++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 30 deletions(-) diff --git a/views/layouts/base.html b/views/layouts/base.html index 0457026..e828b36 100644 --- a/views/layouts/base.html +++ b/views/layouts/base.html @@ -1,6 +1,7 @@ {{ define "base" }} + @@ -34,81 +35,108 @@ - + + -
+
-
+
- IronBuckets + IronBuckets
- Cluster + :class="collapsed ? '!opacity-0 !h-0 !overflow-hidden !mb-0' : ''"> + Cluster
- + Overview - + Drives
- Access + :class="collapsed ? '!opacity-0 !h-0 !overflow-hidden !mt-2 !mb-0' : ''"> + Access
- + Users - + Groups - + Buckets
- System + :class="collapsed ? '!opacity-0 !h-0 !overflow-hidden !mt-2 !mb-0' : ''"> + System
- + Settings
- + Logout @@ -117,17 +145,19 @@
-
+
-
+
Cluster Online - +
- +
@@ -145,10 +175,40 @@ lucide.createIcons(); // Re-init icons on HTMX content swaps - document.body.addEventListener('htmx:afterSwap', function(evt) { + document.body.addEventListener('htmx:afterSwap', function (evt) { lucide.createIcons(); }); + + // Update sidebar active state on navigation + document.body.addEventListener('htmx:pushedIntoHistory', function (evt) { + const path = window.location.pathname; + const links = document.querySelectorAll('.sidebar-nav-link'); + + links.forEach(link => { + const href = link.getAttribute('href'); + // Simple exact match or startswith for sub-paths if needed. + // For now, exact match or /users matching /users/create is good practice, + // but let's stick to exact logic or simple logic matching the Go template: + // Go template used exact match mostly. + + let isActive = false; + if (href === '/' && path === '/') { + isActive = true; + } else if (href !== '/' && path.startsWith(href)) { + isActive = true; + } + + if (isActive) { + link.classList.remove('text-zinc-400', 'hover:text-white', 'hover:bg-white/5'); + link.classList.add('bg-white/10', 'text-white'); + } else { + link.classList.add('text-zinc-400', 'hover:text-white', 'hover:bg-white/5'); + link.classList.remove('bg-white/10', 'text-white'); + } + }); + }); + -{{ end }} +{{ end }} \ No newline at end of file From 3137c9d12698f0ce1162fc8669cb0f5379ed1ffc Mon Sep 17 00:00:00 2001 From: Dan Webb Date: Thu, 22 Jan 2026 16:28:48 +0000 Subject: [PATCH 2/2] Fixes Signed-off-by: Dan Webb --- views/layouts/base.html | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/views/layouts/base.html b/views/layouts/base.html index e828b36..f9499ea 100644 --- a/views/layouts/base.html +++ b/views/layouts/base.html @@ -80,15 +80,13 @@ + class="sidebar-nav-link w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors whitespace-nowrap {{ if eq .ActiveNav "overview" }}bg-white/10 text-white{{ else }}text-zinc-400 hover:text-white hover:bg-white/5{{ end }}"> Overview + class="sidebar-nav-link w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors whitespace-nowrap {{ if eq .ActiveNav "drives" }}bg-white/10 text-white{{ else }}text-zinc-400 hover:text-white hover:bg-white/5{{ end }}"> Drives @@ -100,22 +98,19 @@
+ class="sidebar-nav-link w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors whitespace-nowrap {{ if eq .ActiveNav "users" }}bg-white/10 text-white{{ else }}text-zinc-400 hover:text-white hover:bg-white/5{{ end }}"> Users + class="sidebar-nav-link w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors whitespace-nowrap {{ if eq .ActiveNav "groups" }}bg-white/10 text-white{{ else }}text-zinc-400 hover:text-white hover:bg-white/5{{ end }}"> Groups + class="sidebar-nav-link w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors whitespace-nowrap {{ if eq .ActiveNav "buckets" }}bg-white/10 text-white{{ else }}text-zinc-400 hover:text-white hover:bg-white/5{{ end }}"> Buckets @@ -127,8 +122,7 @@
+ class="sidebar-nav-link w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors whitespace-nowrap {{ if eq .ActiveNav "settings" }}bg-white/10 text-white{{ else }}text-zinc-400 hover:text-white hover:bg-white/5{{ end }}"> Settings @@ -186,8 +180,8 @@ links.forEach(link => { const href = link.getAttribute('href'); - // Simple exact match or startswith for sub-paths if needed. - // For now, exact match or /users matching /users/create is good practice, + // Simple exact match or startswith for sub-paths if needed. + // For now, exact match or /users matching /users/create is good practice, // but let's stick to exact logic or simple logic matching the Go template: // Go template used exact match mostly. @@ -211,4 +205,4 @@ -{{ end }} \ No newline at end of file +{{ end }}