import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { CheckCircleOutlined as CheckCircleOutlinedIcon, ClockCircleOutlined as ClockCircleOutlinedIcon, CloseCircleOutlined as CloseCircleOutlinedIcon, DeleteOutlined as DeleteOutlinedIcon, PauseOutlined as PauseOutlinedIcon, SelectOutlined as SelectOutlinedIcon, StopOutlined as StopOutlinedIcon, SyncOutlined as SyncOutlinedIcon, } from "@ant-design/icons"; import { useRequest } from "ahooks"; import { Button, Empty, Modal, Space, Table, type TableProps, Tag, Tooltip, notification } from "antd"; import dayjs from "dayjs"; import { ClientResponseError } from "pocketbase"; import { cancelRun as cancelWorkflowRun } from "@/api/workflows"; import { WORKFLOW_TRIGGERS } from "@/domain/workflow"; import { WORKFLOW_RUN_STATUSES, type WorkflowRunModel } from "@/domain/workflowRun"; import { list as listWorkflowRuns, remove as removeWorkflowRun, subscribe as subscribeWorkflowRun, unsubscribe as unsubscribeWorkflowRun, } from "@/repository/workflowRun"; import { getErrMsg } from "@/utils/error"; import WorkflowRunDetailDrawer from "./WorkflowRunDetailDrawer"; export type WorkflowRunsProps = { className?: string; style?: React.CSSProperties; workflowId: string; }; const WorkflowRuns = ({ className, style, workflowId }: WorkflowRunsProps) => { const { t } = useTranslation(); const [modalApi, ModelContextHolder] = Modal.useModal(); const [notificationApi, NotificationContextHolder] = notification.useNotification(); const tableColumns: TableProps["columns"] = [ { key: "$index", align: "center", fixed: "left", width: 50, render: (_, __, index) => (page - 1) * pageSize + index + 1, }, { key: "id", title: t("workflow_run.props.id"), ellipsis: true, render: (_, record) => {record.id}, }, { key: "status", title: t("workflow_run.props.status"), ellipsis: true, render: (_, record) => { if (record.status === WORKFLOW_RUN_STATUSES.PENDING) { return }>{t("workflow_run.props.status.pending")}; } else if (record.status === WORKFLOW_RUN_STATUSES.RUNNING) { return ( } color="processing"> {t("workflow_run.props.status.running")} ); } else if (record.status === WORKFLOW_RUN_STATUSES.SUCCEEDED) { return ( } color="success"> {t("workflow_run.props.status.succeeded")} ); } else if (record.status === WORKFLOW_RUN_STATUSES.FAILED) { return ( } color="error"> {t("workflow_run.props.status.failed")} ); } else if (record.status === WORKFLOW_RUN_STATUSES.CANCELED) { return ( } color="warning"> {t("workflow_run.props.status.canceled")} ); } return <>; }, }, { key: "trigger", title: t("workflow_run.props.trigger"), ellipsis: true, render: (_, record) => { if (record.trigger === WORKFLOW_TRIGGERS.AUTO) { return t("workflow_run.props.trigger.auto"); } else if (record.trigger === WORKFLOW_TRIGGERS.MANUAL) { return t("workflow_run.props.trigger.manual"); } return <>; }, }, { key: "startedAt", title: t("workflow_run.props.started_at"), ellipsis: true, render: (_, record) => { if (record.startedAt) { return dayjs(record.startedAt).format("YYYY-MM-DD HH:mm:ss"); } return <>; }, }, { key: "endedAt", title: t("workflow_run.props.ended_at"), ellipsis: true, render: (_, record) => { if (record.endedAt) { return dayjs(record.endedAt).format("YYYY-MM-DD HH:mm:ss"); } return <>; }, }, { key: "$action", align: "end", fixed: "right", width: 120, render: (_, record) => { const allowCancel = record.status === WORKFLOW_RUN_STATUSES.PENDING || record.status === WORKFLOW_RUN_STATUSES.RUNNING; const aloowDelete = record.status === WORKFLOW_RUN_STATUSES.SUCCEEDED || record.status === WORKFLOW_RUN_STATUSES.FAILED || record.status === WORKFLOW_RUN_STATUSES.CANCELED; return (