diff --git a/app/project/detail/components/WorkflowModal.tsx b/app/project/detail/components/WorkflowModal.tsx index 1bf5df6..d71cafd 100644 --- a/app/project/detail/components/WorkflowModal.tsx +++ b/app/project/detail/components/WorkflowModal.tsx @@ -3,7 +3,56 @@ import { getTaskWorkFlow } from "@/components/label/api/task" import { Button, Group, Modal, ScrollArea, Stack, Text } from "@mantine/core" import { notifications } from "@mantine/notifications" -import { useEffect, useState } from "react" +import { DataTable, DataTableColumn } from "mantine-datatable" +import { useEffect, useMemo, useState } from "react" +import TaskStatusTag from "./TaskStatusTag" + +type WorkflowRecord = Record + +type WorkflowRow = WorkflowRecord & { + __rowId: string + __index: number +} + +const DISPLAY_COLUMNS: Array<{ accessor: string; title: string }> = [ + { accessor: "task_status_src", title: "原状态" }, + { accessor: "task_status_dst", title: "目标状态" }, + { accessor: "old_username", title: "原处理人" }, + { accessor: "new_username", title: "目标处理人" }, + { accessor: "action", title: "操作" }, +] + +const MONOSPACE_STYLE = { + fontFamily: + 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace', + whiteSpace: "pre-wrap" as const, + wordBreak: "break-word" as const, +} + +function toPlainRecord(value: unknown): WorkflowRecord { + if (value && typeof value === "object" && !Array.isArray(value)) { + return value as WorkflowRecord + } + return { value } +} + +function parseStatusValue(value: unknown) { + if (typeof value === "number" && Number.isFinite(value)) return value + if (typeof value === "string" && value.trim() !== "") { + const status = Number(value) + return Number.isFinite(status) ? status : null + } + return null +} + +function formatWorkflowValue(value: unknown) { + if (value === null || value === undefined || value === "") return "-" + if (typeof value === "boolean") return value ? "是" : "否" + if (Array.isArray(value) || typeof value === "object") { + return JSON.stringify(value) + } + return String(value) +} export default function WorkflowModal(props: { opened: boolean @@ -12,7 +61,52 @@ export default function WorkflowModal(props: { }) { const { opened, taskId, onCloseAction } = props const [loading, setLoading] = useState(false) - const [records, setRecords] = useState([]) + const [records, setRecords] = useState([]) + + const rows = useMemo(() => { + return records.map((item, index) => { + const record = toPlainRecord(item) + const rawId = record.id ?? record.workflow_id ?? record.log_id ?? index + + return { + ...record, + __index: index + 1, + __rowId: String(rawId), + } + }) + }, [records]) + + const columns = useMemo[]>(() => { + return [ + { + accessor: "__index", + title: "序号", + width: 72, + }, + ...DISPLAY_COLUMNS.map>( + ({ accessor, title }) => ({ + accessor, + title, + render: (record) => { + const status = + accessor === "task_status_src" || accessor === "task_status_dst" + ? parseStatusValue(record[accessor]) + : null + + if (status !== null) { + return + } + + return ( + + {formatWorkflowValue(record[accessor])} + + ) + }, + }) + ), + ] + }, []) useEffect(() => { if (!opened || !taskId) return @@ -44,30 +138,17 @@ export default function WorkflowModal(props: { size={720}> - - {records.length ? ( - records.map((r, idx) => ( - - {JSON.stringify(r, null, 2)} - - )) - ) : ( - - {loading ? "加载中..." : "暂无数据"} - - )} - + + withTableBorder + withRowBorders + pinLastColumn + idAccessor="__rowId" + records={rows} + width={Math.max(columns.length * 140, 640)} + columns={columns} + noRecordsText={loading ? "加载中..." : "暂无数据"} + minHeight={220} + />