DropReplicaConfirmationModal.tsx 2.9 KB

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