mirror of
https://github.com/smittix/intercept.git
synced 2026-04-29 00:59:59 -07:00
feat: persist nav group open/closed state to localStorage
Adds initNavGroupState() and saveNavGroupState() functions so the open/closed state of each .mode-nav-dropdown survives page reloads. Active groups are never force-closed even if localStorage says closed. Adds test_nav_state.py with two tests verifying presence of the functions and data-group attributes on all five nav groups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4162,6 +4162,9 @@
|
||||
// Initialize dropdown nav active state
|
||||
updateDropdownActiveState();
|
||||
|
||||
// Restore nav group open/closed state from localStorage
|
||||
initNavGroupState();
|
||||
|
||||
// Start SDR device status polling
|
||||
startSdrStatusPolling();
|
||||
|
||||
@@ -4189,6 +4192,45 @@
|
||||
if (!isOpen) {
|
||||
dropdown.classList.add('open');
|
||||
}
|
||||
saveNavGroupState();
|
||||
}
|
||||
|
||||
function initNavGroupState() {
|
||||
const NAV_STATE_KEY = 'intercept_nav_groups';
|
||||
let savedState = {};
|
||||
try {
|
||||
savedState = JSON.parse(localStorage.getItem(NAV_STATE_KEY) || '{}');
|
||||
} catch (e) {
|
||||
savedState = {};
|
||||
}
|
||||
|
||||
document.querySelectorAll('.mode-nav-dropdown[data-group]').forEach(dropdown => {
|
||||
const group = dropdown.dataset.group;
|
||||
// If saved state says closed AND this group has no active item, close it
|
||||
if (savedState[group] === false) {
|
||||
const hasActive = dropdown.classList.contains('has-active');
|
||||
if (!hasActive) {
|
||||
dropdown.classList.remove('open');
|
||||
const btn = dropdown.querySelector('.mode-nav-dropdown-btn');
|
||||
if (btn) btn.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
} else if (savedState[group] === true) {
|
||||
dropdown.classList.add('open');
|
||||
const btn = dropdown.querySelector('.mode-nav-dropdown-btn');
|
||||
if (btn) btn.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveNavGroupState() {
|
||||
const NAV_STATE_KEY = 'intercept_nav_groups';
|
||||
const state = {};
|
||||
document.querySelectorAll('.mode-nav-dropdown[data-group]').forEach(dropdown => {
|
||||
state[dropdown.dataset.group] = dropdown.classList.contains('open');
|
||||
});
|
||||
try {
|
||||
localStorage.setItem(NAV_STATE_KEY, JSON.stringify(state));
|
||||
} catch (e) { /* storage full or unavailable */ }
|
||||
}
|
||||
|
||||
function closeAllDropdowns() {
|
||||
|
||||
25
tests/test_nav_state.py
Normal file
25
tests/test_nav_state.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""Tests for nav group localStorage persistence (JS logic verified via structure check)."""
|
||||
|
||||
|
||||
def _logged_in_get(client, path):
|
||||
"""Make a GET request with a pre-seeded logged-in session."""
|
||||
with client.session_transaction() as sess:
|
||||
sess["logged_in"] = True
|
||||
return client.get(path)
|
||||
|
||||
|
||||
def test_index_page_includes_nav_state_init(client):
|
||||
"""nav group init function must be present in the index page."""
|
||||
resp = _logged_in_get(client, "/")
|
||||
assert resp.status_code == 200
|
||||
html = resp.data.decode()
|
||||
assert "initNavGroupState" in html
|
||||
assert "localStorage" in html
|
||||
|
||||
|
||||
def test_nav_groups_have_data_group_attributes(client):
|
||||
"""Each nav group must have a data-group attribute for state keying."""
|
||||
resp = _logged_in_get(client, "/")
|
||||
html = resp.data.decode()
|
||||
for group in ["signals", "tracking", "space", "wireless", "intel"]:
|
||||
assert f'data-group="{group}"' in html, f"Missing data-group={group}"
|
||||
Reference in New Issue
Block a user