DiskSizeConfiguration.tsx225 lines · main
| 1 | import { PermissionAction } from '@supabase/shared-types/out/constants' |
| 2 | import { useParams } from 'common' |
| 3 | import { ExternalLink, Info } from 'lucide-react' |
| 4 | import Link from 'next/link' |
| 5 | import { SetStateAction } from 'react' |
| 6 | import { toast } from 'sonner' |
| 7 | import { Alert, AlertDescription, AlertTitle, Button, InfoIcon } from 'ui' |
| 8 | import { |
| 9 | PageSection, |
| 10 | PageSectionContent, |
| 11 | PageSectionMeta, |
| 12 | PageSectionSummary, |
| 13 | PageSectionTitle, |
| 14 | } from 'ui-patterns' |
| 15 | |
| 16 | import { Markdown } from '@/components/interfaces/Markdown' |
| 17 | import DiskSizeConfigurationModal from '@/components/interfaces/Settings/Database/DiskSizeConfigurationModal' |
| 18 | import { ButtonTooltip } from '@/components/ui/ButtonTooltip' |
| 19 | import { DocsButton } from '@/components/ui/DocsButton' |
| 20 | import Panel from '@/components/ui/Panel' |
| 21 | import { useProjectDiskResizeMutation } from '@/data/config/project-disk-resize-mutation' |
| 22 | import { useDatabaseSizeQuery } from '@/data/database/database-size-query' |
| 23 | import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' |
| 24 | import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' |
| 25 | import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' |
| 26 | import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' |
| 27 | import { |
| 28 | useIsAwsNimbusCloudProvider, |
| 29 | useSelectedProjectQuery, |
| 30 | } from '@/hooks/misc/useSelectedProject' |
| 31 | import { useUrlState } from '@/hooks/ui/useUrlState' |
| 32 | import { DOCS_URL } from '@/lib/constants' |
| 33 | import { formatBytes } from '@/lib/helpers' |
| 34 | |
| 35 | export interface DiskSizeConfigurationProps { |
| 36 | disabled?: boolean |
| 37 | } |
| 38 | |
| 39 | export const DiskSizeConfiguration = ({ disabled = false }: DiskSizeConfigurationProps) => { |
| 40 | const { ref: projectRef } = useParams() |
| 41 | const { data: project } = useSelectedProjectQuery() |
| 42 | const { data: organization } = useSelectedOrganizationQuery() |
| 43 | |
| 44 | const isAwsNimbus = useIsAwsNimbusCloudProvider() |
| 45 | const { reportsAll } = useIsFeatureEnabled(['reports:all']) |
| 46 | |
| 47 | const [{ show_increase_disk_size_modal }, setUrlParams] = useUrlState() |
| 48 | const showIncreaseDiskSizeModal = show_increase_disk_size_modal === 'true' |
| 49 | const setShowIncreaseDiskSizeModal = (value: SetStateAction<boolean>) => { |
| 50 | const show = typeof value === 'function' ? value(showIncreaseDiskSizeModal) : value |
| 51 | setUrlParams({ show_increase_disk_size_modal: show ? 'true' : undefined }) |
| 52 | } |
| 53 | |
| 54 | const { can: canUpdateDiskSizeConfig } = useAsyncCheckPermissions( |
| 55 | PermissionAction.UPDATE, |
| 56 | 'projects', |
| 57 | { |
| 58 | resource: { |
| 59 | project_id: project?.id, |
| 60 | }, |
| 61 | } |
| 62 | ) |
| 63 | |
| 64 | const { isPending: isUpdatingDiskSize } = useProjectDiskResizeMutation({ |
| 65 | onSuccess: (_, variables) => { |
| 66 | toast.success(`Successfully updated disk size to ${variables.volumeSize} GB`) |
| 67 | setShowIncreaseDiskSizeModal(false) |
| 68 | }, |
| 69 | }) |
| 70 | |
| 71 | const { hasAccess: hasAccessToDiskSizeConfig } = useCheckEntitlements( |
| 72 | 'instances.disk_modifications' |
| 73 | ) |
| 74 | |
| 75 | const currentDiskSize = project?.volumeSizeGb ?? 0 |
| 76 | |
| 77 | const { data } = useDatabaseSizeQuery({ |
| 78 | projectRef: project?.ref, |
| 79 | connectionString: project?.connectionString, |
| 80 | }) |
| 81 | const databaseSizeBytesUsed = data ?? 0 |
| 82 | |
| 83 | return ( |
| 84 | <> |
| 85 | <PageSection id="disk-management"> |
| 86 | <PageSectionMeta> |
| 87 | <PageSectionSummary> |
| 88 | <PageSectionTitle>Disk Management</PageSectionTitle> |
| 89 | </PageSectionSummary> |
| 90 | <DocsButton href={`${DOCS_URL}/guides/platform/database-size#disk-management`} /> |
| 91 | </PageSectionMeta> |
| 92 | <PageSectionContent> |
| 93 | {organization?.usage_billing_enabled === true ? ( |
| 94 | <div className="flex flex-col gap-3"> |
| 95 | <Panel className="m-0!"> |
| 96 | <Panel.Content> |
| 97 | <div> |
| 98 | <div> |
| 99 | {currentDiskSize && ( |
| 100 | <span className="text-foreground-light flex gap-2 items-baseline"> |
| 101 | <h4 className="text-foreground">Current Disk Storage</h4> |
| 102 | </span> |
| 103 | )} |
| 104 | <div className="grid grid-cols-2 items-center"> |
| 105 | <p className="text-sm text-lighter max-w-lg"> |
| 106 | Briven employs auto-scaling storage and allows for manual disk size |
| 107 | adjustments when necessary |
| 108 | </p> |
| 109 | {!isAwsNimbus && ( |
| 110 | <ButtonTooltip |
| 111 | type="default" |
| 112 | className="w-min ml-auto" |
| 113 | disabled={!canUpdateDiskSizeConfig || disabled} |
| 114 | onClick={() => setShowIncreaseDiskSizeModal(true)} |
| 115 | tooltip={{ |
| 116 | content: { |
| 117 | side: 'bottom', |
| 118 | text: !canUpdateDiskSizeConfig |
| 119 | ? 'You need additional permissions to increase the disk size' |
| 120 | : undefined, |
| 121 | }, |
| 122 | }} |
| 123 | > |
| 124 | Increase disk size |
| 125 | </ButtonTooltip> |
| 126 | )} |
| 127 | </div> |
| 128 | |
| 129 | <div className="grid grid-cols-12 gap-2 mt-12 items-start"> |
| 130 | <div className="col-span-4 grid grid-cols-2 gap-x-12 gap-y-4 items-start"> |
| 131 | <div className="grid gap-2 col-span-1"> |
| 132 | <h5>Space used</h5> |
| 133 | <span className="text-lg"> |
| 134 | {formatBytes(databaseSizeBytesUsed, 2, 'GB')} |
| 135 | </span> |
| 136 | </div> |
| 137 | <div className="grid gap-2 col-span-1"> |
| 138 | <h5>Total size</h5> |
| 139 | <span className="text-lg">{currentDiskSize} GB</span> |
| 140 | </div> |
| 141 | |
| 142 | {reportsAll && ( |
| 143 | <div className="col-span-2 mt-4"> |
| 144 | <Button asChild type="default" iconRight={<ExternalLink size={14} />}> |
| 145 | <Link |
| 146 | href={`/project/${projectRef}/reports/database#database-size-report`} |
| 147 | > |
| 148 | View detailed summary |
| 149 | </Link> |
| 150 | </Button> |
| 151 | </div> |
| 152 | )} |
| 153 | </div> |
| 154 | |
| 155 | <div className="col-span-8"> |
| 156 | <Alert> |
| 157 | <Info size={16} /> |
| 158 | <AlertTitle>Importing a lot of data?</AlertTitle> |
| 159 | <AlertDescription> |
| 160 | <Markdown |
| 161 | className="max-w-full" |
| 162 | content={` |
| 163 | We auto-scale your disk as you need more storage, but can only do this once every 4 hours. |
| 164 | If you upload more than 1.5x the current size of your storage, your database will go |
| 165 | into read-only mode. If you know how big your database is going to be, you can |
| 166 | manually increase the size here. |
| 167 | |
| 168 | Read more about [disk management](${DOCS_URL}/guides/platform/database-size#disk-management) and how to [free up storage space](${DOCS_URL}/guides/platform/database-size#vacuum-operations). |
| 169 | `} |
| 170 | /> |
| 171 | </AlertDescription> |
| 172 | </Alert> |
| 173 | </div> |
| 174 | </div> |
| 175 | </div> |
| 176 | </div> |
| 177 | </Panel.Content> |
| 178 | </Panel> |
| 179 | </div> |
| 180 | ) : ( |
| 181 | <Alert> |
| 182 | <InfoIcon /> |
| 183 | <AlertTitle> |
| 184 | {hasAccessToDiskSizeConfig === false |
| 185 | ? 'Disk size configuration is not available for projects on the Free Plan' |
| 186 | : 'Disk size configuration is only available when the spend cap has been disabled'} |
| 187 | </AlertTitle> |
| 188 | <AlertDescription> |
| 189 | {hasAccessToDiskSizeConfig === false ? ( |
| 190 | <p> |
| 191 | If you are intending to use more than 500MB of disk space, then you will need to |
| 192 | upgrade to at least the Pro Plan. |
| 193 | </p> |
| 194 | ) : ( |
| 195 | <p> |
| 196 | If you are intending to use more than 8GB of disk space, then you will need to |
| 197 | disable your spend cap. |
| 198 | </p> |
| 199 | )} |
| 200 | <Button asChild type="default" className="mt-3"> |
| 201 | <Link |
| 202 | href={`/org/${organization?.slug}/billing?panel=${ |
| 203 | hasAccessToDiskSizeConfig === false ? 'subscriptionPlan' : 'costControl' |
| 204 | }`} |
| 205 | target="_blank" |
| 206 | > |
| 207 | {hasAccessToDiskSizeConfig === false |
| 208 | ? 'Upgrade subscription' |
| 209 | : 'Disable spend cap'} |
| 210 | </Link> |
| 211 | </Button> |
| 212 | </AlertDescription> |
| 213 | </Alert> |
| 214 | )} |
| 215 | </PageSectionContent> |
| 216 | </PageSection> |
| 217 | |
| 218 | <DiskSizeConfigurationModal |
| 219 | visible={showIncreaseDiskSizeModal} |
| 220 | loading={isUpdatingDiskSize} |
| 221 | hideModal={setShowIncreaseDiskSizeModal} |
| 222 | /> |
| 223 | </> |
| 224 | ) |
| 225 | } |