From d15f6b09ee05c89798d3c1ee9359c164a9916fd3 Mon Sep 17 00:00:00 2001 From: librelad Date: Thu, 28 May 2026 23:06:42 +0100 Subject: [PATCH] ux(system): collapse apps into one "Applications" slice on the System summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The System-page storage ring is an overview, so showing individual app (compose-project) names was wrong — it now shows a single "Applications" slice totalling all apps, alongside Images and Build cache. The per-app breakdown stays on the full Storage page. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- .../frontend/js/components/admin/admin-system.js | 6 +++--- .../js/components/admin/system-storage-page.js | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/containers/libreportal/frontend/js/components/admin/admin-system.js b/containers/libreportal/frontend/js/components/admin/admin-system.js index 5056231..176f5d0 100644 --- a/containers/libreportal/frontend/js/components/admin/admin-system.js +++ b/containers/libreportal/frontend/js/components/admin/admin-system.js @@ -357,9 +357,9 @@ class AdminSystem { `; } const C = window.LPCharts; - // Full LibrePortal breakdown: apps + Docker images/cache, not just the - // engine categories — same story the Storage page tells. - const segments = SP.unifiedSegments(this.d.appStorage, s); + // Summary breakdown: one "Applications" total + Docker images/cache. The + // per-app split lives on the full Storage page this links to. + const segments = SP.summarySegments(this.d.appStorage, s); const grandTotal = segments.reduce((t, seg) => t + ((seg.data && seg.data.size) || 0), 0); const donut = SP.donutSvg(segments, grandTotal, 'in use'); const recl = s.reclaimable || 0; diff --git a/containers/libreportal/frontend/js/components/admin/system-storage-page.js b/containers/libreportal/frontend/js/components/admin/system-storage-page.js index 8896d35..0808abd 100644 --- a/containers/libreportal/frontend/js/components/admin/system-storage-page.js +++ b/containers/libreportal/frontend/js/components/admin/system-storage-page.js @@ -185,8 +185,8 @@ class SystemStoragePage { static get APP_PALETTE() { return ['accent', 'status-info', 'status-success']; } // The full LibrePortal storage breakdown: a slice per app followed by the - // Docker engine categories. Shared by this page's donut and the System - // page's storage summary so both tell the same story. + // Docker engine categories. Used on this page's donut, where the per-app + // detail is the point. static unifiedSegments(appStorage, dockerData) { const pal = SystemStoragePage.APP_PALETTE; const apps = (appStorage && Array.isArray(appStorage.apps)) ? appStorage.apps : []; @@ -195,6 +195,18 @@ class SystemStoragePage { return [...appSegs, ...docker]; } + // Summary breakdown for the System-page overview: all apps collapse into one + // "Applications" slice (their total), then the Docker engine categories. The + // per-app split lives on the full Storage page, not here. + static summarySegments(appStorage, dockerData) { + const appsTotal = (appStorage && Number(appStorage.total)) || 0; + const seg = appsTotal > 0 + ? [{ key: 'apps', label: 'Applications', color: 'accent', data: { size: appsTotal }, kind: 'app' }] + : []; + const docker = dockerData ? SystemStoragePage.segmentsFrom(dockerData).map(s => ({ ...s, kind: 'docker' })) : []; + return [...seg, ...docker]; + } + // Hand-rolled donut, full circle = total. Each slice's dashoffset is the // running cumulative fraction (off), so a slice starts where the previous // one ended and the ring fills proportionally.