전략편집기 복합지표 기능 반영

This commit is contained in:
Macbook
2026-05-25 01:34:52 +09:00
parent ca249ad318
commit 20dd257c29
21 changed files with 1781 additions and 183 deletions
@@ -18,12 +18,13 @@ import {
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import type { Theme } from '../../types/index';
import type { LogicNode } from '../../utils/strategyTypes';
import type { LogicNode, ConditionDSL } from '../../utils/strategyTypes';
import {
addChild,
deleteNode,
mergeAtRoot,
makeNode,
updateNode,
type DefType,
} from '../../utils/strategyEditorShared';
import {
@@ -408,10 +409,10 @@ function StrategyEditorCanvasInner({
}, [setNodes]);
const addOrphanAt = useCallback((
data: { type: string; value: string; label: string },
data: { type: string; value: string; label: string; composite?: boolean },
flowPos: { x: number; y: number },
) => {
const newNode = makeNode(data.type, data.value, signalTab, def);
const newNode = makeNode(data.type, data.value, signalTab, def, data.composite ? { composite: true } : undefined);
positionsRef.current.set(newNode.id, {
x: flowPos.x - FLOW_NODE_W / 2,
y: flowPos.y - FLOW_NODE_H / 2,
@@ -422,10 +423,10 @@ function StrategyEditorCanvasInner({
const applyDropWithAttach = useCallback((
anchorId: string,
data: { type: string; value: string; label: string },
data: { type: string; value: string; label: string; composite?: boolean },
flowPos: { x: number; y: number },
) => {
const newNode = makeNode(data.type, data.value, signalTab, def);
const newNode = makeNode(data.type, data.value, signalTab, def, data.composite ? { composite: true } : undefined);
const anchor = nodesRef.current.find(n => n.id === anchorId);
if (!anchor) return;
@@ -488,12 +489,24 @@ function StrategyEditorCanvasInner({
}
}, [clearDropPreview, applyDropWithAttach, addOrphanAt, root, orphans]);
const handleUpdateCondition = useCallback((id: string, condition: ConditionDSL) => {
if (isOrphanNode(orphans, id)) {
onOrphansChange(orphans.map(o => (
o.id === id ? { ...o, condition } : o
)));
return;
}
if (!root) return;
onChange(updateNode(root, id, n => ({ ...n, condition })));
}, [root, orphans, onChange, onOrphansChange]);
const flowCallbacks = useMemo(() => ({
onDelete: handleDelete,
onUpdateCondition: handleUpdateCondition,
onDropTarget: handleDropTarget,
onDragOverTarget: handleDragOverTarget,
onDragLeaveTarget: handleDragLeaveTarget,
}), [handleDelete, handleDropTarget, handleDragOverTarget, handleDragLeaveTarget]);
}), [handleDelete, handleUpdateCondition, handleDropTarget, handleDragOverTarget, handleDragLeaveTarget]);
const rebuildFlow = useCallback(() => logicNodeToFlow(
root,