Skip to content

feat: add repeat policy child runs for the timeline - #2550

Merged
yohamta0 merged 4 commits into
dagucloud:mainfrom
sohamsshah:feat/timeline-repeat-policy-child-runs
Aug 14, 2026
Merged

yohamta0 merged 4 commits into
dagucloud:mainfrom
sohamsshah:feat/timeline-repeat-policy-child-runs

Conversation

@sohamsshah

@sohamsshah sohamsshah commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add repeat policy child runs for the timeline

Changes

Behavior

  1. Repeat-policy child runs on the timeline — Non-parallel steps with subRunsRepeated expand archived + current children as [...subRunsRepeated, ...subRuns].
  2. Parallel unchanged — Parallel steps still expand only subRuns; archived parallel batches are ignored even if subRunsRepeated is set.
  3. Ordinary child calls stay collapsed — Steps with only subRuns (no subRunsRepeated, not parallel) do not expand.
  4. Click/keyboard drill-down — Sub-DAG bars open via onOpenSubRun (or SubRunOpenProvider); Enter works; parent step bars are not buttons.

Files

File Change
timelineItems.ts getTimelineSubRuns / hasTimelineSubRuns updated for the rules above
TimelineChart.tsx Optional onOpenSubRun; new TimelineBar with click/keyboard open
TimelineChart.test.tsx Coverage for expand order, parallel vs ordinary, click/Enter, tooltips
timelineItems.test.ts Unit tests for archive-then-current labels, parallel isolation, mixed DAGs, missing timing

Related Issues

Closes #2389

Checklist

  • Code follows the project style guidelines
  • Self-review of the code has been performed
  • Tests have been added or updated as needed
  • Documentation has been updated as needed
  • Changes have been tested locally

Summary by cubic

Adds repeat-policy child runs to the timeline and makes sub-DAG bars openable to drill into child runs. Previously only parallel children expanded and bars were non-interactive; now repeat steps expand archived then current children and bars open via click or keyboard.

  • Non-parallel steps with a repeat policy expand children as [archived subRunsRepeated, then current subRuns] with numbered labels; if no archived runs exist yet, current runs still expand.
  • Parallel steps still expand only subRuns; archived parallel batches are ignored. Ordinary non-parallel calls without a repeat policy remain collapsed even if subRuns exist.
  • Sub-DAG bars are focusable buttons with aria-labels and open on click, Enter, or Space; parent step bars are not buttons. Tooltips are unchanged.
  • TimelineChart accepts optional onOpenSubRun (defaults to the open-subrun context). DAGGraph forwards this prop, and DAGExecutionHistory wires it to navigate to the selected child run.
  • Fulfills timeline requirements in feat(ui): show repeat-policy child DAG runs in the timeline #2389.

Written for commit ee8688d. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Timeline charts now display repeated and parallel sub-runs together with clearer ordering and numbered labels.
    • Sub-DAG timeline bars can be opened by clicking or using the keyboard.
    • Parent timeline bars remain non-interactive where appropriate.
    • Existing tooltips and run-status details are preserved.
  • Bug Fixes

    • Improved visibility and handling of archived, repeated, and mixed sub-run entries in timeline views.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

TimelineChart now displays repeat-policy child DAG runs alongside regular and parallel child runs. Valid child bars support click and keyboard activation through an optional or context-provided sub-run opener. Tests cover ordering, filtering, rendering, tooltips, and interactions.

Changes

Timeline sub-run expansion and navigation

Layer / File(s) Summary
Expand repeat-policy child runs
ui/src/features/dags/components/visualization/timelineItems.ts, ui/src/features/dags/components/visualization/__tests__/timelineItems.test.ts, ui/src/features/dags/components/visualization/__tests__/TimelineChart.test.tsx
getTimelineSubRuns now includes regular parallel runs and combines regular with archived repeated runs for non-parallel nodes. Tests validate ordering, labels, metadata, filtering, and coexistence.
Activate child timeline bars
ui/src/features/dags/components/visualization/TimelineChart.tsx, ui/src/features/dags/components/visualization/__tests__/TimelineChart.test.tsx
TimelineBar adds ref forwarding and button semantics for valid sub-DAG runs. Click and Enter activation open the selected sub-run while preserving existing handlers. Parent bars remain non-interactive.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant TimelineChart
  participant TimelineBar
  participant onOpenSubRun
  TimelineChart->>TimelineBar: Render child run with resolved opener
  User->>TimelineBar: Click or press Enter
  TimelineBar->>onOpenSubRun: Open sub-DAG name and run ID
Loading

Possibly related PRs

  • dagucloud/dagu#2093: Both changes update timeline rendering and interaction for parallel or repeated sub-DAG runs.
  • dagucloud/dagu#2533: Both changes use shared sub-run navigation callbacks and child-run opening flows.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes meet issue #2389 by rendering repeated child runs with timing and status, enabling navigation, and preserving parallel and ordinary behavior.
