start: one-container stacks as a single row (project · service), groups only for multi-container stacks; same memory units in rows and headers
All checks were successful
Deploy production / deploy (push) Successful in 1m7s
All checks were successful
Deploy production / deploy (push) Successful in 1m7s
This commit is contained in:
@@ -528,36 +528,57 @@
|
|||||||
</p>
|
</p>
|
||||||
<div class="stacks">
|
<div class="stacks">
|
||||||
{#each containerGroups as g (g.key)}
|
{#each containerGroups as g (g.key)}
|
||||||
<details
|
{#if g.items.length === 1 && g.key}
|
||||||
class="group stack"
|
<!-- A one-container stack is a single row, not a group with one child. -->
|
||||||
open={!closedStacks[g.key]}
|
{@const c = g.items[0]}
|
||||||
ontoggle={(e) => toggleStack(g.key, e.currentTarget.open)}
|
<div
|
||||||
>
|
class="stack solo"
|
||||||
<summary
|
title="{c.name} · {c.image} · {c.state}{c.health ? ` (${c.health})` : ''}"
|
||||||
title={g.key
|
|
||||||
? `compose project ${g.key}`
|
|
||||||
: 'containers without a compose project'}
|
|
||||||
>
|
>
|
||||||
<i class="dot {g.dot}"></i>
|
<i class="dot {containerDot(c)}"></i>
|
||||||
<span class="sname">{g.name}</span>
|
<span class="sname"
|
||||||
<small class={{ bad: g.up < g.items.length && g.dot !== 'off' }}
|
>{g.name}{#if c.service && c.service !== g.name}<small>
|
||||||
>{g.up}/{g.items.length}</small
|
· {c.service}</small
|
||||||
|
>{/if}</span
|
||||||
>
|
>
|
||||||
<span class="num">{g.cpu ? `${g.cpu.toFixed(2)}%` : ''}</span>
|
{#if c.restarts}<span class="tag warn">↻{c.restarts}</span>{/if}
|
||||||
<span class="num">{g.mem ? bytes(g.mem) : ''}</span>
|
<span class="num">{c.cpu ?? ''}</span>
|
||||||
</summary>
|
<span class="num">{c.mem ? bytes(memBytes(c.mem)) : ''}</span>
|
||||||
<ul class="containers">
|
</div>
|
||||||
{#each g.items as c (c.name)}
|
{:else}
|
||||||
<li title="{c.name} · {c.image} · {c.state}{c.health ? ` (${c.health})` : ''}">
|
<details
|
||||||
<i class="dot {containerDot(c)}"></i>
|
class="group stack"
|
||||||
<span class="name">{label(c)}</span>
|
open={!closedStacks[g.key]}
|
||||||
{#if c.restarts}<span class="tag warn">↻{c.restarts}</span>{/if}
|
ontoggle={(e) => toggleStack(g.key, e.currentTarget.open)}
|
||||||
<span class="num">{c.cpu ?? ''}</span>
|
>
|
||||||
<span class="num">{c.mem ?? ''}</span>
|
<summary
|
||||||
</li>
|
title={g.key
|
||||||
{/each}
|
? `compose project ${g.key}`
|
||||||
</ul>
|
: 'containers without a compose project'}
|
||||||
</details>
|
>
|
||||||
|
<i class="dot {g.dot}"></i>
|
||||||
|
<span class="sname">{g.name}</span>
|
||||||
|
<small class={{ bad: g.up < g.items.length && g.dot !== 'off' }}
|
||||||
|
>{g.up}/{g.items.length}</small
|
||||||
|
>
|
||||||
|
<span class="num">{g.cpu ? `${g.cpu.toFixed(2)}%` : ''}</span>
|
||||||
|
<span class="num">{g.mem ? bytes(g.mem) : ''}</span>
|
||||||
|
</summary>
|
||||||
|
<ul class="containers">
|
||||||
|
{#each g.items as c (c.name)}
|
||||||
|
<li
|
||||||
|
title="{c.name} · {c.image} · {c.state}{c.health ? ` (${c.health})` : ''}"
|
||||||
|
>
|
||||||
|
<i class="dot {containerDot(c)}"></i>
|
||||||
|
<span class="name">{label(c)}</span>
|
||||||
|
{#if c.restarts}<span class="tag warn">↻{c.restarts}</span>{/if}
|
||||||
|
<span class="num">{c.cpu ?? ''}</span>
|
||||||
|
<span class="num">{c.mem ? bytes(memBytes(c.mem)) : ''}</span>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -1006,6 +1027,40 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
}
|
}
|
||||||
|
.stack.solo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
/* line up with group headers, whose chevron sits where this padding is */
|
||||||
|
padding: 3px 6px 3px 18px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: var(--site-muted);
|
||||||
|
transition:
|
||||||
|
background 120ms ease,
|
||||||
|
border-color 120ms ease,
|
||||||
|
color 120ms ease;
|
||||||
|
}
|
||||||
|
.stack.solo:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.04);
|
||||||
|
border-color: var(--line);
|
||||||
|
color: var(--site-text);
|
||||||
|
}
|
||||||
|
.stack.solo .dot {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.stack.solo small {
|
||||||
|
opacity: 0.7;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
.stack.solo .num {
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: none;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
.group.stack > summary {
|
.group.stack > summary {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
@@ -1024,6 +1079,7 @@
|
|||||||
.group.stack > summary .dot {
|
.group.stack > summary .dot {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
.stack.solo .sname,
|
||||||
.group.stack .sname {
|
.group.stack .sname {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user