Stabilize multi-peer UI and fix container start API body
Release rolling / release (push) Successful in 8m25s

Keep the containers table scoped to the active peer with a merge store,
restore the last active server on boot with a restoring screen, start
containers without a Docker API body (v1.24+), and stop ⋮ menus from
sticking to the viewport bottom after refreshes.
This commit is contained in:
Raven Scott
2026-07-11 16:52:57 -04:00
parent 79f57d556b
commit c49d7301d0
10 changed files with 986 additions and 149 deletions
+85 -9
View File
@@ -402,7 +402,8 @@ body {
position: relative;
}
#content > #welcome-page {
#content > #welcome-page,
#content > #restoring-page {
margin: auto;
}
@@ -1432,6 +1433,44 @@ body {
animation: none !important;
}
/* ─── Restoring connections (boot) ─── */
#restoring-page {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
max-width: 520px;
width: min(520px, 92%);
margin: auto;
padding: 48px 36px;
background:
linear-gradient(160deg, rgba(52, 211, 153, 0.1) 0%, rgba(15, 19, 26, 0.9) 45%),
var(--bg-elevated);
border: 1px solid var(--border-strong);
border-radius: var(--border-radius-lg);
box-shadow: var(--shadow-lg), 0 0 80px rgba(52, 211, 153, 0.08);
animation: welcomeIn 0.4s ease-out;
}
#restoring-page.hidden,
#restoring-page[hidden],
#restoring-page.is-hidden {
display: none !important;
visibility: hidden !important;
pointer-events: none !important;
animation: none !important;
}
#restoring-page h1 {
margin: 1rem 0 0.5rem;
font-size: 1.5rem;
}
#restoring-page .restoring-spinner {
margin-bottom: 0.25rem;
}
@keyframes welcomeIn {
from {
opacity: 0;
@@ -2066,11 +2105,16 @@ textarea::placeholder {
}
/*
* ⋮ menu must escape .table-responsive overflow (which clips absolute menus
* and stacks under following rows). Popper strategy:fixed + high z-index.
* ⋮ more-actions menu: use static display (no Popper fixed) so menus stay
* anchored to the row and never stick to the bottom of the viewport after
* list refreshes. Elevate the open row above neighbors; never clip the menu.
*/
.container-actions-more {
position: relative;
position: static;
}
.container-actions-cell .dropdown {
position: static;
}
.container-actions .dropdown-menu,
@@ -2081,29 +2125,61 @@ textarea::placeholder {
box-shadow: var(--shadow-lg);
border: 1px solid var(--border-strong);
background: var(--bg-elevated) !important;
/* Anchor to the actions cell, open upward when near table bottom */
position: absolute !important;
inset: auto auto 100% auto !important;
top: auto !important;
left: auto !important;
right: 0 !important;
bottom: 100% !important;
margin: 0 0 4px 0 !important;
transform: none !important;
}
/* Closed menus must never paint (Popper leftovers / list refresh desync) */
.container-actions .dropdown-menu:not(.show),
.container-actions-dropdown-menu:not(.show) {
display: none !important;
visibility: hidden !important;
pointer-events: none !important;
}
/* Elevate the open row so the menu paints above neighboring table rows */
#container-list > tr:has(.container-actions-more.show),
#container-list > tr:has(.dropdown-menu.show) {
#container-list > tr:has(.dropdown-menu.show),
#container-list > tr:has(.dropdown.show) {
position: relative;
z-index: 6;
z-index: 20;
}
#container-list > tr:has(.container-actions-more.show) > td,
#container-list > tr:has(.dropdown-menu.show) > td {
#container-list > tr:has(.dropdown-menu.show) > td,
#container-list > tr:has(.dropdown.show) > td {
background: var(--bg-elevated);
overflow: visible;
}
/* Allow the table area to not clip fixed-strategy menus as badly on Y */
/* Do not clip row action menus */
#containers-view .table-responsive {
overflow-x: auto;
overflow-y: visible;
/* Create a stacking context that still allows fixed children above chrome */
position: relative;
z-index: 1;
}
#containers-view .table {
overflow: visible;
}
#containers-view #container-list > tr > td {
overflow: visible;
}
/* Accordion bodies must stay collapsed when not .show (defensive vs BS CDN lag) */
.accordion-collapse.collapse:not(.show) {
display: none !important;
}
/* Activity history tray */
.activity-tray {
position: relative;