feat: instrument analysis

This commit is contained in:
OpenSquared
2026-06-30 16:32:08 +02:00
parent 9904c066b2
commit 9ffcfeeb71
3 changed files with 17 additions and 7 deletions

View File

@@ -100,7 +100,7 @@ function KeepAlivePage({ path, component: Component }: { path: string; component
// Registers the instrument tab on navigation (renders nothing itself)
function InstrumentRoute() {
const { id = 'EURUSD' } = useParams<{ id: string }>()
const { id = localStorage.getItem('last_instrument') || 'EURUSD' } = useParams<{ id: string }>()
const { openInstrument } = useTabs()
useEffect(() => { openInstrument(id.toUpperCase()) }, [id, openInstrument])
return null
@@ -112,7 +112,7 @@ function InstrumentKeepAlive({ id }: { id: string }) {
const isActive = location.pathname.toLowerCase() === `/instruments/${id.toLowerCase()}`
return (
<div className={isActive ? 'flex-1 min-h-0 overflow-y-auto' : 'hidden'}>
<InstrumentDashboard instrumentIdProp={id} />
<InstrumentDashboard instrumentIdProp={id} isVisible={isActive} />
</div>
)
}
@@ -129,7 +129,7 @@ function NormalRoutes() {
return (
<div className={isInstrument ? 'hidden' : 'flex-1 overflow-auto'}>
<Routes>
<Route path="/instruments" element={<Navigate to="/instruments/EURUSD" replace />} />
<Route path="/instruments" element={<Navigate to={`/instruments/${localStorage.getItem('last_instrument') || 'EURUSD'}`} replace />} />
<Route path="/instruments/:id" element={<InstrumentRoute />} />
{/* Legacy redirects */}
<Route path="/impact" element={<Navigate to="/market-events" replace />} />

View File

@@ -28,8 +28,10 @@ export function TabsProvider({ children }: { children: ReactNode }) {
const forgetRoute = useCallback((r: string) =>
setKept(p => { const n = new Set(p); n.delete(r); return n }), [])
const openInstrument = useCallback((id: string) =>
setInstrumentIds(p => p.includes(id) ? p : [...p, id]), [])
const openInstrument = useCallback((id: string) => {
localStorage.setItem('last_instrument', id)
setInstrumentIds(p => p.includes(id) ? p : [...p, id])
}, [])
const closeInstrument = useCallback((id: string) =>
setInstrumentIds(p => p.filter(x => x !== id)), [])

View File

@@ -1205,8 +1205,8 @@ const PERIODS = [
{ key: '5y', label: '5Y' },
]
export default function InstrumentDashboard({ instrumentIdProp }: { instrumentIdProp?: string } = {}) {
const { id: paramId = 'EURUSD' } = useParams<{ id: string }>()
export default function InstrumentDashboard({ instrumentIdProp, isVisible }: { instrumentIdProp?: string; isVisible?: boolean } = {}) {
const { id: paramId = localStorage.getItem('last_instrument') || 'EURUSD' } = useParams<{ id: string }>()
const navigate = useNavigate()
const [period, setPeriod] = useState('1y')
const [chartStyle, setChartStyle] = useState<'candles' | 'line'>('candles')
@@ -1237,6 +1237,14 @@ export default function InstrumentDashboard({ instrumentIdProp }: { instrumentId
api.get('/causal-lab/templates').then(r => setTemplates(r.data)).catch(() => {})
}, [])
// Silent refresh when the tab becomes visible again (e.g. after analysis updated from MarketEvents)
const mountedRef = useRef(false)
useEffect(() => {
if (!mountedRef.current) { mountedRef.current = true; return }
if (isVisible) fetchSnapshotSilent()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isVisible])
const fetchSnapshot = useCallback(() => {
setLoading(true)
api.get(`/instruments/${instrumentId}/snapshot?period=${period}`)