From bd220050c79ef33e168e7345c175a59344c5984d Mon Sep 17 00:00:00 2001 From: huangzhuang_3rd Date: Thu, 13 Aug 2026 23:12:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20DAG=E7=94=BB=E5=B8=83=E5=B5=8C=E5=85=A5?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E8=AF=A6=E6=83=85=E9=A1=B5=EF=BC=8C=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=8A=82=E7=82=B9=E7=82=B9=E5=87=BB=E5=BC=B9=E8=AF=A6?= =?UTF-8?q?=E6=83=85Modal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/TaskDetailModal.tsx | 140 ++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 frontend/src/components/TaskDetailModal.tsx diff --git a/frontend/src/components/TaskDetailModal.tsx b/frontend/src/components/TaskDetailModal.tsx new file mode 100644 index 0000000..765b41f --- /dev/null +++ b/frontend/src/components/TaskDetailModal.tsx @@ -0,0 +1,140 @@ +import { useEffect, useState } from 'react'; +import { Modal, Descriptions, Spin, Tag, Typography, Empty } from 'antd'; +import { taskApi } from '@/api'; +import type { Task } from '@/types'; +import { TaskStatusTag, PriorityTag } from '@/components/constants'; +import dayjs from 'dayjs'; + +const { Paragraph, Text } = Typography; + +interface Props { + taskId: number | null; + open: boolean; + onClose: () => void; +} + +/** 任务详情弹窗:在 DAG 画布/项目页内点击任务卡片时弹出,不跳转页面 */ +export default function TaskDetailModal({ taskId, open, onClose }: Props) { + const [task, setTask] = useState(null); + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (!open || taskId == null) return; + setLoading(true); + setTask(null); + taskApi + .get(taskId) + .then(setTask) + .catch(() => setTask(null)) + .finally(() => setLoading(false)); + }, [open, taskId]); + + const renderJsonBlock = (raw?: string) => { + if (!raw) return ; + let pretty = raw; + try { + pretty = JSON.stringify(JSON.parse(raw), null, 2); + } catch { + /* keep raw */ + } + return ( +
+        {pretty}
+      
+ ); + }; + + return ( + + {loading ? ( +
+ +
+ ) : !task ? ( + + ) : ( +
+ + + + + + + + {task.task_type} + + {task.requires_review ? ( + + ) : ( + + )} + + {task.review_status && ( + {task.review_status} + )} + {task.worker_id && ( + #{task.worker_id} + )} + {task.due_date && ( + + {dayjs(task.due_date).format('YYYY-MM-DD HH:mm')} + + )} + {task.started_at && ( + + {dayjs(task.started_at).format('YYYY-MM-DD HH:mm')} + + )} + {task.completed_at && ( + + {dayjs(task.completed_at).format('YYYY-MM-DD HH:mm')} + + )} + + {dayjs(task.created_at).format('YYYY-MM-DD HH:mm')} + + {task.description && ( + + {task.description} + + )} + + +
+ + 输入(Prompt / 参数) + + {renderJsonBlock(task.input_data)} +
+ +
+ + 输出结果 + + {renderJsonBlock(task.output_data)} +
+
+ )} +
+ ); +}