Feat: Support URL params for pre-filling Trigger and Backfill forms
closes: #54800
Description
This PR restores and enhances the ability to pre-populate the Trigger DAG and Backfill forms via URL query parameters in the Airflow 3.0 UI. This feature existed in Airflow 2.x and is useful for sharing pre-configured run links.
Key Changes:
-
URL Param Parsing:
- Implemented using the
useSearchParamshook (replacing manual parsing logic from stale PRs). - Added a utility
getTriggerConfto handle both JSON strings (?conf={"a":1}) and Key-Value pairs (?a=1).
- Implemented using the
-
Form Updates:
- Trigger Form: Supports
run_id,logical_date,note, andconf. - Backfill Form: Supports
from_date,to_date,max_active_runs,reprocess_behavior, andrun_backwards. - Config Form: Automatically expands the "Advanced Options" accordion if configuration data is present in the URL.
- Trigger Form: Supports
-
Code Quality:
- Optimized
RunBackfillForm.tsxlogic to keep the file size strictly under the 250-line linting limit. - Ensured consistent naming conventions for backfill parameters (
from_date/to_date) to match the API and UI components.
- Optimized
-
Documentation:
- Updated
docs/core-concepts/params.rstto document the supported URL parameters and examples.
- Updated
How to reproduce / Test
You can test this by running the UI and navigating to any DAG (e.g., tutorial) using the following URLs:
1. Trigger Single Run (JSON Config): The modal should open, fields should be filled, and the JSON editor should show the config. http://localhost:8080/dags/tutorial/trigger/single?run_id=test_run_01¬e=Testing_Note&conf={"environment":"dev","debug":true}
2. Trigger Single Run (Key-Value Config):
The "Advanced Options" should open and show {"foo": "bar"}.
http://localhost:8080/dags/tutorial/trigger/single?foo=bar&retry=3
3. Backfill Form: The Backfill form should open with dates, max runs, and the "Run Backwards" checkbox pre-selected. http://localhost:8080/dags/tutorial/trigger/backfill?from_date=2024-01-01T00:00:00&to_date=2024-01-05T00:00:00&max_active_runs=5&run_backwards=true
^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in airflow-core/newsfragments.
PR Looks clear and good for me.
I tried but the trigger form was not opening. Don't know if I mis-understood but I needed to click the "trigger" button to open the form pre-populated. Otherwise working fine. I'd expected it is oepning pre-populated when calling with a prepared/pre-filled URL.
Hi @jscheffl Thanks for catching that! You are correct, I missed wiring the URL state to the modal visibility logic in the initial commit.
I have pushed a fix in the latest commit (Overview.tsx) where I check for the mode parameter in the URL. Now, if the URL contains /trigger/single or /trigger/backfill, the modal will open automatically with the pre-populated values.
Thanks for the rework. I was testing and it seems there is a bit of a glitch because the two-way synchronization of the UI gets broken if not all parameters are passed in the UI trigger URL.
For example using http://localhost:28080/dags/example_params_ui_tutorial/trigger/single?number_param=77 is changes the dictionary of the run-conf to the value as passed but the form fields of the trigger form are not updated to be in sync. And even worse, if you click on the form (any element) the JSON dictionary will be back-populated to the form elements and most form elements dis-appear.
So a fix is needed to merge/sync the given parameters of the URL to the default values not to break the form and needs to ensure that updated form values are correctly populated to the UI.
Hi @jscheffl Thanks for catching this ! I have pushed a fix that addresses the synchronization glitch and the disappearing fields issue.
Changes made:
- Unified Merge Logic: The form now correctly merges the DAG's default parameters with the incoming URL parameters during initialization. This ensures that defaults are preserved, and only specific fields are overridden by the URL.
- UI Store Synchronization: I added logic to explicitly update the useParamStore (setParamsDict) alongside the React Hook Form state. This ensures the visual input fields update immediately to reflect the URL values (e.g., showing 77 instead of 10) without requiring a click interaction.
- Data Cleaning: Implemented a helper to extract clean values from the parameter objects to prevent [object Object] rendering issues.
Please let me know if this looks good to you!
For me this looks good and I am happy that the function is back!
In the past there was always some discussion about excessive use of "useEffect()" so I'd leave this PR open - from my side it is good - but another pair of Web Development knowledge would be good to ensure it is implemented as it should be.
Thanks @jscheffl for the approval!
I used useEffect to safely sync the async DAG params with URL inputs using react-hook-form's reset() method. This ensures the form updates correctly once data is loaded. That said, I'm happy to refactor if the UI team prefers a different pattern!"