import { toast } from 'sonner' import { useParams } from 'common' import { useReplicationPipelineStatusQuery } from 'data/replication/pipeline-status-query' import { useReplicationPipelineVersionQuery } from 'data/replication/pipeline-version-query' import { Pipeline } from 'data/replication/pipelines-query' import { useRestartPipelineHelper } from 'data/replication/restart-pipeline-helper' import { useUpdatePipelineVersionMutation } from 'data/replication/update-pipeline-version-mutation' import { ChevronDown } from 'lucide-react' import { PipelineStatusRequestStatus, usePipelineRequestStatus, } from 'state/replication-pipeline-request-status' import { Collapsible_Shadcn_, CollapsibleContent_Shadcn_, CollapsibleTrigger_Shadcn_, DialogSectionSeparator, } from 'ui' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { getStatusName } from './Pipeline.utils' import { PipelineStatusName, STATUS_REFRESH_FREQUENCY_MS } from './Replication.constants' interface UpdateVersionModalProps { visible: boolean pipeline?: Pipeline confirmLabel?: string confirmLabelLoading?: string onClose: () => void } export const UpdateVersionModal = ({ visible, pipeline, confirmLabel, confirmLabelLoading = 'Updating', onClose, }: UpdateVersionModalProps) => { const { ref: projectRef } = useParams() const { setRequestStatus } = usePipelineRequestStatus() const { data: pipelineStatusData } = useReplicationPipelineStatusQuery( { projectRef, pipelineId: pipeline?.id }, { refetchInterval: STATUS_REFRESH_FREQUENCY_MS } ) const pipelineStatus = pipelineStatusData?.status const statusName = getStatusName(pipelineStatus) const isStopped = statusName === PipelineStatusName.STOPPED const { data: versionData } = useReplicationPipelineVersionQuery({ projectRef, pipelineId: pipeline?.id, }) const currentVersionName = versionData?.version?.name const newVersionName = versionData?.new_version?.name const { mutateAsync: updatePipelineVersion } = useUpdatePipelineVersionMutation() const { restartPipeline } = useRestartPipelineHelper() const onConfirmUpdate = async () => { if (!projectRef || !pipeline?.id) return const versionId = versionData?.new_version?.id if (!versionId) return // Step 1: Update to the new version try { await updatePipelineVersion({ projectRef, pipelineId: pipeline.id, versionId }) } catch (e: any) { // 404: default changed; version cache will refresh via mutation onError. Keep dialog open. if (e?.code === 404) return // Other errors are already toasted by the mutation; do not double-toast here. return } // Step 2: Reflect optimistic restart (only if not stopped) and close any panels if (!isStopped) { setRequestStatus(pipeline.id, PipelineStatusRequestStatus.RestartRequested, statusName) // Step 3: Restart the pipeline (stop + start) try { await restartPipeline({ projectRef, pipelineId: pipeline.id }) toast.success('Pipeline successfully updated and is currently restarting') } catch (e: any) { // Clear optimistic state and surface a single concise error setRequestStatus(pipeline.id, PipelineStatusRequestStatus.None) toast.error('Failed to restart pipeline') } } else { toast.success('Pipeline successfully updated') } onClose() } return (

A new pipeline image is available with improvements and bug fixes. Proceed to update?

{!isStopped && (

The pipeline will automatically restart when updating. Replication will continue from where it left off.

)}

View version update details

Current version:

{' '} {currentVersionName ?? 'Unknown'}

New version:

{' '} {newVersionName ?? 'Unknown'}
) }