This is an automated email from the ASF dual-hosted git repository.

pierrejeambrun pushed a commit to branch v2-11-stable
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v2-11-stable by this push:
     new 7833f5da87f Fix Confirmation dialog for DagRun MarkAs and Clear 
Actions (#52831)
7833f5da87f is described below

commit 7833f5da87f8c081e2411611b8aa77c8427edf74
Author: punx120 <8940871+punx...@users.noreply.github.com>
AuthorDate: Mon Jul 7 08:15:28 2025 -0400

    Fix Confirmation dialog for DagRun MarkAs and Clear Actions (#52831)
    
    * MarkRunAs.tsx - Confirmation dialog was not correctly displayed
    
    * ClearRun.tsx - Fix confirmation dialog not showing up correctly
---
 .../www/static/js/dag/details/dagRun/ClearRun.tsx  | 82 ++++++++++++++++++----
 .../www/static/js/dag/details/dagRun/MarkRunAs.tsx | 44 +++++++-----
 2 files changed, 95 insertions(+), 31 deletions(-)

diff --git a/airflow/www/static/js/dag/details/dagRun/ClearRun.tsx 
b/airflow/www/static/js/dag/details/dagRun/ClearRun.tsx
index 1c04bad64d4..fdc111654f9 100644
--- a/airflow/www/static/js/dag/details/dagRun/ClearRun.tsx
+++ b/airflow/www/static/js/dag/details/dagRun/ClearRun.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import React, { useState } from "react";
+import React, { useState, useReducer } from "react";
 import {
   Flex,
   Button,
@@ -41,6 +41,38 @@ interface Props extends MenuButtonProps {
   runId: string;
 }
 
+interface State {
+  showConfirmationModal: boolean;
+  confirmingAction: "existing" | "failed" | "queue" | null;
+}
+
+type Action =
+  | {
+      type: "SHOW_CONFIRMATION_MODAL";
+      payload: "existing" | "failed" | "queue";
+    }
+  | { type: "HIDE_CONFIRMATION_MODAL" };
+
+const initialState = {
+  showConfirmationModal: false,
+  confirmingAction: null,
+};
+
+const reducer = (state: State, action: Action): State => {
+  switch (action.type) {
+    case "SHOW_CONFIRMATION_MODAL":
+      return {
+        ...state,
+        showConfirmationModal: true,
+        confirmingAction: action.payload,
+      };
+    case "HIDE_CONFIRMATION_MODAL":
+      return { ...state, showConfirmationModal: false, confirmingAction: null 
};
+    default:
+      return state;
+  }
+};
+
 const ClearRun = ({ runId, ...otherProps }: Props) => {
   const { mutateAsync: onClear, isLoading: isClearLoading } = useClearRun(
     dagId,
@@ -64,27 +96,47 @@ const ClearRun = ({ runId, ...otherProps }: Props) => {
     onQueue({ confirmed: true });
   };
 
-  const [showConfirmationModal, setShowConfirmationModal] = useState(false);
+  const [stateReducer, dispatch] = useReducer(reducer, initialState);
 
   const storedValue = localStorage.getItem("doNotShowClearRunModal");
   const [doNotShowAgain, setDoNotShowAgain] = useState(
     storedValue ? JSON.parse(storedValue) : false
   );
 
+  const confirmClearExisting = () => {
+    if (!doNotShowAgain) {
+      dispatch({ type: "SHOW_CONFIRMATION_MODAL", payload: "existing" });
+    } else clearExistingTasks();
+  };
+
+  const confirmClearFailed = () => {
+    if (!doNotShowAgain) {
+      dispatch({ type: "SHOW_CONFIRMATION_MODAL", payload: "failed" });
+    } else clearFailedTasks();
+  };
+
+  const confirmQueued = () => {
+    if (!doNotShowAgain) {
+      dispatch({ type: "SHOW_CONFIRMATION_MODAL", payload: "queue" });
+    } else queueNewTasks();
+  };
+
   const confirmAction = () => {
     localStorage.setItem(
       "doNotShowClearRunModal",
       JSON.stringify(doNotShowAgain)
     );
-    clearExistingTasks();
-    setShowConfirmationModal(false);
+    if (stateReducer.confirmingAction === "failed") {
+      clearFailedTasks();
+    } else if (stateReducer.confirmingAction === "existing") {
+      clearExistingTasks();
+    } else if (stateReducer.confirmingAction === "queue") {
+      queueNewTasks();
+    }
+    dispatch({ type: "HIDE_CONFIRMATION_MODAL" });
   };
 
-  useKeysPress(keyboardShortcutIdentifier.dagRunClear, () => {
-    if (!doNotShowAgain) {
-      setShowConfirmationModal(true);
-    } else clearExistingTasks();
-  });
+  useKeysPress(keyboardShortcutIdentifier.dagRunClear, confirmClearExisting);
 
   const clearLabel = "Clear tasks or add new tasks";
   return (
@@ -106,16 +158,18 @@ const ClearRun = ({ runId, ...otherProps }: Props) => {
           </Flex>
         </MenuButton>
         <MenuList>
-          <MenuItem onClick={clearExistingTasks}>Clear existing 
tasks</MenuItem>
-          <MenuItem onClick={clearFailedTasks}>
+          <MenuItem onClick={confirmClearExisting}>
+            Clear existing tasks
+          </MenuItem>
+          <MenuItem onClick={confirmClearFailed}>
             Clear only failed tasks
           </MenuItem>
-          <MenuItem onClick={queueNewTasks}>Queue up new tasks</MenuItem>
+          <MenuItem onClick={confirmQueued}>Queue up new tasks</MenuItem>
         </MenuList>
       </Menu>
       <ConfirmationModal
-        isOpen={showConfirmationModal}
-        onClose={() => setShowConfirmationModal(false)}
+        isOpen={stateReducer.showConfirmationModal}
+        onClose={() => dispatch({ type: "HIDE_CONFIRMATION_MODAL" })}
         header="Confirmation"
         submitButton={
           <Button onClick={confirmAction} colorScheme="blue">
diff --git a/airflow/www/static/js/dag/details/dagRun/MarkRunAs.tsx 
b/airflow/www/static/js/dag/details/dagRun/MarkRunAs.tsx
index 43c1107d8a0..f42cc3ac4f6 100644
--- a/airflow/www/static/js/dag/details/dagRun/MarkRunAs.tsx
+++ b/airflow/www/static/js/dag/details/dagRun/MarkRunAs.tsx
@@ -95,6 +95,22 @@ const MarkRunAs = ({ runId, state, ...otherProps }: Props) 
=> {
     markSuccess({ confirmed: true });
   };
 
+  const confirmMarkAsFailed = () => {
+    if (state !== "failed") {
+      if (!doNotShowAgain) {
+        dispatch({ type: "SHOW_CONFIRMATION_MODAL", payload: "failed" });
+      } else markAsFailed();
+    }
+  };
+
+  const confirmMarkAsSuccess = () => {
+    if (state !== "success") {
+      if (!doNotShowAgain) {
+        dispatch({ type: "SHOW_CONFIRMATION_MODAL", payload: "success" });
+      } else markAsSuccess();
+    }
+  };
+
   const confirmAction = () => {
     localStorage.setItem(
       "doNotShowMarkRunModal",
@@ -108,20 +124,8 @@ const MarkRunAs = ({ runId, state, ...otherProps }: Props) 
=> {
     dispatch({ type: "HIDE_CONFIRMATION_MODAL" });
   };
 
-  useKeysPress(keyboardShortcutIdentifier.dagMarkSuccess, () => {
-    if (state !== "success") {
-      if (!doNotShowAgain) {
-        dispatch({ type: "SHOW_CONFIRMATION_MODAL", payload: "success" });
-      } else markAsSuccess();
-    }
-  });
-  useKeysPress(keyboardShortcutIdentifier.dagMarkFailed, () => {
-    if (state !== "failed") {
-      if (!doNotShowAgain) {
-        dispatch({ type: "SHOW_CONFIRMATION_MODAL", payload: "failed" });
-      } else markAsFailed();
-    }
-  });
+  useKeysPress(keyboardShortcutIdentifier.dagMarkSuccess, 
confirmMarkAsSuccess);
+  useKeysPress(keyboardShortcutIdentifier.dagMarkFailed, confirmMarkAsFailed);
 
   const markLabel = "Manually set dag run state";
   return (
@@ -138,16 +142,22 @@ const MarkRunAs = ({ runId, state, ...otherProps }: 
Props) => {
           mt={2}
         >
           <Flex>
-            Mark state as...
+            Mark run as...
             <MdArrowDropDown size="16px" />
           </Flex>
         </MenuButton>
         <MenuList>
-          <MenuItem onClick={markAsFailed} isDisabled={state === "failed"}>
+          <MenuItem
+            onClick={confirmMarkAsFailed}
+            isDisabled={state === "failed"}
+          >
             <SimpleStatus state="failed" mr={2} />
             failed
           </MenuItem>
-          <MenuItem onClick={markAsSuccess} isDisabled={state === "success"}>
+          <MenuItem
+            onClick={confirmMarkAsSuccess}
+            isDisabled={state === "success"}
+          >
             <SimpleStatus state="success" mr={2} />
             success
           </MenuItem>

Reply via email to