From 2708bcec1792a93e485a30b7378915fba0a77547 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Fri, 3 Apr 2026 11:28:26 +0200 Subject: [PATCH] fix: first exchange click doesn't highlight selected row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On first click, Dashboard was in non-split mode. The click set selectedId locally then triggered split view, which remounted Dashboard — losing the selectedId state. Added activeExchangeId prop passed from ExchangesPage so the selection survives the remount. Also syncs via useEffect when parent changes selection (e.g. correlated exchange navigation). Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/src/pages/Dashboard/Dashboard.tsx | 12 +++++++++--- ui/src/pages/Exchanges/ExchangesPage.tsx | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ui/src/pages/Dashboard/Dashboard.tsx b/ui/src/pages/Dashboard/Dashboard.tsx index c258461d..6f688886 100644 --- a/ui/src/pages/Dashboard/Dashboard.tsx +++ b/ui/src/pages/Dashboard/Dashboard.tsx @@ -1,4 +1,4 @@ -import { useState, useMemo, useCallback } from 'react' +import { useState, useMemo, useCallback, useEffect } from 'react' import { useParams, useNavigate, useSearchParams } from 'react-router' import { AlertTriangle, X, Search, Footprints, RotateCcw } from 'lucide-react' import { @@ -169,17 +169,23 @@ export interface SelectedExchange { interface DashboardProps { onExchangeSelect?: (exchange: SelectedExchange) => void; + activeExchangeId?: string; } -export default function Dashboard({ onExchangeSelect }: DashboardProps = {}) { +export default function Dashboard({ onExchangeSelect, activeExchangeId }: DashboardProps = {}) { const { appId, routeId } = useParams<{ appId: string; routeId: string }>() const navigate = useNavigate() const [searchParams, setSearchParams] = useSearchParams() const textFilter = searchParams.get('text') || undefined - const [selectedId, setSelectedId] = useState() + const [selectedId, setSelectedId] = useState(activeExchangeId) const [sortField, setSortField] = useState('startTime') const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc') + // Sync selection from parent (survives remount when split view toggles) + useEffect(() => { + if (activeExchangeId !== undefined) setSelectedId(activeExchangeId); + }, [activeExchangeId]); + const { timeRange, statusFilters } = useGlobalFilters() const timeFrom = timeRange.start.toISOString() const timeTo = timeRange.end.toISOString() diff --git a/ui/src/pages/Exchanges/ExchangesPage.tsx b/ui/src/pages/Exchanges/ExchangesPage.tsx index 635547af..dc6e6385 100644 --- a/ui/src/pages/Exchanges/ExchangesPage.tsx +++ b/ui/src/pages/Exchanges/ExchangesPage.tsx @@ -102,7 +102,7 @@ export default function ExchangesPage() { const showSplit = !!selected || !!scopedRouteId; if (!showSplit) { - return ; + return ; } // Determine what the right panel shows @@ -113,7 +113,7 @@ export default function ExchangesPage() { return (
- +