From b0dadc9a240ce7e77bd00daefd93d5f409ff7709 Mon Sep 17 00:00:00 2001 From: asp_ly Date: Sat, 14 Dec 2024 13:21:57 +0800 Subject: [PATCH] 1 --- .../Workflow/Definition/Design/index.less | 110 ++++++ .../Workflow/Definition/Design/index.tsx | 318 +++++++++--------- 2 files changed, 276 insertions(+), 152 deletions(-) create mode 100644 frontend/src/pages/Workflow/Definition/Design/index.less diff --git a/frontend/src/pages/Workflow/Definition/Design/index.less b/frontend/src/pages/Workflow/Definition/Design/index.less new file mode 100644 index 00000000..1c16e515 --- /dev/null +++ b/frontend/src/pages/Workflow/Definition/Design/index.less @@ -0,0 +1,110 @@ +.workflow-design { + height: 100%; + display: flex; + flex-direction: column; + background: #fff; + + .header { + padding: 16px; + border-bottom: 1px solid #f0f0f0; + display: flex; + justify-content: space-between; + align-items: center; + flex-shrink: 0; + + .back-button { + margin-right: 16px; + } + + .actions { + .ant-space-compact { + margin-right: 8px; + } + } + } + + .content { + flex: 1; + min-height: 0; + display: flex; + padding: 16px; + gap: 16px; + + .sidebar { + width: 280px; + flex-shrink: 0; + border-right: 1px solid #f0f0f0; + overflow-y: auto; + background: #fff; + border-radius: 4px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + + :global { + .ant-collapse { + border: none; + background: transparent; + + .ant-collapse-item { + border-radius: 0; + + .ant-collapse-header { + padding: 8px 16px; + } + + .ant-collapse-content-box { + padding: 0; + } + } + } + } + + .node-item { + padding: 8px 16px; + margin: 4px 8px; + border: 1px solid #d9d9d9; + border-radius: 4px; + cursor: move; + transition: all 0.3s; + + &:hover { + background: #f5f5f5; + border-color: #1890ff; + } + } + } + + .main-area { + flex: 1; + display: flex; + flex-direction: column; + min-width: 0; + + .workflow-container { + flex: 1; + position: relative; + border: 1px solid #d9d9d9; + border-radius: 4px; + background: #f5f5f5; + overflow: hidden; + + .workflow-canvas { + width: 100%; + height: 100%; + } + + .minimap-container { + position: absolute; + right: 20px; + bottom: 20px; + width: 200px; + height: 150px; + border: 1px solid #f0f0f0; + border-radius: 4px; + background: #fff; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + z-index: 1; + } + } + } + } +} diff --git a/frontend/src/pages/Workflow/Definition/Design/index.tsx b/frontend/src/pages/Workflow/Definition/Design/index.tsx index 46efc0e7..fc815715 100644 --- a/frontend/src/pages/Workflow/Definition/Design/index.tsx +++ b/frontend/src/pages/Workflow/Definition/Design/index.tsx @@ -1,6 +1,6 @@ import React, {useEffect, useState, useRef} from 'react'; import {useParams, useNavigate} from 'react-router-dom'; -import {Button, Space, Card, Row, Col, message, Modal} from 'antd'; +import {Button, Space, Card, Row, Col, message, Modal, Collapse} from 'antd'; import { ArrowLeftOutlined, SaveOutlined, @@ -18,6 +18,7 @@ import '@antv/x6-plugin-snapline'; import '@antv/x6-plugin-clipboard'; import '@antv/x6-plugin-history'; import { Selection } from '@antv/x6-plugin-selection'; +import { MiniMap } from '@antv/x6-plugin-minimap'; import {getDefinitionDetail, saveDefinition} from '../service'; import {getNodeDefinitionList} from './service'; import NodePanel from './components/NodePanel'; @@ -32,12 +33,14 @@ import { HIGHLIGHTING_CONFIG, DEFAULT_STYLES, } from './constants'; +import './index.less'; const WorkflowDesign: React.FC = () => { const {id} = useParams<{ id: string }>(); const navigate = useNavigate(); const [title, setTitle] = useState('工作流设计'); const graphContainerRef = useRef(null); + const minimapContainerRef = useRef(null); const [graph, setGraph] = useState(null); const [selectedNode, setSelectedNode] = useState(null); const [selectedNodeDefinition, setSelectedNodeDefinition] = useState(null); @@ -79,6 +82,8 @@ const WorkflowDesign: React.FC = () => { background: { color: '#f5f5f5', }, + width: graphContainerRef.current.clientWidth, + height: graphContainerRef.current.clientHeight, }); // 注册选择插件 @@ -94,6 +99,18 @@ const WorkflowDesign: React.FC = () => { }) ); + // 注册小地图插件 + if (minimapContainerRef.current) { + graph.use( + new MiniMap({ + container: minimapContainerRef.current, + width: 200, + height: 150, + padding: 10, + }) + ); + } + // 添加右键菜单 graph.on('node:contextmenu', ({cell, view, e}) => { e.preventDefault(); @@ -233,6 +250,11 @@ const WorkflowDesign: React.FC = () => { }; }, [graphContainerRef, id, nodeDefinitions, isNodeDefinitionsLoaded]); + useEffect(() => { + if (!graph || !minimapContainerRef.current) return; + + }, [graph]); + const loadDefinitionDetail = async (graphInstance: Graph, definitionId: string) => { try { const response = await getDefinitionDetail(Number(definitionId)); @@ -399,164 +421,156 @@ const WorkflowDesign: React.FC = () => { }; return ( -
- - +
+
+ + + 工作流设计器 + +
+ + + + +
+
+
+
- - - - - - - - } - > -
+
+
+
- - - - setConfigModalVisible(false)} - /> +
+
+
+
+ {configModalVisible && selectedNode && selectedNodeDefinition && ( + setConfigModalVisible(false)} + onOk={handleNodeConfigUpdate} + /> + )}
); };