mermaid workflow coloring
This commit is contained in:
@@ -57,6 +57,25 @@ export function diagram(src: string): HTMLElement {
|
||||
return el;
|
||||
}
|
||||
|
||||
const latest = new WeakMap<HTMLElement, number>();
|
||||
|
||||
export async function redraw(el: HTMLElement, src: string) {
|
||||
const id = next++;
|
||||
latest.set(el, id);
|
||||
try {
|
||||
const m = await load();
|
||||
const { svg } = await m.render(`mermaid-${id}`, src);
|
||||
if (latest.get(el) === id) {
|
||||
el.innerHTML = svg;
|
||||
}
|
||||
} catch (err) {
|
||||
if (latest.get(el) !== id) {
|
||||
return;
|
||||
}
|
||||
el.replaceChildren(h("pre", { class: "mermaid-source" }, src), h("div", { class: "mermaid-error" }, `diagram not rendered: ${errorText(err)}`));
|
||||
}
|
||||
}
|
||||
|
||||
async function render(el: HTMLElement, src: string) {
|
||||
try {
|
||||
const m = await load();
|
||||
|
||||
+28
-4
@@ -1,18 +1,33 @@
|
||||
import { get, type ByreEvent, type Schemas } 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";
|
||||
|
||||
type WorkflowRun = Schemas["WorkflowRun"];
|
||||
type RunStage = Schemas["WorkflowRunStage"];
|
||||
type Attempt = Schemas["StageAttempt"];
|
||||
|
||||
const stateColors: Record<RunStage["state"], [fill: string, stroke: string, text: string]> = {
|
||||
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: WorkflowRun): string {
|
||||
const css = getComputedStyle(document.documentElement);
|
||||
const v = (name: string) => 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) {
|
||||
@@ -113,6 +128,8 @@ export function mountWorkflow(root: HTMLElement): () => void {
|
||||
const list = h("div", { class: "workflow-body" });
|
||||
let run: WorkflowRun | undefined;
|
||||
let drawnRun = "";
|
||||
let drawnSrc = "";
|
||||
let drawn: HTMLElement | undefined;
|
||||
let error = "";
|
||||
let target = 0;
|
||||
let loading = false;
|
||||
@@ -161,6 +178,7 @@ export function mountWorkflow(root: HTMLElement): () => void {
|
||||
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;
|
||||
}
|
||||
@@ -178,9 +196,15 @@ export function mountWorkflow(root: HTMLElement): () => void {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user