From bbbd035ab21d4f37b77217a08c42c8737f7966f8 Mon Sep 17 00:00:00 2001 From: librelad Date: Thu, 28 May 2026 23:37:28 +0100 Subject: [PATCH] refactor(routing): move System out of /admin/config to /admin/system System is live stats, not configuration, so it shouldn't live under /admin/config. adminPath('system') now emits /admin/system; the path parser locates 'system' positionally; all nav targets, breadcrumbs and the dashboard disk-card link point at /admin/system{,/storage,/metric/}. adminCategoryFromPath already resolves /admin/ to that category, so ConfigManager still mounts AdminSystem unchanged. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- .../js/components/admin/admin-system.js | 27 ++++++++++--------- .../js/components/admin/system-metric-page.js | 12 ++++----- .../components/admin/system-storage-page.js | 6 ++--- containers/libreportal/frontend/js/spa.js | 1 + .../frontend/js/utils/data-loader.js | 2 +- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/containers/libreportal/frontend/js/components/admin/admin-system.js b/containers/libreportal/frontend/js/components/admin/admin-system.js index f9280fb..1292074 100644 --- a/containers/libreportal/frontend/js/components/admin/admin-system.js +++ b/containers/libreportal/frontend/js/components/admin/admin-system.js @@ -3,10 +3,10 @@ // One AdminSystem instance per page mount. Reads the URL path on init and // dispatches to one of four sub-views: // -// /admin/config/system → index (gauges + trends + per-app table) -// /admin/config/system/metric/ → single-metric deep-dive page -// /admin/config/system/app/ → per-container app deep-dive -// /admin/config/system/storage → Docker disk breakdown +// /admin/system → index (gauges + trends + per-app table) +// /admin/system/metric/ → single-metric deep-dive page +// /admin/system/app/ → per-container app deep-dive +// /admin/system/storage → Docker disk breakdown // // Sub-views are separate page renderers (system-metric-page.js etc.) that // each own their own DOM + lifecycle inside #config-section. We mount one @@ -32,16 +32,19 @@ class AdminSystem { root() { return document.getElementById(this.rootId); } - // Path → view dispatch. AdminPath base is /admin/config/system; sub-paths + // Path → view dispatch. AdminPath base is /admin/system; sub-paths // add segments after that. Falls through to 'index' for an unknown shape // so a typo'd URL doesn't blank the page. _parsePath() { const segs = String(window.location.pathname || '').split('/').filter(Boolean); - // segs = ['admin','config','system', ...] - const sub = segs[3]; - if (sub === 'metric' && segs[4]) return { view: 'metric', key: decodeURIComponent(segs[4]) }; - if (sub === 'app' && segs[4]) return { view: 'app', name: decodeURIComponent(segs[4]) }; - if (sub === 'storage') return { view: 'storage' }; + // Locate 'system' and read the sub-view after it, so dispatch works for + // /admin/system// regardless of leading segments. + const i = segs.indexOf('system'); + const sub = i >= 0 ? segs[i + 1] : undefined; + const arg = i >= 0 ? segs[i + 2] : undefined; + if (sub === 'metric' && arg) return { view: 'metric', key: decodeURIComponent(arg) }; + if (sub === 'app' && arg) return { view: 'app', name: decodeURIComponent(arg) }; + if (sub === 'storage') return { view: 'storage' }; return { view: 'index' }; } @@ -136,7 +139,7 @@ class AdminSystem { const ex = e.target.closest('[data-sys-expand]'); if (ex) { const k = ex.dataset.sysExpand; - if (window.navigateToRoute) window.navigateToRoute(`/admin/config/system/metric/${encodeURIComponent(k)}`); + if (window.navigateToRoute) window.navigateToRoute(`/admin/system/metric/${encodeURIComponent(k)}`); return; } const ap = e.target.closest('[data-sys-app]'); @@ -151,7 +154,7 @@ class AdminSystem { } const st = e.target.closest('[data-sys-storage]'); if (st) { - if (window.navigateToRoute) window.navigateToRoute('/admin/config/system/storage'); + if (window.navigateToRoute) window.navigateToRoute('/admin/system/storage'); return; } }); diff --git a/containers/libreportal/frontend/js/components/admin/system-metric-page.js b/containers/libreportal/frontend/js/components/admin/system-metric-page.js index f6518dc..4908749 100644 --- a/containers/libreportal/frontend/js/components/admin/system-metric-page.js +++ b/containers/libreportal/frontend/js/components/admin/system-metric-page.js @@ -1,7 +1,7 @@ // Admin → System → Metric — single-metric deep-dive PAGE. // // Replaces the previous fullscreen overlay (system-detail.js) with a real -// in-flow page mounted at /admin/config/system/metric/. Bookmarkable, +// in-flow page mounted at /admin/system/metric/. Bookmarkable, // browser-back navigates, refresh keeps you here. // // Renders into #config-section as a full-width admin page. Owns its own @@ -85,7 +85,7 @@ class SystemMetricPage { _onKey(e) { if (e.key === 'Escape' && window.navigateToRoute) { - window.navigateToRoute('/admin/config/system'); + window.navigateToRoute('/admin/system'); } } _onResize() { this._renderChart(); } @@ -111,12 +111,12 @@ class SystemMetricPage { } const back = e.target.closest('[data-back]'); if (back && window.navigateToRoute) { - window.navigateToRoute('/admin/config/system'); + window.navigateToRoute('/admin/system'); return; } const go = e.target.closest('[data-go-storage]'); if (go && window.navigateToRoute) { - window.navigateToRoute('/admin/config/system/storage'); + window.navigateToRoute('/admin/system/storage'); } } @@ -151,7 +151,7 @@ class SystemMetricPage {