| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 | 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?._runned) ? '#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)
 |