diff --git a/frontend/src/pages/Workflow/Definition/Designer/index.tsx b/frontend/src/pages/Workflow/Definition/Designer/index.tsx index 58a190c9..8130937f 100644 --- a/frontend/src/pages/Workflow/Definition/Designer/index.tsx +++ b/frontend/src/pages/Workflow/Definition/Designer/index.tsx @@ -6,6 +6,12 @@ import {getDefinition, updateDefinition} from '../../service'; import {WorkflowDefinition, WorkflowStatus} from '../../../Workflow/types'; import {Graph, Node, Cell} from '@antv/x6'; import '@antv/x6-react-shape'; +import { Selection } from '@antv/x6-plugin-selection'; +import { History } from '@antv/x6-plugin-history'; +import { Clipboard } from '@antv/x6-plugin-clipboard'; +import { Transform } from '@antv/x6-plugin-transform'; +import { Keyboard } from '@antv/x6-plugin-keyboard'; +import { Snapline } from '@antv/x6-plugin-snapline'; import './index.module.less'; import NodePanel from './components/NodePanel'; import NodeConfig from './components/NodeConfig'; @@ -28,6 +34,7 @@ const FlowDesigner: React.FC = () => { const [detail, setDetail] = useState(); const containerRef = useRef(null); const graphRef = useRef(); + const [graph, setGraph] = useState(); const draggedNodeRef = useRef(); const [configVisible, setConfigVisible] = useState(false); const [currentNode, setCurrentNode] = useState(); @@ -116,6 +123,19 @@ const FlowDesigner: React.FC = () => { vertexMovable: true, vertexAddable: true, vertexDeletable: true, + magnetConnectable: true, + }, + keyboard: { + enabled: true, + }, + clipboard: { + enabled: true, + }, + history: { + enabled: true, + }, + snapline: { + enabled: true, }, translating: { restrict: true, @@ -125,7 +145,79 @@ const FlowDesigner: React.FC = () => { }, }); + // 启用必要的功能 + graph.use( + new Selection({ + enabled: true, + multiple: true, + rubberband: true, + rubberEdge: true, + movable: true, + showNodeSelectionBox: true, + showEdgeSelectionBox: true, + selectCellOnMoved: false, + selectEdgeOnMoved: false, + selectNodeOnMoved: false, + className: 'node-selected', + strict: true, + }) + ); + + graph.use( + new History({ + enabled: true, + beforeAddCommand: (event: string, args: any) => { + if (event === 'cell:change:*') { + return true; + } + return true; + }, + }) + ); + + graph.use( + new Clipboard({ + enabled: true, + }) + ); + + graph.use( + new Transform({ + resizing: { + enabled: true, + minWidth: 1, + minHeight: 1, + orthogonal: true, + restricted: true, + }, + rotating: { + enabled: true, + grid: 15, + }, + }) + ); + + graph.use( + new Keyboard({ + enabled: true, + }) + ); + + graph.use( + new Snapline({ + enabled: true, + }) + ); + + // 启用基础功能 + graph.enableSelection(); + graph.enableRubberband(); + graph.enableKeyboard(); + graph.enableClipboard(); + graph.enableHistory(); + graphRef.current = graph; + setGraph(graph); // 加载流程图数据 if (detail) { @@ -160,6 +252,12 @@ const FlowDesigner: React.FC = () => { setConfigVisible(true); } }); + + // 监听选择状态变化 + graph.on('selection:changed', () => { + // 强制更新工具栏状态 + setGraph(graph); + }); }; // 处理拖拽移动 @@ -400,7 +498,7 @@ const FlowDesigner: React.FC = () => { - +