feat(adminui): MainLayout delegates to ZB.MOM.WW.Theme ThemeShell + kit nav

This commit is contained in:
Joseph Doherty
2026-06-03 03:10:49 -04:00
parent 11bcff6af5
commit 70d764b063
3 changed files with 52 additions and 221 deletions
@@ -1,28 +1,55 @@
@inherits LayoutComponentBase
@using Microsoft.AspNetCore.Components.Routing
@* Layout chrome ported from ScadaLink CentralUI: no separate top bar — brand sits
at the top of the side rail. The sidebar itself is the interactive island
(<NavSidebar/>); MainLayout stays statically rendered so the Body RenderFragment
doesn't have to cross an interactive boundary. *@
@* Thin delegation to the shared ZB.MOM.WW.Theme side-rail chassis. ThemeShell owns
the brand bar, the CSS-only narrow-viewport hamburger, and the responsive collapse,
so MainLayout no longer carries its own .app-shell / hamburger wrapper. Nav sections
are static <details> (NavRailSection) whose expand state is persisted to localStorage
by the kit's <ThemeScripts/> (emitted in App.razor) — replacing the old interactive
NavSidebar island + cookie/URL auto-expand. *@
<div class="app-shell d-flex flex-column flex-lg-row">
@* Hamburger toggle: visible only on viewports <lg.
Bootstrap collapse JS lives in bootstrap.bundle.min.js (loaded in App.razor). *@
<button class="btn btn-outline-secondary btn-sm d-lg-none m-2 align-self-start"
type="button"
data-bs-toggle="collapse"
data-bs-target="#sidebar-collapse"
aria-controls="sidebar-collapse"
aria-expanded="false"
aria-label="Toggle navigation">
&#9776;
</button>
<div class="collapse d-lg-block" id="sidebar-collapse">
<NavSidebar />
</div>
<main class="page">
@Body
</main>
</div>
<ThemeShell Product="OtOpcUa" Accent="#2f5fd0">
<Nav>
<NavRailSection Title="Navigation" Key="nav">
<NavRailItem Href="/" Text="Overview" Match="NavLinkMatch.All" />
<NavRailItem Href="/fleet" Text="Fleet status" />
<NavRailItem Href="/hosts" Text="Host status" />
<NavRailItem Href="/clusters" Text="Clusters" />
<NavRailItem Href="/reservations" Text="Reservations" />
<NavRailItem Href="/certificates" Text="Certificates" />
<NavRailItem Href="/role-grants" Text="Role grants" />
</NavRailSection>
<NavRailSection Title="Scripting" Key="scripting">
<NavRailItem Href="/virtual-tags" Text="Virtual tags" />
<NavRailItem Href="/scripted-alarms" Text="Scripted alarms" />
<NavRailItem Href="/scripts" Text="Scripts" />
<NavRailItem Href="/script-log" Text="Script log" />
</NavRailSection>
<NavRailSection Title="Live" Key="live">
<NavRailItem Href="/deployments" Text="Deployments" />
<NavRailItem Href="/alerts" Text="Alerts" />
<NavRailItem Href="/alarms-historian" Text="Alarms historian" />
</NavRailSection>
</Nav>
<RailFooter>
<AuthorizeView>
<Authorized>
<div class="rail-eyebrow">Session</div>
<a class="rail-user" href="/account">@context.User.Identity?.Name</a>
<div class="rail-roles">
@string.Join(", ", context.User.Claims
.Where(c => c.Type.EndsWith("/role")).Select(c => c.Value))
</div>
<form method="post" action="/auth/logout">
<AntiforgeryToken />
<button class="rail-btn" type="submit">Sign out</button>
</form>
</Authorized>
<NotAuthorized>
<div class="rail-eyebrow">Session</div>
<a class="rail-btn" href="/login">Sign in</a>
</NotAuthorized>
</AuthorizeView>
</RailFooter>
<ChildContent>@Body</ChildContent>
</ThemeShell>