전략평가 목록 정렬
This commit is contained in:
@@ -47,6 +47,15 @@ import {
|
||||
type BacktestRunTimeframeChoice,
|
||||
} from '../utils/backtestRunTimeframe';
|
||||
import { resolveBarSignalHighlight } from '../utils/strategyEvaluationBarSignals';
|
||||
import {
|
||||
loadStrategyListSort,
|
||||
saveStrategyListSort,
|
||||
sortStrategies,
|
||||
strategyListSortLabel,
|
||||
toggleStrategyListSort,
|
||||
type StrategyListSort,
|
||||
type StrategyListSortField,
|
||||
} from '../utils/strategyEvaluationListSort';
|
||||
import type { OHLCVBar } from '../types';
|
||||
import BacktestAnalysisReportModal from './backtest/BacktestAnalysisReportModal';
|
||||
import type { BacktestAnalysisReportModel } from './backtest/BacktestAnalysisReportModal';
|
||||
@@ -132,6 +141,7 @@ function StrategyEvaluationPageInner({ theme = 'dark' }: Props) {
|
||||
const [marketSearchOpen, setMarketSearchOpen] = useState(false);
|
||||
const [strategies, setStrategies] = useState<StrategyDto[]>([]);
|
||||
const [strategySearch, setStrategySearch] = useState('');
|
||||
const [strategyListSort, setStrategyListSort] = useState<StrategyListSort>(loadStrategyListSort);
|
||||
const [selectedStrategyId, setSelectedStrategyId] = useState<number | null>(null);
|
||||
const [selectedStrategy, setSelectedStrategy] = useState<StrategyDto | null>(null);
|
||||
|
||||
@@ -416,6 +426,19 @@ function StrategyEvaluationPageInner({ theme = 'dark' }: Props) {
|
||||
);
|
||||
}, [strategies, strategySearch]);
|
||||
|
||||
const sortedFilteredStrategies = useMemo(
|
||||
() => sortStrategies(filteredStrategies, strategyListSort),
|
||||
[filteredStrategies, strategyListSort],
|
||||
);
|
||||
|
||||
const handleStrategyListSort = useCallback((field: StrategyListSortField) => {
|
||||
setStrategyListSort(prev => {
|
||||
const next = toggleStrategyListSort(prev, field);
|
||||
saveStrategyListSort(next);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const selectedBarTimeSec = bars[selectedBarIndex]?.time ?? null;
|
||||
|
||||
useEffect(() => {
|
||||
@@ -953,11 +976,31 @@ function StrategyEvaluationPageInner({ theme = 'dark' }: Props) {
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="btd-exec-filters seval-strategy-list-sort" role="group" aria-label="전략 목록 정렬">
|
||||
<button
|
||||
type="button"
|
||||
className={`btd-exec-filter${strategyListSort.field === 'name' ? ' btd-exec-filter--on' : ''}`}
|
||||
title="이름순 — 클릭할 때마다 오름차순·내림차순 전환"
|
||||
aria-pressed={strategyListSort.field === 'name'}
|
||||
onClick={() => handleStrategyListSort('name')}
|
||||
>
|
||||
{strategyListSortLabel(strategyListSort, 'name')}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`btd-exec-filter${strategyListSort.field === 'createdAt' ? ' btd-exec-filter--on' : ''}`}
|
||||
title="추가 일시 기준 — 클릭할 때마다 최신순·오래된순 전환"
|
||||
aria-pressed={strategyListSort.field === 'createdAt'}
|
||||
onClick={() => handleStrategyListSort('createdAt')}
|
||||
>
|
||||
{strategyListSortLabel(strategyListSort, 'createdAt')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="btd-exec-scroll">
|
||||
{filteredStrategies.length === 0 ? (
|
||||
{sortedFilteredStrategies.length === 0 ? (
|
||||
<p className="btd-sidebar-empty">저장된 전략이 없습니다</p>
|
||||
) : (
|
||||
filteredStrategies.map(s => {
|
||||
sortedFilteredStrategies.map(s => {
|
||||
const name = repairUtf8Mojibake(s.name ?? `전략 #${s.id}`);
|
||||
const active = selectedStrategyId === s.id;
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user