Out of Scope Changes check ✅ Passed The changes are limited to timeline expansion, sub-run navigation, and related tests required by issue #2389.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly and concisely describes the main change: adding repeat-policy child runs to the timeline.
Description check ✅ Passed The description includes all required sections and clearly explains the behavior changes, tests, related issue, and checklist status.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ui/src/features/dags/components/visualization/TimelineChart.tsx`:
- Around line 303-337: Complete the custom button behavior on the openable
timeline bar: add an aria-label containing the child DAG name and run ID, update
handleKeyDown to activate on both Enter and Space while preventing Space
scrolling, and add a visible focus style when the bar is focused. Extend the
relevant tests to verify the accessible name and Space-key activation.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fa02467c-5e5e-4757-9ac0-236c7f79508c

📥 Commits

Reviewing files that changed from the base of the PR and between 6b0b746 and d56827d.

📒 Files selected for processing (4)
  • ui/src/features/dags/components/visualization/TimelineChart.tsx
  • ui/src/features/dags/components/visualization/__tests__/TimelineChart.test.tsx
  • ui/src/features/dags/components/visualization/__tests__/timelineItems.test.ts
  • ui/src/features/dags/components/visualization/timelineItems.ts

Comment on lines +303 to +337
function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {
onKeyDown?.(event);
if (!canOpen || event.key !== 'Enter') {
return;
}
event.preventDefault();
if (!openSubRun || !item.dagRunId) {
return;
}
openSubRun({
name: item.dagName || item.parentStepName || item.label,
dagRunId: item.dagRunId,
});
}

return (
<div
ref={ref}
data-testid={`timeline-bar-${item.id}`}
{...props}
role={canOpen ? 'button' : undefined}
tabIndex={canOpen ? 0 : undefined}
className={`absolute h-5 rounded transition-opacity hover:opacity-80 ${
canOpen ? 'cursor-pointer' : ''
} ${isActive ? 'animate-pulse' : ''} ${className ?? ''}`}
style={{
left: `calc(${leftPercent}% + 130px)`,
width: `calc(${Math.max(widthPercent, 0.5)}% - 130px)`,
minWidth: '4px',
backgroundColor: colors.bg,
borderLeft: `2px solid ${colors.border}`,
...style,
}}
onClick={canOpen ? handleClick : onClick}
onKeyDown={canOpen ? handleKeyDown : onKeyDown}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Implement complete custom button behavior.

The openable sub-DAG bar has no accessible name. Screen readers announce only “button”.

The handler activates only on Enter. A custom role="button" control must also support Space activation and show a visible focus state.

Add an aria-label that includes the child DAG name and run ID. Handle Space according to button behavior. Add tests for the accessible name and Space activation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/features/dags/components/visualization/TimelineChart.tsx` around lines
303 - 337, Complete the custom button behavior on the openable timeline bar: add
an aria-label containing the child DAG name and run ID, update handleKeyDown to
activate on both Enter and Space while preventing Space scrolling, and add a
visible focus style when the bar is focused. Extend the relevant tests to verify
the accessible name and Space-key activation.

@yohamta0 yohamta0 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening the PR. First pass looks close. I left a few notes inline. Tests and ESLint pass; pnpm typecheck still fails.

widthPercent={widthPercent}
colors={colors}
isActive={isActive}
openSubRun={openSubRun}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useOpenSubRun() can return null here, but the prop does not accept it, so typecheck fails. Passing undefined should do it:

Suggested change
openSubRun={openSubRun}
openSubRun={openSubRun ?? undefined}

Comment on lines +47 to +51
const repeated = node.subRunsRepeated || [];
if (repeated.length === 0) {
return [];
}
return [...repeated, ...(node.subRuns || [])];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this misses the first run. subRunsRepeated is empty until run two starts, so if the policy stops after one run, its child never appears. Can we key this off repeatPolicy instead?

Suggested change
const repeated = node.subRunsRepeated || [];
if (repeated.length === 0) {
return [];
}
return [...repeated, ...(node.subRuns || [])];
if (!node.step.repeatPolicy?.repeat) {
return [];
}
return [...(node.subRunsRepeated || []), ...(node.subRuns || [])];

Please add a test for one current subRuns entry with repeatPolicy set and no subRunsRepeated entries.

function TimelineChart({ status, onOpenSubRun }: Props) {
const remoteNode = useRemoteNode();
const openSubRunFromContext = useOpenSubRun();
const openSubRun = onOpenSubRun ?? openSubRunFromContext;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DAGGraph renders this without an opener or provider, so child bars in execution history are not clickable. Can we pass the opener through DAGGraph and test that path?

@yohamta0 yohamta0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀 Thanks a lot for adding support for child runs for the timeline!

@yohamta0
yohamta0 merged commit c00aef6 into dagucloud:main Aug 14, 2026
11 checks passed
@sohamsshah

sohamsshah commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Apologies for delay in PR comment resolution.
And Thanks @yohamta0 for pushing out my part of fixes.

Glad to see the purple on my PR :))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ui): show repeat-policy child DAG runs in the timeline

2 participants