From c6a8a4471f5798e5bf063dce46331570ff37499c Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Mon, 6 Apr 2026 16:10:02 +0200 Subject: [PATCH] fix: always show Config tab and fix 404 on sidebar navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Config tab now always visible (not just when app selected). Shows all- app config table at /config, single-app detail at /config/:appId. Fixed 404 when clicking sidebar nodes while on Config tab — the sidebar navigation built /config/appId/routeId which had no route. Now falls back to exchanges tab for route-level navigation from config. Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/src/components/ContentTabs.tsx | 10 ++-------- ui/src/components/LayoutShell.tsx | 4 +++- ui/src/router.tsx | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/ui/src/components/ContentTabs.tsx b/ui/src/components/ContentTabs.tsx index a85f366b..02b18588 100644 --- a/ui/src/components/ContentTabs.tsx +++ b/ui/src/components/ContentTabs.tsx @@ -3,15 +3,11 @@ import type { TabKey, Scope } from '../hooks/useScope'; import { TabKpis } from './TabKpis'; import styles from './ContentTabs.module.css'; -const BASE_TABS = [ +const TABS = [ { label: 'Exchanges', value: 'exchanges' }, { label: 'Dashboard', value: 'dashboard' }, { label: 'Runtime', value: 'runtime' }, { label: 'Logs', value: 'logs' }, -]; - -const TABS_WITH_CONFIG = [ - ...BASE_TABS, { label: 'Config', value: 'config' }, ]; @@ -22,12 +18,10 @@ interface ContentTabsProps { } export function ContentTabs({ active, onChange, scope }: ContentTabsProps) { - // Config tab only shown when an app is selected - const tabs = scope.appId ? TABS_WITH_CONFIG : BASE_TABS; return (
onChange(v as TabKey)} /> diff --git a/ui/src/components/LayoutShell.tsx b/ui/src/components/LayoutShell.tsx index b2d2ead3..e679d6c8 100644 --- a/ui/src/components/LayoutShell.tsx +++ b/ui/src/components/LayoutShell.tsx @@ -604,7 +604,9 @@ function LayoutContent() { const appMatch = path.match(/^\/apps\/([^/]+)(?:\/(.+))?$/); if (appMatch) { const [, sAppId, sRouteId] = appMatch; - navigate(sRouteId ? `/${scope.tab}/${sAppId}/${sRouteId}` : `/${scope.tab}/${sAppId}`, { state }); + // Config tab only supports /config/:appId — fall back to exchanges for route-level + const tab = (scope.tab === 'config' && sRouteId) ? 'exchanges' : scope.tab; + navigate(sRouteId ? `/${tab}/${sAppId}/${sRouteId}` : `/${tab}/${sAppId}`, { state }); return; } diff --git a/ui/src/router.tsx b/ui/src/router.tsx index aeb87101..45583f79 100644 --- a/ui/src/router.tsx +++ b/ui/src/router.tsx @@ -77,8 +77,8 @@ export const router = createBrowserRouter([ { path: 'logs/:appId', element: }, { path: 'logs/:appId/:routeId', element: }, - // Config tab (per-app, accessible to VIEWER+) - { path: 'config', element: }, + // Config tab (accessible to VIEWER+, shows all apps or single app) + { path: 'config', element: }, { path: 'config/:appId', element: }, // Legacy redirects — Sidebar uses hardcoded /apps/... and /agents/... paths