import { SupportCategories } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import { SupportLink } from 'components/interfaces/Support/SupportLink' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useBackupDownloadMutation } from 'data/database/backup-download-mutation' import { useDownloadableBackupQuery } from 'data/database/backup-query' import { useInvalidateProjectDetailsQuery } from 'data/projects/project-detail-query' import { useProjectStatusQuery } from 'data/projects/project-status-query' import dayjs from 'dayjs' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { PROJECT_STATUS } from 'lib/constants' import { CheckCircle, Download, Loader } from 'lucide-react' import { useEffect, useState } from 'react' import { Button, Dialog, DialogContent, DialogFooter, DialogHeader, DialogSection, DialogSectionSeparator, DialogTitle, DialogTrigger, } from 'ui' export const RestoringState = () => { const { ref } = useParams() const { data: project } = useSelectedProjectQuery() const [loading, setLoading] = useState(false) const [isCompleted, setIsCompleted] = useState(false) const { data } = useDownloadableBackupQuery({ projectRef: ref }) const backups = data?.backups ?? [] const logicalBackups = backups.filter((b) => !b.isPhysicalBackup) const { invalidateProjectDetailsQuery } = useInvalidateProjectDetailsQuery() const { data: projectStatusData, isSuccess: isProjectStatusSuccess } = useProjectStatusQuery( { projectRef: ref }, { enabled: project?.status !== PROJECT_STATUS.ACTIVE_HEALTHY, refetchInterval: (query) => { const data = query.state.data return data?.status === PROJECT_STATUS.ACTIVE_HEALTHY ? false : 4000 }, } ) const restoreInitiatedSinceMinutes = dayjs().diff(dayjs.utc(project?.updated_at), 'minute') const showSupportCta = restoreInitiatedSinceMinutes >= 30 const { mutate: downloadBackup, isPending: isDownloading } = useBackupDownloadMutation({ onSuccess: (res) => { const { fileUrl } = res // Trigger browser download by create,trigger and remove tempLink const tempLink = document.createElement('a') tempLink.href = fileUrl document.body.appendChild(tempLink) tempLink.click() document.body.removeChild(tempLink) }, }) const onClickDownloadBackup = () => { if (!ref) return console.error('Project ref is required') if (logicalBackups.length === 0) return console.error('No available backups to download') downloadBackup({ ref, backup: logicalBackups[0] }) } const onConfirm = async () => { if (!project) return console.error('Project is required') setLoading(true) if (ref) await invalidateProjectDetailsQuery(ref) } useEffect(() => { if (isProjectStatusSuccess && projectStatusData.status === PROJECT_STATUS.ACTIVE_HEALTHY) { setIsCompleted(true) } }, [isProjectStatusSuccess, projectStatusData]) return (
{isCompleted ? (

Restoration complete!

Your project has been successfully restored and is now back online.

) : ( <>

Restoration in progress

Restoration can take from a few minutes up to several hours depending on the size of your database. Your project will be offline while the restoration is running.

{showSupportCta && ( Restoration taking longer than expected?

Restores may take from a minutes up to several hours depending on the size of your database. However, if the restoration process is taking far longer than expected for the size of your database, you may reach out to us via Support for help.

)} } loading={isDownloading} disabled={logicalBackups.length === 0} tooltip={{ content: { side: 'bottom', text: logicalBackups.length === 0 ? 'No available backups to download' : undefined, }, }} onClick={onClickDownloadBackup} > Download latest backup
)}
) }