feat(ui): browser Back/Forward restores exchange selection via history state
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m1s
CI / docker (push) Successful in 57s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 36s

Each exchange selection (from table or correlation chain) pushes a
browser history entry with the selected exchange in location.state.
When the user navigates away (to agent details, app scope, etc.) and
presses Back, the previous history entry is restored and the split
view with the diagram reappears exactly as they left it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-28 15:48:38 +01:00
parent 8b276a92a7
commit b4c9be9334

View File

@@ -1,5 +1,5 @@
import { useState, useMemo, useCallback, useRef } from 'react';
import { useNavigate } from 'react-router';
import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
import { useNavigate, useLocation } from 'react-router';
import { useGlobalFilters } from '@cameleer/design-system';
import { useExecutionDetail } from '../../api/queries/executions';
import { useDiagramByRoute } from '../../api/queries/diagrams';
@@ -14,20 +14,42 @@ import Dashboard from '../Dashboard/Dashboard';
import type { SelectedExchange } from '../Dashboard/Dashboard';
export default function ExchangesPage() {
const [selected, setSelected] = useState<SelectedExchange | null>(null);
const navigate = useNavigate();
const location = useLocation();
// Restore selection from browser history state (enables Back/Forward)
const stateSelected = (location.state as any)?.selectedExchange as SelectedExchange | undefined;
const [selected, setSelectedInternal] = useState<SelectedExchange | null>(stateSelected ?? null);
// Sync from history state when the user navigates Back/Forward
useEffect(() => {
const restored = (location.state as any)?.selectedExchange as SelectedExchange | undefined;
setSelectedInternal(restored ?? null);
}, [location.state]);
const [splitPercent, setSplitPercent] = useState(50);
const containerRef = useRef<HTMLDivElement>(null);
// Select an exchange: push a history entry so Back restores the previous state
const handleExchangeSelect = useCallback((exchange: SelectedExchange) => {
setSelected(exchange);
}, []);
setSelectedInternal(exchange);
navigate(location.pathname + location.search, {
state: { ...location.state, selectedExchange: exchange },
});
}, [navigate, location.pathname, location.search, location.state]);
// Select a correlated exchange: push another history entry
const handleCorrelatedSelect = useCallback((executionId: string, applicationName: string, routeId: string) => {
setSelected({ executionId, applicationName, routeId });
}, []);
const exchange = { executionId, applicationName, routeId };
setSelectedInternal(exchange);
navigate(location.pathname + location.search, {
state: { ...location.state, selectedExchange: exchange },
});
}, [navigate, location.pathname, location.search, location.state]);
// Clear selection: push a history entry without selection (so Back returns to selected state)
const handleClearSelection = useCallback(() => {
setSelected(null);
setSelectedInternal(null);
}, []);
const handleSplitterDown = useCallback((e: React.PointerEvent) => {