diff --git a/frontend/src/pages/Workflow/Definition/Designer/index.tsx b/frontend/src/pages/Workflow/Definition/Designer/index.tsx index ddbfbe37..d9813183 100644 --- a/frontend/src/pages/Workflow/Definition/Designer/index.tsx +++ b/frontend/src/pages/Workflow/Definition/Designer/index.tsx @@ -1,23 +1,22 @@ import React, {useEffect, useRef, useState} from 'react'; import {useNavigate, useParams} from 'react-router-dom'; import {Button, Card, Layout, message, Space, Spin, Drawer, Form, Dropdown} from 'antd'; -import {ArrowLeftOutlined, SaveOutlined} from '@ant-design/icons'; -import {getDefinition, updateDefinition} from '../../service'; -import {WorkflowDefinition, WorkflowStatus} from '../../../Workflow/types'; +import {ArrowLeftOutlined, SaveOutlined, DeleteOutlined, CopyOutlined, SettingOutlined, ClearOutlined, FullscreenOutlined} from '@ant-design/icons'; +import {getDefinition, updateDefinition, getNodeTypes} from '../../service'; +import {WorkflowStatus} from '../../../Workflow/types'; import {Graph, Node, Cell, Edge, Shape} from '@antv/x6'; import '@antv/x6-react-shape'; import './index.module.less'; import NodePanel from './components/NodePanel'; import NodeConfig from './components/NodeConfig'; import Toolbar from './components/Toolbar'; -import {NodeType, getNodeTypes} from './service'; -import {DeleteOutlined, CopyOutlined, SettingOutlined, ClearOutlined, FullscreenOutlined} from '@ant-design/icons'; import EdgeConfig from './components/EdgeConfig'; import { validateFlow, hasCycle } from './validate'; import { generateNodeStyle, generatePorts, calculateNodePosition, calculateCanvasPosition } from './utils/nodeUtils'; import { NODE_CONFIG } from './configs/nodeConfig'; import { isWorkflowError } from './utils/errors'; import { initGraph } from './utils/graphUtils'; +import { NodeType, NodeData, EdgeData, WorkflowDefinition } from './types'; const {Sider, Content} = Layout; @@ -228,14 +227,19 @@ const FlowDesigner: React.FC = () => { if (detail) { loadGraphData(graph, detail); } - } - return () => { - if (graphRef.current) { - graphRef.current.dispose(); - } - }; - }, [detail]); + // 清理函数 + return () => { + if (containerRef.current) { + containerRef.current.removeEventListener('dragover', handleDragOver); + containerRef.current.removeEventListener('drop', handleDrop); + } + if (graphRef.current) { + graphRef.current.dispose(); + } + }; + } + }, [detail, nodeTypes]); // 处理拖拽移动 const handleDragOver = (e: DragEvent) => { @@ -515,6 +519,27 @@ const FlowDesigner: React.FC = () => { } }; + // 监听画布大小变化 + useEffect(() => { + if (!containerRef.current) return; + + const resizeObserver = new ResizeObserver(() => { + if (graphRef.current) { + const container = containerRef.current; + if (container) { + const { width, height } = container.getBoundingClientRect(); + graphRef.current.resize(width, height); + } + } + }); + + resizeObserver.observe(containerRef.current); + + return () => { + resizeObserver.disconnect(); + }; + }, []); + if (loading) { return (
diff --git a/frontend/src/pages/Workflow/Definition/Designer/types.ts b/frontend/src/pages/Workflow/Definition/Designer/types.ts index ddffb4f7..b7aec164 100644 --- a/frontend/src/pages/Workflow/Definition/Designer/types.ts +++ b/frontend/src/pages/Workflow/Definition/Designer/types.ts @@ -4,26 +4,59 @@ export interface Position { } export interface NodeConfig { - size: { - width: number; - height: number; - }; - shape: 'circle' | 'rect' | 'polygon'; - theme: { - fill: string; - stroke: string; - }; label: string; - extras?: { - rx?: number; - ry?: number; - refPoints?: string; - icon?: { - 'xlink:href': string; - width: number; - height: number; - x: number; - y: number; + style: { + width?: number; + height?: number; + [key: string]: any; + }; + ports?: { + groups?: { + [key: string]: any; }; + items?: Array<{ + group: string; + [key: string]: any; + }>; }; } + +export interface NodeType { + code: string; + name: string; + label: string; + config: NodeConfig; + description?: string; +} + +export interface NodeData { + type: string; + name?: string; + description?: string; + config: { + executor?: string; + retryTimes?: number; + retryInterval?: number; + script?: string; + timeout?: number; + workingDirectory?: string; + environment?: string; + successExitCode?: string; + [key: string]: any; + }; +} + +export interface EdgeData { + condition?: string; + description?: string; + priority?: number; +} + +export interface WorkflowDefinition { + id: number; + name: string; + description?: string; + graphDefinition: string; + nodeConfig: string; + status: string; +}