fix(admin/storage): make the Storage page tablet/mobile friendly
The donut legend collided into the stat cards and the image-row details were squished on tablet widths — the 220px sidebar leaves the content cramped while the old breakpoints assumed full-viewport width. - Headline collapses to a single column at <=1024px (was 800px), the two stat cards reflow side-by-side, and on phones the donut stacks above its legend with one stat per row. Legend labels now ellipsis instead of overflowing into the stats. - Image rows group the name+pill and the size/shared/age metadata so the metadata drops onto its own line under the name at <=1024px instead of competing for width; on phones the Delete button collapses to an icon. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
39ccb08119
commit
9850b9d8e7
@ -136,6 +136,48 @@
|
||||
.sys-img-pill.is-inuse { background: rgba(var(--accent-rgb), 0.16); color: var(--accent); }
|
||||
.sys-img-pill.is-unused { background: rgba(var(--text-rgb), 0.10); color: rgba(var(--text-rgb), 0.6); }
|
||||
.sys-img-pill.is-dangling { background: rgba(251, 189, 35, 0.16); color: #fbbd23; }
|
||||
/* Image row body: name + pill on the left, size/shared/age metadata pushed to
|
||||
the right on a wide row. On narrow screens (see the @media below) the meta
|
||||
drops onto its own line under the name so the details stop being squished. */
|
||||
.sys-img-body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px 10px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.sys-img-headline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0; /* lets a long image name ellipsis instead of pushing */
|
||||
}
|
||||
.sys-image-item .task-title {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.sys-img-pill { flex-shrink: 0; }
|
||||
.sys-img-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px 8px;
|
||||
margin-left: auto; /* right-align the details on a single-line row */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* Tablet & phone (the 220px sidebar leaves the content cramped until 768px):
|
||||
stack the metadata under the name+pill so the details get their own line. */
|
||||
@media (max-width: 1024px) {
|
||||
.sys-img-body { flex-direction: column; align-items: flex-start; gap: 5px; }
|
||||
.sys-img-meta { margin-left: 0; }
|
||||
}
|
||||
/* Phones: collapse the Delete button to an icon so a long name + actions fit. */
|
||||
@media (max-width: 560px) {
|
||||
.sys-image-item .task-btn.delete .task-btn-label { display: none; }
|
||||
.sys-image-item .task-btn.delete { padding: 4px 7px; }
|
||||
}
|
||||
|
||||
.admin-card-body {
|
||||
display: flex;
|
||||
@ -1060,8 +1102,23 @@ table.sys-apps tr:hover td { background: rgba(var(--text-rgb), 0.03); }
|
||||
gap: 18px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
/* Tablet/narrow: with the 220px sidebar eating the width, the two headline
|
||||
columns (donut+legend / stat cards) can't share a row without the legend
|
||||
colliding into the stats — stack them, and let the two stat cards sit side
|
||||
by side while there's still room for them. */
|
||||
@media (max-width: 1024px) {
|
||||
.sys-storage-headline { grid-template-columns: 1fr; }
|
||||
.sys-storage-head-stats {
|
||||
grid-template-rows: none;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
}
|
||||
}
|
||||
/* Phones (sidebar is now a drawer, content is full-width): donut above its
|
||||
legend, one stat card per row. */
|
||||
@media (max-width: 560px) {
|
||||
.sys-storage-head-card { flex-direction: column; text-align: center; }
|
||||
.sys-storage-legend { width: 100%; }
|
||||
.sys-storage-head-stats { grid-template-columns: 1fr; }
|
||||
}
|
||||
.sys-storage-head-card {
|
||||
background: var(--card-bg);
|
||||
@ -1100,7 +1157,7 @@ table.sys-apps tr:hover td { background: rgba(var(--text-rgb), 0.03); }
|
||||
}
|
||||
.sys-storage-legend li {
|
||||
display: grid;
|
||||
grid-template-columns: 14px auto 1fr auto;
|
||||
grid-template-columns: 14px minmax(0, auto) 1fr auto;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 0.85rem;
|
||||
@ -1112,6 +1169,10 @@ table.sys-apps tr:hover td { background: rgba(var(--text-rgb), 0.03); }
|
||||
.sys-storage-leg-k {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.sys-storage-leg-v {
|
||||
color: rgba(var(--text-rgb), 0.65);
|
||||
|
||||
@ -518,11 +518,17 @@ class SystemStoragePage {
|
||||
<div class="task-header">
|
||||
<div class="task-info">
|
||||
${this._imageIconHtml(im)}
|
||||
<span class="task-title" title="${fmt.escape((im.repo_tags || []).join(', '))}">${fmt.escape(this._imageName(im))}</span>
|
||||
<span class="task-status sys-img-pill ${pill.cls}">${fmt.escape(pill.label)}</span>
|
||||
<span class="task-time">${fmt.bytes(im.size || 0)}</span>
|
||||
${im.shared_size ? `<span class="task-duration" title="shared layers">${fmt.bytes(im.shared_size)} shared</span>` : ''}
|
||||
${im.created ? `<span class="task-duration">${fmt.timeAgo(im.created)}</span>` : ''}
|
||||
<div class="sys-img-body">
|
||||
<span class="sys-img-headline">
|
||||
<span class="task-title" title="${fmt.escape((im.repo_tags || []).join(', '))}">${fmt.escape(this._imageName(im))}</span>
|
||||
<span class="task-status sys-img-pill ${pill.cls}">${fmt.escape(pill.label)}</span>
|
||||
</span>
|
||||
<span class="sys-img-meta">
|
||||
<span class="task-time">${fmt.bytes(im.size || 0)}</span>
|
||||
${im.shared_size ? `<span class="task-duration" title="shared layers">${fmt.bytes(im.shared_size)} shared</span>` : ''}
|
||||
${im.created ? `<span class="task-duration">${fmt.timeAgo(im.created)}</span>` : ''}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-actions">
|
||||
<button type="button" class="task-btn delete" data-image-delete="${id}" title="Remove image">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user