import Table from 'components/to-be-cleaned/Table' import AlertError from 'components/ui/AlertError' import { ReplicationPipelinesData } from 'data/replication/pipelines-query' import { ResponseError } from 'types' import ShimmeringLoader from 'ui-patterns/ShimmeringLoader' import RowMenu from './RowMenu' import PipelineStatus, { PipelineStatusRequestStatus } from './PipelineStatus' import { useParams } from 'common' import { useReplicationPipelineStatusQuery } from 'data/replication/pipeline-status-query' import { useState } from 'react' import { toast } from 'sonner' import { useStartPipelineMutation } from 'data/replication/start-pipeline-mutation' import { useStopPipelineMutation } from 'data/replication/stop-pipeline-mutation' import { useDeleteDestinationMutation } from 'data/replication/delete-destination-mutation' import DeleteDestination from './DeleteDestination' import DestinationPanel from './DestinationPanel' export type Pipeline = ReplicationPipelinesData['pipelines'][0] const refreshFrequencyMs: number = 5000 interface DestinationRowProps { sourceId: number | undefined destinationId: number destinationName: string type: string pipeline: Pipeline | undefined error: ResponseError | null isLoading: boolean isError: boolean isSuccess: boolean } const DestinationRow = ({ sourceId, destinationId, destinationName, type, pipeline, error: pipelineError, isLoading: isPipelineLoading, isError: isPipelineError, isSuccess: isPipelineSuccess, }: DestinationRowProps) => { const { ref: projectRef } = useParams() const [showDeleteDestinationForm, setShowDeleteDestinationForm] = useState(false) const [showEditDestinationPanel, setShowEditDestinationPanel] = useState(false) const { data: pipelineStatusData, error: pipelineStatusError, isLoading: isPipelineStatusLoading, isError: isPipelineStatusError, isSuccess: isPipelineStatusSuccess, } = useReplicationPipelineStatusQuery( { projectRef, pipelineId: pipeline?.id, }, { refetchInterval: refreshFrequencyMs } ) const [requestStatus, setRequestStatus] = useState( PipelineStatusRequestStatus.None ) const { mutateAsync: startPipeline } = useStartPipelineMutation() const { mutateAsync: stopPipeline } = useStopPipelineMutation() const pipelineStatus = pipelineStatusData?.status if ( (requestStatus === PipelineStatusRequestStatus.EnableRequested && pipelineStatus === 'Started') || (requestStatus === PipelineStatusRequestStatus.DisableRequested && pipelineStatus === 'Stopped') ) { setRequestStatus(PipelineStatusRequestStatus.None) } const onEnableClick = async () => { if (!projectRef) { console.error('Project ref is required') return } if (!pipeline) { toast.error('No pipeline found') return } try { await startPipeline({ projectRef, pipelineId: pipeline.id }) } catch (error) { toast.error('Failed to enable destination') } setRequestStatus(PipelineStatusRequestStatus.EnableRequested) } const onDisableClick = async () => { if (!projectRef) { console.error('Project ref is required') return } if (!pipeline) { toast.error('No pipeline found') return } try { await stopPipeline({ projectRef, pipelineId: pipeline.id }) } catch (error) { toast.error('Failed to disable destination') } setRequestStatus(PipelineStatusRequestStatus.DisableRequested) } const { mutateAsync: deleteDestination } = useDeleteDestinationMutation({}) const onDeleteClick = async () => { if (!projectRef) { console.error('Project ref is required') return } if (!pipeline) { toast.error('No pipeline found') return } try { await stopPipeline({ projectRef, pipelineId: pipeline.id }) // deleting the destination also deletes the pipeline because of cascade delete // so we don't need to call deletePipeline explicitly await deleteDestination({ projectRef, destinationId: destinationId }) } catch (error) { toast.error('Failed to delete destination') } } return ( <> {isPipelineError && ( )} {isPipelineSuccess && ( {isPipelineLoading ? : destinationName} {isPipelineLoading ? : type} {isPipelineLoading || !pipeline ? ( ) : ( )} {isPipelineLoading || !pipeline ? ( ) : ( pipeline.config.publication_name )} setShowDeleteDestinationForm(true)} onEditClick={() => setShowEditDestinationPanel(true)} > )} setShowEditDestinationPanel(false)} sourceId={sourceId} existingDestination={{ sourceId, destinationId: destinationId, pipelineId: pipeline?.id, enabled: pipelineStatusData?.status === 'Started', }} /> ) } export default DestinationRow