import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate, useSearchParams } from "react-router-dom"; import { CheckCircleOutlined as CheckCircleOutlinedIcon, ClockCircleOutlined as ClockCircleOutlinedIcon, CloseCircleOutlined as CloseCircleOutlinedIcon, DeleteOutlined as DeleteOutlinedIcon, EditOutlined as EditOutlinedIcon, PlusOutlined as PlusOutlinedIcon, ReloadOutlined as ReloadOutlinedIcon, StopOutlined as StopOutlinedIcon, SyncOutlined as SyncOutlinedIcon, } from "@ant-design/icons"; import { PageHeader } from "@ant-design/pro-components"; import { useRequest } from "ahooks"; import { Button, Card, Divider, Empty, Flex, Input, Menu, type MenuProps, Modal, Radio, Space, Switch, Table, type TableProps, Tooltip, Typography, message, notification, theme, } from "antd"; import dayjs from "dayjs"; import { ClientResponseError } from "pocketbase"; import { WORKFLOW_TRIGGERS, type WorkflowModel, isAllNodesValidated } from "@/domain/workflow"; import { WORKFLOW_RUN_STATUSES } from "@/domain/workflowRun"; import { list as listWorkflows, remove as removeWorkflow, save as saveWorkflow } from "@/repository/workflow"; import { getErrMsg } from "@/utils/error"; const WorkflowList = () => { const navigate = useNavigate(); const [searchParams] = useSearchParams(); const { t } = useTranslation(); const { token: themeToken } = theme.useToken(); const [messageApi, MessageContextHolder] = message.useMessage(); 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: "name", title: t("workflow.props.name"), ellipsis: true, render: (_, record) => ( {record.name} {record.description} ), }, { key: "trigger", title: t("workflow.props.trigger"), ellipsis: true, render: (_, record) => { const trigger = record.trigger; if (!trigger) { return "-"; } else if (trigger === WORKFLOW_TRIGGERS.MANUAL) { return {t("workflow.props.trigger.manual")}; } else if (trigger === WORKFLOW_TRIGGERS.AUTO) { return ( {t("workflow.props.trigger.auto")} {record.triggerCron ?? ""} ); } }, }, { key: "state", title: t("workflow.props.state"), defaultFilteredValue: searchParams.has("state") ? [searchParams.get("state") as string] : undefined, filterDropdown: ({ setSelectedKeys, confirm, clearFilters }) => { const items: Required["items"] = [ ["enabled", "workflow.props.state.filter.enabled"], ["disabled", "workflow.props.state.filter.disabled"], ].map(([key, label]) => { return { key, label: {t(label)}, onClick: () => { if (filters["state"] !== key) { setPage(1); setFilters((prev) => ({ ...prev, state: key })); setSelectedKeys([key]); } confirm({ closeDropdown: true }); }, }; }); const handleResetClick = () => { setPage(1); setFilters((prev) => ({ ...prev, state: undefined })); setSelectedKeys([]); clearFilters?.(); confirm(); }; const handleConfirmClick = () => { confirm(); }; return (
); }, render: (_, record) => { const enabled = record.enabled; return ( { handleEnabledChange(record); }} /> ); }, }, { key: "lastRun", title: t("workflow.props.last_run_at"), render: (_, record) => { let icon = <>; if (record.lastRunStatus === WORKFLOW_RUN_STATUSES.PENDING) { icon = ; } else if (record.lastRunStatus === WORKFLOW_RUN_STATUSES.RUNNING) { icon = ; } else if (record.lastRunStatus === WORKFLOW_RUN_STATUSES.SUCCEEDED) { icon = ; } else if (record.lastRunStatus === WORKFLOW_RUN_STATUSES.FAILED) { icon = ; } else if (record.lastRunStatus === WORKFLOW_RUN_STATUSES.CANCELED) { icon = ; } return ( {icon} {record.lastRunTime ? dayjs(record.lastRunTime!).format("YYYY-MM-DD HH:mm:ss") : ""} ); }, }, { key: "createdAt", title: t("workflow.props.created_at"), ellipsis: true, render: (_, record) => { return dayjs(record.created!).format("YYYY-MM-DD HH:mm:ss"); }, }, { key: "updatedAt", title: t("workflow.props.updated_at"), ellipsis: true, render: (_, record) => { return dayjs(record.updated!).format("YYYY-MM-DD HH:mm:ss"); }, }, { key: "$action", align: "end", fixed: "right", width: 120, render: (_, record) => ( , ]} />
columns={tableColumns} dataSource={tableData} loading={loading} locale={{ emptyText: , }} pagination={{ current: page, pageSize: pageSize, total: tableTotal, showSizeChanger: true, onChange: (page: number, pageSize: number) => { setPage(page); setPageSize(pageSize); }, onShowSizeChange: (page: number, pageSize: number) => { setPage(page); setPageSize(pageSize); }, }} rowKey={(record) => record.id} scroll={{ x: "max(100%, 960px)" }} />
); }; export default WorkflowList;