Files
scadaproj/components/ui-theme/current-state/scadabridge/CURRENT-STATE.md
T
2026-06-01 05:15:38 -04:00

166 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UI Theme — current state: ScadaBridge
Repo: `~/Desktop/ScadaBridge`. Stack: .NET 10, Blazor SSR (Akka.NET cluster + central UI).
UI surfaces: `src/ZB.MOM.WW.ScadaBridge.CentralUI/` (RCL) and
`src/ZB.MOM.WW.ScadaBridge.Host/` (the Blazor host that references it).
All paths below are relative to the repo root. Verified against source on 2026-06-01.
**Summary:** ScadaBridge uses a sidebar nav layout and the Technical-Light tokens, with the
correct font-path prefix. The sidebar uses `.sidebar` / `.nav-link` classes (same idiom as
MxGateway), not `.side-rail` / `.rail-link`. Adoption is **medium effort** — sidebar-class
migration + `MainLayout` replacement, no layout redesign. ScadaBridge has several
scoped `.razor.css` files that stay per-project.
---
## 1. CSS / design tokens
**`theme.css`** — 379-line hand copy of the Technical-Light design system.
- Path: `src/ZB.MOM.WW.ScadaBridge.CentralUI/wwwroot/css/theme.css`
- Font path: `url('../fonts/ibm-plex-sans-400.woff2')` (lines 24, 29, 34)
- **Correct path** — resolves from `wwwroot/css/` to `wwwroot/fonts/` without 404. This is
the canonical `url('../fonts/…')` that the RCL also uses.
- Wired in the Host's `App.razor` line 9:
`<link href="_content/ZB.MOM.WW.ScadaBridge.CentralUI/css/theme.css" rel="stylesheet" />`.
**`site.css`** — 128 lines of per-app page layout (sidebar shell, nav overrides).
- Path: `src/ZB.MOM.WW.ScadaBridge.CentralUI/wwwroot/css/site.css`
- Wired in the Host's `App.razor` line 11:
`<link href="_content/ZB.MOM.WW.ScadaBridge.CentralUI/css/site.css" rel="stylesheet" />`.
- Contains: `.sidebar` layout block (~495), Bootstrap-icons integration for nav items.
- After adoption: the `.sidebar` layout section is superseded by RCL `layout.css`. The
remaining rules (Bootstrap-icons, misc overrides) stay in `site.css`.
Note: ScadaBridge uses the `_content/ZB.MOM.WW.ScadaBridge.CentralUI/…` static-web-asset
path for its own CentralUI RCL assets — the same mechanism `ZB.MOM.WW.Theme` will use.
---
## 2. IBM Plex fonts
Three `.woff2` files vendored into:
`src/ZB.MOM.WW.ScadaBridge.CentralUI/wwwroot/fonts/`
- `ibm-plex-sans-400.woff2`
- `ibm-plex-sans-600.woff2`
- `ibm-plex-mono-500.woff2`
After adoption: delete all three from `CentralUI/wwwroot/fonts/`; the RCL serves them
from `_content/ZB.MOM.WW.Theme/fonts/`.
---
## 3. Layout shell
**`MainLayout.razor`** — 29-line static layout. `@inherits LayoutComponentBase`. No
`@rendermode` directive (static SSR).
- Path: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Layout/MainLayout.razor`
- Root element: `<div class="d-flex flex-column flex-lg-row" style="min-height: 100vh;">`.
No `.app-shell` class.
- Renders `<NavMenu />` inside a Bootstrap collapse div, `<main class="flex-grow-1 p-3">`,
plus `<DialogHost />` and `<SessionExpiry />` at the bottom.
**`NavMenu.razor`** — 200+ line interactive sidebar component. `@implements IDisposable`.
- Path: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Layout/NavMenu.razor`
- Brand: `<div class="brand"><span class="mark">&#9646;</span> ScadaBridge</div>` (lines ~99).
- Nav structure: `<nav class="sidebar d-flex flex-column">` with `<ul class="nav flex-column">`
and `<NavSection>` groups ("Admin", "Data", "Audit", etc.) with `<NavLink class="nav-link">`
children. Uses `AuthorizeView` + `AuthorizeView Policy="…"` to gate admin sections.
- Nav state: JS-based expand-state persistence (same pattern as OtOpcUa and MxGateway).
**`NavSection.razor`** (same name as OtOpcUa/MxGateway, independent per-project copy).
- Path: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Layout/NavSection.razor`
---
## 4. Login page
**`Login.razor`** — 36-line static login page. `@layout LoginLayout`, `@attribute [AllowAnonymous]`.
- Path: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Login.razor`
- Form: `<form method="post" action="/auth/login" data-enhance="false">` (line 16).
- Uses Bootstrap `.card` / `.card-body` markup — **not** the Technical-Light `.panel` /
`.login-wrap` idiom used in OtOpcUa. Does not use a `<LoginCard>` yet.
- Error notice: Bootstrap `.alert alert-danger` (line 12) rather than `.panel.notice`.
---
## 5. Scoped `.razor.css` files (stays per-project)
ScadaBridge ships several component-scoped CSS files. These are **not shared** and stay
in the CentralUI RCL after adoption:
| File | Path |
|---|---|
| `MultiSelectDropdown.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Shared/` |
| `TreeView.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Shared/` |
| `AuditDrilldownDrawer.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Audit/` |
| `AuditEventDetail.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Audit/` |
| `ExecutionDetailModal.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Audit/` |
| `ExecutionTree.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Audit/` |
| `AuditResultsGrid.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Audit/` |
| `NodeBrowserDialog.razor.css` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Dialogs/` |
These scoped styles are component-specific overrides and are unaffected by theme adoption.
---
## 6. Divergences from spec
| Item | Current state | Spec |
|---|---|---|
| `theme.css` | Hand copy, 379 lines | Single canonical copy in RCL |
| Font-path `url()` | `url('../fonts/…')`**correct** | `url('../fonts/…')` — same |
| IBM Plex fonts | Vendored 3× in `wwwroot/fonts/` | Single copy in RCL `wwwroot/fonts/` |
| Shell class | `d-flex …` (no `.app-shell`) | `ThemeShell` + `.app-shell` |
| Nav class idiom | `.sidebar` + `.nav-link` + `<ul>/<li>` | `.side-rail` + `.rail-link` + `<a>` |
| Nav items | `<NavLink class="nav-link">` inside `<li>` | `<NavRailItem>` |
| Nav sections | `NavSection` (`EventCallback OnToggle` + JS) | `NavRailSection` (`<details>`, CSS-only) |
| Status chip | None (uses raw `.chip-*` classes inline) | `StatusPill` (`StatusState` enum) |
| Login card | Bootstrap `.card` markup (not Technical-Light `.panel`) | `<LoginCard>` |
| Scoped `.razor.css` | 8 component-scoped files | Stays per-project (no change) |
---
## 7. Adoption plan
**Effort: Medium. Risk: Medium.** The font path is already correct so no 404 fix needed.
The sidebar idiom migration (`.sidebar``.side-rail`, `.nav-link``.rail-link`) and the
`MainLayout` replacement are the main work. The scoped `.razor.css` files are unaffected.
**Steps:**
1. **Delete copies.** Remove `src/ZB.MOM.WW.ScadaBridge.CentralUI/wwwroot/css/theme.css`
and `wwwroot/fonts/ibm-plex-*.woff2` from `CentralUI`.
2. **Reference RCL.** Add `<PackageReference Include="ZB.MOM.WW.Theme" />` to
`ZB.MOM.WW.ScadaBridge.CentralUI.csproj`. Add `@using ZB.MOM.WW.Theme` to
`CentralUI`'s `_Imports.razor`.
3. **Wire `ThemeHead`.** In `Host`'s `App.razor`, replace line 9
(`<link href="_content/…/css/theme.css">`) with `<ThemeHead />` (which now resolves
via `ZB.MOM.WW.Theme`). Keep the `site.css` link on line 11.
4. **Replace `MainLayout`.** Replace the 29-line `MainLayout.razor` with a thin wrapper
around `<ThemeShell Product="ScadaBridge">`. Carry `<NavMenu />` into the `Nav` slot
(or replace it — see step 5). Keep `<DialogHost />` and `<SessionExpiry />` below the
`ThemeShell` or inside `ChildContent` as needed.
5. **Port nav.** Migrate `NavMenu.razor` from `nav.sidebar` + `<ul>/<li>` + `.nav-link`
to `<NavRailSection>` + `<NavRailItem>`. The `AuthorizeView` policy gating on admin
sections stays — wrap `<NavRailSection>` inside the appropriate `<AuthorizeView>` just
as today.
6. **Clean `site.css`.** Remove the `.sidebar` layout block. Keep Bootstrap-icons
integration and any domain-specific overrides.
7. **Replace login card.** In `Login.razor`, replace the Bootstrap `.card`/`.card-body`
markup with `<LoginCard Product="ScadaBridge" Action="/auth/login" ReturnUrl="@ReturnUrl"
Error="@ErrorMessage"><AntiforgeryToken /></LoginCard>`. Align error display with the
Technical-Light `.panel.notice` style from `LoginCard`.
8. **Keep:** all scoped `.razor.css` files (8 files listed above); `site.css` domain rules;
auth and session endpoints; all page components.
**Risk note:** ScadaBridge's `AuthorizeView` policy-gated nav sections require careful
testing — verify that `<NavRailSection>` inside `<AuthorizeView>` renders correctly and
that the section is fully hidden when the policy fails (not just collapsed).