mermaid workflow coloring

This commit is contained in:
Ian Gulliver
2026-10-16 11:25:53 -07:00
parent 6abd1d8cfa
commit 4dff9b7471
8 changed files with 98 additions and 11 deletions
+28 -4
View File
@@ -1,13 +1,27 @@
import { get } from "./api.js";
import { errorText, h, replace } from "./dom.js";
import { markdown } from "./markdown.js";
import { diagram } from "./mermaid.js";
import { diagram, redraw } from "./mermaid.js";
import { findTask, focusTask, onEach, state } from "./state.js";
const stateColors = {
waiting: ["--surface", "--border", "--muted"],
running: ["--accent-tint", "--accent", "--text"],
idle: ["--warn-tint", "--warn", "--text"],
finished: ["--ok-tint", "--ok", "--text"],
merged: ["--ok-tint", "--ok", "--text"],
cleaned_up: ["--ok-tint", "--ok", "--text"],
discarded: ["--danger-tint", "--danger", "--text"],
};
function graph(run) {
const css = getComputedStyle(document.documentElement);
const v = (name) => css.getPropertyValue(name).trim();
const id = new Map(run.stages.map((s, i) => [s.name, `s${i}`]));
const lines = ["flowchart TD"];
for (const [state, [fill, stroke, text]] of Object.entries(stateColors)) {
lines.push(` classDef ${state} fill:${v(fill)},stroke:${v(stroke)},color:${v(text)}`);
}
for (const s of run.stages) {
lines.push(` ${id.get(s.name)}["${s.name.replaceAll('"', "#quot;")}"]`);
lines.push(` ${id.get(s.name)}["${s.name.replaceAll('"', "#quot;")}"]:::${s.state}`);
}
for (const s of run.stages) {
for (const a of s.after) {
@@ -75,6 +89,8 @@ export function mountWorkflow(root) {
const list = h("div", { class: "workflow-body" });
let run;
let drawnRun = "";
let drawnSrc = "";
let drawn;
let error = "";
let target = 0;
let loading = false;
@@ -122,6 +138,7 @@ export function mountWorkflow(root) {
replace(head);
replace(graphBox);
drawnRun = "";
drawn = undefined;
replace(list, h("div", { class: "empty" }, task ? "This task isn't part of a workflow run." : "No task selected."));
return;
}
@@ -134,9 +151,16 @@ export function mountWorkflow(root) {
return;
}
replace(head, h("span", { class: "workflow-name" }, run.name), h("span", { class: "workflow-title" }, run.title), h("span", { class: `workflow-state ${run.finished ? "finished" : "running"}` }, run.finished ? "workflow finished" : "in progress"));
if (drawnRun !== run.run) {
const src = graph(run);
if (drawnRun !== run.run || !drawn) {
drawnRun = run.run;
replace(graphBox, diagram(graph(run)));
drawnSrc = src;
drawn = diagram(src);
replace(graphBox, drawn);
}
else if (drawnSrc !== src) {
drawnSrc = src;
void redraw(drawn, src);
}
replace(list, run.brief.trim() ? h("details", { class: "workflow-brief" }, h("summary", {}, "Brief"), markdown(run.brief, "md", { taskId: task.id })) : null, h("ol", { class: "workflow-stages" }, ...run.stages.map((s) => stageCard(run, s))));
};