Files
ragflow/web/src/pages/agent/canvas/edge/index.tsx
balibabu 390b2b8f26 Feat: Adjust the style of the delete button on the agent side #9869 (#10473)
### What problem does this PR solve?

Feat: Adjust the style of the delete button on the agent side #9869

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
2025-10-10 19:52:08 +08:00

135 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
BaseEdge,
Edge,
EdgeLabelRenderer,
EdgeProps,
getBezierPath,
} from '@xyflow/react';
import { memo } from 'react';
import useGraphStore from '../../store';
import { useFetchAgent } from '@/hooks/use-agent-request';
import { cn } from '@/lib/utils';
import { useMemo } from 'react';
import { NodeHandleId, Operator } from '../../constant';
function InnerButtonEdge({
id,
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
source,
target,
style = {},
markerEnd,
selected,
data,
sourceHandleId,
}: EdgeProps<Edge<{ isHovered: boolean }>>) {
const deleteEdgeById = useGraphStore((state) => state.deleteEdgeById);
const highlightedPlaceholderEdgeId = useGraphStore(
(state) => state.highlightedPlaceholderEdgeId,
);
const [edgePath, labelX, labelY] = getBezierPath({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
});
const selectedStyle = useMemo(() => {
return selected
? { strokeWidth: 1, stroke: 'rgb(var(--accent-primary))' }
: {};
}, [selected]);
const placeholderHighlightStyle = useMemo(() => {
const isHighlighted = highlightedPlaceholderEdgeId === id;
return isHighlighted
? { strokeWidth: 2, stroke: 'var(--accent-primary)' }
: {};
}, [highlightedPlaceholderEdgeId, id]);
const onEdgeClick = () => {
deleteEdgeById(id);
};
// highlight the nodes that the workflow passes through
const { data: flowDetail } = useFetchAgent();
const showHighlight = useMemo(() => {
const path = flowDetail?.dsl?.path ?? [];
const idx = path.findIndex((x) => x === target);
if (idx !== -1) {
let index = idx - 1;
while (index >= 0) {
if (path[index] === source) {
return { strokeWidth: 1, stroke: 'rgb(var(--accent-primary))' };
}
index--;
}
return {};
}
return {};
}, [flowDetail?.dsl?.path, source, target]);
const visible = useMemo(() => {
return (
data?.isHovered &&
sourceHandleId !== NodeHandleId.Tool &&
sourceHandleId !== NodeHandleId.AgentBottom && // The connection between the agent node and the tool node does not need to display the delete button
!target.startsWith(Operator.Tool)
);
}, [data?.isHovered, sourceHandleId, target]);
return (
<>
<BaseEdge
path={edgePath}
markerEnd={markerEnd}
style={{
...style,
...selectedStyle,
...showHighlight,
...placeholderHighlightStyle,
}}
className={cn('text-text-secondary')}
/>
<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={cn(
'size-3.5 border border-state-error text-state-error rounded-full leading-none bg-bg-canvas outline outline-bg-canvas',
'invisible',
{ visible },
)}
type="button"
onClick={onEdgeClick}
>
×
</button>
</div>
</EdgeLabelRenderer>
</>
);
}
export const ButtonEdge = memo(InnerButtonEdge);