Files
supabase/apps/studio/components/interfaces/Database/Replication/RestartTableDialog.tsx
Danny White 0b002892d7 refactor(studio): simplify pipeline reset dialogs (#50443)
## What kind of change does this PR introduce?

Studio UI refactor.

## What is the current behavior?

Pipeline table reset dialogs repeat explanatory content and use more
layout than the reset decision needs.

## What is the new behavior?

Simplifies the single-table and batch reset confirmations while
preserving their cost estimate, destructive consequences, and existing
reset mutations.

| Before | After |
| --- | --- |
| <img width="854" height="1090" alt="CleanShot 2026-09-16 at 12 54
36@2x"
src="https://github.com/user-attachments/assets/f9eef09b-89d1-4747-bc4c-e81fb64c584b"
/> | <img width="840" height="742" alt="CleanShot 2026-09-16 at 17 01
11@2x"
src="https://github.com/user-attachments/assets/fa45728c-ec66-45c8-9fef-9d2eb8310d4d"
/> |

This is an independent slice extracted from #49630. The related review
series is this one, #50444, #50445, #50446, then #49630.

## To test

1. Open `/project/<ref>/database/replication` and select a pipeline.
2. Reset one replicated table and confirm the dialog explains that
destination data will be deleted and resynchronised.
3. Choose **Reset all tables** and confirm the batch dialog shows the
same concise treatment.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## UI Updates

* **UI Updates**
* Renamed replication “restart” actions to “reset” across dialogs,
buttons, notifications, and cost estimates.
* Updated messaging to clarify whether the pipeline will start or
restart automatically after resetting.
* Added clearer initial-sync guidance for all, some, or none of the
affected tables.
* Improved reset cost estimate messaging, including when no additional
initial-sync charge applies.
* Updated reset dialogs with clearer titles, descriptions, loading
states, and error messages.
  * Disabled reset actions when pipeline status is unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-17 12:13:51 +10:00

104 lines
3.4 KiB
TypeScript

import { useParams } from 'common'
import { toast } from 'sonner'
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from 'ui'
import { PipelineStatusName } from './Replication.constants'
import { RestartCostEstimate } from './RestartCostEstimate'
import { shouldCopyTable, type ReplicationTableIdentity } from './TableSyncCopy.utils'
import { useRollbackTablesMutation } from '@/data/replication/rollback-tables-mutation'
import type { TableSyncCopyConfig } from '@/data/replication/types'
interface RestartTableDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
table: ReplicationTableIdentity
tableSyncCopy?: TableSyncCopyConfig | null
sourceId?: number
publicationName?: string
pipelineStatusName?: PipelineStatusName
onRestartStart?: () => void
onRestartComplete?: () => void
}
export const RestartTableDialog = ({
open,
onOpenChange,
table,
tableSyncCopy,
sourceId,
publicationName,
pipelineStatusName,
onRestartStart,
onRestartComplete,
}: RestartTableDialogProps) => {
const { ref: projectRef, pipelineId: _pipelineId } = useParams()
const pipelineId = Number(_pipelineId)
const tableName = `${table.schema}.${table.name}`
const willCopyTable = shouldCopyTable(tableSyncCopy, table.id)
const pipelineAction = pipelineStatusName === PipelineStatusName.STOPPED ? 'start' : 'restart'
const { mutate: rollbackTables, isPending: isResetting } = useRollbackTablesMutation({
onSuccess: () => {
toast.success(`Resetting "${tableName}". Pipeline will ${pipelineAction} automatically.`)
},
onSettled: () => {
onRestartComplete?.()
onOpenChange(false)
},
onError: (error) => {
toast.error(`Failed to reset table: ${error.message}`)
},
})
const handleReset = () => {
if (!projectRef) return toast.error('Project ref is required')
if (!pipelineId) return toast.error('Pipeline ID is required')
onRestartStart?.()
rollbackTables({
projectRef,
pipelineId,
target: { type: 'single_table', table_id: table.id },
rollbackType: 'full',
pipelineStatusName,
})
}
const consequence = willCopyTable
? `Destination data for this table will be deleted, existing rows will sync again, and the pipeline will ${pipelineAction} automatically.`
: `Destination data for this table will be deleted. Initial sync is skipped for this table, so replication resumes with new changes only. The pipeline will ${pipelineAction} automatically.`
return (
<AlertDialog open={open} onOpenChange={onOpenChange}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Reset {tableName}</AlertDialogTitle>
<AlertDialogDescription>{consequence}</AlertDialogDescription>
</AlertDialogHeader>
<RestartCostEstimate
open={open}
projectRef={projectRef}
sourceId={sourceId}
publicationName={publicationName}
tables={willCopyTable ? [table] : []}
/>
<AlertDialogFooter>
<AlertDialogCancel disabled={isResetting}>Cancel</AlertDialogCancel>
<AlertDialogAction disabled={isResetting} onClick={handleReset} variant="warning">
{isResetting ? 'Resetting…' : 'Reset table'}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}