Skip to content

Add support for favorite/pin dags to dashboard - #51264

Merged
pierrejeambrun merged 18 commits into
apache:mainfrom
PNL0:feature
Jul 7, 2025
Merged

pierrejeambrun merged 18 commits into
apache:mainfrom
PNL0:feature

Conversation

@PNL0

@PNL0 PNL0 commented May 31, 2025

Copy link
Copy Markdown
Contributor

The DAGs can be favorited in the DAGs list menu and are displayed in the Dashboard for easier access.
Information about the favorited DAGs is stored by user in the database and retrieved with API calls.

Dashboard view with 3 favorited DAGs (2 of them with previous DAG runs):

image

DAGs list menu view with some of the DAGs favorited:

image

cc @pierrejeambrun @bbovenzi

Closes: #45207

@jscheffl jscheffl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good in general in my view. Besides th i18n also DB migration is missing allowing to upgrade existing setups.

@jason810496 jason810496 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.

@pierrejeambrun pierrejeambrun 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.

Nice!

A few comments

@bbovenzi bbovenzi added this to the Airflow 3.1.0 milestone Jun 4, 2025
@PNL0

PNL0 commented Jun 5, 2025

Copy link
Copy Markdown
Contributor Author

Looks good in general in my view. Besides th i18n also DB migration is missing allowing to upgrade existing setups.

Thanks for the PR, LGMT.

FYI: https://github.com/apache/airflow/blob/main/contributing-docs/14_metadata_database_updates.rst for fixing database migrations

The DB migration should be present now. Let me know if anything is still missing or incomplete.

@pierrejeambrun pierrejeambrun 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.

Nice, thanks for all the hard work.

A few minor suggestions, but looking good overall.

@PNL0

PNL0 commented Jun 18, 2025

Copy link
Copy Markdown
Contributor Author

Hello @pierrejeambrun @bbovenzi,

I just pushed a new commit that corrects the majority of the problems you pointed out.
Let me know if everything is as expected and if I didn't miss any of your requests (except the 2 not resolved in the conversation).

@pierrejeambrun pierrejeambrun 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.

Nice!

We're getting closer, a few suggestions

PNL0 and others added 10 commits July 7, 2025 14:58
Create new tests for the favorite/unfavorite endpoints.
Add favorite button to the dag header. Other small fixes.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>
Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>
@PNL0

PNL0 commented Jul 7, 2025 •

Copy link
Copy Markdown
Contributor Author

There's a conflict on a generated file (because something must have been merged in main).

We need one more rebase and regeneration of front-end types and we should be good to merge.

pre-commit run ts-compile-format-lint-ui --all-files

Hello @pierrejeambrun,

