Frontend UX: app header is empty — add wayfinding (section/breadcrumb, user, app name, global search) #54
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: Medium. From a frontend UX audit. The header is the most persistent surface in a hours-a-day tool and currently carries almost nothing.
Problems
<header>(web/src/shell/app-shell.tsx:66-72) contains only a flex spacer, the language switch, and Sign out — no section title/breadcrumb, no logged-in user identity, no global-search entry./objects/newshows the Objects list with nothing selected and no header cue that you're in create mode (no breadcrumb/page title anywhere).ConfigProviderfetches/api/configapp_name, but the sidebar brand (app-shell.tsx:21) and login heading (login-page.tsx:34) render the hardcodedt("app.name")= "Collection" instead ofuseConfig().app_name(default "Collection Management System"). Two competing names; the configured one appears nowhere.Suggested fixes
useMe()already returns it) and a quick-search affordance on the right.useConfig().app_namefor the brand + login heading; drop/repurpose the hardcodedapp.name.Source: frontend UX/design audit, 2026-06-06.
Done — merged to
main(b7242ca). The header now carries real wayfinding.Breadcrumb (left): a page-driven
useBreadcrumb(trail)hook +BreadcrumbProvider(parallel to the #57 title hook) — every AppShell route sets its trail and the header renders it (non-leaf crumbs are links):Objects/Vocabularies/ …;Objects / New,Objects / Edit;Objects / {object_number};Vocabularies / {key}..keyvia the cache-shareduseVocabularies), so no extra requests and no UUIDs in the crumb.User menu (right): a new reusable
ui/menu.tsxBase UI dropdown wrapper (validated by running) powers aUserMenushowing the signed-inemail+roleand a Sign out item; the standalone Sign out button is gone (logout lives in the menu).Header search (right): a compact
HeaderSearchinput →/search?q=…(encoded), so you can start a search from any screen; hidden belowsm. (The full ⌘K palette / in-place modal remains #33.)Brand + login: the sidebar brand and login heading + tab title now render
useConfig().app_name(default "Collection Management System"); the hardcodedapp.namei18n key is removed from both locales.No new dependency (Base UI Menu is a namespace export of the existing
@base-ui/react); i18n net +1/−1 with en/sv parity; the breadcrumb hook iseslint-disable-free (ref + serialized-key pattern). Gate green: typecheck, lint, 194 tests, build, check:size (196.3 KB gz, +~12 KB for Menu, under the 250 KB budget), check:colors; no codename.Follow-ups (out of scope): full ⌘K command palette (#33); broader responsive header (#58);
/search/:idshowing a search-relative (vs canonical-object) breadcrumb; user avatar / account settings page.