import { PermissionAction } from '@supabase/shared-types/out/constants' import { useQueryClient } from '@tanstack/react-query' import { ChevronDown } from 'lucide-react' import { useRouter } from 'next/router' import { useState } from 'react' import { toast } from 'sonner' import { useIsProjectActive, useProjectContext, } from 'components/layouts/ProjectLayout/ProjectContext' import { useProjectRestartMutation } from 'data/projects/project-restart-mutation' import { useProjectRestartServicesMutation } from 'data/projects/project-restart-services-mutation' import { setProjectStatus } from 'data/projects/projects-query' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' import { useFlag } from 'hooks/ui/useFlag' import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Tooltip, TooltipContent, TooltipTrigger, cn, } from 'ui' import ConfirmModal from 'ui-patterns/Dialogs/ConfirmDialog' const RestartServerButton = () => { const router = useRouter() const queryClient = useQueryClient() const { project } = useProjectContext() const isProjectActive = useIsProjectActive() const [serviceToRestart, setServiceToRestart] = useState<'project' | 'database'>() const projectRef = project?.ref ?? '' const projectRegion = project?.region ?? '' const projectRestartDisabled = useFlag('disableProjectRestarts') const canRestartProject = useCheckPermissions(PermissionAction.INFRA_EXECUTE, 'reboot') const { mutate: restartProject, isLoading: isRestartingProject } = useProjectRestartMutation({ onSuccess: () => { onRestartSuccess() }, onError: (error) => { onRestartFailed(error, 'project') }, }) const { mutate: restartProjectServices, isLoading: isRestartingServices } = useProjectRestartServicesMutation({ onSuccess: () => { onRestartSuccess() }, onError: (error) => { onRestartFailed(error, 'database') }, }) const isLoading = isRestartingProject || isRestartingServices 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: any, type: string) => { toast.error(`Unable to restart ${type}: ${error.message}`) setServiceToRestart(undefined) } const onRestartSuccess = () => { setProjectStatus(queryClient, projectRef, 'RESTARTING') toast.success('Restarting server...') router.push(`/project/${projectRef}`) setServiceToRestart(undefined) } return ( <>
{canRestartProject && isProjectActive && !projectRestartDisabled && (
{((project !== undefined && (!canRestartProject || !isProjectActive)) || projectRestartDisabled) && ( {projectRestartDisabled ? 'Project restart is currently disabled' : !canRestartProject ? 'You need additional permissions to restart this project' : !isProjectActive ? 'Unable to restart project as project is not active' : ''} )}
Are you sure you want to restart the{' '} {serviceToRestart}? There will be a few minutes of downtime. } buttonLabel="Restart" buttonLoadingLabel="Restarting" onSelectCancel={() => setServiceToRestart(undefined)} onSelectConfirm={async () => { if (serviceToRestart === 'project') { await requestProjectRestart() } else if (serviceToRestart === 'database') { await requestDatabaseRestart() } }} /> ) } export default RestartServerButton