feat: render factual horizontal presentation graph

This commit is contained in:
lda
2026-07-12 13:32:57 +07:00 Verified
parent 24d53276b6
commit 92ba1dcf70
11 changed files with 304 additions and 323 deletions
@@ -95,6 +95,19 @@ describe("buildWorkflowGraph", () => {
expect(okEdge?.label).toBe("ok");
});
it("accepts a presentation label override without changing node refs", () => {
const model = buildWorkflowGraph(samplePlan, {
label: (node) => node.id === "open" ? "Open page" : undefined,
});
const openNode = model.nodes.find((node) => node.id === "open");
expect(openNode?.data.label).toBe("Open page");
expect(openNode?.data.nodeRef).toBe("local.browser_click.open_click_page");
expect(model.nodes.find((node) => node.id === "wait")?.data.label).toBe(
"wait_for_click",
);
});
it("keeps the default layout top-to-bottom", () => {
const model = buildWorkflowGraph(samplePlan);
const open = model.nodes.find((node) => node.id === "open");
+9 -3
View File
@@ -42,9 +42,10 @@ export type WorkflowGraphLayoutOptions = {
readonly nodeHeight?: number;
readonly nodesep?: number;
readonly ranksep?: number;
readonly label?: (node: Readonly<Record<string, unknown>>) => string | undefined;
};
const DEFAULT_LAYOUT: Required<WorkflowGraphLayoutOptions> = {
const DEFAULT_LAYOUT: Required<Omit<WorkflowGraphLayoutOptions, "label">> = {
direction: "TB",
nodeWidth: 180,
nodeHeight: 60,
@@ -73,7 +74,12 @@ const mapNodeKind = (type: string): WorkflowGraphNodeKind => {
}
};
const buildLabel = (node: Record<string, unknown>): string => {
const buildLabel = (
node: Record<string, unknown>,
labelOverride?: WorkflowGraphLayoutOptions["label"],
): string => {
const overriddenLabel = labelOverride?.(node);
if (overriddenLabel) return overriddenLabel;
const type = node.type as string;
if (type === "end") return (node.outcome as string) ?? "End";
if (type === "condition") return "Condition";
@@ -137,7 +143,7 @@ export const buildWorkflowGraph = (
data: {
nodeId: id,
kind: mapNodeKind(node.type as string),
label: buildLabel(node),
label: buildLabel(node, layout.label),
nodeRef: (node.node as string | null) ?? null,
raw: node as Record<string, unknown>,
},