Rework Update System dialog to the approved design; match rebuild dialog

The update dialog kept the old bare title + spinner layout from the
previous theme. Rework it (and the rebuild dialog, for consistency) to
the approved The Hub dialog anatomy:

- Header: green chip icon, title, version chip, status pill
  (Checking… / Up to date / Updating… / Restart required / Update
  failed / Status unknown) and a header close button. A spinner appears
  in the header while an update is starting or running.
- System Details card: current version, release channel, and last
  checked (relative time, refreshed on every check).
- The log renders as a console with green "ok" and dim hint lines; the
  up-to-date result shows as a single green console line exactly once
  (the redundant status line is hidden in that state).
- Footer: Close plus a "Check again" primary action that re-runs the
  update check. Close and Check again are disabled while a check or
  update is in flight; all existing recovery actions (Save Error
  Report, Retry Status, Retry Update, Restart Entire System) keep their
  exact semantics.
- Opening the dialog now shows a "Checking…" state immediately while
  the existing reattach-then-check logic runs; reattaching to an
  in-progress update (page reload, RDP reconnect) is unchanged.

Sidebar Update System status tints now use the theme palette (red /
amber / blue / green), and the periodic background check refreshes the
dialog's "last checked" value.

Rebuild dialog gets the same header (icon, version chip, Applying… /
Done / Restart required / Failed pill, header close disabled while a
rebuild runs); its log stays hidden as before.

No API or state-machine changes: same endpoints, same polling, same
reattach and recovery behavior.
This commit is contained in:
2026-09-08 16:40:06 -05:00
parent 2013df55bd
commit d164d423ad
7 changed files with 274 additions and 45 deletions
+87 -9
View File
@@ -48,26 +48,97 @@
/* ── Update / Rebuild modal internals ───────────────────────────── */
.modal-header {
.upd-header {
display: flex;
align-items: center;
gap: 10px;
padding: 20px 24px 0;
gap: 14px;
padding: 22px 24px 0;
}
.modal-title {
.upd-chip { width: 54px; height: 54px; border-radius: 16px; }
.upd-chip-svg { width: 27px; height: 27px; }
.upd-title-wrap {
min-width: 0;
flex: 1;
display: flex;
flex-direction: column;
gap: 7px;
}
.upd-title {
font-size: 1.13rem;
font-weight: 800;
letter-spacing: -0.01em;
line-height: 1.2;
}
.modal-status {
margin-left: auto;
font-size: 0.78rem;
.upd-sub {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.ver-chip {
display: inline-flex;
align-items: center;
white-space: nowrap;
background: rgba(255, 255, 255, 0.05);
color: var(--text-2);
font-family: var(--mono);
font-size: 0.66rem;
font-weight: 600;
padding: 2px 9px;
border-radius: 99px;
border: 1px solid var(--border);
letter-spacing: 0.02em;
min-height: 23px;
}
.upd-pill {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 0.69rem;
font-weight: 700;
padding: 3px 10px;
border-radius: 99px;
letter-spacing: 0.01em;
white-space: nowrap;
background: rgba(255, 255, 255, 0.05);
color: var(--text-2);
border: 1px solid var(--border);
min-height: 23px;
}
.upd-pill.st-active { background: var(--accent-dim); color: var(--accent); border-color: rgba(66, 243, 154, 0.3); }
.upd-pill.st-loading { background: rgba(120, 174, 237, 0.10); color: var(--blue); border-color: rgba(120, 174, 237, 0.3); }
.upd-pill.st-needs-attention { background: rgba(233, 182, 74, 0.10); color: var(--amber); border-color: rgba(233, 182, 74, 0.3); }
.upd-pill.st-failed { background: rgba(246, 97, 81, 0.10); color: var(--red); border-color: rgba(246, 97, 81, 0.3); }
.upd-pill .status-dot.pulse { animation: tile-dot-pulse 1.4s ease-in-out infinite; }
.modal-body-scroll {
padding: 19px 24px 0;
overflow-y: auto;
flex: 1;
min-height: 0;
}
.update-status-msg {
margin-top: 15px;
font-size: 0.85rem;
font-weight: 650;
color: var(--text-2);
line-height: 1.55;
}
.update-status-msg.st-ok { color: var(--accent); }
.update-status-msg.st-warn { color: var(--amber); }
.update-status-msg.st-err { color: var(--red); }
.modal-footer-spacer { flex: 1; }
.modal-spinner {
width: 16px;
height: 16px;
@@ -75,9 +146,13 @@
border: 2.5px solid rgba(255, 255, 255, 0.14);
border-top-color: var(--accent);
flex-shrink: 0;
display: none;
}
.modal-spinner.spinning { animation: spin 0.8s linear infinite; }
.modal-spinner.spinning {
display: inline-block;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@@ -86,7 +161,7 @@
border: 1px solid var(--border);
border-radius: 14px;
padding: 13px 16px;
margin: 16px 24px 0;
margin: 15px 0 0;
font-family: var(--mono);
font-size: 0.72rem;
line-height: 1.85;
@@ -98,6 +173,9 @@
word-break: break-word;
}
.modal-log .ok { color: var(--accent); }
.modal-log .dim { color: var(--text-3); }
.modal-footer {
display: flex;
gap: 10px;