From ad2ac05d7daba8db32a5e513b488084e5114eb76 Mon Sep 17 00:00:00 2001 From: Danny White <3104761+dnywh@users.noreply.github.com> Date: Mon, 15 Dec 2025 10:15:24 +1000 Subject: [PATCH] fix(studio): project resume dialog (#41300) * move desc to body * better copy * loading label * smol gap change * nit * Nit * NIt * Attemt * fix --------- Co-authored-by: Joshen Lim --- .../PausedState/PauseDisabledState.tsx | 17 +++- .../PausedState/ProjectPausedState.tsx | 79 +++++++++++-------- .../layouts/ProjectLayout/PausingState.tsx | 16 ++-- .../layouts/ProjectLayout/RestoringState.tsx | 5 -- .../layouts/ProjectLayout/index.tsx | 2 +- 5 files changed, 67 insertions(+), 52 deletions(-) diff --git a/apps/studio/components/layouts/ProjectLayout/PausedState/PauseDisabledState.tsx b/apps/studio/components/layouts/ProjectLayout/PausedState/PauseDisabledState.tsx index 4929166d957..90b85ea5a45 100644 --- a/apps/studio/components/layouts/ProjectLayout/PausedState/PauseDisabledState.tsx +++ b/apps/studio/components/layouts/ProjectLayout/PausedState/PauseDisabledState.tsx @@ -19,7 +19,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from 'ui' -import { Admonition } from 'ui-patterns' +import { Admonition, TimestampInfo } from 'ui-patterns' export const PauseDisabledState = () => { const { ref } = useParams() @@ -121,10 +121,10 @@ export const PauseDisabledState = () => { -

+

This project has been paused for over{' '} {pauseStatus?.max_days_till_restore_disabled ?? 90} days @@ -133,6 +133,17 @@ export const PauseDisabledState = () => { downloaded as a backup.

+ {!!pauseStatus?.last_paused_on && ( +

+ Project last paused on{' '} + +

+ )} +

Recovery options:

    diff --git a/apps/studio/components/layouts/ProjectLayout/PausedState/ProjectPausedState.tsx b/apps/studio/components/layouts/ProjectLayout/PausedState/ProjectPausedState.tsx index 366cb1463ca..9899cd98fd2 100644 --- a/apps/studio/components/layouts/ProjectLayout/PausedState/ProjectPausedState.tsx +++ b/apps/studio/components/layouts/ProjectLayout/PausedState/ProjectPausedState.tsx @@ -93,7 +93,7 @@ export const ProjectPausedState = ({ product }: ProjectPausedStateProps) => { const { mutate: restoreProject, isPending: isRestoring } = useProjectRestoreMutation({ onSuccess: (_, variables) => { setProjectStatus({ ref: variables.ref, status: PROJECT_STATUS.RESTORING }) - toast.success('Restoring project') + toast.success('Restoring project, project will be ready in a few minutes') }, }) @@ -185,11 +185,21 @@ export const ProjectPausedState = ({ product }: ProjectPausedStateProps) => { ). After that, this project will not be resumable, but data will still be available for download.

    -

    +

    {enableProBenefitWording === 'variant-a' ? 'Upgrade to Pro to prevent pauses and unlock features like branching, compute upgrades, and daily backups.' : 'To prevent future pauses, consider upgrading to Pro.'}

    + {!!pauseStatus.last_paused_on && ( +

    + Project last paused on{' '} + +

    + )} ) : (

    @@ -264,43 +274,46 @@ export const ProjectPausedState = ({ product }: ProjectPausedStateProps) => { setShowConfirmRestore(false)} onConfirm={() => form.handleSubmit(onConfirmRestore)()} loading={isRestoring} - confirmLabel="Confirm resume" + confirmLabel="Resume" + confirmLabelLoading="Resuming" cancelLabel="Cancel" > - -

    - {showPostgresVersionSelector && ( -
    - ( - - )} - /> -
    - )} -
    - +
    +

    + {isFreePlan + ? 'Your project’s data will be restored to when it was initially paused.' + : 'Your project’s data will be restored and billing will resume based on compute size and hours active.'} +

    + +
    + {showPostgresVersionSelector && ( +
    + ( + + )} + /> +
    + )} +
    +
    +
    { +export const PausingState = ({ project }: PausingStateProps) => { const { ref } = useParams() const [startPolling, setStartPolling] = useState(false) @@ -33,9 +33,7 @@ const PausingState = ({ project }: PausingStateProps) => { useEffect(() => { if (!isProjectStatusSuccess) return if (projectStatusData?.status === PROJECT_STATUS.INACTIVE) { - if (ref) { - invalidateProjectDetailsQuery(ref) - } + if (ref) invalidateProjectDetailsQuery(ref) invalidateProjectsQuery() } }, [ @@ -85,5 +83,3 @@ const PausingState = ({ project }: PausingStateProps) => {
) } - -export default PausingState diff --git a/apps/studio/components/layouts/ProjectLayout/RestoringState.tsx b/apps/studio/components/layouts/ProjectLayout/RestoringState.tsx index 43ae5f80dd5..35944239661 100644 --- a/apps/studio/components/layouts/ProjectLayout/RestoringState.tsx +++ b/apps/studio/components/layouts/ProjectLayout/RestoringState.tsx @@ -41,10 +41,6 @@ const RestoringState = () => { if (!isProjectStatusSuccess) return if (projectStatusData.status === PROJECT_STATUS.ACTIVE_HEALTHY) { setIsCompleted(true) - } else { - if (ref) { - invalidateProjectDetailsQuery(ref) - } } }, [isProjectStatusSuccess, projectStatusData, ref, invalidateProjectDetailsQuery]) @@ -70,7 +66,6 @@ const RestoringState = () => { const onConfirm = async () => { if (!project) return console.error('Project is required') - setLoading(true) if (ref) await invalidateProjectDetailsQuery(ref) } diff --git a/apps/studio/components/layouts/ProjectLayout/index.tsx b/apps/studio/components/layouts/ProjectLayout/index.tsx index b987038cf74..3ffa96b4852 100644 --- a/apps/studio/components/layouts/ProjectLayout/index.tsx +++ b/apps/studio/components/layouts/ProjectLayout/index.tsx @@ -23,7 +23,7 @@ import ConnectingState from './ConnectingState' import { LoadingState } from './LoadingState' import { ProjectPausedState } from './PausedState/ProjectPausedState' import { PauseFailedState } from './PauseFailedState' -import PausingState from './PausingState' +import { PausingState } from './PausingState' import ProductMenuBar from './ProductMenuBar' import { ResizingState } from './ResizingState' import RestartingState from './RestartingState'