fix(ui): clicking app or route in exchange header clears selection and returns to table
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m2s
CI / docker (push) Successful in 56s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s

This commit is contained in:
hsiegeln
2026-03-28 15:42:45 +01:00
parent 01c6d5c131
commit 8b276a92a7
2 changed files with 12 additions and 5 deletions

View File

@@ -11,6 +11,7 @@ import styles from './ExchangeHeader.module.css';
interface ExchangeHeaderProps { interface ExchangeHeaderProps {
detail: ExecutionDetail; detail: ExecutionDetail;
onCorrelatedSelect?: (executionId: string, applicationName: string, routeId: string) => void; onCorrelatedSelect?: (executionId: string, applicationName: string, routeId: string) => void;
onClearSelection?: () => void;
} }
type StatusVariant = 'success' | 'error' | 'running' | 'warning'; type StatusVariant = 'success' | 'error' | 'running' | 'warning';
@@ -39,7 +40,7 @@ function formatDuration(ms: number): string {
return `${ms}ms`; return `${ms}ms`;
} }
export function ExchangeHeader({ detail, onCorrelatedSelect }: ExchangeHeaderProps) { export function ExchangeHeader({ detail, onCorrelatedSelect, onClearSelection }: ExchangeHeaderProps) {
const navigate = useNavigate(); const navigate = useNavigate();
const { data: chainResult } = useCorrelationChain(detail.correlationId ?? null); const { data: chainResult } = useCorrelationChain(detail.correlationId ?? null);
const chain = chainResult?.data; const chain = chainResult?.data;
@@ -69,10 +70,10 @@ export function ExchangeHeader({ detail, onCorrelatedSelect }: ExchangeHeaderPro
</> </>
)} )}
<span className={styles.separator} /> <span className={styles.separator} />
<button className={styles.linkBtn} onClick={() => navigate(`/exchanges/${detail.applicationName}`)} title="Show all exchanges for this application"> <button className={styles.linkBtn} onClick={() => { onClearSelection?.(); navigate(`/exchanges/${detail.applicationName}`); }} title="Show all exchanges for this application">
<span className={styles.app}>{detail.applicationName}</span> <span className={styles.app}>{detail.applicationName}</span>
</button> </button>
<button className={styles.linkBtn} onClick={() => navigate(`/exchanges/${detail.applicationName}/${detail.routeId}`)} title="Show all exchanges for this route"> <button className={styles.linkBtn} onClick={() => { onClearSelection?.(); navigate(`/exchanges/${detail.applicationName}/${detail.routeId}`); }} title="Show all exchanges for this route">
<span className={styles.route}>{detail.routeId}</span> <span className={styles.route}>{detail.routeId}</span>
<GitBranch size={12} className={styles.icon} /> <GitBranch size={12} className={styles.icon} />
</button> </button>

View File

@@ -26,6 +26,10 @@ export default function ExchangesPage() {
setSelected({ executionId, applicationName, routeId }); setSelected({ executionId, applicationName, routeId });
}, []); }, []);
const handleClearSelection = useCallback(() => {
setSelected(null);
}, []);
const handleSplitterDown = useCallback((e: React.PointerEvent) => { const handleSplitterDown = useCallback((e: React.PointerEvent) => {
e.currentTarget.setPointerCapture(e.pointerId); e.currentTarget.setPointerCapture(e.pointerId);
const container = containerRef.current; const container = containerRef.current;
@@ -62,6 +66,7 @@ export default function ExchangesPage() {
routeId={selected.routeId} routeId={selected.routeId}
exchangeId={selected.executionId} exchangeId={selected.executionId}
onCorrelatedSelect={handleCorrelatedSelect} onCorrelatedSelect={handleCorrelatedSelect}
onClearSelection={handleClearSelection}
/> />
</div> </div>
</div> </div>
@@ -75,9 +80,10 @@ interface DiagramPanelProps {
routeId: string; routeId: string;
exchangeId: string; exchangeId: string;
onCorrelatedSelect: (executionId: string, applicationName: string, routeId: string) => void; onCorrelatedSelect: (executionId: string, applicationName: string, routeId: string) => void;
onClearSelection: () => void;
} }
function DiagramPanel({ appId, routeId, exchangeId, onCorrelatedSelect }: DiagramPanelProps) { function DiagramPanel({ appId, routeId, exchangeId, onCorrelatedSelect, onClearSelection }: DiagramPanelProps) {
const navigate = useNavigate(); const navigate = useNavigate();
const { timeRange } = useGlobalFilters(); const { timeRange } = useGlobalFilters();
const timeFrom = timeRange.start.toISOString(); const timeFrom = timeRange.start.toISOString();
@@ -107,7 +113,7 @@ function DiagramPanel({ appId, routeId, exchangeId, onCorrelatedSelect }: Diagra
if (detail) { if (detail) {
return ( return (
<> <>
<ExchangeHeader detail={detail} onCorrelatedSelect={onCorrelatedSelect} /> <ExchangeHeader detail={detail} onCorrelatedSelect={onCorrelatedSelect} onClearSelection={onClearSelection} />
<ExecutionDiagram <ExecutionDiagram
executionId={exchangeId} executionId={exchangeId}
executionDetail={detail} executionDetail={detail}