import { ArrowUpRight } from 'lucide-react' import Link from 'next/link' import { parseAsInteger, parseAsStringEnum, useQueryState } from 'nuqs' import { useEffect } from 'react' import { toast } from 'sonner' import { Button, cn, DialogSectionSeparator, Sheet, SheetContent, SheetDescription, SheetHeader, SheetSection, SheetTitle, } from 'ui' import { EnableReplicationCallout } from '../EnableReplicationCallout' import { PipelineStatusName } from '../Replication.constants' import { useDestinationInformation } from '../useDestinationInformation' import { useIsETLPrivateAlpha } from '../useIsETLPrivateAlpha' import { DestinationForm } from './DestinationForm' import { DestinationType } from './DestinationPanel.types' import { DestinationTypeSelection } from './DestinationTypeSelection' import { ReadReplicaForm } from './ReadReplicaForm' import { DocsButton } from '@/components/ui/DocsButton' import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' import { DOCS_URL } from '@/lib/constants' interface DestinationPanelProps { onSuccessCreateReadReplica?: () => void } export const DestinationPanel = ({ onSuccessCreateReadReplica }: DestinationPanelProps) => { const enablePgReplicate = useIsETLPrivateAlpha() const { hasAccess: hasETLReplicationAccess } = useCheckEntitlements('replication.etl') const [urlDestinationType, setDestinationType] = useQueryState( 'destinationType', parseAsStringEnum([ 'Read Replica', 'BigQuery', 'Analytics Bucket', 'DuckLake', 'Snowflake', ]).withOptions({ history: 'push', clearOnDefault: true, }) ) const [edit, setEdit] = useQueryState( 'edit', parseAsInteger.withOptions({ history: 'push', clearOnDefault: true, }) ) const visible = urlDestinationType !== null || edit !== null const editMode = edit !== null const { sourceId, pipeline, statusName, replicationNotEnabled, type: existingDestinationType, destinationFetcher, } = useDestinationInformation({ id: edit }) const destinationType = existingDestinationType ?? urlDestinationType const invalidExistingDestination = destinationFetcher.error?.code === 404 const existingDestination = editMode ? { sourceId, destinationId: edit, pipelineId: pipeline?.id, statusName, enabled: statusName === PipelineStatusName.STARTED || statusName === PipelineStatusName.FAILED, } : undefined const onClose = () => { setDestinationType(null) setEdit(null) } useEffect(() => { if (edit !== null && invalidExistingDestination) { toast(`Unable to find destination ID ${edit}`) setEdit(null) } }, [edit, invalidExistingDestination, setEdit]) return ( <>
{editMode ? 'Edit destination' : 'Create a new destination'} {editMode ? 'Update the configuration for this destination' : 'A destination can be a read replica or an external destination that receives your database changes in real time.'} {destinationType === 'Read Replica' ? ( onSuccessCreateReadReplica?.()} /> ) : !enablePgReplicate ? (

Replicate data to external destinations in real time

External destinations are in alpha{' '} and are being rolled out gradually. Request access below to join the waitlist. Read replicas are available now.

) : replicationNotEnabled ? ( ) : ( )}
) }