From d39852aa3db3484a4da0796db6d45a12a328620e Mon Sep 17 00:00:00 2001 From: librelad Date: Sat, 30 May 2026 07:13:52 +0100 Subject: [PATCH] refactor(webui): reorganize into components/ + core/ taxonomy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Final modularization layout (user-chosen): every page is a self-contained folder under components// (controllers + CSS + its html fragment), and all shared/framework code folds into core/: core/kernel (feature-registry, lifecycle, services, spa) core/boot (auth, system-loader/orchestrator, setup, loaders) core/lib (data-loader, router, helpers, the task kernel, shared modules) core/ui (topbar, modal, notifications, … + topbar.html) core/css (all shared stylesheets) core/icons Top level is now just: components/, core/, themes/, index.html (+ runtime data/). Every path reference rewritten (index.html, scripts arrays, fetch()/ loadFragment()/loadScript() literals, system-loader + config-manager controller paths, kernel manifest URL, feature.json, backend FEATURES_DIR). The /api/features/list endpoint NAME is unchanged (it now scans components/). Deleted 3 dead files (app-content.html, apps-content.html, html-cache.js). Verified: 0 stale prefixes, 0 double-rewrites, all JS/JSON valid. Co-Authored-By: Claude Opus 4.8 Signed-off-by: librelad --- .../libreportal/backend/routes/features.js | 4 +- .../admin/admin-overview.js | 0 .../admin/admin-system.js | 6 +- .../{features => components}/admin/admin.css | 0 .../{features => components}/admin/charts.js | 0 .../admin}/config-content.html | 0 .../admin/config-core.js | 0 .../admin/config-form.js | 0 .../admin/config-manager.js | 20 +-- .../admin/config-renderer.js | 0 .../admin/config-sidebar.js | 2 +- .../admin/config-utils.js | 0 .../admin/config-validator.js | 0 .../admin/domain-manager.js | 0 .../admin/feature.json | 2 +- .../{features => components}/admin/index.js | 2 +- .../admin/ip-whitelist-manager.js | 0 .../admin/ip-whitelist.css | 0 .../admin}/peers-content.html | 0 .../admin/peers-page.js | 0 .../admin/ssh-page.js | 0 .../{features => components}/admin/ssh.css | 0 .../admin/system-metric-page.js | 0 .../admin/system-storage-page.js | 4 +- .../admin/toggle-manager.js | 0 .../app-detail/feature.json | 2 +- .../app-detail/index.js | 2 +- .../apps/app-tabbed-manager.js | 0 .../apps/apps-layout.css | 0 .../apps/apps-manager.js | 46 +++---- .../apps}/apps-unified-layout.html | 0 .../{features => components}/apps/apps.css | 0 .../apps/feature.json | 2 +- .../{features => components}/apps/index.js | 2 +- .../apps/port-manager.css | 0 .../apps/port-manager.js | 0 .../apps/routing-manager.js | 2 +- .../{features => components}/apps/routing.css | 0 .../apps/service-buttons.css | 0 .../apps/services-manager.js | 2 +- .../apps/services.css | 0 .../apps/tools-manager.js | 8 +- .../{features => components}/apps/tools.css | 0 .../backup}/backup-content.html | 0 .../backup/backup-page.js | 10 +- .../backup/backup-schema.js | 0 .../backup/backup.css | 0 .../backup/feature.json | 2 +- .../{features => components}/backup/index.js | 8 +- .../config-redirect/feature.json | 0 .../dashboard}/dashboard-content.html | 0 .../dashboard/dashboard.css | 0 .../dashboard/dashboard.js | 4 +- .../dashboard/feature.json | 2 +- .../dashboard/index.js | 2 +- .../manifest.dev.json | 14 +-- .../peers/feature.json | 0 .../{features => components}/ssh/feature.json | 0 .../tasks/feature.json | 2 +- .../{features => components}/tasks/index.js | 2 +- .../tasks}/tasks-content.html | 0 .../tasks/tasks-manager.js | 10 +- .../{features => components}/tasks/tasks.css | 0 .../updater/feature.json | 2 +- .../{features => components}/updater/index.js | 4 +- .../updater}/updater-content.html | 0 .../updater/updater-page.js | 0 .../updater/updater.css | 0 .../{js/system => core/boot}/auth-manager.js | 2 +- .../{js/system => core/boot}/custom-number.js | 0 .../{js/system => core/boot}/custom-select.js | 0 .../{js/system => core/boot}/loading-ui.js | 2 +- .../boot}/setup-completion-watcher.js | 0 .../system => core/boot}/setup-detector.js | 0 .../{js/system => core/boot}/setup-wizard.js | 6 +- .../{js/system => core/boot}/system-loader.js | 74 +++++------ .../boot}/system-orchestrator.js | 0 .../system => core/boot}/theme-registry.js | 0 .../{ => core}/css/aurora-background.css | 0 .../frontend/{shared => core}/css/config.css | 0 .../frontend/{shared => core}/css/forms.css | 0 .../{ => core}/css/loading-screen.css | 0 .../frontend/{ => core}/css/login.css | 0 .../frontend/{ => core}/css/modal.css | 0 .../frontend/{ => core}/css/setup-wizard.css | 0 .../frontend/{ => core}/css/sidebar.css | 0 .../frontend/{ => core}/css/style.css | 0 .../frontend/{ => core}/css/themes.css | 0 .../frontend/{shared => core}/css/tokens.css | 0 .../frontend/{ => core}/css/topbar.css | 0 .../{ => core}/css/update-notifier.css | 0 .../{ => core}/icons/apps/adguard.svg | 0 .../{ => core}/icons/apps/authelia.svg | 0 .../{ => core}/icons/apps/bookstack.svg | 0 .../{ => core}/icons/apps/crowdsec.svg | 0 .../frontend/{ => core}/icons/apps/dashy.svg | 0 .../{ => core}/icons/apps/default.svg | 0 .../{ => core}/icons/apps/focalboard.svg | 0 .../frontend/{ => core}/icons/apps/gitea.svg | 0 .../{ => core}/icons/apps/gluetun.svg | 0 .../{ => core}/icons/apps/grafana.svg | 0 .../{ => core}/icons/apps/headscale.svg | 0 .../{ => core}/icons/apps/invidious.svg | 0 .../frontend/{ => core}/icons/apps/ipinfo.svg | 0 .../{ => core}/icons/apps/jellyfin.svg | 0 .../{ => core}/icons/apps/jitsimeet.svg | 0 .../{ => core}/icons/apps/libreportal.svg | 0 .../{ => core}/icons/apps/linkding.svg | 0 .../{ => core}/icons/apps/mastodon.svg | 0 .../{ => core}/icons/apps/nextcloud.svg | 0 .../frontend/{ => core}/icons/apps/ollama.svg | 0 .../{ => core}/icons/apps/onlyoffice.svg | 0 .../{ => core}/icons/apps/owncloud.svg | 0 .../frontend/{ => core}/icons/apps/pihole.svg | 0 .../{ => core}/icons/apps/portainer.svg | 0 .../{ => core}/icons/apps/prometheus.svg | 0 .../{ => core}/icons/apps/searxng.svg | 0 .../{ => core}/icons/apps/speedtest.svg | 0 .../{ => core}/icons/apps/traefik.svg | 0 .../{ => core}/icons/apps/trilium.svg | 0 .../{ => core}/icons/apps/unbound.svg | 0 .../{ => core}/icons/apps/vaultwarden.svg | 0 .../{ => core}/icons/apps/wireguard.svg | 0 .../{ => core}/icons/categories/all.svg | 0 .../icons/categories/communication.svg | 0 .../icons/categories/development.svg | 0 .../{ => core}/icons/categories/installed.svg | 0 .../{ => core}/icons/categories/knowledge.svg | 0 .../{ => core}/icons/categories/media.svg | 0 .../{ => core}/icons/categories/misc.svg | 0 .../icons/categories/monitoring.svg | 0 .../icons/categories/networking.svg | 0 .../icons/categories/productivity.svg | 0 .../icons/categories/recommended.svg | 0 .../{ => core}/icons/categories/security.svg | 0 .../{ => core}/icons/categories/storage.svg | 0 .../{ => core}/icons/categories/system.svg | 0 .../{ => core}/icons/categories/utils.svg | 0 .../{ => core}/icons/config/backup.svg | 0 .../{ => core}/icons/config/features.svg | 0 .../{ => core}/icons/config/general.svg | 0 .../{ => core}/icons/config/network.svg | 0 .../{ => core}/icons/config/security.svg | 0 .../{ => core}/icons/config/webui.svg | 0 .../frontend/{ => core}/icons/cpu/amd.svg | 0 .../frontend/{ => core}/icons/cpu/intel.svg | 0 .../frontend/{ => core}/icons/favicon.ico | Bin .../frontend/{ => core}/icons/libreportal.svg | 0 .../frontend/{ => core}/icons/os/arch.svg | 0 .../frontend/{ => core}/icons/os/debian.svg | 0 .../frontend/{ => core}/icons/os/fedora.svg | 0 .../frontend/{ => core}/icons/os/linux.svg | 0 .../frontend/{ => core}/icons/os/ubuntu.svg | 0 .../frontend/{ => core}/icons/vpn/airvpn.svg | 0 .../{ => core}/icons/vpn/cyberghost.png | Bin .../{ => core}/icons/vpn/expressvpn.svg | 0 .../{ => core}/icons/vpn/fastestvpn.png | Bin .../{ => core}/icons/vpn/giganews.png | Bin .../{ => core}/icons/vpn/hidemyass.png | Bin .../{ => core}/icons/vpn/ipvanish.svg | 0 .../frontend/{ => core}/icons/vpn/ivpn.png | Bin .../frontend/{ => core}/icons/vpn/mullvad.svg | 0 .../frontend/{ => core}/icons/vpn/nordvpn.svg | 0 .../frontend/{ => core}/icons/vpn/privado.png | Bin .../icons/vpn/private-internet-access.svg | 0 .../{ => core}/icons/vpn/privatevpn.png | Bin .../{ => core}/icons/vpn/protonvpn.svg | 0 .../frontend/{ => core}/icons/vpn/purevpn.png | Bin .../{ => core}/icons/vpn/slickvpn.png | Bin .../{ => core}/icons/vpn/surfshark.svg | 0 .../{ => core}/icons/vpn/torguard.png | Bin .../{ => core}/icons/vpn/vpn-unlimited.png | Bin .../{ => core}/icons/vpn/vpnsecure.png | Bin .../frontend/{ => core}/icons/vpn/vyprvpn.png | Bin .../{ => core}/icons/vpn/windscribe.png | Bin .../{ => core}/kernel/feature-registry.js | 2 +- .../frontend/{ => core}/kernel/lifecycle.js | 0 .../frontend/{ => core}/kernel/services.js | 0 .../frontend/{js => core/kernel}/spa.js | 16 +-- .../js => core/lib}/backup-app-card.js | 2 +- .../{shared/js => core/lib}/config-options.js | 0 .../{shared/js => core/lib}/config-shared.js | 0 .../{js/utils => core/lib}/data-loader.js | 2 +- .../{js/utils => core/lib}/dismissible.js | 0 .../{js/utils => core/lib}/dom-helpers.js | 0 .../frontend/{js/utils => core/lib}/lp-ui.js | 0 .../frontend/{js/utils => core/lib}/router.js | 0 .../{js/utils => core/lib}/system-live.js | 0 .../{shared/task => core/lib}/task-actions.js | 6 +- .../task => core/lib}/task-commands.js | 2 +- .../task => core/lib}/task-event-bus.js | 0 .../lib}/task-global-functions.js | 0 .../{shared/task => core/lib}/task-manager.js | 0 .../lib}/task-parameter-preserve.js | 0 .../lib}/task-refresh-coordinator.js | 0 .../{shared/task => core/lib}/task-router.js | 0 .../{js/utils => core/lib}/ui-helpers.js | 2 +- .../ui}/confirmation-dialog.js | 0 .../{js/components => core/ui}/eo-modal.js | 2 +- .../{js/components => core/ui}/mobile-menu.js | 0 .../components => core/ui}/notifications.js | 2 +- .../frontend/{html => core/ui}/topbar.html | 2 +- .../{js/components => core/ui}/topbar.js | 2 +- .../components => core/ui}/update-notifier.js | 0 .../frontend/html/app-content.html | 116 ------------------ .../frontend/html/apps-content.html | 71 ----------- containers/libreportal/frontend/index.html | 108 ++++++++-------- .../frontend/js/utils/html-cache.js | 0 208 files changed, 200 insertions(+), 387 deletions(-) rename containers/libreportal/frontend/{features => components}/admin/admin-overview.js (100%) rename containers/libreportal/frontend/{features => components}/admin/admin-system.js (98%) rename containers/libreportal/frontend/{features => components}/admin/admin.css (100%) rename containers/libreportal/frontend/{features => components}/admin/charts.js (100%) rename containers/libreportal/frontend/{html => components/admin}/config-content.html (100%) rename containers/libreportal/frontend/{features => components}/admin/config-core.js (100%) rename containers/libreportal/frontend/{features => components}/admin/config-form.js (100%) rename containers/libreportal/frontend/{features => components}/admin/config-manager.js (96%) rename containers/libreportal/frontend/{features => components}/admin/config-renderer.js (100%) rename containers/libreportal/frontend/{features => components}/admin/config-sidebar.js (99%) rename containers/libreportal/frontend/{features => components}/admin/config-utils.js (100%) rename containers/libreportal/frontend/{features => components}/admin/config-validator.js (100%) rename containers/libreportal/frontend/{features => components}/admin/domain-manager.js (100%) rename containers/libreportal/frontend/{features => components}/admin/feature.json (79%) rename containers/libreportal/frontend/{features => components}/admin/index.js (96%) rename containers/libreportal/frontend/{features => components}/admin/ip-whitelist-manager.js (100%) rename containers/libreportal/frontend/{features => components}/admin/ip-whitelist.css (100%) rename containers/libreportal/frontend/{html => components/admin}/peers-content.html (100%) rename containers/libreportal/frontend/{features => components}/admin/peers-page.js (100%) rename containers/libreportal/frontend/{features => components}/admin/ssh-page.js (100%) rename containers/libreportal/frontend/{features => components}/admin/ssh.css (100%) rename containers/libreportal/frontend/{features => components}/admin/system-metric-page.js (100%) rename containers/libreportal/frontend/{features => components}/admin/system-storage-page.js (99%) rename containers/libreportal/frontend/{features => components}/admin/toggle-manager.js (100%) rename containers/libreportal/frontend/{features => components}/app-detail/feature.json (73%) rename containers/libreportal/frontend/{features => components}/app-detail/index.js (96%) rename containers/libreportal/frontend/{features => components}/apps/app-tabbed-manager.js (100%) rename containers/libreportal/frontend/{features => components}/apps/apps-layout.css (100%) rename containers/libreportal/frontend/{features => components}/apps/apps-manager.js (99%) rename containers/libreportal/frontend/{html => components/apps}/apps-unified-layout.html (100%) rename containers/libreportal/frontend/{features => components}/apps/apps.css (100%) rename containers/libreportal/frontend/{features => components}/apps/feature.json (80%) rename containers/libreportal/frontend/{features => components}/apps/index.js (95%) rename containers/libreportal/frontend/{features => components}/apps/port-manager.css (100%) rename containers/libreportal/frontend/{features => components}/apps/port-manager.js (100%) rename containers/libreportal/frontend/{features => components}/apps/routing-manager.js (99%) rename containers/libreportal/frontend/{features => components}/apps/routing.css (100%) rename containers/libreportal/frontend/{features => components}/apps/service-buttons.css (100%) rename containers/libreportal/frontend/{features => components}/apps/services-manager.js (99%) rename containers/libreportal/frontend/{features => components}/apps/services.css (100%) rename containers/libreportal/frontend/{features => components}/apps/tools-manager.js (99%) rename containers/libreportal/frontend/{features => components}/apps/tools.css (100%) rename containers/libreportal/frontend/{html => components/backup}/backup-content.html (100%) rename containers/libreportal/frontend/{features => components}/backup/backup-page.js (99%) rename containers/libreportal/frontend/{features => components}/backup/backup-schema.js (100%) rename containers/libreportal/frontend/{features => components}/backup/backup.css (100%) rename containers/libreportal/frontend/{features => components}/backup/feature.json (80%) rename containers/libreportal/frontend/{features => components}/backup/index.js (89%) rename containers/libreportal/frontend/{features => components}/config-redirect/feature.json (100%) rename containers/libreportal/frontend/{html => components/dashboard}/dashboard-content.html (100%) rename containers/libreportal/frontend/{features => components}/dashboard/dashboard.css (100%) rename containers/libreportal/frontend/{features => components}/dashboard/dashboard.js (98%) rename containers/libreportal/frontend/{features => components}/dashboard/feature.json (79%) rename containers/libreportal/frontend/{features => components}/dashboard/index.js (95%) rename containers/libreportal/frontend/{features => components}/manifest.dev.json (86%) rename containers/libreportal/frontend/{features => components}/peers/feature.json (100%) rename containers/libreportal/frontend/{features => components}/ssh/feature.json (100%) rename containers/libreportal/frontend/{features => components}/tasks/feature.json (79%) rename containers/libreportal/frontend/{features => components}/tasks/index.js (95%) rename containers/libreportal/frontend/{html => components/tasks}/tasks-content.html (100%) rename containers/libreportal/frontend/{features => components}/tasks/tasks-manager.js (99%) rename containers/libreportal/frontend/{features => components}/tasks/tasks.css (100%) rename containers/libreportal/frontend/{features => components}/updater/feature.json (89%) rename containers/libreportal/frontend/{features => components}/updater/index.js (90%) rename containers/libreportal/frontend/{html => components/updater}/updater-content.html (100%) rename containers/libreportal/frontend/{features => components}/updater/updater-page.js (100%) rename containers/libreportal/frontend/{features => components}/updater/updater.css (100%) rename containers/libreportal/frontend/{js/system => core/boot}/auth-manager.js (97%) rename containers/libreportal/frontend/{js/system => core/boot}/custom-number.js (100%) rename containers/libreportal/frontend/{js/system => core/boot}/custom-select.js (100%) rename containers/libreportal/frontend/{js/system => core/boot}/loading-ui.js (99%) rename containers/libreportal/frontend/{js/system => core/boot}/setup-completion-watcher.js (100%) rename containers/libreportal/frontend/{js/system => core/boot}/setup-detector.js (100%) rename containers/libreportal/frontend/{js/system => core/boot}/setup-wizard.js (99%) rename containers/libreportal/frontend/{js/system => core/boot}/system-loader.js (96%) rename containers/libreportal/frontend/{js/system => core/boot}/system-orchestrator.js (100%) rename containers/libreportal/frontend/{js/system => core/boot}/theme-registry.js (100%) rename containers/libreportal/frontend/{ => core}/css/aurora-background.css (100%) rename containers/libreportal/frontend/{shared => core}/css/config.css (100%) rename containers/libreportal/frontend/{shared => core}/css/forms.css (100%) rename containers/libreportal/frontend/{ => core}/css/loading-screen.css (100%) rename containers/libreportal/frontend/{ => core}/css/login.css (100%) rename containers/libreportal/frontend/{ => core}/css/modal.css (100%) rename containers/libreportal/frontend/{ => core}/css/setup-wizard.css (100%) rename containers/libreportal/frontend/{ => core}/css/sidebar.css (100%) rename containers/libreportal/frontend/{ => core}/css/style.css (100%) rename containers/libreportal/frontend/{ => core}/css/themes.css (100%) rename containers/libreportal/frontend/{shared => core}/css/tokens.css (100%) rename containers/libreportal/frontend/{ => core}/css/topbar.css (100%) rename containers/libreportal/frontend/{ => core}/css/update-notifier.css (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/adguard.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/authelia.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/bookstack.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/crowdsec.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/dashy.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/default.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/focalboard.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/gitea.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/gluetun.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/grafana.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/headscale.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/invidious.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/ipinfo.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/jellyfin.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/jitsimeet.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/libreportal.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/linkding.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/mastodon.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/nextcloud.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/ollama.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/onlyoffice.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/owncloud.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/pihole.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/portainer.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/prometheus.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/searxng.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/speedtest.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/traefik.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/trilium.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/unbound.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/vaultwarden.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/apps/wireguard.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/all.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/communication.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/development.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/installed.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/knowledge.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/media.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/misc.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/monitoring.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/networking.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/productivity.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/recommended.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/security.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/storage.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/system.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/categories/utils.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/config/backup.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/config/features.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/config/general.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/config/network.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/config/security.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/config/webui.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/cpu/amd.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/cpu/intel.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/favicon.ico (100%) rename containers/libreportal/frontend/{ => core}/icons/libreportal.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/os/arch.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/os/debian.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/os/fedora.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/os/linux.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/os/ubuntu.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/airvpn.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/cyberghost.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/expressvpn.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/fastestvpn.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/giganews.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/hidemyass.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/ipvanish.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/ivpn.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/mullvad.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/nordvpn.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/privado.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/private-internet-access.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/privatevpn.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/protonvpn.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/purevpn.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/slickvpn.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/surfshark.svg (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/torguard.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/vpn-unlimited.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/vpnsecure.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/vyprvpn.png (100%) rename containers/libreportal/frontend/{ => core}/icons/vpn/windscribe.png (100%) rename containers/libreportal/frontend/{ => core}/kernel/feature-registry.js (98%) rename containers/libreportal/frontend/{ => core}/kernel/lifecycle.js (100%) rename containers/libreportal/frontend/{ => core}/kernel/services.js (100%) rename containers/libreportal/frontend/{js => core/kernel}/spa.js (97%) rename containers/libreportal/frontend/{shared/js => core/lib}/backup-app-card.js (99%) rename containers/libreportal/frontend/{shared/js => core/lib}/config-options.js (100%) rename containers/libreportal/frontend/{shared/js => core/lib}/config-shared.js (100%) rename containers/libreportal/frontend/{js/utils => core/lib}/data-loader.js (99%) rename containers/libreportal/frontend/{js/utils => core/lib}/dismissible.js (100%) rename containers/libreportal/frontend/{js/utils => core/lib}/dom-helpers.js (100%) rename containers/libreportal/frontend/{js/utils => core/lib}/lp-ui.js (100%) rename containers/libreportal/frontend/{js/utils => core/lib}/router.js (100%) rename containers/libreportal/frontend/{js/utils => core/lib}/system-live.js (100%) rename containers/libreportal/frontend/{shared/task => core/lib}/task-actions.js (98%) rename containers/libreportal/frontend/{shared/task => core/lib}/task-commands.js (99%) rename containers/libreportal/frontend/{shared/task => core/lib}/task-event-bus.js (100%) rename containers/libreportal/frontend/{shared/task => core/lib}/task-global-functions.js (100%) rename containers/libreportal/frontend/{shared/task => core/lib}/task-manager.js (100%) rename containers/libreportal/frontend/{js => core/lib}/task-parameter-preserve.js (100%) rename containers/libreportal/frontend/{shared/task => core/lib}/task-refresh-coordinator.js (100%) rename containers/libreportal/frontend/{shared/task => core/lib}/task-router.js (100%) rename containers/libreportal/frontend/{js/utils => core/lib}/ui-helpers.js (97%) rename containers/libreportal/frontend/{js/components => core/ui}/confirmation-dialog.js (100%) rename containers/libreportal/frontend/{js/components => core/ui}/eo-modal.js (99%) rename containers/libreportal/frontend/{js/components => core/ui}/mobile-menu.js (100%) rename containers/libreportal/frontend/{js/components => core/ui}/notifications.js (99%) rename containers/libreportal/frontend/{html => core/ui}/topbar.html (98%) rename containers/libreportal/frontend/{js/components => core/ui}/topbar.js (99%) rename containers/libreportal/frontend/{js/components => core/ui}/update-notifier.js (100%) delete mode 100755 containers/libreportal/frontend/html/app-content.html delete mode 100755 containers/libreportal/frontend/html/apps-content.html delete mode 100755 containers/libreportal/frontend/js/utils/html-cache.js diff --git a/containers/libreportal/backend/routes/features.js b/containers/libreportal/backend/routes/features.js index fd5f2e3..5f938e4 100644 --- a/containers/libreportal/backend/routes/features.js +++ b/containers/libreportal/backend/routes/features.js @@ -4,12 +4,12 @@ const path = require('path'); const router = express.Router(); -const FEATURES_DIR = path.join(__dirname, '..', '..', 'frontend', 'features'); +const FEATURES_DIR = path.join(__dirname, '..', '..', 'frontend', 'components'); /* ========================= GET /api/features/list - Walks frontend/features// and returns one entry per directory that + Walks frontend/components// and returns one entry per directory that contains a feature.json β€” the WebUI's page manifest, discovered from the folders themselves (exactly how /api/themes/list discovers themes). Drop a features// folder in and its page appears; delete it and the page is diff --git a/containers/libreportal/frontend/features/admin/admin-overview.js b/containers/libreportal/frontend/components/admin/admin-overview.js similarity index 100% rename from containers/libreportal/frontend/features/admin/admin-overview.js rename to containers/libreportal/frontend/components/admin/admin-overview.js diff --git a/containers/libreportal/frontend/features/admin/admin-system.js b/containers/libreportal/frontend/components/admin/admin-system.js similarity index 98% rename from containers/libreportal/frontend/features/admin/admin-system.js rename to containers/libreportal/frontend/components/admin/admin-system.js index 01337d3..50cd39f 100644 --- a/containers/libreportal/frontend/features/admin/admin-system.js +++ b/containers/libreportal/frontend/components/admin/admin-system.js @@ -401,14 +401,14 @@ class AdminSystem { return `
${this.escape(label)}${this.escape(value)}
`; } - // OS stat with a distro icon (bundled under /icons/os/, generic Linux glyph + // OS stat with a distro icon (bundled under /core/icons/os/, generic Linux glyph // for anything we don't have a logo for). _osStat(os) { const slug = String(os || '').toLowerCase().replace(/[^a-z0-9]/g, '') || 'linux'; return `
OS - + ${this.escape(os || 'β€”')}
`; @@ -430,7 +430,7 @@ class AdminSystem { _cpuStat(cpu) { const raw = String(cpu || ''); const vendor = /amd/i.test(raw) ? 'amd' : /intel/i.test(raw) ? 'intel' : null; - const icon = vendor ? `${vendor}` : ''; + const icon = vendor ? `${vendor}` : ''; return `
CPU ${icon}${this.escape(this._cleanCpu(raw))} diff --git a/containers/libreportal/frontend/features/admin/admin.css b/containers/libreportal/frontend/components/admin/admin.css similarity index 100% rename from containers/libreportal/frontend/features/admin/admin.css rename to containers/libreportal/frontend/components/admin/admin.css diff --git a/containers/libreportal/frontend/features/admin/charts.js b/containers/libreportal/frontend/components/admin/charts.js similarity index 100% rename from containers/libreportal/frontend/features/admin/charts.js rename to containers/libreportal/frontend/components/admin/charts.js diff --git a/containers/libreportal/frontend/html/config-content.html b/containers/libreportal/frontend/components/admin/config-content.html similarity index 100% rename from containers/libreportal/frontend/html/config-content.html rename to containers/libreportal/frontend/components/admin/config-content.html diff --git a/containers/libreportal/frontend/features/admin/config-core.js b/containers/libreportal/frontend/components/admin/config-core.js similarity index 100% rename from containers/libreportal/frontend/features/admin/config-core.js rename to containers/libreportal/frontend/components/admin/config-core.js diff --git a/containers/libreportal/frontend/features/admin/config-form.js b/containers/libreportal/frontend/components/admin/config-form.js similarity index 100% rename from containers/libreportal/frontend/features/admin/config-form.js rename to containers/libreportal/frontend/components/admin/config-form.js diff --git a/containers/libreportal/frontend/features/admin/config-manager.js b/containers/libreportal/frontend/components/admin/config-manager.js similarity index 96% rename from containers/libreportal/frontend/features/admin/config-manager.js rename to containers/libreportal/frontend/components/admin/config-manager.js index c7565d7..881a33a 100755 --- a/containers/libreportal/frontend/features/admin/config-manager.js +++ b/containers/libreportal/frontend/components/admin/config-manager.js @@ -44,8 +44,8 @@ if (typeof window.ConfigManager === 'undefined') { try { this.sidebar.populateSidebar(); } catch (e) {} // charts.js is the chart-rendering helper admin-overview pulls in. await Promise.all([ - lazyLoad('/features/admin/admin-overview.js'), - lazyLoad('/features/admin/charts.js') + lazyLoad('/components/admin/admin-overview.js'), + lazyLoad('/components/admin/charts.js') ]); if (typeof AdminOverview !== 'undefined') { window.adminOverview = new AdminOverview('config-section'); @@ -60,7 +60,7 @@ if (typeof window.ConfigManager === 'undefined') { // a config category β€” render its own controller into the main pane. if (category === 'ssh-access') { try { this.sidebar.populateSidebar(); } catch (e) {} - await lazyLoad('/features/admin/ssh-page.js'); + await lazyLoad('/components/admin/ssh-page.js'); if (typeof SshPage !== 'undefined') { window.sshPage = new SshPage('config-section'); await window.sshPage.init(); @@ -76,9 +76,9 @@ if (typeof window.ConfigManager === 'undefined') { // we inject its content template, then init PeersPage. if (category === 'peers') { try { this.sidebar.populateSidebar(); } catch (e) {} - await lazyLoad('/features/admin/peers-page.js'); + await lazyLoad('/components/admin/peers-page.js'); try { - const html = await fetch('/html/peers-content.html').then(r => r.text()); + const html = await fetch('/components/admin/peers-content.html').then(r => r.text()); configSection.innerHTML = html; } catch (e) { configSection.innerHTML = '
Peers page template failed to load.
'; @@ -100,10 +100,10 @@ if (typeof window.ConfigManager === 'undefined') { if (category === 'system') { try { this.sidebar.populateSidebar(); } catch (e) {} await Promise.all([ - lazyLoad('/features/admin/charts.js'), - lazyLoad('/features/admin/admin-system.js'), - lazyLoad('/features/admin/system-metric-page.js'), - lazyLoad('/features/admin/system-storage-page.js') + lazyLoad('/components/admin/charts.js'), + lazyLoad('/components/admin/admin-system.js'), + lazyLoad('/components/admin/system-metric-page.js'), + lazyLoad('/components/admin/system-storage-page.js') ]); if (typeof AdminSystem !== 'undefined') { window.adminSystem = new AdminSystem('config-section'); @@ -216,7 +216,7 @@ if (typeof window.ConfigManager === 'undefined') { var catIcon = catMeta.icon || category; var headerHTML = '