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">
{row.status === 'success' && row.result ? (
<button
<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)}
>
Open
</button>
</Button>
) : (
<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 type { BacktestResult } from '../types';
import { buildInsightCards, toEquitySeries } from '../utils';
import { Button, Select } from '../../components/ui/Primitives';
interface BacktestResultsDashboardProps {
result: BacktestResult;
@ -103,50 +104,55 @@ export const BacktestResultsDashboard: React.FC<BacktestResultsDashboardProps> =
</span>
</div>
<div className="flex flex-wrap items-center gap-2">
<button
<Button
type="button"
onClick={() => setIsPlaying(true)}
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
</button>
<button
</Button>
<Button
type="button"
onClick={() => setIsPlaying(false)}
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
</button>
<button
</Button>
<Button
type="button"
onClick={() => setCursorIndex((prev) => Math.min(prev + 1, Math.max(0, equitySeries.length - 1)))}
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
</button>
<select
</Button>
<Select
value={speed}
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"
>
<option value="1x">1x</option>
<option value="5x">5x</option>
<option value="20x">20x</option>
<option value="instant">Instant</option>
</select>
<button
controlSize="sm"
className="w-28"
options={[
{ value: '1x', label: '1x' },
{ value: '5x', label: '5x' },
{ value: '20x', label: '20x' },
{ value: 'instant', label: 'Instant' },
]}
/>
<Button
type="button"
onClick={() => {
setIsPlaying(false);
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
</button>
</Button>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-xs text-cyan-100/90">
<div data-testid="backtest-replay-cursor">