Skip to content

Commit 54a0cfa

Browse files
Copilotphrocker
andauthored
Implement stateful sidebar with localStorage persistence (#105)
* Initial plan * Implement stateful sidebar with localStorage persistence Co-authored-by: phrocker <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: phrocker <[email protected]>
1 parent 9435377 commit 54a0cfa

File tree

1 file changed

+53
-7
lines changed

1 file changed

+53
-7
lines changed

api/src/main/resources/templates/fragments/header.html

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,10 @@
331331
$("#systemBanner").show();
332332
[/]
333333
334-
// Auto-expand sidebar submenu based on current URL
334+
// Stateful sidebar with localStorage persistence
335335
(function() {
336336
const currentPath = window.location.pathname;
337+
const SIDEBAR_STATE_KEY = 'sidebarState';
337338

338339
// Define URL patterns for each submenu
339340
const submenuPatterns = {
@@ -343,16 +344,61 @@
343344
'systemSubmenu': ['/sso/v1/system/', '/sso/v1/telemetry', '/sso/v1/automation/', '/sso/v1/k8s/']
344345
};
345346

346-
// Find which submenu should be expanded
347+
// Load sidebar state from localStorage
348+
function loadSidebarState() {
349+
try {
350+
const savedState = localStorage.getItem(SIDEBAR_STATE_KEY);
351+
return savedState ? JSON.parse(savedState) : {};
352+
} catch (e) {
353+
console.error('Error loading sidebar state:', e);
354+
return {};
355+
}
356+
}
357+
358+
// Save sidebar state to localStorage
359+
function saveSidebarState(submenuId, isExpanded) {
360+
try {
361+
const state = loadSidebarState();
362+
state[submenuId] = isExpanded;
363+
localStorage.setItem(SIDEBAR_STATE_KEY, JSON.stringify(state));
364+
} catch (e) {
365+
console.error('Error saving sidebar state:', e);
366+
}
367+
}
368+
369+
// Get saved state or default to expanded
370+
const savedState = loadSidebarState();
371+
372+
// Initialize all submenus based on saved state (default to expanded)
373+
for (const submenuId of Object.keys(submenuPatterns)) {
374+
const submenuElement = document.getElementById(submenuId);
375+
if (submenuElement) {
376+
// Default to expanded (true) if no saved state exists
377+
const shouldExpand = savedState[submenuId] !== false;
378+
379+
if (shouldExpand) {
380+
submenuElement.classList.add('show');
381+
} else {
382+
submenuElement.classList.remove('show');
383+
}
384+
385+
// Add event listeners to save state when user expands/collapses
386+
submenuElement.addEventListener('shown.bs.collapse', function() {
387+
saveSidebarState(submenuId, true);
388+
});
389+
390+
submenuElement.addEventListener('hidden.bs.collapse', function() {
391+
saveSidebarState(submenuId, false);
392+
});
393+
}
394+
}
395+
396+
// Highlight active menu items based on current URL
347397
for (const [submenuId, patterns] of Object.entries(submenuPatterns)) {
348398
for (const pattern of patterns) {
349399
if (currentPath.startsWith(pattern)) {
350-
// Use Bootstrap's Collapse API to show the submenu
351400
const submenuElement = document.getElementById(submenuId);
352401
if (submenuElement) {
353-
// Add 'show' class to expand the submenu
354-
submenuElement.classList.add('show');
355-
356402
// Find and highlight the active menu item within this submenu
357403
const links = submenuElement.querySelectorAll('a.nav-link');
358404
let bestMatch = null;
@@ -372,7 +418,7 @@
372418
bestMatch.classList.add('active');
373419
}
374420
}
375-
return; // Exit once we find a match
421+
break;
376422
}
377423
}
378424
}

0 commit comments

Comments
 (0)