전략지표 설정 삭제버튼

This commit is contained in:
Macbook
2026-06-24 01:06:36 +09:00
parent e46ffe838f
commit e5086b2c92
3 changed files with 119 additions and 16 deletions
+73 -10
View File
@@ -42,6 +42,7 @@ import { persistStrategyEditorState } from '../utils/strategyTimeframeSync';
import {
START_NODE_ID,
defaultStartMeta,
isStartNodeId,
type StartCombineOp,
} from '../utils/strategyStartNodes';
import IndicatorPaletteTab from './strategyEditor/IndicatorPaletteTab';
@@ -114,7 +115,7 @@ import {
} from '../utils/strategyEditorLayoutStorage';
import LogicExpressionPreview from './strategyEditor/LogicExpressionPreview';
import LogicExpressionNarrative from './strategyEditor/LogicExpressionNarrative';
import StrategyEditorCanvas, { type FlowLayoutSeed } from './strategyEditor/StrategyEditorCanvas';
import StrategyEditorCanvas, { type FlowLayoutSeed, type StrategyEditorCanvasHandle } from './strategyEditor/StrategyEditorCanvas';
import StrategyListEditor from './strategyEditor/StrategyListEditor';
import StartCombineOpControl from './strategyEditor/StartCombineOpControl';
import { layoutFlushRef } from './strategyEditor/strategyEditorCallbacks';
@@ -333,6 +334,7 @@ export default function StrategyEditorPage({
const [descOpen, setDescOpen] = useState(false);
const [deleteId, setDeleteId] = useState<number | null>(null);
const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null);
const canvasRef = useRef<StrategyEditorCanvasHandle>(null);
const [buyOrphans, setBuyOrphans] = useState<LogicNode[]>([]);
const [sellOrphans, setSellOrphans] = useState<LogicNode[]>([]);
const [snack, setSnack] = useState<{ msg: string; ok: boolean } | null>(null);
@@ -460,6 +462,11 @@ export default function StrategyEditorPage({
);
}, [selectedNodeId, currentRoot, currentOrphans, currentLayout.extraRoots]);
const handleDeleteSelectedNode = useCallback(() => {
if (!selectedNodeId || isStartNodeId(selectedNodeId)) return;
canvasRef.current?.deleteNode(selectedNodeId);
}, [selectedNodeId]);
const stochPairForest = useMemo(
() => [
currentRoot,
@@ -2041,6 +2048,7 @@ export default function StrategyEditorPage({
<>
<ReactFlowProvider>
<StrategyEditorCanvas
ref={canvasRef}
theme={theme}
root={currentRoot}
orphans={currentOrphans}
@@ -2064,11 +2072,22 @@ export default function StrategyEditorPage({
{selectedLogicNode?.type === 'CONDITION' && selectedLogicNode.condition && (
<div className="se-node-config-bar">
<span className="se-node-config-label">
{stochPairEditForSelected && !stochPairEditForSelected.stochLocked
? 'Stoch 과열×보조'
: selectedLogicNode.condition.indicatorType}
</span>
<div className="se-node-config-head">
<span className="se-node-config-label">
{stochPairEditForSelected && !stochPairEditForSelected.stochLocked
? 'Stoch 과열×보조'
: selectedLogicNode.condition.indicatorType}
</span>
<button
type="button"
className="se-node-config-del"
title="삭제"
aria-label="지표 삭제"
onClick={handleDeleteSelectedNode}
>
×
</button>
</div>
<CondEditor
cond={selectedLogicNode.condition}
signalType={signalTab}
@@ -2106,7 +2125,18 @@ export default function StrategyEditorPage({
{selectedLogicNode && isStochOverboughtPairRoot(selectedLogicNode) && selectedLogicNode.stochPair && (
<div className="se-node-config-bar se-node-config-bar--stoch-pair">
<span className="se-node-config-label">Stoch ×</span>
<div className="se-node-config-head">
<span className="se-node-config-label">Stoch ×</span>
<button
type="button"
className="se-node-config-del"
title="삭제"
aria-label="지표 삭제"
onClick={handleDeleteSelectedNode}
>
×
</button>
</div>
<StochPairNodeSettings
variant="inline"
secondaryIndicator={selectedLogicNode.stochPair.secondaryIndicatorType}
@@ -2118,7 +2148,18 @@ export default function StrategyEditorPage({
{selectedLogicNode && isPriceExtremeBreakoutPairRoot(selectedLogicNode) && selectedLogicNode.priceExtremePair && (
<div className="se-node-config-bar se-node-config-bar--price-extreme">
<span className="se-node-config-label">9·20 / </span>
<div className="se-node-config-head">
<span className="se-node-config-label">9·20 / </span>
<button
type="button"
className="se-node-config-del"
title="삭제"
aria-label="지표 삭제"
onClick={handleDeleteSelectedNode}
>
×
</button>
</div>
<PriceExtremePairNodeSettings
variant="inline"
mode={selectedLogicNode.priceExtremePair.mode}
@@ -2132,7 +2173,18 @@ export default function StrategyEditorPage({
)}
{selectedLogicNode && isInflection33PairRoot(selectedLogicNode) && selectedLogicNode.inflection33Pair && (
<div className="se-node-config-bar se-node-config-bar--inflection33">
<span className="se-node-config-label">33 </span>
<div className="se-node-config-head">
<span className="se-node-config-label">33 </span>
<button
type="button"
className="se-node-config-del"
title="삭제"
aria-label="지표 삭제"
onClick={handleDeleteSelectedNode}
>
×
</button>
</div>
<Inflection33PairNodeSettings
variant="inline"
mode={selectedLogicNode.inflection33Pair.mode}
@@ -2145,7 +2197,18 @@ export default function StrategyEditorPage({
)}
{selectedLogicNode && isStableStrategyPairRoot(selectedLogicNode) && selectedLogicNode.stableStrategyPair && (
<div className="se-node-config-bar se-node-config-bar--stable-strategy">
<span className="se-node-config-label"> </span>
<div className="se-node-config-head">
<span className="se-node-config-label"> </span>
<button
type="button"
className="se-node-config-del"
title="삭제"
aria-label="지표 삭제"
onClick={handleDeleteSelectedNode}
>
×
</button>
</div>
<StableStrategyPairNodeSettings
variant="inline"
strategyId={selectedLogicNode.stableStrategyPair.strategyId as StableStrategyId}