diff --git a/src/pages/flowEditor/components/addNodeMenu.tsx b/src/pages/flowEditor/components/addNodeMenu.tsx index 12525af..28858df 100644 --- a/src/pages/flowEditor/components/addNodeMenu.tsx +++ b/src/pages/flowEditor/components/addNodeMenu.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { Menu } from '@arco-design/web-react'; +import { Menu, Tabs } from '@arco-design/web-react'; import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData'; +const TabPane = Tabs.TabPane; + interface AddNodeMenuProps { onAddNode: (nodeType: string) => void; position?: { x: number; y: number }; // 用于画布上下文菜单 @@ -9,8 +11,8 @@ interface AddNodeMenuProps { } const AddNodeMenu: React.FC = ({ - onAddNode -}) => { + onAddNode + }) => { // 按分组组织节点数据 const groupedNodes = localNodeData.reduce((acc, node) => { if (!acc[node.nodeGroup]) { @@ -26,46 +28,55 @@ const AddNodeMenu: React.FC = ({ // 分组名称映射 const groupNames: Record = { - 'common': '系统组件' - // 可以根据需要添加更多分组 - // 'application': '应用组件', - // 'composite': '复合组件' + 'common': '系统组件', + 'application': '应用组件', + 'composite': '复合组件' }; return ( - - {Object.entries(groupedNodes).map(([group, nodes]) => ( - - {nodes.map((node) => ( - handleAddNode(node.nodeType)} - style={{ - padding: '0 16px', - height: 36, - lineHeight: '36px' - }} - > - {node.nodeName} - - ))} - - ))} - + + {Object.entries(groupedNodes).map(([group, nodes]) => ( + +
+ + {nodes.map((node) => ( + handleAddNode(node.nodeType)} + style={{ + padding: '0 16px', + height: 36, + lineHeight: '36px' + }} + > + {node.nodeName} + + ))} + +
+
+ ))} +
+ ); }; diff --git a/src/pages/flowEditor/components/customEdge.tsx b/src/pages/flowEditor/components/customEdge.tsx index b392d55..be0d343 100644 --- a/src/pages/flowEditor/components/customEdge.tsx +++ b/src/pages/flowEditor/components/customEdge.tsx @@ -15,7 +15,7 @@ const CustomEdge: React.FC = ({ selected, data }) => { - const [edgePath, labelX, labelY] = getBezierPath({ + const [edgePath, labelX, labelY, offsetX, offsetY] = getBezierPath({ sourceX, sourceY, sourcePosition, @@ -26,13 +26,12 @@ const CustomEdge: React.FC = ({ // 从数据中获取悬停状态 const hovered = data?.hovered || false; - + // 使用useReactFlow钩子获取setEdges方法 const { setEdges } = useReactFlow(); // 边点击处理函数 - const handleEdgeAddNode = () => { - console.log('handleEdgeAddNode called for edge:', id); + const handleEdgeAddNode = (e) => { // 更新边的数据,触发边上添加节点的流程 setEdges(eds => eds.map(edge => { if (edge.id === id) { @@ -40,7 +39,9 @@ const CustomEdge: React.FC = ({ ...edge, data: { ...edge.data, - addNodeTrigger: true + addNodeTrigger: true, + clientX: e.clientX, + clientY: e.clientY } }; } @@ -71,20 +72,11 @@ const CustomEdge: React.FC = ({ > {hovered && ( handleEdgeAddNode(e)} /> )} - {/* 悬停时显示的高亮线条 */} - {hovered && ( - - )} ); }; diff --git a/src/pages/flowEditor/components/edgeAddNodeButton.tsx b/src/pages/flowEditor/components/edgeAddNodeButton.tsx index 7fe1fcf..c81b957 100644 --- a/src/pages/flowEditor/components/edgeAddNodeButton.tsx +++ b/src/pages/flowEditor/components/edgeAddNodeButton.tsx @@ -3,16 +3,16 @@ import { Button } from '@arco-design/web-react'; import { IconPlus } from '@arco-design/web-react/icon'; interface EdgeAddNodeButtonProps { - onClick: () => void; + onClick: (e) => void; style?: React.CSSProperties; } -const EdgeAddNodeButton: React.FC = ({ - onClick, - style -}) => { +const EdgeAddNodeButton: React.FC = ({ + onClick, + style + }) => { return ( -
= ({ icon={} onClick={(e) => { e.stopPropagation(); - onClick(); + onClick(e); }} style={{ - width: 20, - height: 20, - minWidth: 20, + width: 12, + height: 12, + minWidth: 12, padding: 0, borderRadius: '50%', display: 'flex', diff --git a/src/pages/flowEditor/components/paneContextMenu.tsx b/src/pages/flowEditor/components/paneContextMenu.tsx index 2bd3ae5..c4a7b5c 100644 --- a/src/pages/flowEditor/components/paneContextMenu.tsx +++ b/src/pages/flowEditor/components/paneContextMenu.tsx @@ -2,6 +2,8 @@ import React from 'react'; import { Menu } from '@arco-design/web-react'; import AddNodeMenu from './addNodeMenu'; +const SubMenu = Menu.SubMenu; + interface PaneContextMenuProps { onAddNode: (nodeType: string, position: { x: number; y: number }) => void; position: { x: number; y: number }; @@ -18,7 +20,6 @@ const PaneContextMenu: React.FC = ({ return ( = ({ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)' }} > - -
- -
-
+ +
); }; diff --git a/src/pages/flowEditor/index.tsx b/src/pages/flowEditor/index.tsx index c910c25..d3c9582 100644 --- a/src/pages/flowEditor/index.tsx +++ b/src/pages/flowEditor/index.tsx @@ -289,8 +289,10 @@ const FlowEditor: React.FC = () => { // 监听边的变化,处理添加节点的触发 useEffect(() => { const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger); + const pane = reactFlowWrapper.current?.getBoundingClientRect(); if (edgeToAddNode) { - console.log('Triggering add node for edge:', edgeToAddNode.id); + edgeToAddNode.data.y = (edgeToAddNode.data.clientY as number) - pane.top; + edgeToAddNode.data.x = (edgeToAddNode.data.clientX as number) - pane.left; setEdgeForNodeAdd(edgeToAddNode); // 清除触发标志 @@ -380,7 +382,12 @@ const FlowEditor: React.FC = () => { ); // 点击画布其他区域关闭菜单 - const onPaneClick = useCallback(() => setMenu(null), [setMenu]); + const onPaneClick = useCallback(() => { + setMenu(null); + // 关闭添加节点菜单 + setEdgeForNodeAdd(null); + setPositionForNodeAdd(null); + }, [setMenu]); // 关闭编辑弹窗 const closeEditModal = useCallback(() => { @@ -546,7 +553,7 @@ const FlowEditor: React.FC = () => { else if (positionForNodeAdd) { addNodeOnPane(nodeType, positionForNodeAdd); } - + // 清除状态 setEdgeForNodeAdd(null); setPositionForNodeAdd(null); @@ -711,14 +718,19 @@ const FlowEditor: React.FC = () => {
{ + handleAddNode(nodeType); + // 关闭菜单 + setEdgeForNodeAdd(null); + setPositionForNodeAdd(null); + }} position={positionForNodeAdd || undefined} edgeId={edgeForNodeAdd?.id} />