import { PermissionAction } from '@supabase/shared-types/out/constants' import { useFlag } from 'common' import { ChevronDown, RefreshCw } from 'lucide-react' import { useRouter } from 'next/router' import { useState } from 'react' import { toast } from 'sonner' import { Button, cn, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from 'ui' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { useSetProjectStatus } from '@/data/projects/project-detail-query' import { useProjectRestartMutation } from '@/data/projects/project-restart-mutation' import { useProjectRestartServicesMutation } from '@/data/projects/project-restart-services-mutation' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useIsAwsK8sCloudProvider, useIsProjectActive, useSelectedProjectQuery, } from '@/hooks/misc/useSelectedProject' import { PROJECT_STATUS } from '@/lib/constants' import { type ResponseError } from '@/types' const RestartServerButton = () => { const router = useRouter() const { data: project } = useSelectedProjectQuery() const isProjectActive = useIsProjectActive() const canRestart = isProjectActive || project?.status === PROJECT_STATUS.ACTIVE_UNHEALTHY const isAwsK8s = useIsAwsK8sCloudProvider() const { setProjectStatus } = useSetProjectStatus() const [serviceToRestart, setServiceToRestart] = useState<'project' | 'database'>() const { projectSettingsRestartProject } = useIsFeatureEnabled([ 'project_settings:restart_project', ]) const projectRef = project?.ref ?? '' const projectRegion = project?.region ?? '' const projectRestartDisabled = useFlag('disableProjectRestarts') const { can: canRestartProject } = useAsyncCheckPermissions( PermissionAction.INFRA_EXECUTE, 'reboot' ) const { mutate: restartProject, isPending: isRestartingProject } = useProjectRestartMutation({ onSuccess: () => { onRestartSuccess() }, onError: (error) => { onRestartFailed(error, 'project') }, }) const { mutate: restartProjectServices, isPending: isRestartingServices } = useProjectRestartServicesMutation({ onSuccess: () => { onRestartSuccess() }, onError: (error) => { onRestartFailed(error, 'database') }, }) const isLoading = isRestartingProject || isRestartingServices const hasRestartDropdown = canRestartProject && canRestart && !projectRestartDisabled const requestProjectRestart = () => { if (!canRestartProject) { return toast.error('You do not have the required permissions to restart this project') } restartProject({ ref: projectRef }) } const requestDatabaseRestart = async () => { if (!canRestartProject) { return toast.error('You do not have the required permissions to restart this project') } restartProjectServices({ ref: projectRef, region: projectRegion, services: ['postgresql'] }) } const onRestartFailed = (error: ResponseError, type: string) => { toast.error(`Unable to restart ${type}: ${error.message}`) setServiceToRestart(undefined) } const onRestartSuccess = () => { setProjectStatus({ ref: projectRef, status: PROJECT_STATUS.RESTARTING }) toast.success('Restarting server...') router.push(`/project/${projectRef}`) setServiceToRestart(undefined) } return ( <> {projectSettingsRestartProject ? (
setServiceToRestart('project')} tooltip={{ content: { side: 'bottom', text: projectRestartDisabled ? 'Project restart is currently disabled' : !canRestartProject ? 'You need additional permissions to restart this project' : !canRestart ? 'Unable to restart project as project is not active' : isAwsK8s ? 'Project restart is not supported for AWS (Revamped) projects' : undefined, }, }} > Restart project {hasRestartDropdown && (
) : ( )} Are you sure you want to restart your {serviceToRestart}? There will be a few minutes of downtime. } confirmLabel="Restart" confirmLabelLoading="Restarting" loading={isLoading} onCancel={() => setServiceToRestart(undefined)} onConfirm={async () => { if (serviceToRestart === 'project') { await requestProjectRestart() } else if (serviceToRestart === 'database') { await requestDatabaseRestart() } }} /> ) } export default RestartServerButton