I just rebased and regenerated the frontend types with pre-commit run ts-compile-lint-ui --all-files (the command you suggested wasn't working for me at least).
Let me know if everything is as expected.

@pierrejeambrun
pierrejeambrun merged commit c1a89ae into apache:main Jul 7, 2025
@boring-cyborg

boring-cyborg Bot commented Jul 7, 2025

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

@pierrejeambrun

Copy link
Copy Markdown
Member

Great job!

#protm

@pierrejeambrun

Copy link
Copy Markdown
Member

🎉 🎉 🎉

@bugraoz93

Copy link
Copy Markdown
Contributor

Great job! Congrats! I have been traveling so I couldn't take a look

@jscheffl

jscheffl commented Jul 7, 2025

Copy link
Copy Markdown
Contributor

As expressed earlier... Cool!

HsiuChuanHsu pushed a commit to HsiuChuanHsu/airflow that referenced this pull request Jul 10, 2025
* Add support for favorite/pin dags to dashboard, using localStorage.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Add support for favorite/pin dags to dashboard, persistent between sessions.

Co-authored-by: Mariana Isabel Marçal Santana mariana.marcal.santana@tecnico.ulisboa.pt

* Implement unit tests

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Add support for favorite/pin dags to dashboard.

The favorited DAGs by an user, are stored persistently in the database.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Added no favorites message.
Fix deleted DAGs being shown as favorites.
Review the display structure of the favorite DAGs in the dashboard.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Rebase and minor fixes.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Use i18n module and fix DB migration.
Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Review API endpoints

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Develop favorite filter.
Create new tests for the favorite/unfavorite endpoints.
Add favorite button to the dag header. Other small fixes.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Create new filters and update the frontend to use the UI version of get_dags.

* Small fixes.

* Small fixes.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Rebase and small fix

* Fix issues

* Fixed error in CI pipeline

* Fixed errors in CI pipeline.

* Fix CI pipeline issues.

* Regeneration of front-end types

---------

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>
stephen-bracken pushed a commit to stephen-bracken/airflow that referenced this pull request Jul 15, 2025
* Add support for favorite/pin dags to dashboard, using localStorage.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Add support for favorite/pin dags to dashboard, persistent between sessions.

Co-authored-by: Mariana Isabel Marçal Santana mariana.marcal.santana@tecnico.ulisboa.pt

* Implement unit tests

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Add support for favorite/pin dags to dashboard.

The favorited DAGs by an user, are stored persistently in the database.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Added no favorites message.
Fix deleted DAGs being shown as favorites.
Review the display structure of the favorite DAGs in the dashboard.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Rebase and minor fixes.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Use i18n module and fix DB migration.
Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Review API endpoints

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Develop favorite filter.
Create new tests for the favorite/unfavorite endpoints.
Add favorite button to the dag header. Other small fixes.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Create new filters and update the frontend to use the UI version of get_dags.

* Small fixes.

* Small fixes.

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>

* Rebase and small fix

* Fix issues

* Fixed error in CI pipeline

* Fixed errors in CI pipeline.

* Fix CI pipeline issues.

* Regeneration of front-end types

---------

Co-authored-by: Mariana Isabel Marçal Santana <mariana.marcal.santana@tecnico.ulisboa.pt>
pierrejeambrun added a commit to astronomer/airflow that referenced this pull request Sep 8, 2026
Two more callers of ``session.scalars(...).first()`` /
``session.execute(select(...)).first()`` were still missing an explicit
``.limit(1)``. Because SQLAlchemy 2.0's ``Result.first()`` does not add
one (unlike the legacy ``Query.first``), each call sends every matching
row to the Python process and discards all but the first. The favorite
existence check is bounded to a single row per (dag_id, user_id) by the
schema, but the previous-TI lookup scans every earlier matching TI.

Introduced independently of apache#52325's migration: get_previous_task_instance
came in apache#59712, unfavorite_dag's existence probe in apache#51264. Same
anti-pattern as the four sites apache#72554 fixes; the tests reuse the
``capture_orm_selects`` helper that PR introduces.
pierrejeambrun added a commit to astronomer/airflow that referenced this pull request Sep 8, 2026
Two more callers of ``session.scalars(...).first()`` /
``session.execute(select(...)).first()`` were still missing an explicit
``.limit(1)``. Because SQLAlchemy 2.0's ``Result.first()`` does not add
one (unlike the legacy ``Query.first``), each call sends every matching
row to the Python process and discards all but the first. The favorite
existence check is bounded to a single row per (dag_id, user_id) by the
schema, but the previous-TI lookup scans every earlier matching TI.

Introduced independently of apache#52325's migration: get_previous_task_instance
came in apache#59712, unfavorite_dag's existence probe in apache#51264. Same
anti-pattern as the four sites apache#72554 fixes; the tests reuse the
``capture_orm_selects`` helper that PR introduces.
pierrejeambrun added a commit to astronomer/airflow that referenced this pull request Sep 9, 2026
Two more callers of ``session.scalars(...).first()`` /
``session.execute(select(...)).first()`` were still missing an explicit
``.limit(1)``. Because SQLAlchemy 2.0's ``Result.first()`` does not add
one (unlike the legacy ``Query.first``), each call sends every matching
row to the Python process and discards all but the first. The favorite
existence check is bounded to a single row per (dag_id, user_id) by the
schema, but the previous-TI lookup scans every earlier matching TI.

Introduced independently of apache#52325's migration: get_previous_task_instance
came in apache#59712, unfavorite_dag's existence probe in apache#51264. Same
anti-pattern as the four sites apache#72554 fixes; the tests reuse the
``capture_orm_selects`` helper that PR introduces.
pierrejeambrun added a commit that referenced this pull request Sep 9, 2026
* Bound remaining single-row lookups with .limit(1)

Two more callers of ``session.scalars(...).first()`` /
``session.execute(select(...)).first()`` were still missing an explicit
``.limit(1)``. Because SQLAlchemy 2.0's ``Result.first()`` does not add
one (unlike the legacy ``Query.first``), each call sends every matching
row to the Python process and discards all but the first. The favorite
existence check is bounded to a single row per (dag_id, user_id) by the
schema, but the previous-TI lookup scans every earlier matching TI.

Introduced independently of #52325's migration: get_previous_task_instance
came in #59712, unfavorite_dag's existence probe in #51264. Same
anti-pattern as the four sites #72554 fixes; the tests reuse the
``capture_orm_selects`` helper that PR introduces.

* Also assert the returned row on the previous-TI regression test
vatsrahul1001 added a commit that referenced this pull request Sep 10, 2026
* Bound remaining single-row lookups with .limit(1)

Two more callers of ``session.scalars(...).first()`` /
``session.execute(select(...)).first()`` were still missing an explicit
``.limit(1)``. Because SQLAlchemy 2.0's ``Result.first()`` does not add
one (unlike the legacy ``Query.first``), each call sends every matching
row to the Python process and discards all but the first. The favorite
existence check is bounded to a single row per (dag_id, user_id) by the
schema, but the previous-TI lookup scans every earlier matching TI.

Introduced independently of #52325's migration: get_previous_task_instance
came in #59712, unfavorite_dag's existence probe in #51264. Same
anti-pattern as the four sites #72554 fixes; the tests reuse the
``capture_orm_selects`` helper that PR introduces.

* Also assert the returned row on the previous-TI regression test

(cherry picked from commit ff83957)

Co-authored-by: Pierre Jeambrun <pierrejbrun@gmail.com>
imrichardwu pushed a commit to imrichardwu/airflow that referenced this pull request Sep 11, 2026
* Bound remaining single-row lookups with .limit(1)

Two more callers of ``session.scalars(...).first()`` /
``session.execute(select(...)).first()`` were still missing an explicit
``.limit(1)``. Because SQLAlchemy 2.0's ``Result.first()`` does not add
one (unlike the legacy ``Query.first``), each call sends every matching
row to the Python process and discards all but the first. The favorite
existence check is bounded to a single row per (dag_id, user_id) by the
schema, but the previous-TI lookup scans every earlier matching TI.

Introduced independently of apache#52325's migration: get_previous_task_instance
came in apache#59712, unfavorite_dag's existence probe in apache#51264. Same
anti-pattern as the four sites apache#72554 fixes; the tests reuse the
``capture_orm_selects`` helper that PR introduces.

* Also assert the returned row on the previous-TI regression test
bbovenzi pushed a commit that referenced this pull request Sep 23, 2026
…73411)

* Document the 409 on favorite_dag and return a readable conflict message

favorite_dag returns 409 when the Dag is already a favorite, and its test
has asserted that since #51264, but the response was never declared, so it
is missing from the OpenAPI spec and every client generated from it.

The 409 also came from the generic unique-constraint handler, so a repeat
favorite answered "Serious error when handling your request" and logged an
error, while unfavorite_dag answers "Dag is not marked as favorite". Check
for the row first, as unfavorite_dag does, and declare the 409.

* Drop the unfavorite body assertion

It pinned behaviour this change does not touch, which the review
guidelines count as padding rather than coverage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:airflow-ctl area:API Airflow's REST/HTTP API area:UI Related to UI/UX. For Frontend Developers. type:new-feature Changelog: New Features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for favorite/pin dags to dashboard.

8 participants