RestartProjectDialog.tsx105 lines · main
1'use client'
2
3import { PermissionAction } from '@supabase/shared-types/out/constants'
4import { useRouter } from 'next/router'
5import { toast } from 'sonner'
6import { ConfirmationModal } from 'ui-patterns/Dialogs/ConfirmationModal'
7
8import { useSetProjectStatus } from '@/data/projects/project-detail-query'
9import { useProjectRestartMutation } from '@/data/projects/project-restart-mutation'
10import { useProjectRestartServicesMutation } from '@/data/projects/project-restart-services-mutation'
11import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
12import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
13import { PROJECT_STATUS } from '@/lib/constants'
14
15interface RestartProjectDialogProps {
16 visible: boolean
17 onClose: () => void
18 /** Restart type: 'project' for full restart, 'database' for fast database reboot */
19 restartType?: 'project' | 'database'
20}
21
22export function RestartProjectDialog({
23 visible,
24 onClose,
25 restartType = 'database',
26}: RestartProjectDialogProps) {
27 const router = useRouter()
28 const { data: project } = useSelectedProjectQuery()
29 const { setProjectStatus } = useSetProjectStatus()
30
31 const { can: canRestartProject } = useAsyncCheckPermissions(
32 PermissionAction.INFRA_EXECUTE,
33 'reboot'
34 )
35
36 const { mutate: restartProject, isPending: isRestartingProject } = useProjectRestartMutation({
37 onSuccess: () => {
38 if (project?.ref) {
39 setProjectStatus({ ref: project.ref, status: PROJECT_STATUS.RESTARTING })
40 }
41 toast.success('Restarting project')
42 router.push(`/project/${project?.ref}`)
43 onClose()
44 },
45 onError: (error) => {
46 toast.error(`Unable to restart project: ${error.message}`)
47 },
48 })
49
50 const { mutate: restartProjectServices, isPending: isRestartingServices } =
51 useProjectRestartServicesMutation({
52 onSuccess: () => {
53 if (project?.ref) {
54 setProjectStatus({ ref: project.ref, status: PROJECT_STATUS.RESTARTING })
55 }
56 toast.success('Restarting database')
57 router.push(`/project/${project?.ref}`)
58 onClose()
59 },
60 onError: (error) => {
61 toast.error(`Unable to restart database: ${error.message}`)
62 },
63 })
64
65 const isLoading = isRestartingProject || isRestartingServices
66
67 const handleRestart = () => {
68 if (!project?.ref) return
69
70 if (!canRestartProject) {
71 return toast.error('You do not have the required permissions to restart this project')
72 }
73
74 if (restartType === 'project') {
75 restartProject({ ref: project.ref })
76 } else {
77 restartProjectServices({
78 ref: project.ref,
79 region: project.region,
80 services: ['postgresql'],
81 })
82 }
83 }
84
85 const title = restartType === 'project' ? 'Restart project' : 'Restart database'
86 const description =
87 restartType === 'project'
88 ? 'Are you sure you want to restart your project? There will be a few minutes of downtime.'
89 : 'Are you sure you want to restart your database? There will be a brief downtime.'
90
91 return (
92 <ConfirmationModal
93 visible={visible}
94 variant="warning"
95 title={title}
96 description={description}
97 confirmLabel="Restart"
98 confirmLabelLoading="Restarting"
99 loading={isLoading}
100 disabled={!canRestartProject}
101 onCancel={onClose}
102 onConfirm={handleRestart}
103 />
104 )
105}