RestartTableDialog.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { useParams } from 'common'
  2. import { toast } from 'sonner'
  3. import {
  4. AlertDialog,
  5. AlertDialogAction,
  6. AlertDialogCancel,
  7. AlertDialogContent,
  8. AlertDialogDescription,
  9. AlertDialogFooter,
  10. AlertDialogHeader,
  11. AlertDialogTitle,
  12. } from 'ui'
  13. import { PipelineStatusName } from './Replication.constants'
  14. import { useRollbackTablesMutation } from '@/data/replication/rollback-tables-mutation'
  15. interface RestartTableDialogProps {
  16. open: boolean
  17. onOpenChange: (open: boolean) => void
  18. tableId: number
  19. tableName: string
  20. pipelineStatusName?: PipelineStatusName
  21. onRestartStart?: () => void
  22. onRestartComplete?: () => void
  23. }
  24. export const RestartTableDialog = ({
  25. open,
  26. onOpenChange,
  27. tableId,
  28. tableName,
  29. pipelineStatusName,
  30. onRestartStart,
  31. onRestartComplete,
  32. }: RestartTableDialogProps) => {
  33. const { ref: projectRef, pipelineId: _pipelineId } = useParams()
  34. const pipelineId = Number(_pipelineId)
  35. const { mutate: rollbackTables, isPending: isResetting } = useRollbackTablesMutation({
  36. onSuccess: () => {
  37. toast.success(
  38. `Restarting replication for "${tableName}". Pipeline will ${pipelineStatusName === PipelineStatusName.STOPPED ? 'start' : 'restart'} automatically.`
  39. )
  40. },
  41. onSettled: () => {
  42. onRestartComplete?.()
  43. onOpenChange(false)
  44. },
  45. onError: (error) => {
  46. toast.error(`Failed to restart replication: ${error.message}`)
  47. },
  48. })
  49. const handleReset = () => {
  50. if (!projectRef) return toast.error('Project ref is required')
  51. if (!pipelineId) return toast.error('Pipeline ID is required')
  52. onRestartStart?.()
  53. rollbackTables({
  54. projectRef,
  55. pipelineId,
  56. target: { type: 'single_table', table_id: tableId },
  57. rollbackType: 'full',
  58. pipelineStatusName,
  59. })
  60. }
  61. return (
  62. <AlertDialog open={open} onOpenChange={onOpenChange}>
  63. <AlertDialogContent>
  64. <AlertDialogHeader>
  65. <AlertDialogTitle>
  66. Restart replication for <code className="text-code-inline">{tableName}</code>
  67. </AlertDialogTitle>
  68. <AlertDialogDescription asChild>
  69. <div className="space-y-3 text-sm">
  70. <p>
  71. This will restart replication for{' '}
  72. <code className="text-code-inline">{tableName}</code> from scratch:
  73. </p>
  74. <ul className="list-disc list-inside space-y-1.5 pl-2">
  75. <li>
  76. <strong>The table copy will be re-initialized.</strong> All data will be copied
  77. again from the source.
  78. </li>
  79. <li>
  80. <strong>Existing downstream data will be deleted.</strong> Any replicated data for
  81. this table will be removed.
  82. </li>
  83. <li>
  84. <strong>All other tables remain untouched.</strong> Only this table is affected.
  85. </li>
  86. <li>
  87. <strong>The pipeline will restart automatically.</strong> This is required to
  88. apply this change.
  89. </li>
  90. </ul>
  91. </div>
  92. </AlertDialogDescription>
  93. </AlertDialogHeader>
  94. <AlertDialogFooter>
  95. <AlertDialogCancel disabled={isResetting}>Cancel</AlertDialogCancel>
  96. <AlertDialogAction disabled={isResetting} onClick={handleReset} variant="warning">
  97. {isResetting ? 'Restarting replication...' : 'Restart replication'}
  98. </AlertDialogAction>
  99. </AlertDialogFooter>
  100. </AlertDialogContent>
  101. </AlertDialog>
  102. )
  103. }