Spaces:
Build error
Build error
import { | |
memo, | |
useCallback, | |
useState, | |
} from 'react' | |
import { intersection } from 'lodash-es' | |
import type { EdgeProps } from 'reactflow' | |
import { | |
BaseEdge, | |
EdgeLabelRenderer, | |
Position, | |
getBezierPath, | |
} from 'reactflow' | |
import { | |
useAvailableBlocks, | |
useNodesInteractions, | |
} from './hooks' | |
import BlockSelector from './block-selector' | |
import type { | |
Edge, | |
OnSelectBlock, | |
} from './types' | |
import { ITERATION_CHILDREN_Z_INDEX } from './constants' | |
import cn from '@/utils/classnames' | |
const CustomEdge = ({ | |
id, | |
data, | |
source, | |
sourceHandleId, | |
target, | |
targetHandleId, | |
sourceX, | |
sourceY, | |
targetX, | |
targetY, | |
selected, | |
}: EdgeProps) => { | |
const [ | |
edgePath, | |
labelX, | |
labelY, | |
] = getBezierPath({ | |
sourceX: sourceX - 8, | |
sourceY, | |
sourcePosition: Position.Right, | |
targetX: targetX + 8, | |
targetY, | |
targetPosition: Position.Left, | |
curvature: 0.16, | |
}) | |
const [open, setOpen] = useState(false) | |
const { handleNodeAdd } = useNodesInteractions() | |
const { availablePrevBlocks } = useAvailableBlocks((data as Edge['data'])!.targetType, (data as Edge['data'])?.isInIteration) | |
const { availableNextBlocks } = useAvailableBlocks((data as Edge['data'])!.sourceType, (data as Edge['data'])?.isInIteration) | |
const handleOpenChange = useCallback((v: boolean) => { | |
setOpen(v) | |
}, []) | |
const handleInsert = useCallback<OnSelectBlock>((nodeType, toolDefaultValue) => { | |
handleNodeAdd( | |
{ | |
nodeType, | |
toolDefaultValue, | |
}, | |
{ | |
prevNodeId: source, | |
prevNodeSourceHandle: sourceHandleId || 'source', | |
nextNodeId: target, | |
nextNodeTargetHandle: targetHandleId || 'target', | |
}, | |
) | |
}, [handleNodeAdd, source, sourceHandleId, target, targetHandleId]) | |
return ( | |
<> | |
<BaseEdge | |
id={id} | |
path={edgePath} | |
style={{ | |
stroke: (selected || data?._connectedNodeIsHovering || data?._run) ? '#2970FF' : '#D0D5DD', | |
strokeWidth: 2, | |
}} | |
/> | |
<EdgeLabelRenderer> | |
<div | |
className={cn( | |
'nopan nodrag hover:scale-125', | |
data?._hovering ? 'block' : 'hidden', | |
open && '!block', | |
data.isInIteration && `z-[${ITERATION_CHILDREN_Z_INDEX}]`, | |
)} | |
style={{ | |
position: 'absolute', | |
transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`, | |
pointerEvents: 'all', | |
}} | |
> | |
<BlockSelector | |
open={open} | |
onOpenChange={handleOpenChange} | |
asChild | |
onSelect={handleInsert} | |
availableBlocksTypes={intersection(availablePrevBlocks, availableNextBlocks)} | |
triggerClassName={() => 'hover:scale-150 transition-all'} | |
/> | |
</div> | |
</EdgeLabelRenderer> | |
</> | |
) | |
} | |
export default memo(CustomEdge) | |