From 2ef4cc00e1de52347a2033ef75170b06f5b213cd Mon Sep 17 00:00:00 2001 From: librelad Date: Sat, 30 May 2026 12:42:35 +0100 Subject: [PATCH] refactor(webui): granular sub-system folders per component De-clutter each component into sub-system folders (apps: core/ port-manager/ services/ tools/ routing/; admin: config/ overview/ system/ ssh/ peers/) with the standard js/ css/ html/ icons/ layout inside; single-page components (backup/dashboard/tasks/updater) get js/ css/ html/. Single-feature icon sets moved into their sub-system (vpn -> apps/core/icons, config/cpu/os -> admin/{config,system}/icons); shared app + category icons stay in core/icons. feature.json + index.js stay at each component root (the scanned descriptor + entry). Every controller/CSS/fragment/icon path reference rewritten; verified no stale refs, all JS valid. Co-Authored-By: Claude Opus 4.8 Signed-off-by: librelad --- .../admin/{ => config/css}/ip-whitelist.css | 0 .../{ => config/html}/config-content.html | 0 .../admin/config}/icons/config/backup.svg | 0 .../admin/config}/icons/config/features.svg | 0 .../admin/config}/icons/config/general.svg | 0 .../admin/config}/icons/config/network.svg | 0 .../admin/config}/icons/config/security.svg | 0 .../admin/config}/icons/config/webui.svg | 0 .../admin/{ => config/js}/config-core.js | 0 .../admin/{ => config/js}/config-form.js | 0 .../admin/{ => config/js}/config-manager.js | 20 +++++------ .../admin/{ => config/js}/config-renderer.js | 0 .../admin/{ => config/js}/config-sidebar.js | 2 +- .../admin/{ => config/js}/config-utils.js | 0 .../admin/{ => config/js}/config-validator.js | 0 .../admin/{ => config/js}/domain-manager.js | 0 .../{ => config/js}/ip-whitelist-manager.js | 0 .../admin/{ => config/js}/toggle-manager.js | 0 .../components/admin/{ => css}/admin.css | 0 .../frontend/components/admin/index.js | 2 +- .../admin/{ => overview/js}/admin-overview.js | 0 .../admin/{ => peers/html}/peers-content.html | 0 .../admin/{ => peers/js}/peers-page.js | 0 .../components/admin/{ => ssh/css}/ssh.css | 0 .../components/admin/{ => ssh/js}/ssh-page.js | 0 .../admin/system}/icons/cpu/amd.svg | 0 .../admin/system}/icons/cpu/intel.svg | 0 .../admin/system}/icons/os/arch.svg | 0 .../admin/system}/icons/os/debian.svg | 0 .../admin/system}/icons/os/fedora.svg | 0 .../admin/system}/icons/os/linux.svg | 0 .../admin/system}/icons/os/ubuntu.svg | 0 .../admin/{ => system/js}/admin-system.js | 6 ++-- .../admin/{ => system/js}/charts.js | 0 .../{ => system/js}/system-metric-page.js | 0 .../{ => system/js}/system-storage-page.js | 0 .../frontend/components/app-detail/index.js | 2 +- .../apps/{ => core/css}/apps-layout.css | 0 .../components/apps/{ => core/css}/apps.css | 0 .../apps/{ => core/css}/service-buttons.css | 0 .../{ => core/html}/apps-unified-layout.html | 0 .../apps}/core/icons/vpn/airvpn.svg | 0 .../apps}/core/icons/vpn/cyberghost.png | Bin .../apps}/core/icons/vpn/expressvpn.svg | 0 .../apps}/core/icons/vpn/fastestvpn.png | Bin .../apps}/core/icons/vpn/giganews.png | Bin .../apps}/core/icons/vpn/hidemyass.png | Bin .../apps}/core/icons/vpn/ipvanish.svg | 0 .../apps}/core/icons/vpn/ivpn.png | Bin .../apps}/core/icons/vpn/mullvad.svg | 0 .../apps}/core/icons/vpn/nordvpn.svg | 0 .../apps}/core/icons/vpn/privado.png | Bin .../icons/vpn/private-internet-access.svg | 0 .../apps}/core/icons/vpn/privatevpn.png | Bin .../apps}/core/icons/vpn/protonvpn.svg | 0 .../apps}/core/icons/vpn/purevpn.png | Bin .../apps}/core/icons/vpn/slickvpn.png | Bin .../apps}/core/icons/vpn/surfshark.svg | 0 .../apps}/core/icons/vpn/torguard.png | Bin .../apps}/core/icons/vpn/vpn-unlimited.png | Bin .../apps}/core/icons/vpn/vpnsecure.png | Bin .../apps}/core/icons/vpn/vyprvpn.png | Bin .../apps}/core/icons/vpn/windscribe.png | Bin .../apps/{ => core/js}/app-tabbed-manager.js | 0 .../apps/{ => core/js}/apps-manager.js | 4 +-- .../frontend/components/apps/index.js | 2 +- .../{ => port-manager/css}/port-manager.css | 0 .../{ => port-manager/js}/port-manager.js | 0 .../apps/{ => routing/css}/routing.css | 0 .../apps/{ => routing/js}/routing-manager.js | 0 .../apps/{ => services/css}/services.css | 0 .../{ => services/js}/services-manager.js | 0 .../components/apps/{ => tools/css}/tools.css | 0 .../apps/{ => tools/js}/tools-manager.js | 0 .../components/backup/{ => css}/backup.css | 0 .../backup/{ => html}/backup-content.html | 0 .../frontend/components/backup/index.js | 6 ++-- .../components/backup/{ => js}/backup-page.js | 0 .../backup/{ => js}/backup-schema.js | 0 .../dashboard/{ => css}/dashboard.css | 0 .../{ => html}/dashboard-content.html | 0 .../frontend/components/dashboard/index.js | 2 +- .../dashboard/{ => js}/dashboard.js | 0 .../components/tasks/{ => css}/tasks.css | 0 .../tasks/{ => html}/tasks-content.html | 0 .../frontend/components/tasks/index.js | 2 +- .../tasks/{ => js}/tasks-manager.js | 0 .../components/updater/{ => css}/updater.css | 0 .../updater/{ => html}/updater-content.html | 0 .../frontend/components/updater/index.js | 4 +-- .../updater/{ => js}/updater-page.js | 0 .../frontend/core/boot/system-loader.js | 34 +++++++++--------- .../libreportal/frontend/core/kernel/spa.js | 14 ++++---- containers/libreportal/frontend/index.html | 30 ++++++++-------- 94 files changed, 65 insertions(+), 65 deletions(-) rename containers/libreportal/frontend/components/admin/{ => config/css}/ip-whitelist.css (100%) rename containers/libreportal/frontend/components/admin/{ => config/html}/config-content.html (100%) rename containers/libreportal/frontend/{core => components/admin/config}/icons/config/backup.svg (100%) rename containers/libreportal/frontend/{core => components/admin/config}/icons/config/features.svg (100%) rename containers/libreportal/frontend/{core => components/admin/config}/icons/config/general.svg (100%) rename containers/libreportal/frontend/{core => components/admin/config}/icons/config/network.svg (100%) rename containers/libreportal/frontend/{core => components/admin/config}/icons/config/security.svg (100%) rename containers/libreportal/frontend/{core => components/admin/config}/icons/config/webui.svg (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/config-core.js (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/config-form.js (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/config-manager.js (95%) rename containers/libreportal/frontend/components/admin/{ => config/js}/config-renderer.js (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/config-sidebar.js (99%) rename containers/libreportal/frontend/components/admin/{ => config/js}/config-utils.js (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/config-validator.js (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/domain-manager.js (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/ip-whitelist-manager.js (100%) rename containers/libreportal/frontend/components/admin/{ => config/js}/toggle-manager.js (100%) rename containers/libreportal/frontend/components/admin/{ => css}/admin.css (100%) rename containers/libreportal/frontend/components/admin/{ => overview/js}/admin-overview.js (100%) rename containers/libreportal/frontend/components/admin/{ => peers/html}/peers-content.html (100%) rename containers/libreportal/frontend/components/admin/{ => peers/js}/peers-page.js (100%) rename containers/libreportal/frontend/components/admin/{ => ssh/css}/ssh.css (100%) rename containers/libreportal/frontend/components/admin/{ => ssh/js}/ssh-page.js (100%) rename containers/libreportal/frontend/{core => components/admin/system}/icons/cpu/amd.svg (100%) rename containers/libreportal/frontend/{core => components/admin/system}/icons/cpu/intel.svg (100%) rename containers/libreportal/frontend/{core => components/admin/system}/icons/os/arch.svg (100%) rename containers/libreportal/frontend/{core => components/admin/system}/icons/os/debian.svg (100%) rename containers/libreportal/frontend/{core => components/admin/system}/icons/os/fedora.svg (100%) rename containers/libreportal/frontend/{core => components/admin/system}/icons/os/linux.svg (100%) rename containers/libreportal/frontend/{core => components/admin/system}/icons/os/ubuntu.svg (100%) rename containers/libreportal/frontend/components/admin/{ => system/js}/admin-system.js (98%) rename containers/libreportal/frontend/components/admin/{ => system/js}/charts.js (100%) rename containers/libreportal/frontend/components/admin/{ => system/js}/system-metric-page.js (100%) rename containers/libreportal/frontend/components/admin/{ => system/js}/system-storage-page.js (100%) rename containers/libreportal/frontend/components/apps/{ => core/css}/apps-layout.css (100%) rename containers/libreportal/frontend/components/apps/{ => core/css}/apps.css (100%) rename containers/libreportal/frontend/components/apps/{ => core/css}/service-buttons.css (100%) rename containers/libreportal/frontend/components/apps/{ => core/html}/apps-unified-layout.html (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/airvpn.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/cyberghost.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/expressvpn.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/fastestvpn.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/giganews.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/hidemyass.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/ipvanish.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/ivpn.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/mullvad.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/nordvpn.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/privado.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/private-internet-access.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/privatevpn.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/protonvpn.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/purevpn.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/slickvpn.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/surfshark.svg (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/torguard.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/vpn-unlimited.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/vpnsecure.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/vyprvpn.png (100%) rename containers/libreportal/frontend/{ => components/apps}/core/icons/vpn/windscribe.png (100%) rename containers/libreportal/frontend/components/apps/{ => core/js}/app-tabbed-manager.js (100%) rename containers/libreportal/frontend/components/apps/{ => core/js}/apps-manager.js (99%) rename containers/libreportal/frontend/components/apps/{ => port-manager/css}/port-manager.css (100%) rename containers/libreportal/frontend/components/apps/{ => port-manager/js}/port-manager.js (100%) rename containers/libreportal/frontend/components/apps/{ => routing/css}/routing.css (100%) rename containers/libreportal/frontend/components/apps/{ => routing/js}/routing-manager.js (100%) rename containers/libreportal/frontend/components/apps/{ => services/css}/services.css (100%) rename containers/libreportal/frontend/components/apps/{ => services/js}/services-manager.js (100%) rename containers/libreportal/frontend/components/apps/{ => tools/css}/tools.css (100%) rename containers/libreportal/frontend/components/apps/{ => tools/js}/tools-manager.js (100%) rename containers/libreportal/frontend/components/backup/{ => css}/backup.css (100%) rename containers/libreportal/frontend/components/backup/{ => html}/backup-content.html (100%) rename containers/libreportal/frontend/components/backup/{ => js}/backup-page.js (100%) rename containers/libreportal/frontend/components/backup/{ => js}/backup-schema.js (100%) rename containers/libreportal/frontend/components/dashboard/{ => css}/dashboard.css (100%) rename containers/libreportal/frontend/components/dashboard/{ => html}/dashboard-content.html (100%) rename containers/libreportal/frontend/components/dashboard/{ => js}/dashboard.js (100%) rename containers/libreportal/frontend/components/tasks/{ => css}/tasks.css (100%) rename containers/libreportal/frontend/components/tasks/{ => html}/tasks-content.html (100%) rename containers/libreportal/frontend/components/tasks/{ => js}/tasks-manager.js (100%) rename containers/libreportal/frontend/components/updater/{ => css}/updater.css (100%) rename containers/libreportal/frontend/components/updater/{ => html}/updater-content.html (100%) rename containers/libreportal/frontend/components/updater/{ => js}/updater-page.js (100%) diff --git a/containers/libreportal/frontend/components/admin/ip-whitelist.css b/containers/libreportal/frontend/components/admin/config/css/ip-whitelist.css similarity index 100% rename from containers/libreportal/frontend/components/admin/ip-whitelist.css rename to containers/libreportal/frontend/components/admin/config/css/ip-whitelist.css diff --git a/containers/libreportal/frontend/components/admin/config-content.html b/containers/libreportal/frontend/components/admin/config/html/config-content.html similarity index 100% rename from containers/libreportal/frontend/components/admin/config-content.html rename to containers/libreportal/frontend/components/admin/config/html/config-content.html diff --git a/containers/libreportal/frontend/core/icons/config/backup.svg b/containers/libreportal/frontend/components/admin/config/icons/config/backup.svg similarity index 100% rename from containers/libreportal/frontend/core/icons/config/backup.svg rename to containers/libreportal/frontend/components/admin/config/icons/config/backup.svg diff --git a/containers/libreportal/frontend/core/icons/config/features.svg b/containers/libreportal/frontend/components/admin/config/icons/config/features.svg similarity index 100% rename from containers/libreportal/frontend/core/icons/config/features.svg rename to containers/libreportal/frontend/components/admin/config/icons/config/features.svg diff --git a/containers/libreportal/frontend/core/icons/config/general.svg b/containers/libreportal/frontend/components/admin/config/icons/config/general.svg similarity index 100% rename from containers/libreportal/frontend/core/icons/config/general.svg rename to containers/libreportal/frontend/components/admin/config/icons/config/general.svg diff --git a/containers/libreportal/frontend/core/icons/config/network.svg b/containers/libreportal/frontend/components/admin/config/icons/config/network.svg similarity index 100% rename from containers/libreportal/frontend/core/icons/config/network.svg rename to containers/libreportal/frontend/components/admin/config/icons/config/network.svg diff --git a/containers/libreportal/frontend/core/icons/config/security.svg b/containers/libreportal/frontend/components/admin/config/icons/config/security.svg similarity index 100% rename from containers/libreportal/frontend/core/icons/config/security.svg rename to containers/libreportal/frontend/components/admin/config/icons/config/security.svg diff --git a/containers/libreportal/frontend/core/icons/config/webui.svg b/containers/libreportal/frontend/components/admin/config/icons/config/webui.svg similarity index 100% rename from containers/libreportal/frontend/core/icons/config/webui.svg rename to containers/libreportal/frontend/components/admin/config/icons/config/webui.svg diff --git a/containers/libreportal/frontend/components/admin/config-core.js b/containers/libreportal/frontend/components/admin/config/js/config-core.js similarity index 100% rename from containers/libreportal/frontend/components/admin/config-core.js rename to containers/libreportal/frontend/components/admin/config/js/config-core.js diff --git a/containers/libreportal/frontend/components/admin/config-form.js b/containers/libreportal/frontend/components/admin/config/js/config-form.js similarity index 100% rename from containers/libreportal/frontend/components/admin/config-form.js rename to containers/libreportal/frontend/components/admin/config/js/config-form.js diff --git a/containers/libreportal/frontend/components/admin/config-manager.js b/containers/libreportal/frontend/components/admin/config/js/config-manager.js similarity index 95% rename from containers/libreportal/frontend/components/admin/config-manager.js rename to containers/libreportal/frontend/components/admin/config/js/config-manager.js index 881a33a..39f92be 100755 --- a/containers/libreportal/frontend/components/admin/config-manager.js +++ b/containers/libreportal/frontend/components/admin/config/js/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('/components/admin/admin-overview.js'), - lazyLoad('/components/admin/charts.js') + lazyLoad('/components/admin/overview/js/admin-overview.js'), + lazyLoad('/components/admin/system/js/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('/components/admin/ssh-page.js'); + await lazyLoad('/components/admin/ssh/js/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('/components/admin/peers-page.js'); + await lazyLoad('/components/admin/peers/js/peers-page.js'); try { - const html = await fetch('/components/admin/peers-content.html').then(r => r.text()); + const html = await fetch('/components/admin/peers/html/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('/components/admin/charts.js'), - lazyLoad('/components/admin/admin-system.js'), - lazyLoad('/components/admin/system-metric-page.js'), - lazyLoad('/components/admin/system-storage-page.js') + lazyLoad('/components/admin/system/js/charts.js'), + lazyLoad('/components/admin/system/js/admin-system.js'), + lazyLoad('/components/admin/system/js/system-metric-page.js'), + lazyLoad('/components/admin/system/js/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 = '