From 610ec3613273aedfe17bf64c57c22d1f84512ee2 Mon Sep 17 00:00:00 2001 From: Kinflou Date: Fri, 4 Sep 2026 03:31:29 +0800 Subject: [PATCH] sim: fold the connection status dot into the status row + a title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The connection inspector showed "status: live" and then a separate `● live` line whose dot was never coloured. Drop the standalone line; the status fact now carries an inline `.conn-dot` — green when live, red when refused / timed out (`facts()` takes a Node value for this). Add a `connection` section heading to match `faults`, with the panel's first section losing its top divider. --- app/src/sim/ui/view.ts | 15 +++++++++++---- app/src/style.css | 7 +++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/src/sim/ui/view.ts b/app/src/sim/ui/view.ts index 4c5e7cc..442a213 100644 --- a/app/src/sim/ui/view.ts +++ b/app/src/sim/ui/view.ts @@ -881,12 +881,18 @@ export function createSim(opts: SimOpts = {}): SimView { const framing = conn.framing === "auto" ? findProtocol(shape!, server?.schemaNs ?? "", server?.protocol ?? "")?.protocol.framing ?? "?" : conn.framing; + const status = document.createElement("span"); + const dot = document.createElement("span"); + dot.className = `conn-dot ${err || dead ? "err" : "ok"}`; + dot.textContent = "●"; + status.append(dot, ` ${err ? `refused · ${err}` : dead ? "timed out" : "live"}`); inspectorEl.append( + section("connection"), facts([ ["client", client?.name ?? conn.clientId], ["server", server?.name ?? conn.serverId], ["framing", framing], - ["status", err ? `refused · ${err}` : dead ? "timed out" : "live"], + ["status", status], ]), ); if (err) inspectorEl.append(muted(`connection refused · ${err}`, "err")); @@ -898,7 +904,7 @@ export function createSim(opts: SimOpts = {}): SimView { redraw(); }), ); - } else inspectorEl.append(muted("● live", "ok")); + } inspectorEl.append(section("faults")); inspectorEl.append(faultControls(conn)); @@ -1311,7 +1317,7 @@ function row(label: string, control: HTMLElement): HTMLElement { r.append(l, control); return r; } -function facts(pairs: [string, string][]): HTMLElement { +function facts(pairs: [string, string | Node][]): HTMLElement { const f = div("insp-facts"); for (const [k, v] of pairs) { const kv = div("fact"); @@ -1320,7 +1326,8 @@ function facts(pairs: [string, string][]): HTMLElement { kk.textContent = k; const vv = document.createElement("span"); vv.className = "fact-v"; - vv.textContent = v; + if (typeof v === "string") vv.textContent = v; + else vv.append(v); kv.append(kk, vv); f.append(kv); } diff --git a/app/src/style.css b/app/src/style.css index 197b033..57dee87 100644 --- a/app/src/style.css +++ b/app/src/style.css @@ -665,6 +665,12 @@ body.mode-simulate #gen-controls { border-top: 1px solid var(--border); padding-top: 0.6rem; } +/* the first section heads the panel — no divider above nothing */ +.sim-inspector > .insp-section:first-child { + margin-top: 0.1rem; + border-top: none; + padding-top: 0; +} .insp-facts { display: grid; gap: 0.25rem; @@ -696,6 +702,7 @@ body.mode-simulate #gen-controls { .conn-dot { color: var(--muted); font-size: 0.7rem; + vertical-align: middle; } .conn-dot.ok { color: var(--ok);