ui: Central UI density/consistency sweep + Theme 0.4.1
Applies the family-wide admin-UI cleanup playbook to the Central UI so the Blazor surfaces stop diverging from the shared kit: buttons are grouped rather than individually sized, long cell values are contained instead of widening tables, and hard-coded colours give way to theme tokens. The headline fix is that MainLayout passed Accent="#2f5fd0" to ThemeShell, which the kit emits as an inline style on the shell root. Being a descendant of <html>, it beat the [data-bs-theme="dark"] override for the entire app, so the dark accent had never rendered. Declaring --accent in site.css :root instead lets both schemes resolve; light is unchanged because the value already matched the kit's light default. Theme pins to 0.4.1, which upstreams the local .btn sizing block verbatim, so that block is deleted here rather than duplicated. Verified byte-identical before removal; the repo now declares no --bs-btn-* anywhere. NOT purely cosmetic, contrary to the sweep's stated scope: four detail-modal surfaces (NotificationReport, ConfigurationAuditLog, ParkedMessages, SiteCallsReport) were additionally refactored from holding the selected record to holding its id and re-resolving from the current page each render, with the resolve doubling as the visibility gate. A background refresh that drops the row now closes the modal instead of showing a stale snapshot. This is a behaviour change and is called out rather than buried: a full-suite run turned up one intermittent CentralUI failure, CloseButton_DismissesModal, whose stack (GetRequiredEventBindingEntry during DispatchEventAsync) indicates the handler was disposed between render and click — a window the previous field-held record made structurally impossible. Treat the modal lifecycle here as unreviewed. Build 0/0; suite green apart from that one intermittent failure.
This commit is contained in:
+29
-19
@@ -30,7 +30,6 @@
|
||||
|
||||
<div class="d-flex align-items-baseline flex-wrap mb-3">
|
||||
<h4 class="mb-0 me-3">Secured Writes</h4>
|
||||
<span class="text-muted small">Two-person MxGateway writes — operator submits, a different verifier approves.</span>
|
||||
</div>
|
||||
|
||||
@* ── Operator region: submit form ───────────────────────────────────── *@
|
||||
@@ -142,8 +141,11 @@
|
||||
<tr @key="row.Id" data-test="secured-write-pending-row">
|
||||
<td>@row.SiteId</td>
|
||||
<td>@row.ConnectionName</td>
|
||||
<td><code>@row.TagPath</code></td>
|
||||
<td>@row.ValueJson</td>
|
||||
@* Tag path and value are device/operator supplied and unbounded.
|
||||
.cell-clip is display:block, so it goes on an inner element —
|
||||
putting it on the <td> would drop the cell out of the row. *@
|
||||
<td><code class="cell-clip" title="@row.TagPath">@row.TagPath</code></td>
|
||||
<td><span class="cell-clip" title="@row.ValueJson">@row.ValueJson</span></td>
|
||||
<td>@row.ValueType</td>
|
||||
<td>@row.OperatorUser</td>
|
||||
<td class="text-nowrap">@row.SubmittedAtUtc.ToString("u")</td>
|
||||
@@ -152,18 +154,20 @@
|
||||
{
|
||||
<span class="text-muted small me-2" data-test="secured-write-own-note">your submission</span>
|
||||
}
|
||||
<button class="btn btn-outline-success btn-sm me-1"
|
||||
@onclick="() => Approve(row)"
|
||||
disabled="@(isOwn || _actionInProgress)"
|
||||
data-test="secured-write-approve">
|
||||
Approve
|
||||
</button>
|
||||
<button class="btn btn-outline-danger btn-sm"
|
||||
@onclick="() => Reject(row)"
|
||||
disabled="@(isOwn || _actionInProgress)"
|
||||
data-test="secured-write-reject">
|
||||
Reject
|
||||
</button>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button class="btn btn-outline-success"
|
||||
@onclick="() => Approve(row)"
|
||||
disabled="@(isOwn || _actionInProgress)"
|
||||
data-test="secured-write-approve">
|
||||
Approve
|
||||
</button>
|
||||
<button class="btn btn-outline-danger"
|
||||
@onclick="() => Reject(row)"
|
||||
disabled="@(isOwn || _actionInProgress)"
|
||||
data-test="secured-write-reject">
|
||||
Reject
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@@ -207,15 +211,21 @@
|
||||
<tr @key="row.Id" data-test="secured-write-history-row">
|
||||
<td>@row.SiteId</td>
|
||||
<td>@row.ConnectionName</td>
|
||||
<td><code>@row.TagPath</code></td>
|
||||
<td>@row.ValueJson</td>
|
||||
@* 11 columns here, and the three timestamps to the right are
|
||||
text-nowrap — so the free-text cells clip narrow (-sm). *@
|
||||
<td><code class="cell-clip cell-clip-sm" title="@row.TagPath">@row.TagPath</code></td>
|
||||
<td><span class="cell-clip cell-clip-sm" title="@row.ValueJson">@row.ValueJson</span></td>
|
||||
<td><span class="badge @StatusBadgeClass(row.Status)">@row.Status</span></td>
|
||||
<td>@row.OperatorUser</td>
|
||||
<td>@(row.VerifierUser ?? "—")</td>
|
||||
<td class="text-nowrap">@row.SubmittedAtUtc.ToString("u")</td>
|
||||
<td class="text-nowrap">@(row.DecidedAtUtc?.ToString("u") ?? "—")</td>
|
||||
<td class="text-nowrap">@(row.ExecutedAtUtc?.ToString("u") ?? "—")</td>
|
||||
<td class="text-danger small">@(row.ExecutionError ?? "")</td>
|
||||
@* Raw device/MxGateway exception text in the last column — clamp to
|
||||
two lines so one bad message can't set the whole table's width. *@
|
||||
<td class="text-danger small">
|
||||
<span class="cell-clamp-2" title="@row.ExecutionError">@(row.ExecutionError ?? "")</span>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
@@ -229,7 +239,7 @@
|
||||
Showing @(_historyPage * HistoryPageSize + 1)–@Math.Min((_historyPage + 1) * HistoryPageSize, _historyTotalCount)
|
||||
of @_historyTotalCount
|
||||
</span>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button class="btn btn-outline-secondary" @onclick="HistoryPrev"
|
||||
disabled="@(_historyPage == 0)" data-test="secured-write-history-prev">Prev</button>
|
||||
<button class="btn btn-outline-secondary" @onclick="HistoryNext"
|
||||
|
||||
Reference in New Issue
Block a user