mirror of
https://github.com/supabase/supabase.git
synced 2026-06-10 04:26:19 +08:00
## Problem Now that we migrated old components to their new shadcn alternatives, we don't need the `_Shadcn_` suffix anymore. ## Solution Remove it <img width="659" height="609" alt="image" src="https://github.com/user-attachments/assets/2d7271a9-066a-4dcc-92fe-729b106d2c2f" />
140 lines
5.4 KiB
TypeScript
140 lines
5.4 KiB
TypeScript
import { useParams } from 'common'
|
|
import { ChevronDown } from 'lucide-react'
|
|
import { toast } from 'sonner'
|
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger, DialogSectionSeparator } from 'ui'
|
|
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
|
|
|
|
import { getStatusName } from './Pipeline.utils'
|
|
import { PipelineStatusName, STATUS_REFRESH_FREQUENCY_MS } from './Replication.constants'
|
|
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 {
|
|
PipelineStatusRequestStatus,
|
|
usePipelineRequestStatus,
|
|
} from '@/state/replication-pipeline-request-status'
|
|
import { type ResponseError } from '@/types'
|
|
|
|
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, isPending: isLoadingVersion } = 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) {
|
|
// 404: default changed; version cache will refresh via mutation onError. Keep dialog open.
|
|
if ((e as ResponseError)?.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) {
|
|
// Clear optimistic state and surface a single concise error
|
|
setRequestStatus(pipeline.id, PipelineStatusRequestStatus.None)
|
|
toast.error(`Failed to restart pipeline: ${(e as ResponseError).message}`)
|
|
}
|
|
} else {
|
|
toast.success('Pipeline successfully updated')
|
|
}
|
|
|
|
onClose()
|
|
}
|
|
|
|
return (
|
|
<ConfirmationModal
|
|
size="small"
|
|
visible={visible}
|
|
title="Update pipeline image"
|
|
className="p-0!"
|
|
confirmLabel={confirmLabel ?? (isStopped ? 'Update image' : 'Update and restart')}
|
|
confirmLabelLoading={confirmLabelLoading}
|
|
onCancel={onClose}
|
|
onConfirm={onConfirmUpdate}
|
|
>
|
|
<div className="flex flex-col gap-y-3 py-4 px-5">
|
|
<p className="text-sm text-foreground">
|
|
A new pipeline image is available with improvements and bug fixes. Proceed to update?
|
|
</p>
|
|
{!isStopped && (
|
|
<p className="text-sm text-foreground-light">
|
|
The pipeline will automatically restart when updating. Replication will continue from
|
|
where it left off.
|
|
</p>
|
|
)}
|
|
</div>
|
|
<DialogSectionSeparator />
|
|
|
|
<Collapsible className="px-5 py-3 group">
|
|
<CollapsibleTrigger className="w-full flex items-center justify-between text-sm text-foreground-light">
|
|
<p>View version update details</p>
|
|
<ChevronDown size={14} className="group-data-open:-rotate-180 transition" />
|
|
</CollapsibleTrigger>
|
|
<CollapsibleContent>
|
|
<div className="flex flex-col gap-y-2 mt-2 pb-2">
|
|
<div className="text-sm text-foreground prose max-w-full">
|
|
<p className="text-foreground-light mb-1">Current version:</p>{' '}
|
|
<code className="text-code-inline">
|
|
{isLoadingVersion ? 'Loading...' : (currentVersionName ?? 'Unknown')}
|
|
</code>
|
|
</div>
|
|
<div className="text-sm text-foreground prose max-w-full">
|
|
<p className="text-foreground-light mb-1">New version:</p>{' '}
|
|
<code className="text-code-inline">
|
|
{isLoadingVersion ? 'Loading...' : (newVersionName ?? 'Unknown')}
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</CollapsibleContent>
|
|
</Collapsible>
|
|
</ConfirmationModal>
|
|
)
|
|
}
|