Files
Danny White 0b27205ae4 fix(studio): clarify fast database reboot (#49741)
## What kind of change does this PR introduce?

Bug fix. Resolves DEPR-657.

## What is the current behavior?

The Fast database reboot description suggests the action may fail to
recover from some failure modes, which can be read as a risk of the
reboot itself.

## What is the new behavior?

The description clearly explains that the faster option restarts only
the database service, has less downtime than a full project restart, and
leaves other project services running.

| Before | After |
| --- | --- |
| <img width="1460" height="512" alt="CleanShot 2026-08-31 at 09 24
49@2x"
src="https://github.com/user-attachments/assets/2d4a940c-4d66-4753-99d8-9d0d2b4951af"
/> | <img width="1458" height="500" alt="CleanShot 2026-08-31 at 09 31
18@2x"
src="https://github.com/user-attachments/assets/f58aa351-5c8c-4a9a-b31d-b771659defd3"
/> |

## To test

1. Open a project's **Settings > General** page.
2. Under **Project availability**, tab to **Restart project**, then tab
again to the adjacent chevron button.
3. Press Enter and confirm focus moves to **Fast database reboot**.
4. Confirm its description reads: “Restarts only the database service,
with less downtime than a full project restart. Other project services
remain running.”
5. Confirm the project availability descriptions appear as secondary
text beneath their action labels.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Accessibility Improvements**
* Improved keyboard navigation with separate tab stops for restart
actions and restart-type selection.
* Added clearer labeling and focus behavior when choosing a restart
type.

* **UI Improvements**
* Clarified that fast database restarts affect only PostgreSQL while
other services continue running.
  * Improved text contrast on the project settings page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-31 13:01:17 +10:00

116 lines
4.4 KiB
TypeScript

import Link from 'next/link'
import { Button, Card, CardContent } from 'ui'
import {
PageSection,
PageSectionContent,
PageSectionDescription,
PageSectionMeta,
PageSectionSummary,
PageSectionTitle,
} from 'ui-patterns/PageSection'
import { PauseProjectButton } from './Infrastructure/PauseProjectButton'
import { RestartServerButton } from './Infrastructure/RestartServerButton'
import { ResumeProjectButton } from '@/components/interfaces/Project/ResumeProjectButton'
import { useProjectPauseStatusQuery } from '@/data/projects/project-pause-status-query'
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { PROJECT_STATUS } from '@/lib/constants'
export const Project = () => {
const { data: project } = useSelectedProjectQuery()
const isBranch = Boolean(project?.parent_project_ref)
const isPaused = project?.status === PROJECT_STATUS.INACTIVE
const entityLabel = isBranch ? 'branch' : 'project'
const entityLabelCapitalized = isBranch ? 'Branch' : 'Project'
const { projectSettingsRestartProject } = useIsFeatureEnabled([
'project_settings:restart_project',
])
const {
data: pauseStatus,
isError: isPauseStatusError,
isSuccess: isPauseStatusSuccess,
} = useProjectPauseStatusQuery({ ref: project?.ref }, { enabled: isPaused })
const shouldShowDashboardLink =
isPaused && (isPauseStatusError || (isPauseStatusSuccess && !pauseStatus.can_restore))
const primaryActionLabel = isPaused
? shouldShowDashboardLink
? `View ${entityLabel} dashboard`
: `Resume ${entityLabel}`
: projectSettingsRestartProject
? `Restart ${entityLabel}`
: 'Restart database'
const primaryActionDescription = isPaused
? isPauseStatusSuccess && !pauseStatus.can_restore
? `This ${entityLabel} can no longer be resumed here. Open the dashboard to download backups and view recovery options.`
: isPauseStatusError
? `Open the dashboard to manage this paused ${entityLabel}.`
: `Bring your paused ${entityLabel} back online.`
: `Your ${entityLabel} will not be available for a few minutes.`
return (
<>
<PageSection id="restart-project">
<PageSectionMeta>
<PageSectionSummary>
<PageSectionTitle>{entityLabelCapitalized} availability</PageSectionTitle>
<PageSectionDescription>
{isPaused
? `Resume your paused ${entityLabel} or review recovery options`
: `Restart or pause your ${entityLabel} when performing maintenance`}
</PageSectionDescription>
</PageSectionSummary>
</PageSectionMeta>
<PageSectionContent>
<Card>
<CardContent>
<div className="flex flex-col @lg:flex-row @lg:justify-between @lg:items-center gap-4">
<div>
<p className="text-sm">{primaryActionLabel}</p>
<div className="max-w-[420px]">
<p className="text-sm text-foreground-lighter">{primaryActionDescription}</p>
</div>
</div>
{isPaused ? (
shouldShowDashboardLink ? (
<Button asChild variant="default">
<Link href={`/project/${project?.ref}`}>View project dashboard</Link>
</Button>
) : (
<ResumeProjectButton />
)
) : (
<RestartServerButton />
)}
</div>
</CardContent>
{!isPaused && (
<CardContent>
<div
className="flex w-full flex-col @lg:flex-row @lg:justify-between @lg:items-center gap-4"
id="pause-project"
>
<div>
<p className="text-sm">Pause {entityLabel}</p>
<div className="max-w-[420px]">
<p className="text-sm text-foreground-lighter">
Your {entityLabel} will not be accessible while it is paused.
</p>
</div>
</div>
<PauseProjectButton />
</div>
</CardContent>
)}
</Card>
</PageSectionContent>
</PageSection>
</>
)
}