refactor(ui): normalize backtest replay controls

This commit is contained in:
Saravana Achu Mac 2026-05-09 01:46:14 -07:00
parent 3d97e9a0d8
commit e1d8ec8a7b
2 changed files with 31 additions and 23 deletions

View File

@ -558,13 +558,15 @@ export const BacktestComparePanel: React.FC<BacktestComparePanelProps> = ({ prof
<td className="px-3 py-2 text-zinc-300">{(row.durationMs / 1000).toFixed(1)}s</td> <td className="px-3 py-2 text-zinc-300">{(row.durationMs / 1000).toFixed(1)}s</td>
<td className="px-3 py-2"> <td className="px-3 py-2">
{row.status === 'success' && row.result ? ( {row.status === 'success' && row.result ? (
<button <Button
type="button" type="button"
className="rounded-md bg-white/10 px-2 py-1 text-[10px] font-bold uppercase tracking-wide text-zinc-200 hover:bg-white/20" variant="ghost"
size="sm"
className="min-h-7 px-2 text-[10px]"
onClick={() => setSelectedResultProfileId(row.profileId)} onClick={() => setSelectedResultProfileId(row.profileId)}
> >
Open Open
</button> </Button>
) : ( ) : (
<span className="text-[11px] text-rose-300">{row.error || 'Run failed'}</span> <span className="text-[11px] text-rose-300">{row.error || 'Run failed'}</span>
)} )}

View File

@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ReferenceLine } from 'recharts'; import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ReferenceLine } from 'recharts';
import type { BacktestResult } from '../types'; import type { BacktestResult } from '../types';
import { buildInsightCards, toEquitySeries } from '../utils'; import { buildInsightCards, toEquitySeries } from '../utils';
import { Button, Select } from '../../components/ui/Primitives';
interface BacktestResultsDashboardProps { interface BacktestResultsDashboardProps {
result: BacktestResult; result: BacktestResult;
@ -103,50 +104,55 @@ export const BacktestResultsDashboard: React.FC<BacktestResultsDashboardProps> =
</span> </span>
</div> </div>
<div className="flex flex-wrap items-center gap-2"> <div className="flex flex-wrap items-center gap-2">
<button <Button
type="button" type="button"
onClick={() => setIsPlaying(true)} onClick={() => setIsPlaying(true)}
disabled={isPlaying || !equitySeries.length || isAtEnd} disabled={isPlaying || !equitySeries.length || isAtEnd}
className={`rounded-lg px-3 py-1 text-[11px] font-bold uppercase tracking-wide ${isPlaying || isAtEnd ? 'bg-zinc-800 text-zinc-500' : 'bg-emerald-400 text-black hover:bg-emerald-300'}`} size="sm"
> >
Play Play
</button> </Button>
<button <Button
type="button" type="button"
onClick={() => setIsPlaying(false)} onClick={() => setIsPlaying(false)}
disabled={!isPlaying} disabled={!isPlaying}
className={`rounded-lg px-3 py-1 text-[11px] font-bold uppercase tracking-wide ${!isPlaying ? 'bg-zinc-800 text-zinc-500' : 'bg-zinc-200 text-black hover:bg-white'}`} variant="outline"
size="sm"
> >
Pause Pause
</button> </Button>
<button <Button
type="button" type="button"
onClick={() => setCursorIndex((prev) => Math.min(prev + 1, Math.max(0, equitySeries.length - 1)))} onClick={() => setCursorIndex((prev) => Math.min(prev + 1, Math.max(0, equitySeries.length - 1)))}
disabled={!equitySeries.length || isAtEnd} disabled={!equitySeries.length || isAtEnd}
className={`rounded-lg px-3 py-1 text-[11px] font-bold uppercase tracking-wide ${isAtEnd ? 'bg-zinc-800 text-zinc-500' : 'bg-indigo-400 text-black hover:bg-indigo-300'}`} variant="secondary"
size="sm"
> >
Step Step
</button> </Button>
<select <Select
value={speed} value={speed}
onChange={(event) => setSpeed(event.target.value as '1x' | '5x' | '20x' | 'instant')} onChange={(event) => setSpeed(event.target.value as '1x' | '5x' | '20x' | 'instant')}
className="rounded-lg border border-white/10 bg-zinc-900 px-2 py-1 text-[11px] text-white" controlSize="sm"
> className="w-28"
<option value="1x">1x</option> options={[
<option value="5x">5x</option> { value: '1x', label: '1x' },
<option value="20x">20x</option> { value: '5x', label: '5x' },
<option value="instant">Instant</option> { value: '20x', label: '20x' },
</select> { value: 'instant', label: 'Instant' },
<button ]}
/>
<Button
type="button" type="button"
onClick={() => { onClick={() => {
setIsPlaying(false); setIsPlaying(false);
setCursorIndex(0); setCursorIndex(0);
}} }}
className="rounded-lg px-3 py-1 text-[11px] font-bold uppercase tracking-wide bg-white/10 text-zinc-300 hover:bg-white/20" variant="ghost"
size="sm"
> >
Reset Reset
</button> </Button>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-xs text-cyan-100/90"> <div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-xs text-cyan-100/90">
<div data-testid="backtest-replay-cursor"> <div data-testid="backtest-replay-cursor">