Compare commits
No commits in common. "935faa4c58f297f4adaf05d6f0241a1f8d355c74" and "4c368e43de41e010c4c174403545f6e127f91e80" have entirely different histories.
935faa4c58
...
4c368e43de
@ -1,42 +0,0 @@
|
|||||||
// features/dashboard/index.js — the landing Dashboard as a feature module.
|
|
||||||
//
|
|
||||||
// dashboard.js exposes bare global functions (loadInstalledApps,
|
|
||||||
// loadDashboardData live in dashboard.js / data-loader.js, both eager core
|
|
||||||
// scripts) — there is no controller class to lazy-load, so scripts is empty.
|
|
||||||
// system-loader's 'dashboard' component already ran initializeData()/
|
|
||||||
// loadSystemInfo()/setupEventListeners() once at boot; mount() only does the
|
|
||||||
// per-navigation refresh (mirrors the old handleDashboard + the navigate()
|
|
||||||
// data-reload special-case, which has been removed from spa.js so the reload
|
|
||||||
// now fires exactly once here).
|
|
||||||
LP.features.register({
|
|
||||||
id: 'dashboard',
|
|
||||||
routes: ['/', '/dashboard'],
|
|
||||||
|
|
||||||
async mount(ctx) {
|
|
||||||
const html = await ctx.loadFragment('/html/dashboard-content.html');
|
|
||||||
ctx.setContent(html, 'Dashboard');
|
|
||||||
|
|
||||||
// Render the installed-apps icon grid (handleDashboard's only post-render call).
|
|
||||||
if (typeof loadInstalledApps === 'function') loadInstalledApps();
|
|
||||||
|
|
||||||
// Repaint the stat cards / disk donut + (re)wire the 1 Hz live SSE. The
|
|
||||||
// 100 ms cushion lets the freshly-injected DOM settle (loadSystemInfo also
|
|
||||||
// guards on element presence). ctx.sub() cancels it if we navigate away
|
|
||||||
// before it fires.
|
|
||||||
const reloadTimer = setTimeout(() => {
|
|
||||||
if (typeof loadDashboardData === 'function') loadDashboardData();
|
|
||||||
}, 100);
|
|
||||||
ctx.sub(() => clearTimeout(reloadTimer));
|
|
||||||
},
|
|
||||||
|
|
||||||
async unmount() {
|
|
||||||
// Nothing this view owns is destroyable from here: the dashboard has no
|
|
||||||
// handler-newed controller and no system-loader singleton to tear down.
|
|
||||||
// The pending reload timer is cancelled via the ctx.sub() above (ctx.teardown).
|
|
||||||
// The 1 Hz LiveSystem SSE sub (attachDashboardLive) self-releases on its
|
|
||||||
// next sample once the dashboard DOM is gone, and the 1 s update countdown
|
|
||||||
// is a module-private interval with no exported stopper (pre-existing; it
|
|
||||||
// self-clears on the next dashboard mount). Both are noted for the Phase 5
|
|
||||||
// dashboard cleanup; neither is reachable here.
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
// features/tasks/index.js — the Tasks page as a feature module.
|
|
||||||
//
|
|
||||||
// window.tasksManager is a system-loader singleton (its "task-system" component
|
|
||||||
// loads all task scripts, starts the shared SSE bus, then news TasksManager).
|
|
||||||
// So mount() does NOT new it or load scripts — it renders the fragment and
|
|
||||||
// re-inits the view, exactly like the old handleTasks(). unmount() releases
|
|
||||||
// only this view's per-mount leaks (the 30s auto-refresh interval + open log
|
|
||||||
// streams); it must never stop the shared taskEventBus or null the singleton.
|
|
||||||
LP.features.register({
|
|
||||||
id: 'tasks',
|
|
||||||
routes: ['/tasks', '/tasks*'],
|
|
||||||
|
|
||||||
async mount(ctx) {
|
|
||||||
const html = await ctx.loadFragment('/html/tasks-content.html');
|
|
||||||
ctx.setContent(html, 'Tasks');
|
|
||||||
|
|
||||||
if (window.tasksManager) {
|
|
||||||
await window.tasksManager.init();
|
|
||||||
} else {
|
|
||||||
// Don't throw — matches handleTasks: the page still renders, task
|
|
||||||
// functionality is just limited until the task-system component is ready.
|
|
||||||
console.warn('TasksManager not available yet, task functionality will be limited');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async unmount() {
|
|
||||||
const tm = window.tasksManager;
|
|
||||||
// The one per-view leak init() opens: the 30s auto-refresh interval stored
|
|
||||||
// on the singleton. Each init() recreates it, so clearing here is idempotent.
|
|
||||||
if (tm && tm.refreshInterval) {
|
|
||||||
clearInterval(tm.refreshInterval);
|
|
||||||
tm.refreshInterval = null;
|
|
||||||
}
|
|
||||||
// Stop any open per-task log streams this view started (each removes its own
|
|
||||||
// SSE listeners + map entry). Snapshot keys first — stopLogStreaming mutates
|
|
||||||
// the map. Does NOT touch the shared bus.
|
|
||||||
if (tm && tm.activeLogStreams && typeof tm.stopLogStreaming === 'function') {
|
|
||||||
for (const id of Array.from(tm.activeLogStreams.keys())) {
|
|
||||||
try { tm.stopLogStreaming(id); } catch (_) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// DO NOT: stop window.taskEventBus (shared SSE singleton), remove the
|
|
||||||
// singleton's once-bound task listeners, or null window.tasksManager.
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@ -111,9 +111,7 @@
|
|||||||
<script src="/kernel/lifecycle.js"></script>
|
<script src="/kernel/lifecycle.js"></script>
|
||||||
<!-- Feature modules self-register here (eager, tiny). Their heavy controllers
|
<!-- Feature modules self-register here (eager, tiny). Their heavy controllers
|
||||||
are still lazy-loaded by the module's mount(). -->
|
are still lazy-loaded by the module's mount(). -->
|
||||||
<script src="/features/dashboard/index.js"></script>
|
|
||||||
<script src="/features/backup/index.js"></script>
|
<script src="/features/backup/index.js"></script>
|
||||||
<script src="/features/tasks/index.js"></script>
|
|
||||||
<!--
|
<!--
|
||||||
Page-specific controllers are loaded on demand by spa.js / config-manager.js
|
Page-specific controllers are loaded on demand by spa.js / config-manager.js
|
||||||
when the user navigates to the relevant route. Keeping them out of the
|
when the user navigates to the relevant route. Keeping them out of the
|
||||||
|
|||||||
@ -231,9 +231,16 @@ class LibrePortalSPAClean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (The dashboard data-reload that used to live here is now folded into the
|
// Force data reload when navigating to dashboard, even if same route
|
||||||
// dashboard feature module's mount(), so it fires exactly once per
|
if (path === '/dashboard' || path === '/') {
|
||||||
// navigation. See features/dashboard/index.js.)
|
// console.log('🔄 Dashboard navigation detected, forcing data reload');
|
||||||
|
// Trigger dashboard data reload after a short delay to ensure DOM is ready
|
||||||
|
setTimeout(() => {
|
||||||
|
if (typeof loadDashboardData === 'function') {
|
||||||
|
loadDashboardData();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
//console.log('🧭 Navigating to:', path);
|
//console.log('🧭 Navigating to:', path);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user