import { useMemo } from 'react' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import { useReplicationCostEstimateQuery } from '@/data/replication/cost-estimate-query' import { formatBytes, formatCurrency } from '@/lib/helpers' interface RestartCostEstimateProps { open: boolean projectRef?: string sourceId?: number publicationName?: string tableNames: string[] } interface EstimatedTable { schema: string name: string estimated_bytes: number estimated_cost: number is_row_filtered: boolean } export const calculateRestartCostEstimate = (tables: EstimatedTable[], tableNames: string[]) => { const tableNameSet = new Set(tableNames) const matchedTables = tables.filter((table) => tableNameSet.has(`${table.schema}.${table.name}`)) return { isComplete: matchedTables.length === tableNames.length, estimatedBytes: matchedTables.reduce((total, table) => total + table.estimated_bytes, 0), estimatedCost: matchedTables.reduce((total, table) => total + table.estimated_cost, 0), hasRowFilteredTables: matchedTables.some((table) => table.is_row_filtered), } } export const RestartCostEstimate = ({ open, projectRef, sourceId, publicationName, tableNames, }: RestartCostEstimateProps) => { const { data: estimate, isFetching } = useReplicationCostEstimateQuery( { projectRef, sourceId, publicationName }, { enabled: open } ) const restartEstimate = useMemo( () => estimate === undefined ? undefined : calculateRestartCostEstimate(estimate.table_copy.tables, tableNames), [estimate, tableNames] ) return (
{isFetching ? ( ) : restartEstimate?.isComplete ? (

Estimated additional initial sync

{formatBytes(restartEstimate.estimatedBytes)} across {tableNames.length}{' '} {tableNames.length === 1 ? 'table' : 'tables'}

{formatCurrency(restartEstimate.estimatedCost)} {restartEstimate.hasRowFilteredTables ? '*' : null}
) : (

A cost estimate is unavailable. You can still restart the{' '} {tableNames.length === 1 ? 'table' : 'tables'}.

)} {restartEstimate?.isComplete && restartEstimate.hasRowFilteredTables && (

*Tables with row filters may cost less than shown.

)}
) }