feat(flowEditor): 实现流程图中在边上添加节点的功能
- 在 CustomEdge 组件中添加悬停状态和添加节点按钮 - 在 EdgeContextMenu 中添加"添加节点"选项 - 在 FlowEditor组件中实现添加节点的逻辑 - 新增 AddNodeMenu、EdgeAddNodeButton 和 PaneContextMenu 组件用于添加节点 - 优化流程图的右键菜单,支持在画布空白处添加节点master
parent
09222ca3b9
commit
c0f7ffabf8
@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import { Menu } from '@arco-design/web-react';
|
||||
import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData';
|
||||
|
||||
interface AddNodeMenuProps {
|
||||
onAddNode: (nodeType: string) => void;
|
||||
position?: { x: number; y: number }; // 用于画布上下文菜单
|
||||
edgeId?: string; // 用于边上下文菜单
|
||||
}
|
||||
|
||||
const AddNodeMenu: React.FC<AddNodeMenuProps> = ({
|
||||
onAddNode
|
||||
}) => {
|
||||
// 按分组组织节点数据
|
||||
const groupedNodes = localNodeData.reduce((acc, node) => {
|
||||
if (!acc[node.nodeGroup]) {
|
||||
acc[node.nodeGroup] = [];
|
||||
}
|
||||
acc[node.nodeGroup].push(node);
|
||||
return acc;
|
||||
}, {} as Record<string, typeof localNodeData>);
|
||||
|
||||
const handleAddNode = (nodeType: string) => {
|
||||
onAddNode(nodeType);
|
||||
};
|
||||
|
||||
// 分组名称映射
|
||||
const groupNames: Record<string, string> = {
|
||||
'common': '系统组件'
|
||||
// 可以根据需要添加更多分组
|
||||
// 'application': '应用组件',
|
||||
// 'composite': '复合组件'
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu
|
||||
style={{
|
||||
width: 200,
|
||||
border: '1px solid #e4e7ed',
|
||||
borderRadius: 4,
|
||||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)'
|
||||
}}
|
||||
mode="vertical"
|
||||
hasCollapseButton={false}
|
||||
>
|
||||
{Object.entries(groupedNodes).map(([group, nodes]) => (
|
||||
<Menu.SubMenu
|
||||
key={group}
|
||||
title={groupNames[group] || group}
|
||||
popup
|
||||
trigger="hover"
|
||||
>
|
||||
{nodes.map((node) => (
|
||||
<Menu.Item
|
||||
key={node.nodeType}
|
||||
onClick={() => handleAddNode(node.nodeType)}
|
||||
style={{
|
||||
padding: '0 16px',
|
||||
height: 36,
|
||||
lineHeight: '36px'
|
||||
}}
|
||||
>
|
||||
{node.nodeName}
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu.SubMenu>
|
||||
))}
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddNodeMenu;
|
||||
@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import { Button } from '@arco-design/web-react';
|
||||
import { IconPlus } from '@arco-design/web-react/icon';
|
||||
|
||||
interface EdgeAddNodeButtonProps {
|
||||
onClick: () => void;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const EdgeAddNodeButton: React.FC<EdgeAddNodeButtonProps> = ({
|
||||
onClick,
|
||||
style
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
pointerEvents: 'all',
|
||||
...style
|
||||
}}
|
||||
className="nodrag nopan"
|
||||
>
|
||||
<Button
|
||||
size="mini"
|
||||
icon={<IconPlus />}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onClick();
|
||||
}}
|
||||
style={{
|
||||
width: 20,
|
||||
height: 20,
|
||||
minWidth: 20,
|
||||
padding: 0,
|
||||
borderRadius: '50%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#1890ff', // 使用项目主题蓝色
|
||||
borderColor: '#1890ff',
|
||||
color: '#ffffff'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EdgeAddNodeButton;
|
||||
@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { Menu } from '@arco-design/web-react';
|
||||
import AddNodeMenu from './addNodeMenu';
|
||||
|
||||
interface PaneContextMenuProps {
|
||||
onAddNode: (nodeType: string, position: { x: number; y: number }) => void;
|
||||
position: { x: number; y: number };
|
||||
}
|
||||
|
||||
const PaneContextMenu: React.FC<PaneContextMenuProps> = ({
|
||||
onAddNode,
|
||||
position
|
||||
}) => {
|
||||
// 包装onAddNode函数以适配AddNodeMenu组件的接口
|
||||
const handleAddNode = (nodeType: string) => {
|
||||
onAddNode(nodeType, position);
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu
|
||||
mode="pop"
|
||||
style={{
|
||||
minWidth: 200,
|
||||
border: '1px solid #e4e7ed',
|
||||
borderRadius: 4,
|
||||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)'
|
||||
}}
|
||||
>
|
||||
<Menu.SubMenu
|
||||
key="add-node"
|
||||
title="添加节点"
|
||||
popup
|
||||
>
|
||||
<div style={{
|
||||
padding: '4px 0'
|
||||
}}>
|
||||
<AddNodeMenu onAddNode={handleAddNode} />
|
||||
</div>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaneContextMenu;
|
||||
Loading…
Reference in New Issue