feat(adminui): collapsible nav sidebar with cookie state + LoginLayout
Port the ScadaLink CentralUI sidebar pattern into the OtOpcUa AdminUI: - Drop the top app-bar. Brand moves into the side rail's header — same visual rhythm as ScadaLink's NavMenu. - New NavSection.razor: collapsible eyebrow toggle (rail-eyebrow-toggle CSS) with a chevron + label. Mirrors ScadaLink/Components/Layout/NavSection. - New NavSidebar.razor: interactive island carrying the three section groups (Navigation / Scripting / Live) + session block. Marked @rendermode InteractiveServer; MainLayout itself stays static-rendered because layouts can't take a RenderFragment Body across an interactive boundary. - New wwwroot/js/nav-state.js: window.navState.get/.set persists the expanded-section list to the otopcua_nav cookie (one-year lifetime, SameSite=Lax). Same shape as ScadaLink's scadabridge_nav. - New LoginLayout.razor + @layout LoginLayout on Login.razor: the login page now renders without the side rail — clean centred card. - MainLayout.razor: slimmed down to the d-flex shell + hamburger toggle + <NavSidebar/> + @Body. - Login.razor: also drops the trailing "LDAP bind against the configured directory..." footer that the user asked to remove. - site.css: adds .side-rail .brand styles (mirrored from ScadaLink) and the .rail-eyebrow-toggle / .rail-eyebrow-chevron / .rail-section-body styles for the new collapsible UI. Auto-expand on page load: NavSidebar seeds the expanded set from the current URL's first path segment (in OnInitialized so it works even on the very first server render) and from the cookie (in OnAfterRenderAsync once JS interop is available). LocationChanged hooks keep the expanded state in sync as the user navigates between sections.
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
@page "/login"
|
||||
@layout LoginLayout
|
||||
@* Login MUST stay anonymously reachable — otherwise the fallback authorization policy
|
||||
would lock operators out of the only way in (Admin-001). Static-rendered on purpose:
|
||||
the form POSTs to /auth/login while ASP.NET still owns an unstarted HTTP response.
|
||||
Calling SignInAsync from an interactive circuit would be too late. *@
|
||||
Calling SignInAsync from an interactive circuit would be too late.
|
||||
|
||||
Uses LoginLayout (no side rail) so the page renders as a clean centred card. *@
|
||||
@attribute [Microsoft.AspNetCore.Authorization.AllowAnonymous]
|
||||
|
||||
<div class="login-wrap rise" style="animation-delay:.02s">
|
||||
@@ -32,12 +35,6 @@
|
||||
|
||||
<button class="btn btn-primary w-100" type="submit">Sign in</button>
|
||||
</form>
|
||||
|
||||
<div style="margin-top:1rem;padding-top:.85rem;border-top:1px solid var(--rule);
|
||||
font-size:.78rem;color:var(--ink-faint)">
|
||||
LDAP bind against the configured directory (per Q5 of the AdminUI rebuild plan:
|
||||
generic error in production; specific reason when <span class="mono">Authentication:Ldap:AllowInsecureLdap=true</span>).
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user