fix: race condition causing wrong symbol data in chart and evaluation
- Add cancelled flags to evaluation and scorecard effects so stale
responses from a previous symbol cannot overwrite current data
- Clear evaluation and scorecard state immediately in pickSymbol so
old data never flashes when switching symbols
- Add key={symbol} to ConfluenceChart to force clean remount on
symbol change
This commit is contained in:
@@ -55,6 +55,9 @@ export function ConfluencePanel() {
|
||||
setSymbol(sym);
|
||||
setSearchQuery(sym);
|
||||
setActiveSymbol(sym);
|
||||
// Clear stale data immediately so old symbol never flashes
|
||||
setEvaluation(null);
|
||||
setScorecard(null);
|
||||
}, [setActiveSymbol]);
|
||||
|
||||
// Sync searchQuery when activeSymbol changes externally (e.g., from another panel)
|
||||
@@ -62,6 +65,11 @@ export function ConfluencePanel() {
|
||||
setSearchQuery(activeSymbol);
|
||||
}, [activeSymbol]);
|
||||
|
||||
// Sync symbol state when activeSymbol changes externally
|
||||
useEffect(() => {
|
||||
setSymbol(activeSymbol);
|
||||
}, [activeSymbol]);
|
||||
|
||||
// Racks
|
||||
const [racks, setRacks] = useState<{ system: Array<{ id: string; name: string }>; user: Array<{ id: string; name: string }> }>({ system: [], user: [] });
|
||||
useEffect(() => {
|
||||
@@ -73,18 +81,22 @@ export function ConfluencePanel() {
|
||||
const rackId = selectedRackId ?? racks.system[0]?.id ?? null;
|
||||
useEffect(() => {
|
||||
if (!symbol) return;
|
||||
let cancelled = false;
|
||||
api.confluence.evaluation(symbol, { rackId: rackId ?? undefined, limit: 6 })
|
||||
.then((r) => setEvaluation(r as Record<string, unknown>))
|
||||
.catch(() => setEvaluation(null));
|
||||
.then((r) => { if (!cancelled) setEvaluation(r as Record<string, unknown>); })
|
||||
.catch(() => { if (!cancelled) setEvaluation(null); });
|
||||
return () => { cancelled = true; };
|
||||
}, [symbol, rackId]);
|
||||
|
||||
// Scorecard
|
||||
const [scorecard, setScorecard] = useState<{ slots: Array<Record<string, unknown>>; note: string } | null>(null);
|
||||
useEffect(() => {
|
||||
if (!symbol) return;
|
||||
let cancelled = false;
|
||||
api.confluence.scorecard(symbol)
|
||||
.then((r) => setScorecard(r as { slots: Array<Record<string, unknown>>; note: string }))
|
||||
.catch(() => setScorecard(null));
|
||||
.then((r) => { if (!cancelled) setScorecard(r as { slots: Array<Record<string, unknown>>; note: string }); })
|
||||
.catch(() => { if (!cancelled) setScorecard(null); });
|
||||
return () => { cancelled = true; };
|
||||
}, [symbol]);
|
||||
|
||||
// Slots
|
||||
@@ -194,7 +206,7 @@ export function ConfluencePanel() {
|
||||
{/* Signal Timeline chart */}
|
||||
{symbol && (
|
||||
<CollapsibleSection title="Signal Timeline" defaultOpen>
|
||||
<ConfluenceChart symbol={symbol} />
|
||||
<ConfluenceChart key={symbol} symbol={symbol} />
|
||||
</CollapsibleSection>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user