File size: 2,984 Bytes
be99f83 b1ea792 8207a08 be99f83 53f091c 09aa395 be99f83 38d5a53 be99f83 8207a08 be99f83 53f091c be99f83 38d5a53 be99f83 38d5a53 09aa395 970e973 38d5a53 09aa395 38d5a53 09aa395 38d5a53 09aa395 38d5a53 be99f83 38d5a53 be99f83 2bdad3e be99f83 53f091c be99f83 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
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>
</>
);
}
|