diff --git a/frontend/src/pages/DagCanvas.tsx b/frontend/src/pages/DagCanvas.tsx index a6f873e..700da04 100644 --- a/frontend/src/pages/DagCanvas.tsx +++ b/frontend/src/pages/DagCanvas.tsx @@ -14,8 +14,6 @@ import { import type { Node, Edge, Connection, NodeProps } from 'reactflow'; import 'reactflow/dist/style.css'; import { - Card, - Select, Button, Space, message, @@ -30,9 +28,10 @@ import { ReloadOutlined, DeleteOutlined, } from '@ant-design/icons'; -import { projectApi, dagApi } from '@/api'; -import type { Project, TaskStatus, DagGraphNode, DagGraphEdge } from '@/types'; +import { dagApi } from '@/api'; +import type { TaskStatus, DagGraphNode, DagGraphEdge } from '@/types'; import { taskStatusConfig, priorityConfig } from '@/components/constants'; +import TaskDetailModal from '@/components/TaskDetailModal'; const { Text } = Typography; @@ -52,6 +51,7 @@ function TaskNode({ data }: NodeProps) { borderRadius: 8, boxShadow: '0 2px 8px rgba(0,0,0,0.08)', overflow: 'hidden', + cursor: 'pointer', }} > @@ -121,23 +121,19 @@ function layoutNodes(graphNodes: DagGraphNode[], graphEdges: DagGraphEdge[]) { return positions; } -export default function DagCanvas() { - const [projects, setProjects] = useState([]); - const [projectId, setProjectId] = useState(); +interface Props { + projectId: number; +} + +/** DAG 编排画布(嵌入项目详情页使用) */ +export default function DagCanvas({ projectId }: Props) { const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [loading, setLoading] = useState(false); const [executing, setExecuting] = useState(false); const [selectedEdge, setSelectedEdge] = useState(null); - - // Load projects - useEffect(() => { - projectApi.list().then((ps) => { - setProjects(ps); - if (ps.length > 0 && !projectId) setProjectId(ps[0].id); - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + const [detailTaskId, setDetailTaskId] = useState(null); + const [detailOpen, setDetailOpen] = useState(false); const loadGraph = useCallback(async (pid: number) => { setLoading(true); @@ -182,7 +178,7 @@ export default function DagCanvas() { // Connect: add dependency (drag from source(bottom) to target(top)) const onConnect = useCallback( async (conn: Connection) => { - if (!conn.source || !conn.target || !projectId) return; + if (!conn.source || !conn.target) return; try { await dagApi.addDependency({ task_id: Number(conn.target), @@ -205,9 +201,15 @@ export default function DagCanvas() { message.error(e.response?.data?.detail || '添加依赖失败'); } }, - [projectId, setEdges] + [setEdges] ); + // Node click -> open task detail modal + const onNodeClick = useCallback((_: unknown, node: Node) => { + setDetailTaskId(Number(node.id)); + setDetailOpen(true); + }, []); + // Delete selected edge const removeSelectedEdge = useCallback(async () => { if (!selectedEdge) return; @@ -269,70 +271,73 @@ export default function DagCanvas() { return (
- -