refactor: consolidate tabs — remove standalone Logs and Config tabs
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m18s
CI / docker (push) Successful in 1m5s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 42s

Logs functionality already exists in Runtime tab (AgentHealth/AgentInstance).
Config functionality moved to Deployments tab ConfigSubTab.
Old routes redirect to /runtime and /apps respectively.
Navigation links updated throughout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-08 18:02:29 +02:00
parent b7f215e90c
commit 0a0733def7
6 changed files with 14 additions and 20 deletions

View File

@@ -9,8 +9,6 @@ const BASE_TABS = [
{ label: 'Exchanges', value: 'exchanges' },
{ label: 'Dashboard', value: 'dashboard' },
{ label: 'Runtime', value: 'runtime' },
{ label: 'Logs', value: 'logs' },
{ label: 'Config', value: 'config' },
];
interface ContentTabsProps {

View File

@@ -107,10 +107,10 @@ export function LogTab({ applicationId, exchangeId, processorId }: LogTabProps)
{exchangeId && (
<div className={logStyles.footer}>
<button
onClick={() => navigate(`/logs/${applicationId}?exchangeId=${exchangeId}`)}
onClick={() => navigate(`/runtime/${applicationId}`)}
className={logStyles.openLogsButton}
>
Open in Logs tab {'\u2192'}
Open in Runtime {'\u2192'}
</button>
</div>
)}

View File

@@ -618,9 +618,9 @@ function LayoutContent() {
const appMatch = path.match(/^\/apps\/([^/]+)(?:\/(.+))?$/);
if (appMatch) {
const [, sAppId, sRouteId] = appMatch;
if (scope.tab === 'config') {
// Config tab: always navigate to /config/:appId (route click → same app config)
navigate(`/config/${sAppId}`, { state });
if (scope.tab === 'apps') {
// Deployments tab: navigate to /apps/:appId
navigate(`/apps/${sAppId}`, { state });
} else {
navigate(sRouteId ? `/${scope.tab}/${sAppId}/${sRouteId}` : `/${scope.tab}/${sAppId}`, { state });
}

View File

@@ -2,9 +2,9 @@
import { useParams, useNavigate, useLocation } from 'react-router';
import { useCallback } from 'react';
export type TabKey = 'exchanges' | 'dashboard' | 'runtime' | 'logs' | 'config' | 'apps';
export type TabKey = 'exchanges' | 'dashboard' | 'runtime' | 'apps';
const VALID_TABS = new Set<TabKey>(['exchanges', 'dashboard', 'runtime', 'logs', 'config', 'apps']);
const VALID_TABS = new Set<TabKey>(['exchanges', 'dashboard', 'runtime', 'apps']);
export interface Scope {
tab: TabKey;

View File

@@ -118,7 +118,7 @@ export function ExchangeHeader({ detail, onCorrelatedSelect, onClearSelection }:
<span className={styles.duration}>{formatDuration(detail.durationMs)}</span>
<button
className={styles.linkBtn}
onClick={() => navigate(`/logs/${detail.applicationId}?exchangeId=${detail.exchangeId}`)}
onClick={() => navigate(`/runtime/${detail.applicationId}`)}
title="View surrounding logs"
>
<FileText size={12} className={styles.icon} />

View File

@@ -18,9 +18,7 @@ const OidcConfigPage = lazy(() => import('./pages/Admin/OidcConfigPage'));
const DatabaseAdminPage = lazy(() => import('./pages/Admin/DatabaseAdminPage'));
const ClickHouseAdminPage = lazy(() => import('./pages/Admin/ClickHouseAdminPage'));
const EnvironmentsPage = lazy(() => import('./pages/Admin/EnvironmentsPage'));
const AppConfigPage = lazy(() => import('./pages/Admin/AppConfigPage'));
const AppsTab = lazy(() => import('./pages/AppsTab/AppsTab'));
const LogsPage = lazy(() => import('./pages/LogsTab/LogsPage'));
const SwaggerPage = lazy(() => import('./pages/Swagger/SwaggerPage'));
function SuspenseWrapper({ children }: { children: React.ReactNode }) {
@@ -61,14 +59,12 @@ export const router = createBrowserRouter([
{ path: 'runtime/:appId', element: <SuspenseWrapper><RuntimePage /></SuspenseWrapper> },
{ path: 'runtime/:appId/:instanceId', element: <SuspenseWrapper><RuntimePage /></SuspenseWrapper> },
// Logs tab
{ path: 'logs', element: <SuspenseWrapper><LogsPage /></SuspenseWrapper> },
{ path: 'logs/:appId', element: <SuspenseWrapper><LogsPage /></SuspenseWrapper> },
{ path: 'logs/:appId/:routeId', element: <SuspenseWrapper><LogsPage /></SuspenseWrapper> },
// Config tab (accessible to VIEWER+, shows all apps or single app)
{ path: 'config', element: <SuspenseWrapper><AppConfigPage /></SuspenseWrapper> },
{ path: 'config/:appId', element: <SuspenseWrapper><AppConfigPage /></SuspenseWrapper> },
// Redirects for removed tabs
{ path: 'logs', element: <Navigate to="/runtime" replace /> },
{ path: 'logs/:appId', element: <Navigate to="/runtime" replace /> },
{ path: 'logs/:appId/:routeId', element: <Navigate to="/runtime" replace /> },
{ path: 'config', element: <Navigate to="/apps" replace /> },
{ path: 'config/:appId', element: <Navigate to="/apps" replace /> },
// Apps tab (OPERATOR+ via UI guard, shows all or single app)
{ path: 'apps', element: <SuspenseWrapper><AppsTab /></SuspenseWrapper> },