Files
member-console/internal/embeds/templates/partials/shell_topbar.html
T
cgalo5758 3283df19b1 Move account menu into mobile rail drawer
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.
2026-09-09 22:57:26 -05:00

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>