71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
BaseEdge,
|
|
EdgeLabelRenderer,
|
|
getSmoothStepPath,
|
|
type EdgeProps,
|
|
} from '@xyflow/react';
|
|
import type { StartCombineOp } from '../../utils/strategyStartNodes';
|
|
|
|
export type StartCombineEdgeData = {
|
|
op?: StartCombineOp;
|
|
onToggle?: (op: StartCombineOp) => void;
|
|
};
|
|
|
|
/**
|
|
* START 노드끼리 잇는 결합 엣지 — 가운데 AND/OR 토글 배지.
|
|
* 클릭하면 startCombineOp 를 전환한다. (연결 자체는 START 2개 이상이면 자동 생성)
|
|
*/
|
|
export function StartCombineEdge({
|
|
id,
|
|
sourceX,
|
|
sourceY,
|
|
targetX,
|
|
targetY,
|
|
sourcePosition,
|
|
targetPosition,
|
|
data,
|
|
}: EdgeProps) {
|
|
const op: StartCombineOp = (data as StartCombineEdgeData | undefined)?.op === 'OR' ? 'OR' : 'AND';
|
|
const onToggle = (data as StartCombineEdgeData | undefined)?.onToggle;
|
|
|
|
const [edgePath, labelX, labelY] = getSmoothStepPath({
|
|
sourceX,
|
|
sourceY,
|
|
targetX,
|
|
targetY,
|
|
sourcePosition,
|
|
targetPosition,
|
|
borderRadius: 10,
|
|
});
|
|
|
|
return (
|
|
<>
|
|
<BaseEdge
|
|
id={id}
|
|
path={edgePath}
|
|
className={`se-flow-start-combine-edge se-flow-start-combine-edge--${op.toLowerCase()}`}
|
|
style={{ strokeWidth: 2, strokeDasharray: '6 4', pointerEvents: 'none' }}
|
|
/>
|
|
<EdgeLabelRenderer>
|
|
<button
|
|
type="button"
|
|
className={`se-start-combine-edge-badge se-start-combine-edge-badge--${op.toLowerCase()}`}
|
|
title={op === 'AND' ? 'START 간 AND (모두 충족) — 클릭하면 OR' : 'START 간 OR (하나만 충족) — 클릭하면 AND'}
|
|
style={{
|
|
position: 'absolute',
|
|
transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,
|
|
pointerEvents: 'all',
|
|
}}
|
|
onClick={(ev) => {
|
|
ev.stopPropagation();
|
|
onToggle?.(op === 'AND' ? 'OR' : 'AND');
|
|
}}
|
|
>
|
|
{op}
|
|
</button>
|
|
</EdgeLabelRenderer>
|
|
</>
|
|
);
|
|
}
|