diff --git a/containers/libreportal/frontend/features/admin/index.js b/containers/libreportal/frontend/features/admin/index.js
index 21b76a3..eb627b4 100644
--- a/containers/libreportal/frontend/features/admin/index.js
+++ b/containers/libreportal/frontend/features/admin/index.js
@@ -14,7 +14,7 @@ LP.features.register({
routes: ['/admin', '/admin*'],
async mount(ctx) {
- window.configCategory = window.adminCategoryFromPath(window.location.pathname);
+ window.configCategory = ctx.services.router.adminCategoryFromPath(window.location.pathname);
const html = await ctx.loadFragment('/html/config-content.html');
ctx.setContent(html, 'Admin');
@@ -30,7 +30,7 @@ LP.features.register({
}
},
- async unmount() {
+ async unmount(ctx) {
// Release only this view's leaks; never destroy the configManager singleton.
// The sub-controllers renderConfig() spawns are re-created on each visit, so
// null them; AdminSystem additionally holds a live SSE sub + a 30s interval
@@ -48,7 +48,7 @@ LP.features.register({
} catch (_) {}
// Drop AdminOverview's task-refresh registration so a finished verify/update
// task doesn't repaint a torn-down board.
- try { window.taskRefresh && window.taskRefresh.unregister && window.taskRefresh.unregister('admin-overview'); } catch (_) {}
+ try { ctx.services.tasks.refresh && ctx.services.tasks.refresh.unregister('admin-overview'); } catch (_) {}
window.adminOverview = null;
window.adminSystem = null;
window.sshPage = null;
diff --git a/containers/libreportal/frontend/features/app-detail/index.js b/containers/libreportal/frontend/features/app-detail/index.js
index d32f9a4..197d220 100644
--- a/containers/libreportal/frontend/features/app-detail/index.js
+++ b/containers/libreportal/frontend/features/app-detail/index.js
@@ -36,7 +36,7 @@ LP.features.register({
const tab = legacyTab === 'logs' ? 'tasks' : (legacyTab || 'config');
const sub = (tab === 'config') ? legacyConfig : null;
const taskId = url.searchParams.get('task');
- const canonical = window.appPath(appName, tab, sub, taskId);
+ const canonical = ctx.services.router.appPath(appName, tab, sub, taskId);
if (canonical !== url.pathname + url.search) {
window.history.replaceState({ route: canonical }, '', canonical);
}
diff --git a/containers/libreportal/frontend/features/backup/index.js b/containers/libreportal/frontend/features/backup/index.js
index b80f39b..81e663e 100644
--- a/containers/libreportal/frontend/features/backup/index.js
+++ b/containers/libreportal/frontend/features/backup/index.js
@@ -29,13 +29,13 @@ LP.features.register({
await window.backupPage.init();
},
- async unmount() {
+ async unmount(ctx) {
// Best-effort teardown. BackupPage self-guards stale work via
// (window.backupPage === this), so nulling the global neutralises any
// pending task-refresh repaint; we also drop its coordinator registration.
// A proper dispose() (removing the leaked document listeners) lands with
// the Phase 5 backup decomposition.
- try { window.taskRefresh && window.taskRefresh.unregister && window.taskRefresh.unregister('backups'); } catch (_) {}
+ try { ctx.services.tasks.refresh && ctx.services.tasks.refresh.unregister('backups'); } catch (_) {}
window.backupPage = null;
},
});
diff --git a/containers/libreportal/frontend/index.html b/containers/libreportal/frontend/index.html
index cc306be..ef54dd6 100755
--- a/containers/libreportal/frontend/index.html
+++ b/containers/libreportal/frontend/index.html
@@ -108,6 +108,7 @@
loads the page manifest; spa.js consults it for routing. See
docs/frontend-modularization.md. -->
+