fix: sidebar selection highlight and scoped command palette search
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m9s
CI / deploy (push) Has been cancelled
CI / deploy-feature (push) Has been cancelled
CI / docker (push) Has been cancelled

Two fixes:
- Pass sidebarReveal state on sidebar navigation so the design system
  can highlight the selected entry (it compares internal /apps/... paths
  against this state value, not the browser URL)
- Command palette search now includes scope.appId and scope.routeId
  so results are filtered to the current sidebar selection

Note: sidebar highlighting works on the exchanges tab. The design
system's selectedPath logic only checks pathname.startsWith("/exchanges/")
for sidebarReveal — a DS update is needed to support /dashboard/ and
/runtime/ tabs too.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-01 20:41:42 +02:00
parent a028905e41
commit 4168a6d45b

View File

@@ -98,11 +98,17 @@ function LayoutContent() {
const { open: paletteOpen, setOpen: setPaletteOpen } = useCommandPalette(); const { open: paletteOpen, setOpen: setPaletteOpen } = useCommandPalette();
const { scope, setTab } = useScope(); const { scope, setTab } = useScope();
// Exchange full-text search via command palette // Exchange full-text search via command palette (scoped to current sidebar selection)
const [paletteQuery, setPaletteQuery] = useState(''); const [paletteQuery, setPaletteQuery] = useState('');
const debouncedQuery = useDebouncedValue(paletteQuery, 300); const debouncedQuery = useDebouncedValue(paletteQuery, 300);
const { data: exchangeResults } = useSearchExecutions( const { data: exchangeResults } = useSearchExecutions(
{ text: debouncedQuery || undefined, offset: 0, limit: 10 }, {
text: debouncedQuery || undefined,
application: scope.appId || undefined,
routeId: scope.routeId || undefined,
offset: 0,
limit: 10,
},
false, false,
); );
@@ -243,13 +249,17 @@ function LayoutContent() {
navigate(`${baseParts.join('/')}?text=${encodeURIComponent(query)}`); navigate(`${baseParts.join('/')}?text=${encodeURIComponent(query)}`);
}, [navigate, scope.appId, scope.routeId]); }, [navigate, scope.appId, scope.routeId]);
// Translate Sidebar's internal paths to our URL structure // Translate Sidebar's internal paths to our URL structure.
// Pass `sidebarReveal` state so the Sidebar can highlight the selected entry
// (it compares its internal /apps/... paths against this state value).
const handleSidebarNavigate = useCallback((path: string) => { const handleSidebarNavigate = useCallback((path: string) => {
const state = { sidebarReveal: path };
// /apps/:appId and /apps/:appId/:routeId → current tab // /apps/:appId and /apps/:appId/:routeId → current tab
const appMatch = path.match(/^\/apps\/([^/]+)(?:\/(.+))?$/); const appMatch = path.match(/^\/apps\/([^/]+)(?:\/(.+))?$/);
if (appMatch) { if (appMatch) {
const [, sAppId, sRouteId] = appMatch; const [, sAppId, sRouteId] = appMatch;
navigate(sRouteId ? `/${scope.tab}/${sAppId}/${sRouteId}` : `/${scope.tab}/${sAppId}`); navigate(sRouteId ? `/${scope.tab}/${sAppId}/${sRouteId}` : `/${scope.tab}/${sAppId}`, { state });
return; return;
} }
@@ -257,11 +267,11 @@ function LayoutContent() {
const agentMatch = path.match(/^\/agents\/([^/]+)(?:\/(.+))?$/); const agentMatch = path.match(/^\/agents\/([^/]+)(?:\/(.+))?$/);
if (agentMatch) { if (agentMatch) {
const [, sAppId, sInstanceId] = agentMatch; const [, sAppId, sInstanceId] = agentMatch;
navigate(sInstanceId ? `/runtime/${sAppId}/${sInstanceId}` : `/runtime/${sAppId}`); navigate(sInstanceId ? `/runtime/${sAppId}/${sInstanceId}` : `/runtime/${sAppId}`, { state });
return; return;
} }
navigate(path); navigate(path, { state });
}, [navigate, scope.tab]); }, [navigate, scope.tab]);
return ( return (