DurableDashboard.Components.Workflow.TimelineTab (DurableDashboard v0.1.0-rc)

Copy Markdown View Source

Timeline tab — absolute-time Gantt of step executions for a single workflow run.

Model

  • X-axis is wall-clock time spanning the workflow's run window.
  • One row per step name; multiple step_execs for the same name (suspend/resume cycles, retries) render as multiple segments on that row at their actual started_at positions.
  • This is what makes parallel blocks read as parallel — three children that started together overlap horizontally on three rows. Sequential steps appear left-to-right. Suspensions are visible as gaps in the row.

Tiny-bar visibility

Naively scaling 4ms inside a 28s window produces an invisible 1px sliver. Bars carry an inline width: max(6px, X%) so they're always visible regardless of how wide the workflow window is. The trailing duration in the gutter (active 11ms · waited 28s) plus the per-bar tooltip carry the precise numbers.

Window calculation

  • window_start = earliest started_at across all step_execs.
  • window_end:
    • now when the workflow is in-flight (live grow).
    • else the latest real timestamp we have: completed_at || updated_at || started_at per row.

Uses workflow_live?/1 (driven off the workflow's status, not step statuses) to avoid stale :waiting step_exec rows from durable's wait/resume model pulling the window forward to "now" indefinitely.

Live updates

WorkflowLive ticks assigns.now every 500ms while the workflow is in-flight. Running segments grow toward now; the bar's width transitions over 150ms for smooth animation.

Click to inspect

Each row is a button: clicking it expands an inline detail panel (timing, I/O, error, and the step's captured logs) directly under the bar — a lightweight in-place inspector so issues are spottable without leaving the timeline. Multiple rows can be open at once. Stateful (the open set), so this is a LiveComponent.

Pure HEEx + CSS for the chart — no SVG, no React island.