From 0eb377b515e478662daaf9ada72eb6ed34984e97 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sat, 28 Mar 2026 13:52:49 +0100 Subject: [PATCH] feat(ui): add ScopeTrail component for scope-based breadcrumbs Co-Authored-By: Claude Sonnet 4.6 --- ui/src/components/ScopeTrail.module.css | 40 +++++++++++++++++++++++++ ui/src/components/ScopeTrail.tsx | 38 +++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 ui/src/components/ScopeTrail.module.css create mode 100644 ui/src/components/ScopeTrail.tsx diff --git a/ui/src/components/ScopeTrail.module.css b/ui/src/components/ScopeTrail.module.css new file mode 100644 index 00000000..844c4b5b --- /dev/null +++ b/ui/src/components/ScopeTrail.module.css @@ -0,0 +1,40 @@ +.trail { + display: flex; + align-items: center; + gap: 0; + font-size: 0.8125rem; + color: var(--text-muted); + min-height: 1.5rem; +} + +.segment { + display: inline-flex; + align-items: center; +} + +.link { + color: var(--text-secondary); + text-decoration: none; + cursor: pointer; + background: none; + border: none; + padding: 0; + font: inherit; + font-size: 0.8125rem; +} + +.link:hover { + color: var(--amber); + text-decoration: underline; +} + +.separator { + margin: 0 0.375rem; + color: var(--text-muted); + user-select: none; +} + +.current { + color: var(--text-primary); + font-weight: 500; +} diff --git a/ui/src/components/ScopeTrail.tsx b/ui/src/components/ScopeTrail.tsx new file mode 100644 index 00000000..fa733661 --- /dev/null +++ b/ui/src/components/ScopeTrail.tsx @@ -0,0 +1,38 @@ +import type { Scope } from '../hooks/useScope'; +import styles from './ScopeTrail.module.css'; + +interface ScopeTrailProps { + scope: Scope; + onNavigate: (path: string) => void; +} + +export function ScopeTrail({ scope, onNavigate }: ScopeTrailProps) { + const segments: { label: string; path: string }[] = [ + { label: 'All Applications', path: `/${scope.tab}` }, + ]; + + if (scope.appId) { + segments.push({ label: scope.appId, path: `/${scope.tab}/${scope.appId}` }); + } + + if (scope.routeId) { + segments.push({ label: scope.routeId, path: `/${scope.tab}/${scope.appId}/${scope.routeId}` }); + } + + return ( + + ); +}