refactor(ui/admin): card grid, search, kebab; LDAP scope-rule chips

LdapMappings: flex header, search filter, per-row Edit + kebab Delete,
@key, dropped Site-Scope-Rules cell in favor of a {n rule(s)} badge.

LdapMappingForm: two stacked cards (Mapping then Site Scope Rules);
scope rules render as removable chips with an inline "Add scope rule"
form; create-mode disables the scope card with an explainer; role
select gets form-text help.

DataConnections: <h4> in flex header, Bulk actions dropdown holding
Expand/Collapse, hover-visible kebab on tree nodes mirroring the
right-click context menu, aria-labels, "No connections match the
filter." inline empty state.

DataConnectionForm: Site rendered as readonly plaintext + lock-after-
creation note in edit mode; parallel Primary endpoint / Backup endpoint
headings; "Optional" badge on Backup when null; form-text on
FailoverRetryCount.

ApiKeys: search filter, Status column dropped (state now lives in the
kebab menu label "Disable"/"Enable"), Edit + kebab actions, @key,
aria-labels.

ApiKeyForm: nested card removed; fixed-text Back header; real
clipboard copy via IJSRuntime + toast confirmation.

Test selector fix in DataConnectionFormTests for the new Site
readonly-plaintext rendering.
This commit is contained in:
Joseph Doherty
2026-05-12 03:32:17 -04:00
parent f7b10f2ff7
commit da2c0d714e
7 changed files with 364 additions and 197 deletions

View File

@@ -60,10 +60,12 @@ public class DataConnectionFormTests : BunitContext
.First(i => i.GetAttribute("placeholder")?.StartsWith("opc.tcp") == true)
.Change("not-a-url");
// Name field (the first text input that is NOT the OPC URL)
// Name field (the first editable text input that is NOT the OPC URL).
// Site renders as a readonly plaintext input when locked — skip it.
cut.FindAll("input[type='text']")
.First(i => i.GetAttribute("placeholder") is null
|| !i.GetAttribute("placeholder")!.StartsWith("opc.tcp"))
.First(i => !i.HasAttribute("readonly")
&& (i.GetAttribute("placeholder") is null
|| !i.GetAttribute("placeholder")!.StartsWith("opc.tcp")))
.Change("My Connection");
await cut.FindAll("button")
@@ -82,10 +84,11 @@ public class DataConnectionFormTests : BunitContext
var cut = RenderForCreateSite(1);
// Name
// Name (skip readonly Site plaintext input)
cut.FindAll("input[type='text']")
.First(i => i.GetAttribute("placeholder") is null
|| !i.GetAttribute("placeholder")!.StartsWith("opc.tcp"))
.First(i => !i.HasAttribute("readonly")
&& (i.GetAttribute("placeholder") is null
|| !i.GetAttribute("placeholder")!.StartsWith("opc.tcp")))
.Change("PLC-1");
// Endpoint URL
cut.FindAll("input[type='text']")