feat: configure-tap action navigates to AppConfig page
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 57s
CI / docker (push) Successful in 52s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 35s

The tap button in the node toolbar now navigates to
/admin/appconfig?app=<application>&processor=<nodeId>, which
auto-selects the application in the AppConfigPage. The AppConfigPage
reads the ?app query param to open the detail panel for that app.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-27 20:23:19 +01:00
parent bd8e95c6ce
commit cbe41d7ac7
2 changed files with 17 additions and 2 deletions

View File

@@ -1,5 +1,5 @@
import { useState, useMemo, useEffect } from 'react'; import { useState, useMemo, useEffect } from 'react';
import { useNavigate } from 'react-router'; import { useNavigate, useSearchParams } from 'react-router';
import { import {
DataTable, Badge, MonoText, DetailPanel, SectionHeader, Button, Toggle, Spinner, useToast, DataTable, Badge, MonoText, DetailPanel, SectionHeader, Button, Toggle, Spinner, useToast,
} from '@cameleer/design-system'; } from '@cameleer/design-system';
@@ -311,9 +311,22 @@ function AppConfigDetail({ appId, onClose }: { appId: string; onClose: () => voi
export default function AppConfigPage() { export default function AppConfigPage() {
const { data: configs } = useAllApplicationConfigs(); const { data: configs } = useAllApplicationConfigs();
const [searchParams, setSearchParams] = useSearchParams();
const [selectedApp, setSelectedApp] = useState<string | null>(null); const [selectedApp, setSelectedApp] = useState<string | null>(null);
const columns = useMemo(buildColumns, []); const columns = useMemo(buildColumns, []);
// Auto-select app from query param (e.g., ?app=caller-app)
useEffect(() => {
const appParam = searchParams.get('app');
if (appParam && !selectedApp) {
setSelectedApp(appParam);
// Clean up the query param
searchParams.delete('app');
searchParams.delete('processor');
setSearchParams(searchParams, { replace: true });
}
}, [searchParams]); // eslint-disable-line react-hooks/exhaustive-deps
return ( return (
<div> <div>
<DataTable<ConfigRow> <DataTable<ConfigRow>

View File

@@ -243,8 +243,10 @@ export default function ExchangeDetail() {
const handleNodeAction = useCallback((nodeId: string, action: NodeAction) => { const handleNodeAction = useCallback((nodeId: string, action: NodeAction) => {
if (action === 'toggle-trace') { if (action === 'toggle-trace') {
handleToggleTracing(nodeId) handleToggleTracing(nodeId)
} else if (action === 'configure-tap' && detail?.applicationName) {
navigate(`/admin/appconfig?app=${encodeURIComponent(detail.applicationName)}&processor=${encodeURIComponent(nodeId)}`)
} }
}, [handleToggleTracing]) }, [handleToggleTracing, detail?.applicationName, navigate])
// ── Replay ───────────────────────────────────────────────────────────── // ── Replay ─────────────────────────────────────────────────────────────
const { data: liveAgents } = useAgents('LIVE', detail?.applicationName) const { data: liveAgents } = useAgents('LIVE', detail?.applicationName)