feat(ui): display artifact certificates in WorkflowRunDetail
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Alert, Typography } from "antd";
|
||||
import { SelectOutlined as SelectOutlinedIcon } from "@ant-design/icons";
|
||||
import { useRequest } from "ahooks";
|
||||
import { Alert, Button, Divider, Empty, Table, type TableProps, Tooltip, Typography, notification } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import CertificateDetailDrawer from "@/components/certificate/CertificateDetailDrawer";
|
||||
import Show from "@/components/Show";
|
||||
import { type CertificateModel } from "@/domain/certificate";
|
||||
import { WORKFLOW_RUN_STATUSES, type WorkflowRunModel } from "@/domain/workflowRun";
|
||||
import { listByWorkflowRunId as listCertificateByWorkflowRunId } from "@/repository/certificate";
|
||||
import { getErrMsg } from "@/utils/error";
|
||||
|
||||
export type WorkflowRunDetailProps = {
|
||||
className?: string;
|
||||
@@ -45,8 +53,108 @@ const WorkflowRunDetail = ({ data, ...props }: WorkflowRunDetailProps) => {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Show when={data.status === WORKFLOW_RUN_STATUSES.SUCCEEDED}>
|
||||
<Divider />
|
||||
|
||||
<WorkflowRunArtifacts runId={data.id} />
|
||||
</Show>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const WorkflowRunArtifacts = ({ runId }: { runId: string }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [notificationApi, NotificationContextHolder] = notification.useNotification();
|
||||
|
||||
const tableColumns: TableProps<CertificateModel>["columns"] = [
|
||||
{
|
||||
key: "$index",
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
width: 50,
|
||||
render: (_, __, index) => index + 1,
|
||||
},
|
||||
{
|
||||
key: "type",
|
||||
title: t("workflow_run_artifact.props.type"),
|
||||
render: () => t("workflow_run_artifact.props.type.certificate"),
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
title: t("workflow_run_artifact.props.name"),
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return (
|
||||
<Typography.Text delete={!!record.deleted} ellipsis>
|
||||
{record.subjectAltNames}
|
||||
</Typography.Text>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "$action",
|
||||
align: "end",
|
||||
width: 120,
|
||||
render: (_, record) => (
|
||||
<Button.Group>
|
||||
<CertificateDetailDrawer
|
||||
data={record}
|
||||
trigger={
|
||||
<Tooltip title={t("certificate.action.view")}>
|
||||
<Button color="primary" disabled={!!record.deleted} icon={<SelectOutlinedIcon />} variant="text" />
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
</Button.Group>
|
||||
),
|
||||
},
|
||||
];
|
||||
const [tableData, setTableData] = useState<CertificateModel[]>([]);
|
||||
const { loading: tableLoading } = useRequest(
|
||||
() => {
|
||||
return listCertificateByWorkflowRunId(runId);
|
||||
},
|
||||
{
|
||||
refreshDeps: [runId],
|
||||
onBefore: () => {
|
||||
setTableData([]);
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
setTableData(res.items);
|
||||
},
|
||||
onError: (err) => {
|
||||
if (err instanceof ClientResponseError && err.isAbort) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
|
||||
|
||||
throw err;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{NotificationContextHolder}
|
||||
|
||||
<Typography.Title level={5}>{t("workflow_run.artifacts")}</Typography.Title>
|
||||
<Table<CertificateModel>
|
||||
columns={tableColumns}
|
||||
dataSource={tableData}
|
||||
loading={tableLoading}
|
||||
locale={{
|
||||
emptyText: <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />,
|
||||
}}
|
||||
pagination={false}
|
||||
rowKey={(record) => record.id}
|
||||
size="small"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default WorkflowRunDetail;
|
||||
|
||||
@@ -301,7 +301,7 @@ const WorkflowRuns = ({ className, style, workflowId }: WorkflowRunsProps) => {
|
||||
setPageSize(pageSize);
|
||||
},
|
||||
}}
|
||||
rowKey={(record: WorkflowRunModel) => record.id}
|
||||
rowKey={(record) => record.id}
|
||||
scroll={{ x: "max(100%, 960px)" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -86,7 +86,7 @@ const NotifyNodeConfigForm = forwardRef<NotifyNodeConfigFormInstance, NotifyNode
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="message" label={t("workflow_node.notify.form.message.label")} rules={[formRule]}>
|
||||
<Input.TextArea autoSize={{ minRows: 3, maxRows: 10 }} placeholder={t("workflow_node.notify.form.message.placeholder")} />
|
||||
<Input.TextArea autoSize={{ minRows: 3, maxRows: 5 }} placeholder={t("workflow_node.notify.form.message.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item className="mb-0">
|
||||
|
||||
@@ -3,8 +3,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { Flex, Typography } from "antd";
|
||||
import { produce } from "immer";
|
||||
|
||||
import type { WorkflowNodeConfigForUpload } from "@/domain/workflow";
|
||||
import { WorkflowNodeType } from "@/domain/workflow";
|
||||
import { type WorkflowNodeConfigForUpload, WorkflowNodeType } from "@/domain/workflow";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ const UploadNodeConfigForm = forwardRef<UploadNodeConfigFormInstance, UploadNode
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="certificate" label={t("workflow_node.upload.form.certificate.label")} rules={[formRule]}>
|
||||
<Input.TextArea readOnly autoSize={{ minRows: 5, maxRows: 10 }} placeholder={t("workflow_node.upload.form.certificate.placeholder")} />
|
||||
<Input.TextArea readOnly autoSize={{ minRows: 5, maxRows: 5 }} placeholder={t("workflow_node.upload.form.certificate.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
@@ -151,7 +151,7 @@ const UploadNodeConfigForm = forwardRef<UploadNodeConfigFormInstance, UploadNode
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="privateKey" label={t("workflow_node.upload.form.private_key.label")} rules={[formRule]}>
|
||||
<Input.TextArea readOnly autoSize={{ minRows: 5, maxRows: 10 }} placeholder={t("workflow_node.upload.form.private_key.placeholder")} />
|
||||
<Input.TextArea readOnly autoSize={{ minRows: 5, maxRows: 5 }} placeholder={t("workflow_node.upload.form.private_key.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
|
||||
Reference in New Issue
Block a user