mirror of
https://github.com/smittix/intercept.git
synced 2026-07-11 02:58:12 -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
|
// Initialize dropdown nav active state
|
||||||
updateDropdownActiveState();
|
updateDropdownActiveState();
|
||||||
|
|
||||||
|
// Restore nav group open/closed state from localStorage
|
||||||
|
initNavGroupState();
|
||||||
|
|
||||||
// Start SDR device status polling
|
// Start SDR device status polling
|
||||||
startSdrStatusPolling();
|
startSdrStatusPolling();
|
||||||
|
|
||||||
@@ -4189,6 +4192,45 @@
|
|||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
dropdown.classList.add('open');
|
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() {
|
function closeAllDropdowns() {
|
||||||
|
|||||||
@@ -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