balibabu
Feat: The Begin and IterationStart operators cannot be deleted using shortcut keys #4287 (#4288)
b1ea792
| import { | |
| BaseEdge, | |
| EdgeLabelRenderer, | |
| EdgeProps, | |
| getBezierPath, | |
| } from '@xyflow/react'; | |
| import useGraphStore from '../../store'; | |
| import { useTheme } from '@/components/theme-provider'; | |
| import { useFetchFlow } from '@/hooks/flow-hooks'; | |
| import { useMemo } from 'react'; | |
| import styles from './index.less'; | |
| export function ButtonEdge({ | |
| id, | |
| sourceX, | |
| sourceY, | |
| targetX, | |
| targetY, | |
| sourcePosition, | |
| targetPosition, | |
| source, | |
| target, | |
| style = {}, | |
| markerEnd, | |
| selected, | |
| }: EdgeProps) { | |
| const deleteEdgeById = useGraphStore((state) => state.deleteEdgeById); | |
| const [edgePath, labelX, labelY] = getBezierPath({ | |
| sourceX, | |
| sourceY, | |
| sourcePosition, | |
| targetX, | |
| targetY, | |
| targetPosition, | |
| }); | |
| const { theme } = useTheme(); | |
| const selectedStyle = useMemo(() => { | |
| return selected ? { strokeWidth: 2, stroke: '#1677ff' } : {}; | |
| }, [selected]); | |
| const onEdgeClick = () => { | |
| deleteEdgeById(id); | |
| }; | |
| // highlight the nodes that the workflow passes through | |
| const { data: flowDetail } = useFetchFlow(); | |
| const graphPath = useMemo(() => { | |
| // TODO: this will be called multiple times | |
| const path = flowDetail?.dsl?.path ?? []; | |
| // The second to last | |
| const previousGraphPath: string[] = path.at(-2) ?? []; | |
| let graphPath: string[] = path.at(-1) ?? []; | |
| // The last of the second to last article | |
| const previousLatestElement = previousGraphPath.at(-1); | |
| if (previousGraphPath.length > 0 && previousLatestElement) { | |
| graphPath = [previousLatestElement, ...graphPath]; | |
| } | |
| return graphPath; | |
| }, [flowDetail.dsl?.path]); | |
| const highlightStyle = useMemo(() => { | |
| const idx = graphPath.findIndex((x) => x === source); | |
| if (idx !== -1) { | |
| // The set of elements following source | |
| const slicedGraphPath = graphPath.slice(idx + 1); | |
| if (slicedGraphPath.some((x) => x === target)) { | |
| return { strokeWidth: 2, stroke: 'red' }; | |
| } | |
| } | |
| return {}; | |
| }, [source, target, graphPath]); | |
| return ( | |
| <> | |
| <BaseEdge | |
| path={edgePath} | |
| markerEnd={markerEnd} | |
| style={{ ...style, ...selectedStyle, ...highlightStyle }} | |
| /> | |
| <EdgeLabelRenderer> | |
| <div | |
| style={{ | |
| position: 'absolute', | |
| transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`, | |
| fontSize: 12, | |
| // everything inside EdgeLabelRenderer has no pointer events by default | |
| // if you have an interactive element, set pointer-events: all | |
| pointerEvents: 'all', | |
| zIndex: 1001, // https://github.com/xyflow/xyflow/discussions/3498 | |
| }} | |
| className="nodrag nopan" | |
| > | |
| <button | |
| className={ | |
| theme === 'dark' ? styles.edgeButtonDark : styles.edgeButton | |
| } | |
| type="button" | |
| onClick={onEdgeClick} | |
| > | |
| × | |
| </button> | |
| </div> | |
| </EdgeLabelRenderer> | |
| </> | |
| ); | |
| } | |