mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 09:59:03 +08:00
## Context As per PR title, disables disk management for HA projects, which involves - Disabling "Increase disk size" CTAs in reports/database and the old disk config settings in database/settings - Disabling all input fields related to disk management in settings/infrastructure <img width="1076" height="857" alt="image" src="https://github.com/user-attachments/assets/bfbdfc36-8ae3-41ce-af12-c05b46e620f4" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added High Availability notices and restrictions throughout disk management settings. * Disabled disk size, IOPS, throughput, and autoscaling controls where High Availability limits changes. * Added explanatory tooltips for restricted disk-size actions. * Updated database observability controls to reflect High Availability restrictions. * **Accessibility** * Added an accessible label to the database observability refresh button. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
340 lines
12 KiB
TypeScript
340 lines
12 KiB
TypeScript
import { type RefObject } from 'react'
|
|
import { type UseFormReturn } from 'react-hook-form'
|
|
import { Button, Card, CardContent } from 'ui'
|
|
import { Admonition } from 'ui-patterns/Admonition'
|
|
import {
|
|
PageSection,
|
|
PageSectionAside,
|
|
PageSectionContent,
|
|
PageSectionDescription,
|
|
PageSectionMeta,
|
|
PageSectionSummary,
|
|
PageSectionTitle,
|
|
} from 'ui-patterns/PageSection'
|
|
|
|
import { DiskStorageSchemaType } from './DiskManagement.schema'
|
|
import { AutoScaleFields } from './fields/AutoScaleFields'
|
|
import {
|
|
ComputeSectionBillingBadge,
|
|
ComputeSizeField,
|
|
ComputeSizeFieldMeta,
|
|
} from './fields/ComputeSizeField'
|
|
import { DiskSizeField } from './fields/DiskSizeField'
|
|
import { IOPSField } from './fields/IOPSField'
|
|
import { StorageTypeField } from './fields/StorageTypeField'
|
|
import { ThroughputField } from './fields/ThroughputField'
|
|
import { BillingChangeBadge } from './ui/BillingChangeBadge'
|
|
import { DiskCountdownRadial } from './ui/DiskCountdownRadial'
|
|
import { DiskSpaceBar } from './ui/DiskSpaceBar'
|
|
import { NoticeBar } from './ui/NoticeBar'
|
|
import { SpendCapDisabledSection } from './ui/SpendCapDisabledSection'
|
|
import { DocsButton } from '@/components/ui/DocsButton'
|
|
import { HighAvailabilityDisabledSectionNotice } from '@/components/ui/HighAvailability/HighAvailabilityDisabledSectionNotice'
|
|
import { RequestUpgradeToBillingOwners } from '@/components/ui/RequestUpgradeToBillingOwners'
|
|
import { DOCS_URL } from '@/lib/constants'
|
|
|
|
interface ComputeSectionProps {
|
|
form: UseFormReturn<DiskStorageSchemaType>
|
|
settingsRef: RefObject<HTMLDivElement | null>
|
|
showBillingBadge: boolean
|
|
beforePrice: number
|
|
afterPrice: number
|
|
disabled: boolean
|
|
}
|
|
|
|
export function ComputeSection({
|
|
form,
|
|
settingsRef,
|
|
showBillingBadge,
|
|
beforePrice,
|
|
afterPrice,
|
|
disabled,
|
|
}: ComputeSectionProps) {
|
|
return (
|
|
<PageSection className="pt-0">
|
|
<PageSectionMeta>
|
|
<PageSectionSummary>
|
|
<PageSectionTitle className="heading-default text-base">Compute size</PageSectionTitle>
|
|
<PageSectionDescription>
|
|
<ComputeSizeFieldMeta />
|
|
</PageSectionDescription>
|
|
</PageSectionSummary>
|
|
<PageSectionAside>
|
|
<ComputeSectionBillingBadge
|
|
form={form}
|
|
show={showBillingBadge}
|
|
beforePrice={beforePrice}
|
|
afterPrice={afterPrice}
|
|
/>
|
|
<DocsButton href={`${DOCS_URL}/guides/platform/compute-and-disk`} />
|
|
</PageSectionAside>
|
|
</PageSectionMeta>
|
|
<PageSectionContent
|
|
ref={settingsRef}
|
|
id="compute"
|
|
className="scroll-mt-24 flex flex-col gap-4"
|
|
>
|
|
<HighAvailabilityDisabledSectionNotice
|
|
title="Compute size can't be changed on High Availability projects"
|
|
description="High Availability projects run on a fixed compute size during Alpha. Contact support if this is blocking your work."
|
|
/>
|
|
<ComputeSizeField form={form} disabled={disabled} />
|
|
</PageSectionContent>
|
|
</PageSection>
|
|
)
|
|
}
|
|
|
|
interface DiskSectionProps {
|
|
form: UseFormReturn<DiskStorageSchemaType>
|
|
settingsRef: RefObject<HTMLDivElement | null>
|
|
showBillingBadge: boolean
|
|
beforePrice: number
|
|
afterPrice: number
|
|
isAws: boolean
|
|
isAwsK8s: boolean
|
|
isBranch: boolean
|
|
isNoticeVisible: boolean
|
|
isReadOnlyMode: boolean
|
|
usedPercentage: number
|
|
isWithinCooldownWindow: boolean
|
|
currentDiskSizeGb?: number
|
|
disableDiskSizeInput: boolean
|
|
}
|
|
|
|
function getDiskNoticeDescription({
|
|
isAwsK8s,
|
|
isBranch,
|
|
}: Pick<DiskSectionProps, 'isAwsK8s' | 'isBranch'>) {
|
|
if (isAwsK8s) {
|
|
return 'Configuring your disk for AWS (Revamped) projects is unavailable for now.'
|
|
}
|
|
if (isBranch) {
|
|
return 'Delete and recreate your Preview Branch to configure disk size. It was deployed on an older branching infrastructure.'
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
export function DiskSection({
|
|
form,
|
|
settingsRef,
|
|
showBillingBadge,
|
|
beforePrice,
|
|
afterPrice,
|
|
isAws,
|
|
isAwsK8s,
|
|
isBranch,
|
|
isNoticeVisible,
|
|
isReadOnlyMode,
|
|
usedPercentage,
|
|
isWithinCooldownWindow,
|
|
currentDiskSizeGb,
|
|
disableDiskSizeInput,
|
|
}: DiskSectionProps) {
|
|
const noticeDescription = getDiskNoticeDescription({ isAwsK8s, isBranch })
|
|
|
|
return (
|
|
<PageSection id="disk-size">
|
|
<PageSectionMeta>
|
|
<PageSectionSummary>
|
|
<PageSectionTitle className="heading-default text-base">Disk</PageSectionTitle>
|
|
<PageSectionDescription>
|
|
Configure provisioned storage for your primary database.
|
|
</PageSectionDescription>
|
|
</PageSectionSummary>
|
|
<PageSectionAside>
|
|
<BillingChangeBadge
|
|
show={showBillingBadge}
|
|
beforePrice={beforePrice}
|
|
afterPrice={afterPrice}
|
|
/>
|
|
<DocsButton href={`${DOCS_URL}/guides/platform/database-size`} />
|
|
</PageSectionAside>
|
|
</PageSectionMeta>
|
|
|
|
<HighAvailabilityDisabledSectionNotice title="Disk management is unavailable for High Availability projects" />
|
|
|
|
<PageSectionContent ref={settingsRef} className="flex flex-col gap-4 scroll-mt-24">
|
|
{isAws && <DiskSpaceBar form={form} />}
|
|
|
|
<SpendCapDisabledSection currentDiskSizeGb={currentDiskSizeGb} />
|
|
|
|
<NoticeBar
|
|
type="default"
|
|
visible={isNoticeVisible}
|
|
title="Disk configuration is only available for projects in the AWS cloud provider"
|
|
description={noticeDescription}
|
|
/>
|
|
|
|
{isAws && (
|
|
<>
|
|
<div className="flex flex-col gap-y-3">
|
|
<DiskCountdownRadial />
|
|
{!isReadOnlyMode && usedPercentage >= 90 && isWithinCooldownWindow && (
|
|
<Admonition
|
|
type="destructive"
|
|
title="Database size is currently over 90% of disk size"
|
|
description="Your project will enter read-only mode once you reach 95% of the disk space to prevent your database from exceeding the disk limitations"
|
|
>
|
|
<DocsButton
|
|
abbrev={false}
|
|
className="mt-2"
|
|
href={`${DOCS_URL}/guides/platform/database-size#read-only-mode`}
|
|
/>
|
|
</Admonition>
|
|
)}
|
|
{isReadOnlyMode && (
|
|
<Admonition
|
|
type="destructive"
|
|
title="Project is currently in read-only mode"
|
|
description="You will need to manually override read-only mode and reduce the database size to below 95% of the disk size"
|
|
>
|
|
<DocsButton
|
|
abbrev={false}
|
|
className="mt-2"
|
|
href={`${DOCS_URL}/guides/platform/database-size#disabling-read-only-mode`}
|
|
/>
|
|
</Admonition>
|
|
)}
|
|
</div>
|
|
|
|
<Card>
|
|
<CardContent>
|
|
<DiskSizeField form={form} disableInput={disableDiskSizeInput} />
|
|
</CardContent>
|
|
</Card>
|
|
</>
|
|
)}
|
|
</PageSectionContent>
|
|
</PageSection>
|
|
)
|
|
}
|
|
|
|
interface AdvancedSectionProps {
|
|
form: UseFormReturn<DiskStorageSchemaType>
|
|
autoscaleSettingsRef: RefObject<HTMLDivElement | null>
|
|
storageSettingsRef: RefObject<HTMLDivElement | null>
|
|
showBillingBadge: boolean
|
|
beforePrice: number
|
|
afterPrice: number
|
|
disableIopsThroughputConfig?: boolean
|
|
canUpdateDiskConfiguration: boolean
|
|
isDiskTooSmallForCustomIops: boolean
|
|
disableDiskInputs: boolean
|
|
disableDiskSizeInput: boolean
|
|
suggestedDiskSizeForCustomIops: number
|
|
}
|
|
|
|
export function AdvancedSection({
|
|
form,
|
|
autoscaleSettingsRef,
|
|
storageSettingsRef,
|
|
showBillingBadge,
|
|
beforePrice,
|
|
afterPrice,
|
|
disableIopsThroughputConfig,
|
|
canUpdateDiskConfiguration,
|
|
isDiskTooSmallForCustomIops,
|
|
disableDiskInputs,
|
|
disableDiskSizeInput,
|
|
suggestedDiskSizeForCustomIops,
|
|
}: AdvancedSectionProps) {
|
|
return (
|
|
<PageSection>
|
|
<PageSectionMeta>
|
|
<PageSectionSummary>
|
|
<PageSectionTitle className="heading-default text-base">Advanced</PageSectionTitle>
|
|
<PageSectionDescription>
|
|
Configure autoscaling, storage type, IOPS, and throughput.
|
|
</PageSectionDescription>
|
|
</PageSectionSummary>
|
|
<PageSectionAside>
|
|
<BillingChangeBadge
|
|
show={showBillingBadge}
|
|
beforePrice={beforePrice}
|
|
afterPrice={afterPrice}
|
|
/>
|
|
</PageSectionAside>
|
|
</PageSectionMeta>
|
|
<PageSectionContent className="flex flex-col gap-4">
|
|
<Card ref={autoscaleSettingsRef} className="scroll-mt-24">
|
|
<CardContent className="flex flex-col gap-y-8">
|
|
<AutoScaleFields form={form} disableInput={disableDiskInputs && disableDiskSizeInput} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card ref={storageSettingsRef} className="scroll-mt-24">
|
|
<CardContent className="flex flex-col gap-y-8">
|
|
<NoticeBar
|
|
type="default"
|
|
visible={!!disableIopsThroughputConfig}
|
|
title="Adjusting disk configuration requires LARGE Compute size or above"
|
|
description={`Increase your compute size to adjust your disk's storage type, ${form.getValues('storageType') === 'gp3' ? 'IOPS, ' : ''} and throughput`}
|
|
actions={
|
|
canUpdateDiskConfiguration ? (
|
|
<Button
|
|
variant="default"
|
|
onClick={() => {
|
|
form.setValue('computeSize', 'ci_large', {
|
|
shouldDirty: true,
|
|
shouldValidate: true,
|
|
})
|
|
form.trigger('provisionedIOPS')
|
|
form.trigger('throughput')
|
|
}}
|
|
>
|
|
Change to LARGE Compute
|
|
</Button>
|
|
) : (
|
|
<RequestUpgradeToBillingOwners
|
|
addon="computeSize"
|
|
featureProposition="adjust disk configuration"
|
|
/>
|
|
)
|
|
}
|
|
/>
|
|
<NoticeBar
|
|
type="default"
|
|
visible={
|
|
isDiskTooSmallForCustomIops && !disableIopsThroughputConfig && !disableDiskInputs
|
|
}
|
|
title="Increase disk size to adjust IOPS or throughput"
|
|
description={`This disk is too small to update IOPS or throughput, since gp3 volumes are capped at 500 IOPS per GB with a 3,000 IOPS minimum. Resizing to ${suggestedDiskSizeForCustomIops} GB unlocks custom IOPS and throughput, and leaves headroom for further adjustments (disk config changes are limited to 4 within a rolling 24-hour window).`}
|
|
actions={
|
|
!disableDiskSizeInput ? (
|
|
<Button
|
|
variant="default"
|
|
onClick={() => {
|
|
form.setValue('totalSize', suggestedDiskSizeForCustomIops, {
|
|
shouldDirty: true,
|
|
shouldValidate: true,
|
|
})
|
|
}}
|
|
>
|
|
Increase to {suggestedDiskSizeForCustomIops} GB
|
|
</Button>
|
|
) : undefined
|
|
}
|
|
/>
|
|
<StorageTypeField
|
|
form={form}
|
|
disableInput={!!disableIopsThroughputConfig || disableDiskInputs}
|
|
/>
|
|
<IOPSField
|
|
form={form}
|
|
disableInput={
|
|
!!disableIopsThroughputConfig || disableDiskInputs || isDiskTooSmallForCustomIops
|
|
}
|
|
/>
|
|
<ThroughputField
|
|
form={form}
|
|
disableInput={
|
|
!!disableIopsThroughputConfig || disableDiskInputs || isDiskTooSmallForCustomIops
|
|
}
|
|
/>
|
|
</CardContent>
|
|
</Card>
|
|
</PageSectionContent>
|
|
</PageSection>
|
|
)
|
|
}
|