DropReplicaConfirmationModal.tsx85 lines · main
1import { useQueryClient } from '@tanstack/react-query'
2import { useParams } from 'common'
3import { toast } from 'sonner'
4import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
5
6import { REPLICA_STATUS } from './InstanceConfiguration.constants'
7import { replicaKeys } from '@/data/read-replicas/keys'
8import { useReadReplicaRemoveMutation } from '@/data/read-replicas/replica-remove-mutation'
9import type { Database } from '@/data/read-replicas/replicas-query'
10import { formatDatabaseID } from '@/data/read-replicas/replicas.utils'
11
12interface DropReplicaConfirmationModalProps {
13 selectedReplica?: Database
14 onSuccess: () => void
15 onCancel: () => void
16}
17
18export const DropReplicaConfirmationModal = ({
19 selectedReplica,
20 onSuccess,
21 onCancel,
22}: DropReplicaConfirmationModalProps) => {
23 const { ref: projectRef } = useParams()
24 const queryClient = useQueryClient()
25 const formattedId = formatDatabaseID(selectedReplica?.identifier ?? '')
26 const { mutate: removeReadReplica, isPending: isRemoving } = useReadReplicaRemoveMutation({
27 onSuccess: () => {
28 toast.success(`Tearing down read replica (ID: ${formattedId})`)
29
30 // [Joshen] Temporarily optimistic rendering until API supports immediate status update
31 queryClient.setQueriesData(
32 { queryKey: replicaKeys.list(projectRef) },
33 (old: Database[] | undefined) => {
34 const updatedReplicas = old?.map((x) => {
35 if (x.identifier === selectedReplica?.identifier) {
36 return { ...x, status: REPLICA_STATUS.GOING_DOWN }
37 }
38 return x
39 })
40 return updatedReplicas
41 }
42 )
43
44 onSuccess()
45 onCancel()
46 },
47 })
48
49 const onConfirmRemove = async () => {
50 if (!projectRef) return console.error('Project is required')
51 if (selectedReplica === undefined) return toast.error('No replica selected')
52
53 removeReadReplica({
54 projectRef,
55 identifier: selectedReplica.identifier,
56 invalidateReplicaQueries: true,
57 })
58 }
59
60 return (
61 <ConfirmationModal
62 variant="destructive"
63 size="medium"
64 loading={isRemoving}
65 visible={selectedReplica !== undefined}
66 title={`Confirm to drop selected replica? (ID: ${formattedId})`}
67 confirmLabel="Drop replica"
68 confirmLabelLoading="Dropping replica"
69 onCancel={() => onCancel()}
70 onConfirm={() => onConfirmRemove()}
71 alert={{
72 title: 'This action cannot be undone',
73 description: 'You may still deploy a new replica in this region thereafter',
74 }}
75 >
76 <p className="text-sm">Before deleting this replica, consider:</p>
77 <ul className="text-sm text-foreground-light py-1 list-disc mx-4 space-y-1">
78 <li>
79 Network traffic from this region may slow down, especially if you have no other replicas
80 in this region
81 </li>
82 </ul>
83 </ConfirmationModal>
84 )
85}