diff --git a/ui/src/components/workflow/WorkflowRunDetail.tsx b/ui/src/components/workflow/WorkflowRunDetail.tsx
index e104410a..18a2f40d 100644
--- a/ui/src/components/workflow/WorkflowRunDetail.tsx
+++ b/ui/src/components/workflow/WorkflowRunDetail.tsx
@@ -5,6 +5,7 @@ import {
CheckOutlined as CheckOutlinedIcon,
ClockCircleOutlined as ClockCircleOutlinedIcon,
CloseCircleOutlined as CloseCircleOutlinedIcon,
+ DownloadOutlined as DownloadOutlinedIcon,
RightOutlined as RightOutlinedIcon,
SelectOutlined as SelectOutlinedIcon,
SettingOutlined as SettingOutlinedIcon,
@@ -188,6 +189,34 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
);
};
+ const handleDownloadClick = () => {
+ const NEWLINE = "\n";
+ const logstr = listData
+ .map((group) => {
+ return (
+ group.name +
+ NEWLINE +
+ group.records
+ .map((record) => {
+ const datetime = dayjs(record.timestamp).format("YYYY-MM-DDTHH:mm:ss.SSSZ");
+ const level = record.level;
+ const message = record.message.trim().replaceAll("\r", "\\r").replaceAll("\n", "\\n");
+ return `[${datetime}] [${level}] ${message}`;
+ })
+ .join(NEWLINE)
+ );
+ })
+ .join(NEWLINE + NEWLINE);
+ const blob = new Blob([logstr], { type: "text/plain" });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = `certimate_workflow_run_#${runId}_logs.txt`;
+ a.click();
+ URL.revokeObjectURL(url);
+ a.remove();
+ };
+
return (
<>
{t("workflow_run.logs")}
@@ -210,6 +239,15 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
icon: ,
onClick: () => setShowWhitespace(!showWhitespace),
},
+ {
+ type: "divider",
+ },
+ {
+ key: "download-logs",
+ label: t("workflow_run.logs.menu.download_logs"),
+ icon: ,
+ onClick: handleDownloadClick,
+ },
],
}}
trigger={["click"]}
diff --git a/ui/src/i18n/locales/en/nls.workflow.runs.json b/ui/src/i18n/locales/en/nls.workflow.runs.json
index e177dcb3..c48e54b7 100644
--- a/ui/src/i18n/locales/en/nls.workflow.runs.json
+++ b/ui/src/i18n/locales/en/nls.workflow.runs.json
@@ -21,6 +21,7 @@
"workflow_run.logs": "Logs",
"workflow_run.logs.menu.show_timestamps": "Show timestamps",
"workflow_run.logs.menu.show_whitespaces": "Show whitespaces",
+ "workflow_run.logs.menu.download_logs": "Download logs",
"workflow_run.artifacts": "Artifacts",
"workflow_run_artifact.props.type": "Type",
diff --git a/ui/src/i18n/locales/zh/nls.workflow.runs.json b/ui/src/i18n/locales/zh/nls.workflow.runs.json
index 79d46abe..ce3ac15d 100644
--- a/ui/src/i18n/locales/zh/nls.workflow.runs.json
+++ b/ui/src/i18n/locales/zh/nls.workflow.runs.json
@@ -21,6 +21,7 @@
"workflow_run.logs": "日志",
"workflow_run.logs.menu.show_timestamps": "显示日期时间",
"workflow_run.logs.menu.show_whitespaces": "显示转义换行符",
+ "workflow_run.logs.menu.download_logs": "下载日志",
"workflow_run.artifacts": "输出产物",
"workflow_run_artifact.props.type": "类型",