Add Clear All Mapped Tasks button for mapped task instances#60591
Add Clear All Mapped Tasks button for mapped task instances#60591VedantMadane wants to merge 8 commits intoapache:mainfrom
Conversation
Hi @VedantMadane , thanks for the PR — the implementation looks solid 👍 I was actually working on this issue as well (I’m the assignee), and my approach was slightly different on the UI side. Instead of placing the button in the mapped task header, I was adding the “Clear all mapped task instances” button next to the Filter button in the Task Instances section, to keep it consistent with other bulk actions on that page. I’ve attached a screenshot below showing the placement I was testing locally. Functionality-wise, your approach of passing only task_id (without map_index) matches what I had in mind, and we could reuse the same dialog logic. @maintainers — would you prefer the button in the header (as in this PR), or alongside the filter in the Task Instances section? Based on your guidance, I’m happy to either: follow up with a small PR adjusting the placement, or help refine this PR instead. Thanks! |
|
Sorry about that Rachana, feel free to modify this PR or reuse code from it. |
Hi @VedantMadane — quick check while testing this locally 🙂
On my side, when I open the “Clear All Mapped Task Instances” dialog, the mapped task instances are not appearing in the dialog (the ActionAccordion looks empty). Could you please share a quick screenshot from your local setup showing whether the mapped task instances are listed correctly in the dialog? That would really help confirm whether this is environment-specific or something we need to adjust in the PR. Thanks! |
|
Hi @rachanadutta, thanks for catching this! I found the bug. The I've pushed a fix that adds the missing props. Could you try pulling the latest changes and testing again? The accordion should now show the list of mapped task instances that will be affected by the clear operation. |
|
@VedantMadane I reviewed and tested the changes locally. I tested the clear task instance behavior both locally and on released Airflow (3.1.3) using airflow standalone: the confirmation dialog shows the affected tasks with No Status, but the Task Instances list and the individual task instance page still show the previous state (e.g. Success). This makes it difficult for users to tell from the main page that the clear action actually took effect as there is no success message like delete instance. One minor UX thought (happy to defer to maintainers): placing the action closer to the existing +Filter button (instead of the header) might better align with the overall UI patterns, but I understand this is a design choice and should be maintainer-driven. |
pierrejeambrun
left a comment
There was a problem hiding this comment.
Nice!
Tested locally and working as expected.
A few suggestions before we can merge.
...-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearAllMappedTaskInstancesButton.tsx
Outdated
Show resolved
Hide resolved
...-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearAllMappedTaskInstancesDialog.tsx
Outdated
Show resolved
Hide resolved
...-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearAllMappedTaskInstancesDialog.tsx
Outdated
Show resolved
Hide resolved
...-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearAllMappedTaskInstancesDialog.tsx
Outdated
Show resolved
Hide resolved
...-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearAllMappedTaskInstancesDialog.tsx
Outdated
Show resolved
Hide resolved
...-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearAllMappedTaskInstancesButton.tsx
Outdated
Show resolved
Hide resolved
bbovenzi
left a comment
There was a problem hiding this comment.
We only call mapIndex in a handful of places in our existing ClearTaskInstanceDialog. I wonder if we can add a allMapped boolean param to it to handle this condition instead of making an entire parallel set of components.
…0460) This adds a 'Clear All Mapped Tasks' button to the mapped task instance header, allowing users to clear all mapped task instances at once. Changes: - Added ClearAllMappedTaskInstancesButton component - Added ClearAllMappedTaskInstancesDialog component - Updated MappedTaskInstance Header to include the clear all button - Added translation keys for the new feature The backend already supports clearing all map indices when only task_id is provided (without map_index), so this UI change leverages that existing functionality. Closes apache#60460
The ActionAccordion component requires note and setNote props but they were missing, causing the accordion to appear empty.
50b548d to
fba7b51
Compare
- Add allMapped boolean prop to ClearTaskInstanceButton and ClearTaskInstanceDialog - Eliminate need for parallel ClearAllMapped* components - Fix tooltip ternary to use different translation keys based on allMapped and isHotkeyEnabled - Conditionally handle mapIndex in 6 places (taskIds, patch hook, confirmation dialog, note patching, title, tooltips) Addresses review feedback from @bbovenzi in PR apache#60591
- Add allMapped boolean prop to ClearTaskInstanceButton and ClearTaskInstanceDialog - Eliminate need for parallel ClearAllMapped* components - Fix tooltip ternary to use different translation keys based on allMapped and isHotkeyEnabled - Conditionally handle mapIndex in 6 places (taskIds, patch hook, confirmation dialog, note patching, title, tooltips) Addresses review feedback from @bbovenzi in PR apache#60591
|
Added allMapped?: boolean prop to existing components instead of creating parallel ClearAllMapped* components. Commit 5e53ef7 |
- Delete ClearAllMappedTaskInstancesButton.tsx and ClearAllMappedTaskInstancesDialog.tsx - Update Header.tsx to use ClearTaskInstanceButton with allMapped=true - All functionality now consolidated into existing components with allMapped boolean param Addresses @bbovenzi review feedback in PR apache#60591: 1. Eliminated parallel component set - now using single allMapped param 2. Fixed tooltip ternary to use different translation keys 3. Translation keys already exist in dags.json (clearAllMapped.button, clearAllMapped.buttonTooltip, clearAllMapped.title)
- Keep ClearAllMappedTaskInstancesButton with explicit props (dagId, dagRunId, taskId) - Delete redundant ClearAllMappedTaskInstancesDialog (200 lines) - Enhance ClearTaskInstanceDialog to accept both TaskInstanceResponse OR explicit props - Add allMapped parameter to ClearTaskInstanceDialog for conditional logic - Fix task_ids API format: [taskId] for all mapped vs [[taskId, mapIndex]] for single - Fix tooltip ternary to show different text when hotkey disabled - Handle optional taskInstance fields gracefully (note, dag_version, task_display_name, start_date, logical_date) Addresses @bbovenzi review feedback in PR apache#60591: 1. Consolidate dialog logic with allMapped param instead of parallel components 2. Fix tooltip ternary dead code (lines 53-55) 3. Properly handle mapIndex in handful of places with conditional logic Net change: -173 lines of code
ce26f2f to
1db8d12
Compare
pierrejeambrun
left a comment
There was a problem hiding this comment.
Thanks,
That's looking better.
A few things to address
| // Support both taskInstance and explicit props | ||
| const dagId = propDagId ?? taskInstance?.dag_id ?? ""; | ||
| const dagRunId = propDagRunId ?? taskInstance?.dag_run_id ?? ""; | ||
| const taskId = propTaskId ?? taskInstance?.task_id ?? ""; | ||
| const mapIndex = propMapIndex ?? taskInstance?.map_index ?? -1; |
There was a problem hiding this comment.
This is confusing and we should probably support only one mode. (TI or explicit props)
| dagId, | ||
| dagRunId, | ||
| mapIndex, | ||
| mapIndex: allMapped ? -1 : mapIndex, |
There was a problem hiding this comment.
I think that's wrong. If "allMapped" we should update the note for all of the mapped instances. And this is done when passing 'None' to the backend, problaby passing null or undefined there.
| if (!allMapped && taskInstance && note !== taskInstance.note) { | ||
| mutatePatchTaskInstance({ | ||
| dagId, | ||
| dagRunId, | ||
| mapIndex, | ||
| requestBody: { note }, | ||
| taskId, | ||
| }); | ||
| } | ||
| onCloseDialog(); |
There was a problem hiding this comment.
We need to update the note of all mapped task instances. This is just plainly skipping the note I believe when clearing all task instances with a note.
| configurable: true, | ||
| value: createLocalStorage(), | ||
| }); | ||
|
|
There was a problem hiding this comment.
Can you explain why is this code needed? I suppose the test was failing ?


Summary
This PR adds a "Clear All Mapped Tasks" button to the mapped task instance header, allowing users to clear all mapped task instances at once.
Closes #60460
Problem
Currently, there is no way to clear all mapped task instances at once for a specific task. Users have to clear each individual mapped task instance separately, which is tedious when dealing with many mapped instances.
Solution
Added a "Clear All Mapped Tasks" button to the mapped task instance header that clears all map indices for a given task. The backend already supports this functionality - when only the
task_idis provided (withoutmap_index), all map indices are targeted for clearing.Changes
task_ids: [taskId]instead of[[taskId, mapIndex]]to clear all mapped instancesdagIdanddagRunIdprops and render the new buttondagIdanddagRunIdto the Header componentScreenshot Location
The button appears in the header of the mapped task instance page (e.g.,
/dags/{dag_id}/runs/{run_id}/tasks/{task_id}/mapped), next to the task name and statistics.Testing