diff --git a/frontend/src/views/Dashboard/Dashboard.js b/frontend/src/views/Dashboard/Dashboard.js
index 56228e5..6af2df5 100644
--- a/frontend/src/views/Dashboard/Dashboard.js
+++ b/frontend/src/views/Dashboard/Dashboard.js
@@ -483,9 +483,9 @@ export function useDashboard() {
}
function statusClass(value) {
- return value === "active"
+ return value === "active" || value === "success"
? "success"
- : value === "error"
+ : value === "error" || value === "failed"
? "danger"
: "warning";
}
diff --git a/frontend/src/views/Dashboard/Dashboard.test.js b/frontend/src/views/Dashboard/Dashboard.test.js
index 6c07aaa..4d668dd 100644
--- a/frontend/src/views/Dashboard/Dashboard.test.js
+++ b/frontend/src/views/Dashboard/Dashboard.test.js
@@ -257,3 +257,51 @@ test("settingsReadEditSaveContract", async (t) => {
assert.deepEqual(submitted.notification.recipients, ["owner@example.test"]);
assert.deepEqual(submitted.notification.retry_intervals_secs, [30, 120, 600]);
});
+
+
+test("statusClass", async (t) => {
+ const { state } = await setup(t, () => verifiedResponse());
+ for (const status of ["active", "success"]) {
+ assert.equal(state.statusClass(status), "success");
+ }
+ for (const status of ["error", "failed"]) {
+ assert.equal(state.statusClass(status), "danger");
+ }
+ for (const status of ["running", "queued", "cancelled", "unknown", null]) {
+ assert.equal(state.statusClass(status), "warning");
+ }
+});
+
+test("auditStatusRendering", async () => {
+ const { readFile } = await import("node:fs/promises");
+ const { compileTemplate } = await import("@vue/compiler-sfc");
+ const { renderToString } = await import("@vue/server-renderer");
+ const { createSSRApp } = await import("vue");
+ const source = await readFile(new URL("./Dashboard.vue", import.meta.url), "utf8");
+ const start = source.indexOf('", start) + "".length;
+ const compiled = compileTemplate({
+ source: source.slice(start, end),
+ filename: "AuditStatus.vue",
+ id: "audit-status-regression",
+ compilerOptions: { mode: "function" },
+ });
+ assert.deepEqual(compiled.errors, []);
+ const Vue = await import("vue");
+ const render = new Function("Vue", compiled.code)(Vue);
+ for (const status of ["running", "queued", "cancelled", "unknown"]) {
+ const html = await renderToString(createSSRApp({
+ render,
+ setup: () => ({
+ auditLogs: [{ id: status, action: "test", status, message: "test" }],
+ auditActionLabel: (value) => value,
+ statusClass: () => "warning",
+ taskStatusLabels: { [status]: `label-${status}` },
+ displayLabel: (labels, value) => labels[value],
+ }),
+ }));
+ assert.match(html, new RegExp(`label-${status}`));
+ assert.doesNotMatch(html, /danger/);
+ }
+});
diff --git a/frontend/src/views/Dashboard/Dashboard.vue b/frontend/src/views/Dashboard/Dashboard.vue
index 9a8add0..b80113d 100644
--- a/frontend/src/views/Dashboard/Dashboard.vue
+++ b/frontend/src/views/Dashboard/Dashboard.vue
@@ -253,7 +253,10 @@ const {
{{ auditActionLabel(item.action) }}
{{ item.message || item.resource_type }}
- {{ item.status === "success" ? "成功" : "失败" }}
+ {{ item.status === "success" ? "成功" : "失败" }}
+
+ {{ displayLabel(taskStatusLabels, item.status) }}
+