Uh oh!
There was an error while loading. Please reload this page.
feat(ui): add aggregate Dag schedule overview view (#68532) - #68547
feat(ui): add aggregate Dag schedule overview view (#68532)#68547anmolxlight wants to merge 4 commits into
Conversation
64767cb to
a33d4bdCompare…ssion Address failures of CI image checks / Static checks on PR apache#68547: 1. Regenerate airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml and the airflow-core/src/airflow/ui/openapi-gen/ TS client files. The prek generate-openapi-spec hook wanted to reorder /ui/teams and /ui/dag_schedule_overview, expand the multi-line docstring for get_dag_schedule_overview, switch minimum: 0 to minimum: 0.0 (Pydantic v2 float coercion), and drop start_*_seconds / end_*_seconds from the DagScheduleOverviewEntry required list. This change matches what prek would have done in CI. 2. Move the @provide_session 'session' argument to keyword-only in the autouse setup fixture of test_dag_schedule_overview.py. New @provide_session functions must declare session after a bare '*' per scripts/ci/prek/check_provide_session_kwargs.py. Local verification: - prek run --files <changed files>: passed - prek run mypy-airflow-core --files <changed files>: passed - prek run check-no-new-provide-session-positional --files <test file>: passed - uv run --project airflow-core pytest test_dag_schedule_overview.py: 11/11 passed
choo121600
commented
Jun 15, 2026
Could you please attach a short recording of this feature following the PR template? It would be helpful for the review. |
Adds a 24h Gantt-style view that answers the question `across my whole deployment, when during the day does each Dag usually run?` — a complement to the per-Dag Gantt view, which only shows a single run. Backend * New `/ui/dag_schedule_overview` endpoint that aggregates the most-recent successful Dag runs per Dag and returns mean/median start/end times-of-day in UTC, plus duration statistics. * Optional `run_after_gte` / `run_after_lte` window and `dag_id_pattern` / `dag_display_name_pattern` filters. * 11 backend tests covering 200/401/403, all-three-dag fixture, morning/evening/no-runs statistics, FAILED-run exclusion, and the filter / window edge cases. * OpenAPI YAML updated, `pnpm codegen` regenerated. Frontend * New `/dags/schedule` page (one row per Dag, mean start→end bar across a 24h tick rail, hover tooltip with mean+median start, end, duration, and recent-runs range). * New `Schedule Overview` sidebar nav link. * i18n keys for English locale.
…ssion Address failures of CI image checks / Static checks on PR apache#68547: 1. Regenerate airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml and the airflow-core/src/airflow/ui/openapi-gen/ TS client files. The prek generate-openapi-spec hook wanted to reorder /ui/teams and /ui/dag_schedule_overview, expand the multi-line docstring for get_dag_schedule_overview, switch minimum: 0 to minimum: 0.0 (Pydantic v2 float coercion), and drop start_*_seconds / end_*_seconds from the DagScheduleOverviewEntry required list. This change matches what prek would have done in CI. 2. Move the @provide_session 'session' argument to keyword-only in the autouse setup fixture of test_dag_schedule_overview.py. New @provide_session functions must declare session after a bare '*' per scripts/ci/prek/check_provide_session_kwargs.py. Local verification: - prek run --files <changed files>: passed - prek run mypy-airflow-core --files <changed files>: passed - prek run check-no-new-provide-session-positional --files <test file>: passed - uv run --project airflow-core pytest test_dag_schedule_overview.py: 11/11 passed
The OpenAPI spec regen in the previous commit changed the DagScheduleOverviewEntry
schema: start_*_seconds, end_*_seconds, duration_*_seconds, and their median
counterparts were moved out of the 'required' list in Pydantic v2. The auto-generated
TS type now marks these fields as 'number | null | undefined'.
The hand-written formatTooltipBody in scheduleOverviewUtils.ts only accepted
'number | null', causing:
error TS2345 in ScheduleOverviewRow.tsx:44
Argument of type 'DagScheduleOverviewEntry' is not assignable to parameter
of type '{ readonly end_mean_seconds: number | null; ... }'
Types of property 'end_mean_seconds' are incompatible.
Type 'number | null | undefined' is not assignable to type 'number | null'.
Widen the formatTooltipBody parameter to allow 'undefined' for the now-optional
duration/start/end fields. The downstream helpers (formatSecondsAsClock,
formatDurationSeconds) already accept undefined and render it as em-dash.
Local verification:
- prek run ts-compile-lint-ui --files <changed file>: Passed
- prek run --files <changed file>: Passed…nd params The previous commit added '| undefined' to the duration/start/end types in formatTooltipBody's parameter, but TypeScript's structural typing is stricter about optional vs required properties. Since DagScheduleOverviewEntry marks end_mean_seconds / end_median_seconds / start_mean_seconds / start_median_seconds as '?: number | null' (truly optional, undefined comes from optionality, not the value type), the parameter must mirror that with '?:' on the same fields. '?: number | null' and ': number | null | undefined' are NOT structurally assignable in either direction under TypeScript's strictness here. Use '?: number | null' to match the auto-generated type shape. The downstream helpers (formatSecondsAsClock, formatDurationSeconds) still handle the undefined case and render em-dash. Local verification: - pnpm tsc --noEmit -p tsconfig.app.json: clean - prek run --files <changed file>: Passed - prek run ts-compile-lint-ui --files <changed file>: Passed
VID_20260615_232836_381.mp4Screen recording of the new Schedule Overview page: Shows the /dags/schedule page with the 24h UTC timeline bars, hover tooltips, and the filter working. |
a60f1d5 to
b3353f0CompareThere was a problem hiding this comment.
Based on the screen recording you attached, this appears to be somewhat inconsistent with the existing UI patterns.
I think we need more discussion in the issue before moving forward with an implementation. In particular, we should first align on whether this feature should be included at all, and if so, how it should be integrated into the UI (tab placement, design, UX, and overall approach).
Could you please close this PR for now? I'd prefer to continue the discussion in the issue first and revisit the implementation once we've reached agreement on the design.
Once we've aligned on the direction in the issue, I'd be happy to see this PR reopened.
jroachgolf84
commented
Jun 17, 2026
I don't think that this is a feature that should be implemented. See my comment from the issue: Not quite sure how this is useful:
If I run a DAG hourly, that would make the average noon. That's pretty useless IMO. Plus, I don't think we could make this robust enough to handle all the scheduling use-cases that Airflow offers. |
Fixes#68532
What
Adds a new
/dags/schedulepage that visualizes the typical (mean / median) start and end time of each Dag over a 24-hour timeline, aggregated from recent successful Dag runs. This complements the existing per-Dag Gantt view, which only shows a single run at a time. The new view operates at a different level: it aggregates across all Dags to answer "across my whole deployment, when during the day does each Dag usually run?"Why
Operators running many Dags currently have no at-a-glance way to see how scheduled load is distributed across the day. The new view makes the whole schedule visible at once, which helps to:
How
Backend
/ui/dag_schedule_overviewendpoint (inapi_fastapi/core_api/routes/ui/dag_schedule_overview.py) gated byrequires_access_dag(method="GET", access_entity=DagAccessEntity.RUN).DagScheduleOverviewService(api_fastapi/core_api/services/ui/dag_schedule_overview.py) that:DagRuns per dag, optionally scoped by arun_afterwindow,start_dateandend_datemapped to seconds-of-day in UTC, plus mean/median duration,dag_id_patternanddag_display_name_patternfilters.DagScheduleOverviewEntry+DagScheduleOverviewCollectionResponse(api_fastapi/core_api/datamodels/ui/dag_schedule_overview.py).tests/unit/api_fastapi/core_api/routes/ui/test_dag_schedule_overview.py: 200/401/403, all-three-dag fixture, morning/evening/no-runs statistics, FAILED-run exclusion, pattern filters, run_after window edges._private_ui.yamlupdated;pnpm codegenregenerated.Frontend
src/pages/DagsList/ScheduleOverview/mounted at/dags/schedulewith:Schedule Overview(FiBarChart2) on the main nav, alongsideDags.dags.scheduleOverview.*andcommon.nav.scheduleOverview(English locale).Verification
The two pre-existing vitest failures in
useTagFilter.test.tsxandLogs.test.tsxreproduce onmain(verified withgit stash), so they are unrelated to this PR.