전략평가 목록 정렬
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import type { StrategyDto } from './backendApi';
|
||||
import { repairUtf8Mojibake } from './textEncoding';
|
||||
|
||||
export type StrategyListSortField = 'name' | 'createdAt';
|
||||
export type StrategyListSortDir = 'asc' | 'desc';
|
||||
|
||||
export interface StrategyListSort {
|
||||
field: StrategyListSortField;
|
||||
dir: StrategyListSortDir;
|
||||
}
|
||||
|
||||
const STORAGE_KEY = 'seval-strategy-list-sort';
|
||||
|
||||
const DEFAULT_SORT: StrategyListSort = { field: 'createdAt', dir: 'desc' };
|
||||
|
||||
export function loadStrategyListSort(): StrategyListSort {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) return DEFAULT_SORT;
|
||||
const parsed = JSON.parse(raw) as Partial<StrategyListSort>;
|
||||
const field = parsed.field === 'name' || parsed.field === 'createdAt' ? parsed.field : DEFAULT_SORT.field;
|
||||
const dir = parsed.dir === 'asc' || parsed.dir === 'desc' ? parsed.dir : DEFAULT_SORT.dir;
|
||||
return { field, dir };
|
||||
} catch {
|
||||
return DEFAULT_SORT;
|
||||
}
|
||||
}
|
||||
|
||||
export function saveStrategyListSort(sort: StrategyListSort): void {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(sort));
|
||||
} catch {
|
||||
/* ignore quota */
|
||||
}
|
||||
}
|
||||
|
||||
/** 같은 필드 재클릭 시 방향 토글, 다른 필드는 해당 필드 기본 방향 */
|
||||
export function toggleStrategyListSort(
|
||||
prev: StrategyListSort,
|
||||
field: StrategyListSortField,
|
||||
): StrategyListSort {
|
||||
if (prev.field !== field) {
|
||||
return field === 'name'
|
||||
? { field: 'name', dir: 'asc' }
|
||||
: { field: 'createdAt', dir: 'desc' };
|
||||
}
|
||||
return { field, dir: prev.dir === 'asc' ? 'desc' : 'asc' };
|
||||
}
|
||||
|
||||
function strategyCreatedTimeMs(s: StrategyDto): number {
|
||||
if (s.createdAt) {
|
||||
const t = Date.parse(s.createdAt);
|
||||
if (Number.isFinite(t)) return t;
|
||||
}
|
||||
return s.id ?? 0;
|
||||
}
|
||||
|
||||
export function sortStrategies(
|
||||
list: StrategyDto[],
|
||||
sort: StrategyListSort,
|
||||
): StrategyDto[] {
|
||||
const mul = sort.dir === 'asc' ? 1 : -1;
|
||||
return [...list].sort((a, b) => {
|
||||
if (sort.field === 'name') {
|
||||
const na = repairUtf8Mojibake(a.name ?? '');
|
||||
const nb = repairUtf8Mojibake(b.name ?? '');
|
||||
return mul * na.localeCompare(nb, 'ko');
|
||||
}
|
||||
return mul * (strategyCreatedTimeMs(a) - strategyCreatedTimeMs(b));
|
||||
});
|
||||
}
|
||||
|
||||
export function strategyListSortLabel(sort: StrategyListSort, field: StrategyListSortField): string {
|
||||
if (sort.field !== field) {
|
||||
return field === 'name' ? '이름순' : '최신순';
|
||||
}
|
||||
if (field === 'name') {
|
||||
return sort.dir === 'asc' ? '이름순 ↑' : '이름순 ↓';
|
||||
}
|
||||
return sort.dir === 'desc' ? '최신순 ↓' : '최신순 ↑';
|
||||
}
|
||||
Reference in New Issue
Block a user