refactor(ui): normalize backtest replay controls
This commit is contained in:
parent
3d97e9a0d8
commit
e1d8ec8a7b
@ -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>
|
||||
)}
|
||||
|
||||
@ -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">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user