ux(system): one unified Storage donut — apps + Docker together
Put everything back in a single donut instead of an app-only one: a slice per app plus Docker's images and build cache, with one legend listing them all. Colours run continuously so app and Docker slices stay distinct, and the Docker cards below reuse the same colours. The per-folder app drill-down table stays. This is the "all the data, with app usage added" view that was asked for. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
beed825778
commit
e6cc84271c
@ -202,22 +202,41 @@ class SystemStoragePage {
|
||||
const palette = SystemStoragePage.PALETTE;
|
||||
const colorFor = i => palette[i % palette.length];
|
||||
|
||||
// ---- Headline: on-disk usage by app (the disk question that matters) ----
|
||||
// ---- Headline: ONE donut covering everything — a slice per app, then
|
||||
// Docker's own categories (images, build cache). Colours run continuously
|
||||
// across the whole list so app and Docker slices stay distinct, and the
|
||||
// legend lists them all. This is the unified "where's my disk going" view.
|
||||
const appTotal = (as && as.total) || 0;
|
||||
const appSegs = appRows.map((a, i) => ({ color: colorFor(i), data: { size: a.bytes || 0 } }));
|
||||
const headline = appRows.length
|
||||
const appSegs = appRows.map((a, i) => ({ label: a.app, color: colorFor(i), data: { size: a.bytes || 0 } }));
|
||||
const dockerCats = d ? SystemStoragePage.segmentsFrom(d).map((s, j) => ({ ...s, color: colorFor(appSegs.length + j) })) : [];
|
||||
const allSegs = [...appSegs, ...dockerCats];
|
||||
const grandTotal = allSegs.reduce((t, s) => t + ((s.data && s.data.size) || 0), 0);
|
||||
const legend = `
|
||||
<ul class="sys-storage-legend">
|
||||
${allSegs.map(s => `
|
||||
<li>
|
||||
<span class="sys-storage-swatch" style="background: var(--${s.color})"></span>
|
||||
<span class="sys-storage-leg-k">${fmt.escape(s.label)}</span>
|
||||
<span></span>
|
||||
<span class="sys-storage-leg-v">${fmt.bytes((s.data && s.data.size) || 0)}</span>
|
||||
</li>`).join('')}
|
||||
</ul>`;
|
||||
const headline = allSegs.length
|
||||
? `<div class="sys-storage-headline">
|
||||
<div class="sys-storage-head-card">${SystemStoragePage.donutSvg(appSegs, appTotal, 'app data')}</div>
|
||||
<div class="sys-storage-head-card">
|
||||
${SystemStoragePage.donutSvg(allSegs, grandTotal, 'in use')}
|
||||
${legend}
|
||||
</div>
|
||||
<div class="sys-storage-head-stats">
|
||||
<div class="sys-storage-stat">
|
||||
<span class="sys-storage-stat-k">App data on disk</span>
|
||||
<strong class="sys-storage-stat-v">${fmt.bytes(appTotal)}</strong>
|
||||
<span class="sys-storage-stat-sub">${appRows.length} app${appRows.length === 1 ? '' : 's'}${as && as.total_external ? ` · ${fmt.bytes(as.total_external)} on external drives` : ''}</span>
|
||||
<span class="sys-storage-stat-sub">${appRows.length} app${appRows.length === 1 ? '' : 's'}${as && as.total_external ? ` · ${fmt.bytes(as.total_external)} external` : ''}</span>
|
||||
</div>
|
||||
${d ? `<div class="sys-storage-stat">
|
||||
<span class="sys-storage-stat-k">Docker engine</span>
|
||||
<strong class="sys-storage-stat-v">${fmt.bytes(d.total || 0)}</strong>
|
||||
<span class="sys-storage-stat-sub">${fmt.bytes(d.reclaimable || 0)} reclaimable</span>
|
||||
${d ? `<div class="sys-storage-stat sys-storage-stat-recl">
|
||||
<span class="sys-storage-stat-k">Docker reclaimable</span>
|
||||
<strong class="sys-storage-stat-v">${fmt.bytes(d.reclaimable || 0)}</strong>
|
||||
<span class="sys-storage-stat-sub">of ${fmt.bytes(d.total || 0)} engine overhead</span>
|
||||
</div>` : ''}
|
||||
</div>
|
||||
</div>`
|
||||
@ -262,10 +281,9 @@ class SystemStoragePage {
|
||||
// plus the largest images. The cleanup view, clearly separate from data.
|
||||
let dockerSection = '';
|
||||
if (d) {
|
||||
const segments = SystemStoragePage.segmentsFrom(d);
|
||||
const total = d.total || 0;
|
||||
const recl = d.reclaimable || 0;
|
||||
const cards = segments.map(s => {
|
||||
const cards = dockerCats.map(s => {
|
||||
const v = s.data || {};
|
||||
const pct = v.size && total ? (v.size / total) * 100 : 0;
|
||||
const rPct = v.size ? (v.reclaimable / v.size) * 100 : 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user