전략편집기 템플릿 탭 추가,수정, 삭제 기능 적용

This commit is contained in:
Macbook
2026-06-12 13:30:40 +09:00
parent 52137cf1db
commit cb1bde2563
4 changed files with 278 additions and 81 deletions
@@ -0,0 +1,127 @@
import React from 'react';
import type { StrategyTemplateDef } from '../../utils/strategyPresets';
import type { UserStrategyTemplate } from '../../utils/strategyTemplateStorage';
export type TemplatePaletteRow = {
key: string;
source: 'user' | 'builtin';
label: string;
description?: string;
signal: 'buy' | 'sell';
user?: UserStrategyTemplate;
builtinId?: string;
builtin?: StrategyTemplateDef;
};
interface Props {
rows: TemplatePaletteRow[];
searchQuery: string;
onSearchChange: (query: string) => void;
selectedKey: string | null;
onSelectKey: (key: string | null) => void;
onApply: (row: TemplatePaletteRow) => void;
onAdd: () => void;
onEdit: () => void;
onDelete: () => void;
}
export default function TemplatePaletteTab({
rows,
searchQuery,
onSearchChange,
selectedKey,
onSelectKey,
onApply,
onAdd,
onEdit,
onDelete,
}: Props) {
return (
<div className="se-palette-section se-palette-section--templates se-palette-section--scroll">
<div className="se-palette-toolbar">
<span className="se-palette-toolbar-title">릿</span>
<div className="se-palette-toolbar-actions" role="toolbar" aria-label="템플릿 관리">
<button
type="button"
className="se-palette-tool-btn"
title="현재 조건을 템플릿으로 추가"
aria-label="템플릿 추가"
onClick={onAdd}
>
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden>
<path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
</svg>
</button>
<button
type="button"
className="se-palette-tool-btn"
title="선택 템플릿 수정"
aria-label="템플릿 수정"
disabled={!selectedKey}
onClick={onEdit}
>
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden>
<path d="M4 20h4l10-10-4-4L4 16v4z" stroke="currentColor" strokeWidth="1.75" fill="none" strokeLinejoin="round" />
<path d="M14 6l4 4" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" />
</svg>
</button>
<button
type="button"
className="se-palette-tool-btn se-palette-tool-btn--danger"
title="선택 템플릿 삭제"
aria-label="템플릿 삭제"
disabled={!selectedKey}
onClick={onDelete}
>
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden>
<path d="M6 7h12M9 7V5h6v2M10 11v6M14 11v6M8 7l1 12h6l1-12" stroke="currentColor" strokeWidth="1.75" fill="none" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</button>
</div>
</div>
<input
className="se-palette-search"
placeholder="템플릿 검색 (RSI, MA, 매수…)"
value={searchQuery}
onChange={e => onSearchChange(e.target.value)}
/>
<div className="se-template-list">
{rows.length === 0 ? (
<div className="se-template-empty"> </div>
) : (
rows.map(row => (
<div
key={row.key}
className={`se-template-row${selectedKey === row.key ? ' se-template-row--selected' : ''}`}
onClick={() => onSelectKey(row.key)}
onDoubleClick={() => onApply(row)}
role="button"
tabIndex={0}
onKeyDown={e => {
if (e.key === 'Enter') {
e.preventDefault();
onApply(row);
}
}}
>
<div className="se-template-item">
<span className="se-template-label">
{row.source === 'user' && <span className="se-template-user-badge"> 릿</span>}
{row.label}
</span>
{row.description && (
<span className="se-template-desc">{row.description}</span>
)}
<span className={`se-template-signal se-template-signal--${row.signal}`}>
{row.signal === 'buy' ? '매수' : '매도'}
</span>
</div>
</div>
))
)}
</div>
</div>
);
}