Below lg the top bar now holds the brand and one toggler; the account items render in the drawer as a second, labelled list from a shared partial, so both surfaces cannot drift. Desktop unchanged.
45 lines
3.4 KiB
HTML
45 lines
3.4 KiB
HTML
{{- /* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial */ -}}
|
|
{{- /* SPDX-FileCopyrightText: 2025-2026 Christian Galo */ -}}
|
|
|
|
{{/* Application shell: the top bar, 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", "The top bar holds the brand and one
|
|
control" and "Session controls live in the account menu on both
|
|
surfaces". The bar holds the brand at its left edge and exactly one
|
|
control at its right, and nothing else, ever: no section links (the
|
|
rail carries those) and no surface label (the trail's root crumb states
|
|
the surface instead, design D18). Which control depends on the width,
|
|
and the DOM order does not: the account menu renders at lg and up
|
|
(d-none d-lg-flex), the menu toggler below lg (d-lg-none), each with
|
|
ms-auto, so whichever renders lands at the right end and the brand
|
|
stays first (mobile-shell-menu D2). Below lg the toggler opens the
|
|
rail (#app-rail), which is the shell's one menu at that width and
|
|
carries the account items itself (partials/shell_rail_account.html);
|
|
at lg and up the rail is always visible and the account menu is here.
|
|
The account menu's trigger is a <button> so hx-boost never treats it
|
|
as a link. Sign out is a button too: it posts, so a link from another
|
|
origin cannot end the session, and the handler answers with
|
|
HX-Redirect to the identity provider. */}}
|
|
<nav class="navbar navbar-expand navbar-dark bg-dark app-topbar" aria-label="Account">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="/">{{ deploymentName }}</a>
|
|
<ul class="navbar-nav ms-auto d-none d-lg-flex">
|
|
<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>
|
|
{{ with supportURL }}<li><a class="dropdown-item" href="{{ . }}" target="_blank" hx-boost="false" title="Get help. Opens in a new tab.">Get help</a></li>{{ end }}
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><button type="button" class="dropdown-item" hx-post="/logout" hx-swap="none">Sign out</button></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<button class="navbar-toggler d-lg-none ms-auto" type="button" data-bs-toggle="offcanvas" data-bs-target="#app-rail" aria-controls="app-rail" aria-label="Open menu">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
</div>
|
|
</nav>
|