Extract the top bar and account menu into shell_topbar.html and the member rail into shell_rail_member.html, backed by a single server.Shell value. Move session controls into the account menu, add the mirrored Operator panel/Member dashboard surface switch, and turn the rail into an offcanvas drawer below lg with shell.js closing it on navigation. Update docs, specs, and tests. Unify application shell across both surfaces Extract the top bar and member rail into shared partials and introduce server.Shell as the single data value for page chrome. Move session controls into an account menu, make the rail an offcanvas drawer below lg, and add the mirrored surface switch.
31 lines
2.4 KiB
HTML
31 lines
2.4 KiB
HTML
{{/* Application shell: the top bar and the account menu, shared by the
|
|
member surface (index.html, products.html, billing.html) and the
|
|
operator surface (operator.html). Pipeline: server.Shell. Convention:
|
|
docs/design-system.md "Application shell"; contract: chrome-conventions
|
|
"One shell for both surfaces" and "Session controls live in the account
|
|
menu on both surfaces". The top bar carries the place and the person's
|
|
utilities; it carries no section links on either surface, the rail does.
|
|
The toggler opens the rail (#app-rail) as a drawer below lg and is
|
|
hidden at lg and up, where the rail is always visible. The account
|
|
menu's trigger is a <button> so hx-boost never treats it as a link. */}}
|
|
<nav class="navbar navbar-expand navbar-dark bg-dark app-topbar" aria-label="Account">
|
|
<div class="container-fluid">
|
|
<button class="navbar-toggler d-lg-none me-2" type="button" data-bs-toggle="offcanvas" data-bs-target="#app-rail" aria-controls="app-rail" aria-label="Open navigation">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<a class="navbar-brand" href="/">{{ deploymentName }}</a>
|
|
{{ if .IsOperatorSurface }}<span class="navbar-text text-secondary app-surface-label">Operator</span>{{ end }}
|
|
<ul class="navbar-nav ms-auto">
|
|
<li class="nav-item dropdown">
|
|
<button class="nav-link dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"><span class="app-account-label">{{ .Label }}</span></button>
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
<li><h6 class="dropdown-header">{{ .Label }}{{ if .Email }}<br><span class="fw-normal">{{ .Email }}</span>{{ end }}</h6></li>
|
|
<li><a class="dropdown-item" href="{{ .KeycloakAccountURL }}" target="_blank" hx-boost="false" title="Manage your account and sign-in. Opens in a new tab.">Identity and <span class="text-nowrap">Access<svg class="external-link-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg></span></a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="/logout" hx-boost="false">Sign out</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|