542ea59869
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 30s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 48s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 46s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 55s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 1m19s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m35s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m7s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m10s
AI Code Review / AI Code Review (pull_request) Successful in 4m13s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 3m11s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 6m38s
CI/CD Pipeline / CI Gate (pull_request) Failing after 5s
CI/CD Pipeline / Production Browser E2E (pull_request) Failing after 1174h8m56s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 1174h8m57s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 1174h8m57s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 1174h8m58s
CI/CD Pipeline / Integration Tests (pull_request) Failing after 1174h8m58s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 1174h14m15s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 1174h14m17s
CI/CD Pipeline / PR Build Worker Image (pull_request) Failing after 1174h14m19s
CI/CD Pipeline / PR Build API Image (pull_request) Failing after 1174h14m21s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 1174h15m9s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 1174h15m28s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 1174h15m30s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 1174h41m57s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 1174h41m58s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 1174h47m17s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 1174h48m7s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 1174h48m28s
132 lines
3.6 KiB
TypeScript
Executable File
132 lines
3.6 KiB
TypeScript
Executable File
import React from "react"
|
|
import { Tag, Button, Popconfirm, Tooltip } from "antd"
|
|
import { RedoOutlined, InfoCircleOutlined } from "@ant-design/icons"
|
|
import type { ColumnsType } from "antd/es/table"
|
|
import type { TaskItem, TaskStatus } from "@/api/tasks"
|
|
import { STATUS_CONFIG, TYPE_LABELS } from "../../constants"
|
|
import { formatDuration, formatTime } from "../../utils"
|
|
|
|
interface UseTaskTableColumnsOptions {
|
|
retryLoading: boolean
|
|
onRetry: (id: string) => void
|
|
onViewDetail: (record: TaskItem) => void
|
|
}
|
|
|
|
export function useTaskTableColumns({
|
|
retryLoading,
|
|
onRetry,
|
|
onViewDetail,
|
|
}: UseTaskTableColumnsOptions): ColumnsType<TaskItem> {
|
|
return [
|
|
{
|
|
title: "任务ID",
|
|
dataIndex: "id",
|
|
key: "id",
|
|
width: 120,
|
|
ellipsis: true,
|
|
render: (id: string) => (
|
|
<Tooltip title={id}>
|
|
<span className="task-id">{id.slice(0, 8)}...</span>
|
|
</Tooltip>
|
|
),
|
|
},
|
|
{
|
|
title: "类型",
|
|
dataIndex: "task_type",
|
|
key: "task_type",
|
|
width: 100,
|
|
render: (type: string) => {
|
|
const config = TYPE_LABELS[type] || { label: type, color: "default" }
|
|
return <Tag color={config.color}>{config.label}</Tag>
|
|
},
|
|
},
|
|
{
|
|
title: "状态",
|
|
dataIndex: "status",
|
|
key: "status",
|
|
width: 120,
|
|
render: (status: TaskStatus, record: TaskItem) => {
|
|
const config = STATUS_CONFIG[status] || {
|
|
label: status,
|
|
color: "default",
|
|
icon: null,
|
|
}
|
|
return (
|
|
<Tag color={config.color} icon={config.icon} className="task-status-tag">
|
|
{config.label}
|
|
{status === "running" && record.progress > 0 && (
|
|
<span className="task-progress"> {record.progress}%</span>
|
|
)}
|
|
</Tag>
|
|
)
|
|
},
|
|
},
|
|
{
|
|
title: "当前步骤",
|
|
dataIndex: "current_step",
|
|
key: "current_step",
|
|
width: 150,
|
|
ellipsis: true,
|
|
render: (step: string) => <span className="task-step">{step || "-"}</span>,
|
|
},
|
|
{
|
|
title: "耗时",
|
|
dataIndex: "duration_seconds",
|
|
key: "duration_seconds",
|
|
width: 100,
|
|
render: (seconds: number) => (
|
|
<span className="task-duration">{formatDuration(seconds)}</span>
|
|
),
|
|
},
|
|
{
|
|
title: "创建时间",
|
|
dataIndex: "created_at",
|
|
key: "created_at",
|
|
width: 120,
|
|
render: (time: string) => <span className="task-time">{formatTime(time)}</span>,
|
|
},
|
|
{
|
|
title: "操作",
|
|
key: "action",
|
|
width: 100,
|
|
fixed: "right",
|
|
render: (_: unknown, record: TaskItem) => {
|
|
if (record.status === "failed" && record.retryable) {
|
|
return (
|
|
<Popconfirm
|
|
title="确认重试"
|
|
description="确定要重试这个失败的任务吗?"
|
|
onConfirm={() => onRetry(record.id)}
|
|
okText="确定"
|
|
cancelText="取消"
|
|
>
|
|
<Button
|
|
type="link"
|
|
size="small"
|
|
icon={<RedoOutlined />}
|
|
loading={retryLoading}
|
|
className="task-retry-btn"
|
|
>
|
|
重试
|
|
</Button>
|
|
</Popconfirm>
|
|
)
|
|
}
|
|
if (record.status === "failed") {
|
|
return (
|
|
<Button
|
|
type="link"
|
|
size="small"
|
|
icon={<InfoCircleOutlined />}
|
|
onClick={() => onViewDetail(record)}
|
|
>
|
|
详情
|
|
</Button>
|
|
)
|
|
}
|
|
return <span className="task-action-placeholder">-</span>
|
|
},
|
|
},
|
|
]
|
|
}
|