Merge claude/1
This commit is contained in:
commit
3dd2444bc2
@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"note": "Phase-0 hand-committed manifest. Mirrors spa.js setupRoutes() exactly. Will be replaced by the generated /data/webui/generated/features.json once the scan generator lands (see docs/frontend-modularization.md). 'handler' names the LibrePortalSPAClean method that still does the rendering during the strangler migration; 'navId' is the existing topbar element id for active-state highlighting.",
|
"note": "Phase-0 hand-committed manifest (to be replaced by the generated /data/webui/generated/features.json once the scan generator lands — see docs/frontend-modularization.md). 'module' is the feature's self-registering index.js; the kernel loads these from here so they no longer need <script> tags in index.html. 'handler' names the LibrePortalSPAClean method kept as the fallback during the strangler migration; 'navId' is the topbar element id for active-state highlighting.",
|
||||||
"features": [
|
"features": [
|
||||||
{
|
{
|
||||||
"id": "dashboard",
|
"id": "dashboard",
|
||||||
"routes": ["/", "/dashboard"],
|
"routes": ["/", "/dashboard"],
|
||||||
|
"module": "/features/dashboard/index.js",
|
||||||
"handler": "handleDashboard",
|
"handler": "handleDashboard",
|
||||||
"navId": "nav-dashboard",
|
"navId": "nav-dashboard",
|
||||||
"nav": { "label": "Dashboard", "order": 10 }
|
"nav": { "label": "Dashboard", "order": 10 }
|
||||||
@ -12,6 +13,7 @@
|
|||||||
{
|
{
|
||||||
"id": "apps",
|
"id": "apps",
|
||||||
"routes": ["/apps", "/apps*"],
|
"routes": ["/apps", "/apps*"],
|
||||||
|
"module": "/features/apps/index.js",
|
||||||
"handler": "handleApps",
|
"handler": "handleApps",
|
||||||
"navId": "nav-app-center",
|
"navId": "nav-app-center",
|
||||||
"nav": { "label": "App Center", "order": 20 }
|
"nav": { "label": "App Center", "order": 20 }
|
||||||
@ -19,12 +21,14 @@
|
|||||||
{
|
{
|
||||||
"id": "app-detail",
|
"id": "app-detail",
|
||||||
"routes": ["/app", "/app*"],
|
"routes": ["/app", "/app*"],
|
||||||
|
"module": "/features/app-detail/index.js",
|
||||||
"handler": "handleAppDetail",
|
"handler": "handleAppDetail",
|
||||||
"navId": "nav-app-center"
|
"navId": "nav-app-center"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "admin",
|
"id": "admin",
|
||||||
"routes": ["/admin", "/admin*"],
|
"routes": ["/admin", "/admin*"],
|
||||||
|
"module": "/features/admin/index.js",
|
||||||
"handler": "handleAdmin",
|
"handler": "handleAdmin",
|
||||||
"navId": "nav-config",
|
"navId": "nav-config",
|
||||||
"nav": { "label": "Admin", "order": 40 }
|
"nav": { "label": "Admin", "order": 40 }
|
||||||
@ -38,6 +42,7 @@
|
|||||||
{
|
{
|
||||||
"id": "tasks",
|
"id": "tasks",
|
||||||
"routes": ["/tasks", "/tasks*"],
|
"routes": ["/tasks", "/tasks*"],
|
||||||
|
"module": "/features/tasks/index.js",
|
||||||
"handler": "handleTasks",
|
"handler": "handleTasks",
|
||||||
"navId": "nav-tasks",
|
"navId": "nav-tasks",
|
||||||
"nav": { "label": "Tasks", "order": 60 }
|
"nav": { "label": "Tasks", "order": 60 }
|
||||||
@ -45,6 +50,7 @@
|
|||||||
{
|
{
|
||||||
"id": "backup",
|
"id": "backup",
|
||||||
"routes": ["/backup", "/backup*"],
|
"routes": ["/backup", "/backup*"],
|
||||||
|
"module": "/features/backup/index.js",
|
||||||
"handler": "handleBackup",
|
"handler": "handleBackup",
|
||||||
"navId": "nav-backup",
|
"navId": "nav-backup",
|
||||||
"nav": { "label": "Backups", "order": 50 }
|
"nav": { "label": "Backups", "order": 50 }
|
||||||
|
|||||||
@ -109,14 +109,10 @@
|
|||||||
docs/frontend-modularization.md. -->
|
docs/frontend-modularization.md. -->
|
||||||
<script src="/kernel/feature-registry.js"></script>
|
<script src="/kernel/feature-registry.js"></script>
|
||||||
<script src="/kernel/lifecycle.js"></script>
|
<script src="/kernel/lifecycle.js"></script>
|
||||||
<!-- Feature modules self-register here (eager, tiny). Their heavy controllers
|
<!-- Feature modules are NOT listed here: the kernel loads each feature's
|
||||||
are still lazy-loaded by the module's mount(). -->
|
self-registering index.js from the manifest (features/manifest.dev.json)
|
||||||
<script src="/features/dashboard/index.js"></script>
|
before routing. Adding a page = drop a features/<id>/ folder + a manifest
|
||||||
<script src="/features/apps/index.js"></script>
|
entry, no index.html edit. Heavy controllers stay lazy (loaded by mount). -->
|
||||||
<script src="/features/app-detail/index.js"></script>
|
|
||||||
<script src="/features/admin/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
|
||||||
|
|||||||
@ -102,6 +102,17 @@ class LibrePortalSPAClean {
|
|||||||
this.setupRoutes();
|
this.setupRoutes();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load each feature's self-registering module (if declared) BEFORE building
|
||||||
|
// routes, so LP.features.get(id) sees the registered mount(). This is what
|
||||||
|
// lets index.html drop its per-feature <script> list — the manifest is the
|
||||||
|
// one place a feature is declared. loadScript is idempotent + non-fatal: a
|
||||||
|
// module that 404s or fails to register simply leaves that route on its
|
||||||
|
// legacy handler.
|
||||||
|
const modules = [...new Set(entries.map(f => f.module).filter(Boolean))];
|
||||||
|
await Promise.all(modules.map(src =>
|
||||||
|
this.loadScript(src).catch(err => console.warn(`[spa] feature module "${src}" failed to load:`, err))
|
||||||
|
));
|
||||||
// All-or-nothing: a single missing handler means we don't trust the
|
// All-or-nothing: a single missing handler means we don't trust the
|
||||||
// manifest enough to route from it — use the known-good built-in table.
|
// manifest enough to route from it — use the known-good built-in table.
|
||||||
for (const f of entries) {
|
for (const f of entries) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user