| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- import { useParams } from 'common'
- import { useMemo } from 'react'
- import { toast } from 'sonner'
- import {
- AlertDialog,
- AlertDialogAction,
- AlertDialogCancel,
- AlertDialogContent,
- AlertDialogDescription,
- AlertDialogFooter,
- AlertDialogHeader,
- AlertDialogTitle,
- } from 'ui'
- import { PipelineStatusName } from './Replication.constants'
- import { ReplicationPipelineTableStatus } from '@/data/replication/pipeline-replication-status-query'
- import { useRollbackTablesMutation } from '@/data/replication/rollback-tables-mutation'
- interface BatchRestartDialogProps {
- open: boolean
- onOpenChange: (open: boolean) => void
- mode: 'all' | 'errored'
- totalTables: number
- erroredTablesCount: number
- tables: ReplicationPipelineTableStatus[]
- pipelineStatusName?: PipelineStatusName
- onRestartStart?: (tableIds: number[]) => void
- onRestartComplete?: (tableIds: number[]) => void
- }
- export const BatchRestartDialog = ({
- open,
- onOpenChange,
- mode,
- totalTables,
- erroredTablesCount,
- tables,
- pipelineStatusName,
- onRestartStart,
- onRestartComplete,
- }: BatchRestartDialogProps) => {
- const { ref: projectRef, pipelineId: _pipelineId } = useParams()
- const pipelineId = Number(_pipelineId)
- // Calculate which table IDs will be restarted based on mode (memoized)
- const affectedTableIds = useMemo(() => {
- if (mode === 'all') {
- return tables.map((t) => t.table_id)
- } else {
- return tables
- .filter(
- (t) =>
- t.state.name === 'error' &&
- 'retry_policy' in t.state &&
- t.state.retry_policy?.policy === 'manual_retry'
- )
- .map((t) => t.table_id)
- }
- }, [mode, tables])
- const { mutate: rollbackTables, isPending: isResetting } = useRollbackTablesMutation({
- onSuccess: (data) => {
- const count = data.tables.length
- toast.success(
- `Restarting replication for ${count} table${count > 1 ? 's' : ''}. Pipeline will restart automatically.`
- )
- },
- onSettled: () => {
- onRestartComplete?.(affectedTableIds)
- onOpenChange(false)
- },
- onError: (error) => {
- toast.error(`Failed to restart replication: ${error.message}`)
- },
- })
- const handleReset = () => {
- if (!projectRef) return toast.error('Project ref is required')
- onRestartStart?.(affectedTableIds)
- rollbackTables({
- projectRef,
- pipelineId,
- target: mode === 'all' ? { type: 'all_tables' } : { type: 'all_errored_tables' },
- rollbackType: 'full',
- pipelineStatusName,
- })
- }
- const dialogContent =
- mode === 'all'
- ? {
- title: 'Restart all tables',
- description: (
- <div className="space-y-3 text-sm">
- <p>
- This will restart replication for all
- {totalTables === 0 ? '' : totalTables} table{totalTables > 1 ? 's' : ''} in this
- pipeline from scratch:
- </p>
- <ul className="list-disc list-inside space-y-1.5 pl-2">
- <li>
- <strong>All table copies will be re-initialized.</strong> Every table will be
- copied again from the source.
- </li>
- <li>
- <strong>All downstream data will be deleted.</strong> All replicated data will be
- removed.
- </li>
- <li>
- <strong>The pipeline will restart automatically.</strong> This is required to
- apply this change.
- </li>
- </ul>
- </div>
- ),
- action: 'Restart all tables',
- }
- : {
- title: 'Restart failed tables',
- description: (
- <div className="space-y-3 text-sm">
- <p>
- This will restart replication for{' '}
- <strong>all {erroredTablesCount} failed tables</strong> from scratch:
- </p>
- <ul className="list-disc list-inside space-y-1.5 pl-2">
- <li>
- <strong>Failed table copies will be re-initialized.</strong> These tables will be
- copied again from the source.
- </li>
- <li>
- <strong>Existing downstream data will be deleted.</strong> Replicated data for
- these tables will be removed.
- </li>
- <li>
- <strong>All other tables remain untouched.</strong> Only failed tables are
- affected.
- </li>
- <li>
- <strong>The pipeline will restart automatically.</strong> This is required to
- apply this change.
- </li>
- </ul>
- </div>
- ),
- action: 'Restart failed tables',
- }
- return (
- <AlertDialog open={open} onOpenChange={onOpenChange}>
- <AlertDialogContent>
- <AlertDialogHeader>
- <AlertDialogTitle>{dialogContent.title}</AlertDialogTitle>
- <AlertDialogDescription asChild>{dialogContent.description}</AlertDialogDescription>
- </AlertDialogHeader>
- <AlertDialogFooter>
- <AlertDialogCancel disabled={isResetting}>Cancel</AlertDialogCancel>
- <AlertDialogAction disabled={isResetting} onClick={handleReset} variant="warning">
- {isResetting ? 'Restarting replication...' : dialogContent.action}
- </AlertDialogAction>
- </AlertDialogFooter>
- </AlertDialogContent>
- </AlertDialog>
- )
- }
|