This is an automated email from the ASF dual-hosted git repository.
pierrejeambrun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new ad47a5c3262 AIP-38: align delete model (#49514)
ad47a5c3262 is described below
commit ad47a5c32622da59dd706bf0d06e63073912757b
Author: Guan Ming(Wesley) Chiu <[email protected]>
AuthorDate: Tue Apr 22 22:23:52 2025 +0800
AIP-38: align delete model (#49514)
---
.../src/components/DagActions/DeleteDagButton.tsx | 39 ++++--------
.../src/airflow/ui/src/components/DeleteDialog.tsx | 74 ++++++++++++++++++++++
.../ui/src/pages/Pools/DeletePoolButton.tsx | 61 ++++++------------
.../src/airflow/ui/src/pages/Pools/PoolBar.tsx | 4 +-
4 files changed, 107 insertions(+), 71 deletions(-)
diff --git
a/airflow-core/src/airflow/ui/src/components/DagActions/DeleteDagButton.tsx
b/airflow-core/src/airflow/ui/src/components/DagActions/DeleteDagButton.tsx
index 78cb556557d..28645696b15 100644
--- a/airflow-core/src/airflow/ui/src/components/DagActions/DeleteDagButton.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DagActions/DeleteDagButton.tsx
@@ -16,11 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Text, Heading, HStack, useDisclosure } from "@chakra-ui/react";
+import { useDisclosure } from "@chakra-ui/react";
import { FiTrash2 } from "react-icons/fi";
import { useNavigate } from "react-router-dom";
-import { Button, Dialog } from "src/components/ui";
+import DeleteDialog from "src/components/DeleteDialog";
import ActionButton from "src/components/ui/ActionButton";
import { useDeleteDag } from "src/queries/useDeleteDag";
@@ -54,32 +54,15 @@ const DeleteDagButton = ({ dagDisplayName, dagId, withText
= true }: DeleteDagBu
withText={withText}
/>
- <Dialog.Root lazyMount onOpenChange={onClose} open={open} size="md"
unmountOnExit>
- <Dialog.Content backdrop>
- <Dialog.Header>
- <Heading size="lg">Delete DAG</Heading>
- </Dialog.Header>
- <Dialog.CloseTrigger />
- <Dialog.Body>
- <Text>
- Are you sure you want to delete
<strong>{dagDisplayName}</strong>? This action cannot be undone.
- </Text>
- <Text color="red.500" fontWeight="bold" mt={4}>
- This will remove all metadata related to the DAG, including DAG
Runs and Tasks.
- </Text>
- </Dialog.Body>
- <Dialog.Footer>
- <HStack justifyContent="flex-end" width="100%">
- <Button onClick={onClose} variant="outline">
- Cancel
- </Button>
- <Button colorPalette="red" loading={isPending} onClick={() =>
deleteDag({ dagId })}>
- <FiTrash2 style={{ marginRight: "8px" }} /> Delete
- </Button>
- </HStack>
- </Dialog.Footer>
- </Dialog.Content>
- </Dialog.Root>
+ <DeleteDialog
+ isDeleting={isPending}
+ onClose={onClose}
+ onDelete={() => deleteDag({ dagId })}
+ open={open}
+ resourceName={dagDisplayName}
+ title="Delete DAG"
+ warningText="This will remove all metadata related to the DAG,
including DAG Runs and Tasks."
+ />
</>
);
};
diff --git a/airflow-core/src/airflow/ui/src/components/DeleteDialog.tsx
b/airflow-core/src/airflow/ui/src/components/DeleteDialog.tsx
new file mode 100644
index 00000000000..6d8ac6b56fc
--- /dev/null
+++ b/airflow-core/src/airflow/ui/src/components/DeleteDialog.tsx
@@ -0,0 +1,74 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Text, Heading, HStack } from "@chakra-ui/react";
+import React from "react";
+import { FiTrash2 } from "react-icons/fi";
+
+import { Button, Dialog } from "src/components/ui";
+
+type DeleteDialogProps = {
+ readonly deleteButtonText?: string;
+ readonly isDeleting: boolean;
+ readonly onClose: () => void;
+ readonly onDelete: () => void;
+ readonly open: boolean;
+ readonly resourceName: string;
+ readonly title: string;
+ readonly warningText: string;
+};
+
+const DeleteDialog: React.FC<DeleteDialogProps> = ({
+ deleteButtonText = "Delete",
+ isDeleting,
+ onClose,
+ onDelete,
+ open,
+ resourceName,
+ title,
+ warningText,
+}) => (
+ <Dialog.Root lazyMount onOpenChange={onClose} open={open} size="md"
unmountOnExit>
+ <Dialog.Content backdrop>
+ <Dialog.Header>
+ <Heading size="lg">{title}</Heading>
+ </Dialog.Header>
+ <Dialog.CloseTrigger />
+ <Dialog.Body>
+ <Text>
+ Are you sure you want to delete <strong>{resourceName}</strong>?
This action cannot be undone.
+ </Text>
+ <Text color="red.500" fontWeight="bold" mt={4}>
+ {warningText}
+ </Text>
+ </Dialog.Body>
+ <Dialog.Footer>
+ <HStack justifyContent="flex-end" width="100%">
+ <Button onClick={onClose} variant="outline">
+ Cancel
+ </Button>
+ <Button colorPalette="red" loading={isDeleting} onClick={onDelete}>
+ <FiTrash2 style={{ marginRight: "8px" }} /> {deleteButtonText}
+ </Button>
+ </HStack>
+ </Dialog.Footer>
+ </Dialog.Content>
+ </Dialog.Root>
+);
+
+export default DeleteDialog;
diff --git a/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx
b/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx
index f2b7adf2769..1e76102ba83 100644
--- a/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Pools/DeletePoolButton.tsx
@@ -16,18 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Flex, useDisclosure, Text, VStack, Heading } from "@chakra-ui/react";
-import { FiTrash } from "react-icons/fi";
+import { useDisclosure } from "@chakra-ui/react";
+import { FiTrash2 } from "react-icons/fi";
-import { Button, Dialog } from "src/components/ui";
+import DeleteDialog from "src/components/DeleteDialog";
import ActionButton from "src/components/ui/ActionButton";
import { useDeletePool } from "src/queries/useDeletePool";
type Props = {
readonly poolName: string;
+ readonly withText?: boolean;
};
-const DeletePoolButton = ({ poolName }: Props) => {
+const DeletePoolButton = ({ poolName, withText = false }: Props) => {
const { onClose, onOpen, open } = useDisclosure();
const { isPending, mutate } = useDeletePool({
onSuccessConfirm: onClose,
@@ -37,47 +38,23 @@ const DeletePoolButton = ({ poolName }: Props) => {
<>
<ActionButton
actionName="Delete Pool"
- icon={<FiTrash />}
- onClick={() => {
- onOpen();
- }}
+ colorPalette="red"
+ icon={<FiTrash2 />}
+ onClick={onOpen}
text="Delete Pool"
- withText={false}
+ variant="solid"
+ withText={withText}
/>
- <Dialog.Root onOpenChange={onClose} open={open} size="xl">
- <Dialog.Content backdrop>
- <Dialog.Header>
- <VStack align="start" gap={4}>
- <Heading size="xl">Delete Pool</Heading>
- </VStack>
- </Dialog.Header>
-
- <Dialog.CloseTrigger />
-
- <Dialog.Body width="full">
- <Text color="gray.solid" fontSize="md" fontWeight="semibold"
mb={4}>
- You are about to delete pool <strong>{poolName}</strong>.
- <br />
- This action is permanent and cannot be undone.{" "}
- <strong>Are you sure you want to proceed?</strong>
- </Text>
- <Flex justifyContent="end" mt={3}>
- <Button
- colorPalette="red"
- loading={isPending}
- onClick={() => {
- mutate({
- poolName,
- });
- }}
- >
- <FiTrash /> <Text fontWeight="bold">Yes, Delete</Text>
- </Button>
- </Flex>
- </Dialog.Body>
- </Dialog.Content>
- </Dialog.Root>
+ <DeleteDialog
+ isDeleting={isPending}
+ onClose={onClose}
+ onDelete={() => mutate({ poolName })}
+ open={open}
+ resourceName={poolName}
+ title="Delete Pool"
+ warningText="This will remove all metadata related to the pool and may
affect tasks using this pool."
+ />
</>
);
};
diff --git a/airflow-core/src/airflow/ui/src/pages/Pools/PoolBar.tsx
b/airflow-core/src/airflow/ui/src/pages/Pools/PoolBar.tsx
index 22bf9a0c43a..9c086cb5276 100644
--- a/airflow-core/src/airflow/ui/src/pages/Pools/PoolBar.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Pools/PoolBar.tsx
@@ -57,7 +57,9 @@ const PoolBar = ({ pool }: PoolBarProps) => (
</Text>
<HStack gap={0}>
<EditPoolButton pool={pool} />
- {pool.name === "default_pool" ? undefined : <DeletePoolButton
poolName={pool.name} />}
+ {pool.name === "default_pool" ? undefined : (
+ <DeletePoolButton poolName={pool.name} withText={false} />
+ )}
</HStack>
</HStack>
{pool.description ?? (