docs(ui-theme): record 0.2.0 publish + adoption across all 3 apps (local feat branches)

This commit is contained in:
Joseph Doherty
2026-06-03 04:06:20 -04:00
parent a474eb6bd6
commit ca21615090
3 changed files with 62 additions and 17 deletions
+12 -5
View File
@@ -121,7 +121,7 @@ each project's **code-verified current state**, and the **gaps** between. See
| Component | Status | Goal | Design | Implementation |
|---|---|---|---|---|
| Auth (login / identity / authz) | Adopted (lib `0.1.3`; all 3 apps, merged to **local default** main/master + **pushed to origin** (gitea)) | Shared `ZB.MOM.WW.Auth` lib | [`components/auth/`](components/auth/) | [`ZB.MOM.WW.Auth/`](ZB.MOM.WW.Auth/) |
| UI Theme (layout / tokens / components) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Theme` RCL | [`components/ui-theme/`](components/ui-theme/) | [`ZB.MOM.WW.Theme/`](ZB.MOM.WW.Theme/) |
| UI Theme (layout / tokens / components) | Adopted (lib `0.2.0`; all 3 apps, local `feat/adopt-zb-theme` branches) | Shared `ZB.MOM.WW.Theme` RCL | [`components/ui-theme/`](components/ui-theme/) | [`ZB.MOM.WW.Theme/`](ZB.MOM.WW.Theme/) |
| Health (readiness / liveness / active-node) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Health` lib | [`components/health/`](components/health/) | [`ZB.MOM.WW.Health/`](ZB.MOM.WW.Health/) |
| Observability (metrics / traces / logs) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Telemetry` lib + `.Serilog` | [`components/observability/`](components/observability/) | [`ZB.MOM.WW.Telemetry/`](ZB.MOM.WW.Telemetry/) |
| Config + validation (options / startup validation) | Adopted (lib `0.1.0`; all 3 apps, local) | Shared `ZB.MOM.WW.Configuration` lib | [`components/configuration/`](components/configuration/) | [`ZB.MOM.WW.Configuration/`](ZB.MOM.WW.Configuration/) |
@@ -156,10 +156,17 @@ backlog. Shared = Technical-Light tokens + IBM Plex fonts + side-rail shell + wi
per-project = each app's `site.css` page layout, route content, scoped `.razor.css`.
The shared RCL is **built and lives in this repo** at [`ZB.MOM.WW.Theme/`](ZB.MOM.WW.Theme/)
(.NET 10 Razor Class Library; single package; 32 bUnit tests; `dotnet pack` → 1 nupkg @ 0.1.0).
The implementation plan is at
[`docs/plans/2026-06-01-zb-mom-ww-theme-shared-library.md`](docs/plans/2026-06-01-zb-mom-ww-theme-shared-library.md).
**Not yet adopted** by the three apps — that's the follow-on tracked in [`components/ui-theme/GAPS.md`](components/ui-theme/GAPS.md).
(.NET 10 Razor Class Library; single package; 44 bUnit tests; `dotnet pack` → 1 nupkg @ 0.2.0,
**published to the Gitea feed**). The build plan is at
[`docs/plans/2026-06-01-zb-mom-ww-theme-shared-library.md`](docs/plans/2026-06-01-zb-mom-ww-theme-shared-library.md);
the adoption plan at [`docs/plans/2026-06-03-ui-theme-adoption.md`](docs/plans/2026-06-03-ui-theme-adoption.md).
**Adopted across all three apps on 2026-06-03** (full canonical cutover, SPEC §7) on each repo's local-only
`feat/adopt-zb-theme` branch (OtOpcUa `11de14d`, ScadaBridge `58352a6`, MxGateway `73e54e2` — committed,
spec+code reviewed, **not yet merged/pushed**). The `0.1.0 → 0.2.0` bump first promoted nav-expand persistence
into the kit (`NavRailSection.Key`/`data-nav-key` + a localStorage `nav-state.js` enhancer emitted by a new
`<ThemeScripts/>`), so all three apps share one persistence mechanism (OtOpcUa's bespoke cookie/JS-interop nav
island retired); MxGateway additionally gained a net-new Blazor `<LoginCard>` `/login` page over its existing
hardened endpoint. Per-app result in [`components/ui-theme/GAPS.md`](components/ui-theme/GAPS.md).
Build/test from `ZB.MOM.WW.Theme/`: `dotnet test`. Consumer matrix: all three apps consume
the single `ZB.MOM.WW.Theme` package (OtOpcUa AdminUI, MxGateway Server, ScadaBridge Host + CentralUI).
+17
View File
@@ -3,6 +3,23 @@
Divergence of each project from [`spec/SPEC.md`](spec/SPEC.md), and the ordered backlog to
reach adoption of the `ZB.MOM.WW.Theme` shared RCL. Status legend: ⛔ gap · 🟡 partial · ✅ matches.
> **✅ ADOPTED 2026-06-03 (local-only).** Backlog #2#4 implemented across all three apps on each repo's
> **`feat/adopt-zb-theme`** branch — full canonical cutover (SPEC §7): `<ThemeHead/>`/`<ThemeScripts/>`,
> thin `MainLayout` → `<ThemeShell>` + `NavRailItem`/`NavRailSection`, per-app `theme.css`/IBM-Plex fonts/
> `nav-state.js` deleted, `<LoginCard>` sign-in, and `StatusPill` (OtOpcUa's dead `StatusBadge` deleted;
> MxGateway's `StatusBadge` redirected to a thin `StatusPill` adapter; inline domain `.chip-*` kept as page
> content per §6). **Library first enhanced to `0.2.0`** — nav-expand persistence promoted INTO the kit
> (`NavRailSection.Key` → `data-nav-key` + a localStorage `nav-state.js` enhancer emitted by a new
> `<ThemeScripts/>`), so all three apps get uniform persistence from one source (OtOpcUa's bespoke
> cookie/JS-interop nav island retired). 0.2.0 published to the Gitea feed; 44 bUnit tests. **MxGateway
> additionally gained a net-new Blazor `<LoginCard>` `/login` page** reusing its existing hardened
> `POST /login` endpoint (antiforgery + `SanitizeReturnUrl` + `SignInAsync` preserved). Every task spec+code
> reviewed (high-risk via serial spec→code; the MxGateway login via an Opus security review). Branch heads:
> OtOpcUa `11de14d`, ScadaBridge `58352a6`, MxGateway `73e54e2` — **committed local-only, not yet merged/pushed**.
> Plan: `docs/plans/2026-06-03-ui-theme-adoption*.md`. The ⛔/🟡 cells below describe the PRE-adoption
> divergence (kept for history). Deferred follow-ups: prune now-dead `.sidebar`/`.nav-link` residual from each
> app's kept `site.css`; a kit-side `layout.css` `calc(100vh - 3.3rem)` review.
---
## Divergence vs spec
@@ -1,9 +1,15 @@
# Shared library: `ZB.MOM.WW.Theme`
**Status: Built (`0.1.0`).** The RCL lives at
[`scadaproj/ZB.MOM.WW.Theme/`](../../../ZB.MOM.WW.Theme/) — built and tested. Adoption
by the three apps is follow-on, tracked in [`../GAPS.md`](../GAPS.md). Realizes
[`../spec/SPEC.md`](../spec/SPEC.md).
**Status: Built + Published + Adopted (`0.2.0`).** The RCL lives at
[`scadaproj/ZB.MOM.WW.Theme/`](../../../ZB.MOM.WW.Theme/) — built, tested (44 bUnit tests), and
**published to the Gitea NuGet feed**. **Adopted across all three apps on 2026-06-03** (local-only
`feat/adopt-zb-theme` branches; see [`../GAPS.md`](../GAPS.md)). Realizes [`../spec/SPEC.md`](../spec/SPEC.md).
`0.2.0` adds **shared nav-expand persistence**: `NavRailSection` gained a `Key` parameter (emitted as
`data-nav-key`, defaulting to a slug of `Title`), a vendored `wwwroot/js/nav-state.js` localStorage enhancer
(keyed by `data-nav-key`, prefix `zbnav:`, idempotent), and a new **`ThemeScripts`** component (sibling to
`ThemeHead`) that emits the enhancer `<script defer>` before `</body>`. This lets every app persist nav
expand-state from one shared, static-SSR-friendly mechanism (no per-app cookie/JS-interop island).
---
@@ -16,12 +22,14 @@ tokens-only or components-only consumers; all three apps consume the full kit.
|---|---|---|
| `ZB.MOM.WW.Theme` | `net10.0` Razor Class Library | Tokens + fonts + layout CSS + all components |
Published to the Gitea NuGet feed; `Version 0.1.0`. SemVer — token changes are
breaking (major bump). Build from `scadaproj/ZB.MOM.WW.Theme/`:
Published to the Gitea NuGet feed; `Version 0.2.0`. SemVer — token changes are
breaking (major bump); the `0.1.0 → 0.2.0` bump added nav persistence (`NavRailSection.Key` +
`ThemeScripts` + `nav-state.js`) additively. Build from `scadaproj/ZB.MOM.WW.Theme/`:
```bash
dotnet build -c Release # 0 warnings (TreatWarningsAsErrors)
dotnet test # 32 bUnit tests
./build/pack.sh # → ./artifacts/ZB.MOM.WW.Theme.0.1.0.nupkg
dotnet test # 44 bUnit tests
./build/pack.sh # → ./artifacts/ZB.MOM.WW.Theme.0.2.0.nupkg
GITEA_NUGET_SOURCE=GITEA_NUGET_KEY=… ./build/push.sh # publish to the Gitea feed
```
---
@@ -72,6 +80,18 @@ Place in `App.razor` `<head>` **after** the app's Bootstrap link.
---
### `ThemeScripts`
Emits the nav-state localStorage enhancer `<script src="_content/ZB.MOM.WW.Theme/js/nav-state.js" defer>`.
No parameters. Place in `App.razor` **before `</body>`**. Persists each `NavRailSection`'s open/closed
state (keyed by its `data-nav-key`) across navigation and reloads; pure client-side, works in static SSR.
```razor
<ThemeScripts />
```
---
### `ThemeShell`
Canonical side-rail chassis. **Not a `LayoutComponentBase`** — delegated to from the app's
@@ -134,14 +154,15 @@ One rail navigation link. Wraps Blazor `<NavLink class="rail-link">`.
### `NavRailSection`
Collapsible nav section group using CSS-only `<details open>` — no JavaScript, works in
static Blazor SSR. Apps that need interactive cookie-persisted expand state may keep a
bespoke interactive `NavSection` alongside this.
Collapsible nav section group using CSS-only `<details open>` — no JavaScript required. Open/closed
state is persisted in localStorage by `<ThemeScripts/>` (keyed by `Key``data-nav-key`); works in
static Blazor SSR.
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
| `Title` | `string` | Yes | — | Eyebrow label |
| `Expanded` | `bool` | No | `true` | Initial open state |
| `Key` | `string?` | No | slug of `Title` | Stable persistence key, emitted as `data-nav-key` |
| `Expanded` | `bool` | No | `true` | Initial open state (before localStorage restore) |
| `ChildContent` | `RenderFragment?` | No | `null` | `NavRailItem` children |
---