mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
Fix: Fixed the issue where the connection lines of placeholder nodes in the agent canvas could not be displayed #9869 (#10485)
### What problem does this PR solve? Fix: Fixed the issue where the connection lines of placeholder nodes in the agent canvas could not be displayed #9869 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -1619,12 +1619,12 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
tokenizerRequired: '请先添加Tokenizer节点',
|
tokenizerRequired: '请先添加Tokenizer节点',
|
||||||
tokenizerDescription:
|
tokenizerDescription:
|
||||||
'根据所选的搜索方法,将文本转换为所需的数据结构(例如,用于嵌入搜索的向量嵌入)。',
|
'根据所选的搜索方法,将文本转换为所需的数据结构(例如,用于嵌入搜索的向量嵌入)。',
|
||||||
splitter: '分词器拆分器',
|
splitter: '按字符分割',
|
||||||
splitterDescription:
|
splitterDescription:
|
||||||
'根据分词器长度将文本拆分成块,并带有可选的分隔符和重叠。',
|
'根据分词器长度将文本拆分成块,并带有可选的分隔符和重叠。',
|
||||||
hierarchicalMergerDescription:
|
hierarchicalMergerDescription:
|
||||||
'使用正则表达式规则按标题层次结构将文档拆分成多个部分,以实现更精细的控制。',
|
'使用正则表达式规则按标题层次结构将文档拆分成多个部分,以实现更精细的控制。',
|
||||||
hierarchicalMerger: '标题拆分器',
|
hierarchicalMerger: '按标题分割',
|
||||||
extractor: '提取器',
|
extractor: '提取器',
|
||||||
extractorDescription:
|
extractorDescription:
|
||||||
'使用 LLM 从文档块(例如摘要、分类等)中提取结构化见解。',
|
'使用 LLM 从文档块(例如摘要、分类等)中提取结构化见解。',
|
||||||
|
|||||||
@ -29,9 +29,8 @@ function InnerButtonEdge({
|
|||||||
data,
|
data,
|
||||||
sourceHandleId,
|
sourceHandleId,
|
||||||
}: EdgeProps<Edge<{ isHovered: boolean }>>) {
|
}: EdgeProps<Edge<{ isHovered: boolean }>>) {
|
||||||
const deleteEdgeById = useGraphStore((state) => state.deleteEdgeById);
|
const { deleteEdgeById, getOperatorTypeFromId } = useGraphStore(
|
||||||
const highlightedPlaceholderEdgeId = useGraphStore(
|
(state) => state,
|
||||||
(state) => state.highlightedPlaceholderEdgeId,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const [edgePath, labelX, labelY] = getBezierPath({
|
const [edgePath, labelX, labelY] = getBezierPath({
|
||||||
@ -48,12 +47,16 @@ function InnerButtonEdge({
|
|||||||
: {};
|
: {};
|
||||||
}, [selected]);
|
}, [selected]);
|
||||||
|
|
||||||
|
const isTargetPlaceholder = useMemo(() => {
|
||||||
|
return getOperatorTypeFromId(target) === Operator.Placeholder;
|
||||||
|
}, [getOperatorTypeFromId, target]);
|
||||||
|
|
||||||
const placeholderHighlightStyle = useMemo(() => {
|
const placeholderHighlightStyle = useMemo(() => {
|
||||||
const isHighlighted = highlightedPlaceholderEdgeId === id;
|
const isHighlighted = isTargetPlaceholder;
|
||||||
return isHighlighted
|
return isHighlighted
|
||||||
? { strokeWidth: 2, stroke: 'var(--accent-primary)' }
|
? { strokeWidth: 2, stroke: 'rgb(var(--accent-primary))' }
|
||||||
: {};
|
: {};
|
||||||
}, [highlightedPlaceholderEdgeId, id]);
|
}, [isTargetPlaceholder]);
|
||||||
|
|
||||||
const onEdgeClick = () => {
|
const onEdgeClick = () => {
|
||||||
deleteEdgeById(id);
|
deleteEdgeById(id);
|
||||||
@ -83,9 +86,10 @@ function InnerButtonEdge({
|
|||||||
data?.isHovered &&
|
data?.isHovered &&
|
||||||
sourceHandleId !== NodeHandleId.Tool &&
|
sourceHandleId !== NodeHandleId.Tool &&
|
||||||
sourceHandleId !== NodeHandleId.AgentBottom && // The connection between the agent node and the tool node does not need to display the delete button
|
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)
|
!target.startsWith(Operator.Tool) &&
|
||||||
|
!isTargetPlaceholder
|
||||||
);
|
);
|
||||||
}, [data?.isHovered, sourceHandleId, target]);
|
}, [data?.isHovered, isTargetPlaceholder, sourceHandleId, target]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { Connection, Position } from '@xyflow/react';
|
import { Connection, OnConnectEnd, Position } from '@xyflow/react';
|
||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import { useDropdownManager } from '../canvas/context';
|
import { useDropdownManager } from '../canvas/context';
|
||||||
import { Operator, PREVENT_CLOSE_DELAY } from '../constant';
|
import { Operator, PREVENT_CLOSE_DELAY } from '../constant';
|
||||||
import useGraphStore from '../store';
|
|
||||||
import { useAddNode } from './use-add-node';
|
import { useAddNode } from './use-add-node';
|
||||||
|
|
||||||
interface ConnectionStartParams {
|
interface ConnectionStartParams {
|
||||||
@ -40,7 +39,6 @@ export const useConnectionDrag = (
|
|||||||
|
|
||||||
const { addCanvasNode } = useAddNode(reactFlowInstance);
|
const { addCanvasNode } = useAddNode(reactFlowInstance);
|
||||||
const { setActiveDropdown } = useDropdownManager();
|
const { setActiveDropdown } = useDropdownManager();
|
||||||
const { setHighlightedPlaceholderEdgeId } = useGraphStore();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection start handler function
|
* Connection start handler function
|
||||||
@ -66,8 +64,8 @@ export const useConnectionDrag = (
|
|||||||
/**
|
/**
|
||||||
* Connection end handler function
|
* Connection end handler function
|
||||||
*/
|
*/
|
||||||
const onConnectEnd = useCallback(
|
const onConnectEnd: OnConnectEnd = useCallback(
|
||||||
(event: MouseEvent | TouchEvent) => {
|
(event) => {
|
||||||
if ('clientX' in event && 'clientY' in event) {
|
if ('clientX' in event && 'clientY' in event) {
|
||||||
const { clientX, clientY } = event;
|
const { clientX, clientY } = event;
|
||||||
setDropdownPosition({ x: clientX, y: clientY });
|
setDropdownPosition({ x: clientX, y: clientY });
|
||||||
@ -113,11 +111,6 @@ export const useConnectionDrag = (
|
|||||||
|
|
||||||
if (newNodeId) {
|
if (newNodeId) {
|
||||||
setCreatedPlaceholderRef(newNodeId);
|
setCreatedPlaceholderRef(newNodeId);
|
||||||
|
|
||||||
if (connectionStartRef.current) {
|
|
||||||
const edgeId = `xy-edge__${connectionStartRef.current.nodeId}${connectionStartRef.current.handleId}-${newNodeId}end`;
|
|
||||||
setHighlightedPlaceholderEdgeId(edgeId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate placeholder node position and display dropdown menu
|
// Calculate placeholder node position and display dropdown menu
|
||||||
@ -154,7 +147,6 @@ export const useConnectionDrag = (
|
|||||||
calculateDropdownPosition,
|
calculateDropdownPosition,
|
||||||
setActiveDropdown,
|
setActiveDropdown,
|
||||||
showModal,
|
showModal,
|
||||||
setHighlightedPlaceholderEdgeId,
|
|
||||||
checkAndRemoveExistingPlaceholder,
|
checkAndRemoveExistingPlaceholder,
|
||||||
removePlaceholderNode,
|
removePlaceholderNode,
|
||||||
hideModal,
|
hideModal,
|
||||||
@ -206,13 +198,7 @@ export const useConnectionDrag = (
|
|||||||
removePlaceholderNode();
|
removePlaceholderNode();
|
||||||
hideModal();
|
hideModal();
|
||||||
clearActiveDropdown();
|
clearActiveDropdown();
|
||||||
setHighlightedPlaceholderEdgeId(null);
|
}, [removePlaceholderNode, hideModal, clearActiveDropdown]);
|
||||||
}, [
|
|
||||||
removePlaceholderNode,
|
|
||||||
hideModal,
|
|
||||||
clearActiveDropdown,
|
|
||||||
setHighlightedPlaceholderEdgeId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onConnectStart,
|
onConnectStart,
|
||||||
|
|||||||
@ -42,9 +42,6 @@ export const usePlaceholderManager = (reactFlowInstance: any) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear highlighted placeholder edge
|
|
||||||
useGraphStore.getState().setHighlightedPlaceholderEdgeId(null);
|
|
||||||
|
|
||||||
// Update ref reference
|
// Update ref reference
|
||||||
if (createdPlaceholderRef.current === existingPlaceholder.id) {
|
if (createdPlaceholderRef.current === existingPlaceholder.id) {
|
||||||
createdPlaceholderRef.current = null;
|
createdPlaceholderRef.current = null;
|
||||||
@ -62,8 +59,7 @@ export const usePlaceholderManager = (reactFlowInstance: any) => {
|
|||||||
reactFlowInstance &&
|
reactFlowInstance &&
|
||||||
!userSelectedNodeRef.current
|
!userSelectedNodeRef.current
|
||||||
) {
|
) {
|
||||||
const { nodes, edges, setHighlightedPlaceholderEdgeId } =
|
const { nodes, edges } = useGraphStore.getState();
|
||||||
useGraphStore.getState();
|
|
||||||
|
|
||||||
// Remove edges related to placeholder
|
// Remove edges related to placeholder
|
||||||
const edgesToRemove = edges.filter(
|
const edgesToRemove = edges.filter(
|
||||||
@ -84,8 +80,6 @@ export const usePlaceholderManager = (reactFlowInstance: any) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setHighlightedPlaceholderEdgeId(null);
|
|
||||||
|
|
||||||
createdPlaceholderRef.current = null;
|
createdPlaceholderRef.current = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,13 +95,7 @@ export const usePlaceholderManager = (reactFlowInstance: any) => {
|
|||||||
(newNodeId: string) => {
|
(newNodeId: string) => {
|
||||||
// First establish connection between new node and source, then delete placeholder
|
// First establish connection between new node and source, then delete placeholder
|
||||||
if (createdPlaceholderRef.current && reactFlowInstance) {
|
if (createdPlaceholderRef.current && reactFlowInstance) {
|
||||||
const {
|
const { nodes, edges, addEdge, updateNode } = useGraphStore.getState();
|
||||||
nodes,
|
|
||||||
edges,
|
|
||||||
addEdge,
|
|
||||||
updateNode,
|
|
||||||
setHighlightedPlaceholderEdgeId,
|
|
||||||
} = useGraphStore.getState();
|
|
||||||
|
|
||||||
// Find placeholder node to get its position
|
// Find placeholder node to get its position
|
||||||
const placeholderNode = nodes.find(
|
const placeholderNode = nodes.find(
|
||||||
@ -157,8 +145,6 @@ export const usePlaceholderManager = (reactFlowInstance: any) => {
|
|||||||
edges: edgesToRemove,
|
edges: edgesToRemove,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setHighlightedPlaceholderEdgeId(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark that user has selected a node
|
// Mark that user has selected a node
|
||||||
|
|||||||
@ -39,7 +39,6 @@ export type RFState = {
|
|||||||
selectedEdgeIds: string[];
|
selectedEdgeIds: string[];
|
||||||
clickedNodeId: string; // currently selected node
|
clickedNodeId: string; // currently selected node
|
||||||
clickedToolId: string; // currently selected tool id
|
clickedToolId: string; // currently selected tool id
|
||||||
highlightedPlaceholderEdgeId: string | null;
|
|
||||||
onNodesChange: OnNodesChange<RAGFlowNodeType>;
|
onNodesChange: OnNodesChange<RAGFlowNodeType>;
|
||||||
onEdgesChange: OnEdgesChange;
|
onEdgesChange: OnEdgesChange;
|
||||||
onEdgeMouseEnter?: EdgeMouseHandler<Edge>;
|
onEdgeMouseEnter?: EdgeMouseHandler<Edge>;
|
||||||
@ -90,7 +89,6 @@ export type RFState = {
|
|||||||
) => void; // Deleting a condition of a classification operator will delete the related edge
|
) => void; // Deleting a condition of a classification operator will delete the related edge
|
||||||
findAgentToolNodeById: (id: string | null) => string | undefined;
|
findAgentToolNodeById: (id: string | null) => string | undefined;
|
||||||
selectNodeIds: (nodeIds: string[]) => void;
|
selectNodeIds: (nodeIds: string[]) => void;
|
||||||
setHighlightedPlaceholderEdgeId: (edgeId: string | null) => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
||||||
@ -103,7 +101,6 @@ const useGraphStore = create<RFState>()(
|
|||||||
selectedEdgeIds: [] as string[],
|
selectedEdgeIds: [] as string[],
|
||||||
clickedNodeId: '',
|
clickedNodeId: '',
|
||||||
clickedToolId: '',
|
clickedToolId: '',
|
||||||
highlightedPlaceholderEdgeId: null,
|
|
||||||
onNodesChange: (changes) => {
|
onNodesChange: (changes) => {
|
||||||
set({
|
set({
|
||||||
nodes: applyNodeChanges(changes, get().nodes),
|
nodes: applyNodeChanges(changes, get().nodes),
|
||||||
@ -530,9 +527,6 @@ const useGraphStore = create<RFState>()(
|
|||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
setHighlightedPlaceholderEdgeId: (edgeId) => {
|
|
||||||
set({ highlightedPlaceholderEdgeId: edgeId });
|
|
||||||
},
|
|
||||||
})),
|
})),
|
||||||
{ name: 'graph', trace: true },
|
{ name: 'graph', trace: true },
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user