feat: add compact workflow graph variant

This commit is contained in:
lda
2026-07-09 03:55:15 +07:00 Verified
parent 6bc0946baf
commit 6300d682ee
2 changed files with 33 additions and 2 deletions
@@ -83,6 +83,33 @@ describe("WorkflowGraphStage", () => {
expect(screen.getByLabelText("workflow graph proof")).toHaveTextContent("JSON-RPC captured"); expect(screen.getByLabelText("workflow graph proof")).toHaveTextContent("JSON-RPC captured");
}); });
it("marks compact graph mode and suppresses proof chips", () => {
render(
<WorkflowGraphStage
execution={{ completedNodeIds: ["read_docs", "build_report"], currentNodeId: "review_issues" }}
selectedNodeId={null}
selectNode={vi.fn()}
variant="compact"
proof={{ runId: "run_recorded_lda_report", traceLabel: "5 workflow nodes", evidenceLabel: "JSON-RPC evidence" }}
/>,
);
expect(screen.getByLabelText("workflow graph")).toHaveAttribute("data-graph-variant", "compact");
expect(screen.queryByLabelText("workflow graph proof")).not.toBeInTheDocument();
});
it("keeps full graph mode as the default", () => {
render(
<WorkflowGraphStage
execution={{ completedNodeIds: ["read_docs"], currentNodeId: "build_report" }}
selectedNodeId={null}
selectNode={vi.fn()}
/>,
);
expect(screen.getByLabelText("workflow graph")).toHaveAttribute("data-graph-variant", "full");
});
it("shows unavailable runId fallback when proof runId is null", () => { it("shows unavailable runId fallback when proof runId is null", () => {
render( render(
<WorkflowGraphStage <WorkflowGraphStage
@@ -41,6 +41,7 @@ type WorkflowGraphStageProps = {
readonly selectedNodeId: string | null; readonly selectedNodeId: string | null;
readonly selectNode: (nodeId: string) => void; readonly selectNode: (nodeId: string) => void;
readonly proof?: WorkflowGraphProof; readonly proof?: WorkflowGraphProof;
readonly variant?: "full" | "compact";
}; };
const executionStateForNode = ( const executionStateForNode = (
@@ -63,20 +64,23 @@ export const WorkflowGraphStage = ({
selectedNodeId, selectedNodeId,
selectNode, selectNode,
proof, proof,
variant = "full",
}: WorkflowGraphStageProps) => { }: WorkflowGraphStageProps) => {
const markerPrefix = useId().replaceAll(":", ""); const markerPrefix = useId().replaceAll(":", "");
const arrowMarkerId = `${markerPrefix}-workflow-arrow`; const arrowMarkerId = `${markerPrefix}-workflow-arrow`;
const activeArrowMarkerId = `${markerPrefix}-workflow-arrow-active`; const activeArrowMarkerId = `${markerPrefix}-workflow-arrow-active`;
return ( return (
<div className="workflow-graph-stage" role="group" aria-label="workflow graph"> <div className="workflow-graph-stage" role="group" aria-label="workflow graph" data-graph-variant={variant}>
<div className="workflow-graph-stage__legend" aria-hidden="true"> <div className="workflow-graph-stage__legend" aria-hidden="true">
<span><i data-state="completed" />Completed</span> <span><i data-state="completed" />Completed</span>
<span><i data-state="current" />Current</span> <span><i data-state="current" />Current</span>
<span><i data-state="interrupt" />Human boundary</span> <span><i data-state="interrupt" />Human boundary</span>
</div> </div>
{proof && ( {/* Compact mode is used beside interrupt contracts; proof chips would
compete with the contract and outcome panel in that narrow layout. */}
{variant === "full" && proof && (
<div className="workflow-graph-stage__proof" aria-label="workflow graph proof"> <div className="workflow-graph-stage__proof" aria-label="workflow graph proof">
<span><b>Run</b><code>{proof.runId ?? "run unavailable"}</code></span> <span><b>Run</b><code>{proof.runId ?? "run unavailable"}</code></span>
<span><b>Trace</b>{proof.traceLabel}</span> <span><b>Trace</b>{proof.traceLabel}</span>