Skip to content

Dag run breadcrumb switcher - #74471

Merged
bbovenzi merged 6 commits into
apache:mainfrom
astronomer:dag-run-breadcrumb-switcher
Oct 8, 2026
Merged

bbovenzi merged 6 commits into
apache:mainfrom
astronomer:dag-run-breadcrumb-switcher

Conversation

@bbovenzi

@bbovenzi bbovenzi commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Extend our breadcrumb dropdown search to apply to both Dags and Dag Runs. This makes it easier to switch between runs especially on the Graph view and when no runs are yet selected. Also fixed an issue with the dropdown that always fetched the data on every dropdown open and forced a spinner to show up before results.

Screenshot 2026-10-08 at 2 17 09 PM
Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)
    Claude Opus 5

  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

Switching to a different run meant leaving the page you were looking at, or
digging the run picker out of the graph view's options popover. The run is
already named in the breadcrumb next to the Dag it belongs to, so that is
where picking a different one belongs — the same place, and the same two-part
control, the Dag level already uses.
Both panels asked react-select to load their options from a mount effect, and
both unmount when the panel closes, so every open was a round trip that started
as a spinner over an empty list — including when the same Dags or runs had just
been on screen a moment earlier.

What a panel lists is not the panel's own business: it belongs to the level that
opens it, which stays on the page. From there it is loaded before anyone opens
anything, and the run list keeps up with the page's auto-refresh.

Giving the run level a permanent place in the bar follows from the same idea: the
breadcrumb is where runs are switched, so every page of a Dag can reach the
latest run, not only the pages that already have one in the URL.
Neither panel has anything to wait for any more: what they list is loaded by the
breadcrumb level that opens them, and a typed search replaces the results once it
answers rather than blanking them first. A spinner over a list that is already
there only reads as the panel losing its place.

The run level also had to declare the `dag` namespace to name itself. It had not
needed to while it only appeared on task pages without a run; now that it is on
every page of a Dag, it was showing its translation key.
Neither search is reusable — each has exactly one caller, the switcher button it
belongs to — so sitting in `components/` only put distance between the two halves
of one control. The query that feeds a panel was a hook of its own for the same
reason, read once, in a component short enough to hold it.

Only the combo-box chrome is genuinely shared, and a folder holding one file
behind a re-export is not a module.
Folding the option builders and query constants into the panel components left
each one exporting things that are not components, which costs the file its fast
refresh. They are shared between a panel and the level that opens it, so they
belong beside both rather than inside either.
Switching runs from a mapped task built its own path and sent `/tasks/<id>`,
which has no row once the task is expanded, so the page it landed on reported no
task instance found. It also dropped whichever tab was open. The shared builder
the grid and keyboard navigation already use handles both, and knows to stop at
the list of instances.

Suppressing react-select's loading message as well as its spinner went too far:
on the first search after the input is cleared react-select empties the list
itself, and with nothing to say in that window it rendered no menu at all.

`checkPendingRuns` does not scale the refresh interval back, it switches it off,
so the list stopped noticing runs once the current ones finished — and while any
run was active, every page of a Dag polled for a panel nobody had opened. The
panel is the only thing that reads this list, so it is also the only thing that
needs it kept current.

Rebuilding every option on each poll cost react-select the focused row, since it
tracks focus by reference: arrowing down and pressing Enter could open a
different run than the one highlighted.
@bbovenzi

bbovenzi commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

CI failure was already in main

@bbovenzi
bbovenzi merged commit e82b196 into apache:main Oct 8, 2026
87 of 88 checks passed
@bbovenzi
bbovenzi deleted the dag-run-breadcrumb-switcher branch October 8, 2026 21:57
@bbovenzi bbovenzi added this to the Airflow 3.4.0 milestone Oct 8, 2026
@bbovenzi bbovenzi added the backport-to-v3-4-test Backport to v3-4-test label Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:translations area:UI Related to UI/UX. For Frontend Developers. backport-to-v3-4-test Backport to v3-4-test translation:default

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants