diff options
| author | Dan Engelbrecht <[email protected]> | 2026-03-22 13:13:13 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-22 13:13:13 +0100 |
| commit | 365229bcb24426dc3e02cb632b865e79ba01a9f9 (patch) | |
| tree | 7c52640c73616e93bd993095e7a7295b1e1bcc22 /src/zenserver/frontend/html/zen.css | |
| parent | Upgrade mimalloc to v2.2.7 and log active memory allocator (#876) (diff) | |
| download | zen-365229bcb24426dc3e02cb632b865e79ba01a9f9.tar.xz zen-365229bcb24426dc3e02cb632b865e79ba01a9f9.zip | |
hub web UI improvements (#878)
- Improvement: Hub dashboard module list improved
- Animated state dots, with flashing transitions for hibernating, waking, provisioning, and deprovisioning
- Per-row port used by the provisioned instance
- Per-row hibernate, wake, and deprovision actions with confirmation for destructive operations
- Per-row button to open the instance dashboard in a new window
- Multi-select with bulk hibernate/wake/deprovision and select-all
- Pagination at 50 lines per page
- Inline fold-out panel per row with human-readable process metrics
Diffstat (limited to 'src/zenserver/frontend/html/zen.css')
| -rw-r--r-- | src/zenserver/frontend/html/zen.css | 222 |
1 files changed, 221 insertions, 1 deletions
diff --git a/src/zenserver/frontend/html/zen.css b/src/zenserver/frontend/html/zen.css index 74336f0e1..5ce60d2d2 100644 --- a/src/zenserver/frontend/html/zen.css +++ b/src/zenserver/frontend/html/zen.css @@ -471,7 +471,7 @@ a { border-radius: 6px; background-color: var(--theme_p4); border: 1px solid var(--theme_g2); - width: 6em; + min-width: 6em; cursor: pointer; font-weight: 500; transition: background 0.15s; @@ -486,6 +486,8 @@ a { padding: 2em; min-height: 8em; align-content: center; + white-space: pre-wrap; + text-align: left; } } @@ -1081,3 +1083,221 @@ tr:last-child td { background: var(--theme_g2); color: var(--theme_bright); } + +/* module action controls --------------------------------------------------- */ + +.module-state-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: 6px; + vertical-align: middle; + flex-shrink: 0; +} + +.module-state-dot[data-state="provisioned"] { background: var(--theme_ok); } +.module-state-dot[data-state="hibernated"] { background: var(--theme_warn); } +.module-state-dot[data-state="unprovisioned"] { background: var(--theme_g1); } + +@keyframes module-dot-hibernating { + 0%, 59.9% { background: var(--theme_warn); } + 60%, 100% { background: var(--theme_ok); } +} +@keyframes module-dot-waking { + 0%, 59.9% { background: var(--theme_ok); } + 60%, 100% { background: var(--theme_warn); } +} +@keyframes module-dot-provisioning { + 0%, 59.9% { background: var(--theme_ok); } + 60%, 100% { background: var(--theme_g1); } +} +@keyframes module-dot-deprovisioning-from-provisioned { + 0%, 59.9% { background: var(--theme_fail); } + 60%, 100% { background: var(--theme_ok); } +} +@keyframes module-dot-deprovisioning-from-hibernated { + 0%, 59.9% { background: var(--theme_fail); } + 60%, 100% { background: var(--theme_warn); } +} + +.module-state-dot[data-state="hibernating"] { animation: module-dot-hibernating 1s steps(1, end) infinite; } +.module-state-dot[data-state="waking"] { animation: module-dot-waking 1s steps(1, end) infinite; } +.module-state-dot[data-state="provisioning"] { animation: module-dot-provisioning 1s steps(1, end) infinite; } +.module-state-dot[data-state="deprovisioning"][data-prev-state="provisioned"] { + animation: module-dot-deprovisioning-from-provisioned 1s steps(1, end) infinite; +} +.module-state-dot[data-state="deprovisioning"][data-prev-state="hibernated"] { + animation: module-dot-deprovisioning-from-hibernated 1s steps(1, end) infinite; +} +.module-state-dot[data-state="deprovisioning"] { + animation: module-dot-deprovisioning-from-provisioned 1s steps(1, end) infinite; +} + +.module-action-cell { + white-space: nowrap; + display: flex; + gap: 4px; +} + +.module-action-wrap { + display: inline-block; + cursor: default; +} + +.module-action-wrap:has(button:disabled) { + cursor: default; +} + +.module-action-btn { + background: transparent; + border: 1px solid var(--theme_g2); + border-radius: 4px; + color: var(--theme_g1); + cursor: pointer; + font-size: 13px; + line-height: 1; + padding: 3px 6px; + transition: background 0.1s, color 0.1s; +} + +.module-action-btn:not(:disabled):hover { + background: var(--theme_g2); + color: var(--theme_bright); +} + +.module-action-btn:disabled { + color: var(--theme_border_subtle); + border-color: var(--theme_border_subtle); + pointer-events: none; +} + +.module-bulk-btn { + display: inline-flex; + align-items: center; + gap: 5px; + background: transparent; + border: 1px solid var(--theme_g2); + border-radius: 4px; + cursor: pointer; + font-size: 12px; + font-weight: 600; + padding: 4px 10px; + color: var(--theme_g1); + transition: background 0.1s, color 0.1s; +} + +.module-bulk-btn:not(:disabled):hover { + background: var(--theme_p3); + color: var(--theme_bright); +} + +.module-bulk-btn:disabled { + opacity: 0.4; +} + +.module-bulk-bar { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 10px; + margin-bottom: 8px; + background: var(--theme_g2); + border-radius: 4px; + font-size: 12px; +} + +.module-bulk-label { + margin-right: 8px; + color: var(--theme_g1); +} + +.module-bulk-sep { + flex: 1; +} + +.module-pager { + position: absolute; + right: 0; + top: 0; + display: flex; + align-items: center; + gap: 10px; +} + +.module-pager-btn { + background: transparent; + border: 1px solid var(--theme_g2); + border-radius: 4px; + color: var(--theme_g1); + cursor: pointer; + font-size: 12px; + padding: 4px 10px; + transition: background 0.1s, color 0.1s; +} + +.module-pager-btn:not(:disabled):hover { + background: var(--theme_g2); + color: var(--theme_bright); +} + +.module-pager-btn:disabled { + opacity: 0.35; + cursor: default; +} + +.module-pager-label { + font-size: 12px; + color: var(--theme_g1); + min-width: 8em; + text-align: center; +} + +.module-table td, .module-table th { + padding-top: 4px; + padding-bottom: 4px; +} + +.module-expand-btn { + background: transparent; + border: none; + color: var(--theme_g1); + cursor: pointer; + font-size: 16px; + line-height: 1; + padding: 0 4px 0 0; + vertical-align: middle; +} + +.module-expand-btn:hover { + color: var(--theme_bright); +} + +.module-metrics-row td { + padding: 6px 10px 10px 42px; + background: var(--theme_g3); + border-bottom: 1px solid var(--theme_g2); +} + +.module-metrics-grid { + display: grid; + grid-template-columns: max-content minmax(9em, 1fr) max-content minmax(9em, 1fr); + gap: 3px 12px; + font-size: 11px; + font-variant-numeric: tabular-nums; +} + +.module-metrics-label { + color: var(--theme_faint); + white-space: nowrap; +} + +/* Right-column labels get extra left padding to visually separate the two pairs */ +.module-metrics-label:nth-child(4n+3) { + padding-left: 16px; +} + +.module-metrics-value { + color: var(--theme_g0); + text-align: right; +} |