Skip to content

Commit 99c147a

Browse files
delgado3djoshenlim
andauthored
feat: support for restarting and resizing statuses (supabase#29881)
* start using restarting and resizing statuses * pretty 1 * Minor updates * Small revert, to prevent conflicts * PRETTY --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
1 parent ca80c28 commit 99c147a

File tree

11 files changed

+106
-37
lines changed

11 files changed

+106
-37
lines changed

apps/studio/components/interfaces/Home/ProjectList/ProjectCard.utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ export const inferProjectStatus = (project: ProjectInfo) => {
2020
case PROJECT_STATUS.RESTARTING:
2121
status = 'isRestarting'
2222
break
23+
case PROJECT_STATUS.RESIZING:
24+
status = 'isResizing'
25+
break
2326
case PROJECT_STATUS.RESTORING:
2427
status = 'isRestoring'
2528
break
@@ -43,6 +46,7 @@ export type InferredProjectStatus =
4346
| 'isPaused'
4447
| 'isPauseFailed'
4548
| 'isRestarting'
49+
| 'isResizing'
4650
| 'isRestoring'
4751
| 'isRestoreFailed'
4852
| 'isComingUp'

apps/studio/components/interfaces/Home/ProjectList/ProjectCardStatus.tsx

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
import * as Tooltip from '@radix-ui/react-tooltip'
1+
import { AlertTriangle, Info, PauseCircle, RefreshCcw } from 'lucide-react'
2+
23
import { RESOURCE_WARNING_MESSAGES } from 'components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.constants'
34
import { getWarningContent } from 'components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.utils'
45
import type { ResourceWarning } from 'data/usage/resource-warnings-query'
5-
import { AlertTriangle, Info, PauseCircle, RefreshCcw } from 'lucide-react'
6-
import { Alert_Shadcn_, AlertTitle_Shadcn_, cn } from 'ui'
6+
import {
7+
Alert_Shadcn_,
8+
AlertTitle_Shadcn_,
9+
cn,
10+
Tooltip_Shadcn_,
11+
TooltipContent_Shadcn_,
12+
TooltipTrigger_Shadcn_,
13+
} from 'ui'
714
import { InferredProjectStatus } from './ProjectCard.utils'
815

916
export interface ProjectCardWarningsProps {
@@ -50,6 +57,7 @@ export const ProjectCardStatus = ({
5057
if (projectStatus === 'isPaused') return 'Project is paused'
5158
if (projectStatus === 'isPausing') return 'Project is pausing'
5259
if (projectStatus === 'isRestarting') return 'Project is restarting'
60+
if (projectStatus === 'isResizing') return 'Project is resizing'
5361
if (projectStatus === 'isComingUp') return 'Project is coming up'
5462
if (projectStatus === 'isRestoring') return 'Project is restoring'
5563
if (projectStatus === 'isUpgrading') return 'Project is upgrading'
@@ -67,14 +75,21 @@ export const ProjectCardStatus = ({
6775
}
6876

6977
const getDescription = () => {
70-
if (projectStatus === 'isPaused') return 'This project will not accept requests until resumed'
71-
if (projectStatus === 'isPausing') return 'The pause process will complete in a few minutes'
72-
if (projectStatus === 'isRestarting') return 'Your project will be ready in a few minutes'
73-
if (projectStatus === 'isComingUp') return 'Your project will be ready in a few minutes'
74-
if (projectStatus === 'isRestoring') return 'Your project will be ready in a few minutes'
75-
if (projectStatus === 'isUpgrading') return 'Your project will be ready in a few minutes'
76-
if (projectStatus === 'isRestoreFailed') return 'Please contact support for assistance'
77-
if (projectStatus === 'isPauseFailed') return 'Please contact support for assistance'
78+
switch (projectStatus) {
79+
case 'isPaused':
80+
return 'This project will not accept requests until resumed'
81+
case 'isPausing':
82+
return 'The pause process will complete in a few minutes'
83+
case 'isRestarting':
84+
case 'isResizing':
85+
case 'isComingUp':
86+
case 'isRestoring':
87+
case 'isUpgrading':
88+
return 'Your project will be ready in a few minutes'
89+
case 'isRestoreFailed':
90+
case 'isPauseFailed':
91+
return 'Please contact support for assistance'
92+
}
7893

7994
if (!resourceWarnings) return undefined
8095

@@ -111,35 +126,23 @@ export const ProjectCardStatus = ({
111126
!isCritical ? '[&>svg]:text-foreground [&>svg]:bg-surface-100' : ''
112127
)}
113128
>
114-
{projectStatus === 'isPaused' || projectStatus === 'isPausing' ? (
129+
{['isPaused', 'isPausing'].includes(projectStatus ?? '') ? (
115130
<PauseCircle strokeWidth={1.5} size={12} />
116-
) : projectStatus === 'isRestoring' ||
117-
projectStatus === 'isComingUp' ||
118-
projectStatus === 'isRestarting' ? (
131+
) : ['isRestoring', 'isComingUp', 'isRestarting', 'isResizing'].includes(
132+
projectStatus ?? ''
133+
) ? (
119134
<RefreshCcw strokeWidth={1.5} size={12} />
120135
) : (
121136
<AlertTriangle strokeWidth={1.5} size={12} />
122137
)}
123138
<div className="flex justify-between items-center w-full gap-x-1">
124139
<AlertTitle_Shadcn_ className="text-xs mb-0">{alertTitle}</AlertTitle_Shadcn_>
125-
<Tooltip.Root delayDuration={0}>
126-
<Tooltip.Trigger>
140+
<Tooltip_Shadcn_>
141+
<TooltipTrigger_Shadcn_>
127142
<Info size={14} className="text-foreground-light hover:text-foreground" />
128-
</Tooltip.Trigger>
129-
<Tooltip.Portal>
130-
<Tooltip.Content side="bottom">
131-
<Tooltip.Arrow className="radix-tooltip-arrow" />
132-
<div
133-
className={[
134-
'rounded bg-alternative py-1 px-2 leading-none shadow',
135-
'border bg-studio w-[280px]',
136-
].join(' ')}
137-
>
138-
<span className="text-xs text-foreground">{alertDescription}</span>
139-
</div>
140-
</Tooltip.Content>
141-
</Tooltip.Portal>
142-
</Tooltip.Root>
143+
</TooltipTrigger_Shadcn_>
144+
<TooltipContent_Shadcn_ side="bottom">{alertDescription}</TooltipContent_Shadcn_>
145+
</Tooltip_Shadcn_>
143146
</div>
144147
</Alert_Shadcn_>
145148
)

apps/studio/components/interfaces/Settings/Addons/ComputeInstanceSidePanel.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Link from 'next/link'
55
import { useRouter } from 'next/router'
66
import { useEffect, useMemo, useState } from 'react'
77
import { toast } from 'sonner'
8+
import { ExternalLink, Info } from 'lucide-react'
89

910
import { useParams } from 'common'
1011
import {
@@ -37,7 +38,6 @@ import {
3738
SidePanel,
3839
WarningIcon,
3940
} from 'ui'
40-
import { ExternalLink, Info } from 'lucide-react'
4141

4242
const ComputeInstanceSidePanel = () => {
4343
const queryClient = useQueryClient()
@@ -68,7 +68,7 @@ const ComputeInstanceSidePanel = () => {
6868
`Successfully updated compute instance to ${selectedCompute?.name}. Your project is currently being restarted to update its instance`,
6969
{ duration: 8000 }
7070
)
71-
setProjectStatus(queryClient, projectRef!, PROJECT_STATUS.RESTORING)
71+
setProjectStatus(queryClient, projectRef!, PROJECT_STATUS.RESIZING)
7272
closePanel()
7373
router.push(`/project/${projectRef}`)
7474
},
@@ -82,7 +82,7 @@ const ComputeInstanceSidePanel = () => {
8282
`Successfully updated compute instance. Your project is currently being restarted to update its instance`,
8383
{ duration: 8000 }
8484
)
85-
setProjectStatus(queryClient, projectRef!, PROJECT_STATUS.RESTORING)
85+
setProjectStatus(queryClient, projectRef!, PROJECT_STATUS.RESIZING)
8686
closePanel()
8787
router.push(`/project/${projectRef}`)
8888
},

apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ export const ReplicaNode = ({ data }: NodeProps<ReplicaNodeData>) => {
207207
REPLICA_STATUS.COMING_UP,
208208
REPLICA_STATUS.GOING_DOWN,
209209
REPLICA_STATUS.RESTORING,
210+
REPLICA_STATUS.RESTARTING,
211+
REPLICA_STATUS.RESIZING,
210212
REPLICA_STATUS.INIT_READ_REPLICA,
211213
] as string[]
212214
).includes(status) || initStatus === ReplicaInitializationStatus.InProgress
@@ -266,6 +268,10 @@ export const ReplicaNode = ({ data }: NodeProps<ReplicaNodeData>) => {
266268
<Badge>Going down</Badge>
267269
) : status === REPLICA_STATUS.RESTORING ? (
268270
<Badge>Restarting</Badge>
271+
) : status === REPLICA_STATUS.RESTARTING ? (
272+
<Badge>Restarting</Badge>
273+
) : status === REPLICA_STATUS.RESIZING ? (
274+
<Badge>Resizing</Badge>
269275
) : initStatus === ReplicaInitializationStatus.Completed &&
270276
status === REPLICA_STATUS.ACTIVE_HEALTHY ? (
271277
<Badge variant="brand">Healthy</Badge>

apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/MapView.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ const MapView = ({
273273
<Badge>Coming up</Badge>
274274
) : database.status === REPLICA_STATUS.RESTORING ? (
275275
<Badge>Restarting</Badge>
276+
) : database.status === REPLICA_STATUS.RESTARTING ? (
277+
<Badge>Restarting</Badge>
278+
) : database.status === REPLICA_STATUS.RESIZING ? (
279+
<Badge>Resizing</Badge>
276280
) : (
277281
<Badge variant="warning">Unhealthy</Badge>
278282
)}

apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/RestartReplicaConfirmationModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const RestartReplicaConfirmationModal = ({
3232
queryClient.setQueriesData<any>(replicaKeys.list(ref), (old: Database[]) => {
3333
const updatedReplicas = old.map((x) => {
3434
if (x.identifier === selectedReplica?.identifier) {
35-
return { ...x, status: REPLICA_STATUS.RESTORING }
35+
return { ...x, status: REPLICA_STATUS.RESTARTING }
3636
} else {
3737
return x
3838
}

apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import RestartingState from './RestartingState'
3030
import RestoreFailedState from './RestoreFailedState'
3131
import RestoringState from './RestoringState'
3232
import { UpgradingState } from './UpgradingState'
33+
import { ResizingState } from './ResizingState'
3334

3435
// [Joshen] This is temporary while we unblock users from managing their project
3536
// if their project is not responding well for any reason. Eventually needs a bit of an overhaul
@@ -239,6 +240,7 @@ const ContentWrapper = ({ isLoading, isBlocking = true, children }: ContentWrapp
239240
const requiresProjectDetails = !routesToIgnoreProjectDetailsRequest.includes(router.pathname)
240241

241242
const isRestarting = selectedProject?.status === PROJECT_STATUS.RESTARTING
243+
const isResizing = selectedProject?.status === PROJECT_STATUS.RESIZING
242244
const isProjectUpgrading = selectedProject?.status === PROJECT_STATUS.UPGRADING
243245
const isProjectRestoring = selectedProject?.status === PROJECT_STATUS.RESTORING
244246
const isProjectRestoreFailed = selectedProject?.status === PROJECT_STATUS.RESTORE_FAILED
@@ -263,6 +265,10 @@ const ContentWrapper = ({ isLoading, isBlocking = true, children }: ContentWrapp
263265
return <RestartingState />
264266
}
265267

268+
if (isResizing && !isBackupsPage) {
269+
return <ResizingState />
270+
}
271+
266272
if (isProjectUpgrading && !isBackupsPage) {
267273
return <UpgradingState />
268274
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { useParams } from 'common'
2+
import { Loader2 } from 'lucide-react'
3+
4+
import { useProjectDetailQuery } from 'data/projects/project-detail-query'
5+
import { PROJECT_STATUS } from 'lib/constants'
6+
7+
export const ResizingState = () => {
8+
const { ref } = useParams()
9+
useProjectDetailQuery(
10+
{ ref },
11+
{
12+
// setting a refetch interval here will cause the `useSelectedProject()` in `ProjectLayout.tsx` to
13+
// rerender every 4 seconds while the project is resizing. Once resizing is complete, it will
14+
// no longer show this state.
15+
refetchInterval(data) {
16+
return data?.status !== PROJECT_STATUS.ACTIVE_HEALTHY ? 4000 : false
17+
},
18+
}
19+
)
20+
21+
return (
22+
<div className="flex items-center justify-center h-full">
23+
<div className="bg-surface-100 border border-overlay rounded-md w-3/4 lg:w-1/2">
24+
<div className="space-y-6 py-6">
25+
<div className="flex px-8 space-x-8">
26+
<div className="mt-1">
27+
<Loader2 className="animate-spin" size={18} />
28+
</div>
29+
<div className="space-y-1">
30+
<p>Resizing project...</p>
31+
<p className="text-sm text-foreground-light">
32+
Your project is being restarted to apply compute size changes. It can take a few
33+
minutes. Your project will be offline while it is being restarted.
34+
</p>
35+
</div>
36+
</div>
37+
</div>
38+
</div>
39+
</div>
40+
)
41+
}

apps/studio/data/organizations/organization-billing-subscription-preview.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ export type OrganizationBillingSubscriptionPreviewResponse = {
3535
| 'INIT_FAILED'
3636
| 'REMOVED'
3737
| 'RESTORING'
38+
| 'RESTARTING'
39+
| 'RESIZING'
3840
| 'UPGRADING'
3941
instance_size: string
4042
name: string

apps/studio/lib/constants/infrastructure.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const PROJECT_STATUS: {
5858
UPGRADING: 'UPGRADING',
5959
PAUSING: 'PAUSING',
6060
PAUSE_FAILED: 'PAUSE_FAILED',
61+
RESIZING: 'RESIZING',
6162
}
6263

6364
export const DEFAULT_MINIMUM_PASSWORD_STRENGTH = 4

0 commit comments

Comments
 (0)