| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- import { PermissionAction } from '@supabase/shared-types/out/constants'
- import { useParams } from 'common'
- import { ExternalLink, Info } from 'lucide-react'
- import Link from 'next/link'
- import { SetStateAction } from 'react'
- import { toast } from 'sonner'
- import { Alert, AlertDescription, AlertTitle, Button, InfoIcon } from 'ui'
- import {
- PageSection,
- PageSectionContent,
- PageSectionMeta,
- PageSectionSummary,
- PageSectionTitle,
- } from 'ui-patterns'
- import { Markdown } from '@/components/interfaces/Markdown'
- import DiskSizeConfigurationModal from '@/components/interfaces/Settings/Database/DiskSizeConfigurationModal'
- import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
- import { DocsButton } from '@/components/ui/DocsButton'
- import Panel from '@/components/ui/Panel'
- import { useProjectDiskResizeMutation } from '@/data/config/project-disk-resize-mutation'
- import { useDatabaseSizeQuery } from '@/data/database/database-size-query'
- import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
- import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
- import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
- import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
- import {
- useIsAwsNimbusCloudProvider,
- useSelectedProjectQuery,
- } from '@/hooks/misc/useSelectedProject'
- import { useUrlState } from '@/hooks/ui/useUrlState'
- import { DOCS_URL } from '@/lib/constants'
- import { formatBytes } from '@/lib/helpers'
- export interface DiskSizeConfigurationProps {
- disabled?: boolean
- }
- export const DiskSizeConfiguration = ({ disabled = false }: DiskSizeConfigurationProps) => {
- const { ref: projectRef } = useParams()
- const { data: project } = useSelectedProjectQuery()
- const { data: organization } = useSelectedOrganizationQuery()
- const isAwsNimbus = useIsAwsNimbusCloudProvider()
- const { reportsAll } = useIsFeatureEnabled(['reports:all'])
- const [{ show_increase_disk_size_modal }, setUrlParams] = useUrlState()
- const showIncreaseDiskSizeModal = show_increase_disk_size_modal === 'true'
- const setShowIncreaseDiskSizeModal = (value: SetStateAction<boolean>) => {
- const show = typeof value === 'function' ? value(showIncreaseDiskSizeModal) : value
- setUrlParams({ show_increase_disk_size_modal: show ? 'true' : undefined })
- }
- const { can: canUpdateDiskSizeConfig } = useAsyncCheckPermissions(
- PermissionAction.UPDATE,
- 'projects',
- {
- resource: {
- project_id: project?.id,
- },
- }
- )
- const { isPending: isUpdatingDiskSize } = useProjectDiskResizeMutation({
- onSuccess: (_, variables) => {
- toast.success(`Successfully updated disk size to ${variables.volumeSize} GB`)
- setShowIncreaseDiskSizeModal(false)
- },
- })
- const { hasAccess: hasAccessToDiskSizeConfig } = useCheckEntitlements(
- 'instances.disk_modifications'
- )
- const currentDiskSize = project?.volumeSizeGb ?? 0
- const { data } = useDatabaseSizeQuery({
- projectRef: project?.ref,
- connectionString: project?.connectionString,
- })
- const databaseSizeBytesUsed = data ?? 0
- return (
- <>
- <PageSection id="disk-management">
- <PageSectionMeta>
- <PageSectionSummary>
- <PageSectionTitle>Disk Management</PageSectionTitle>
- </PageSectionSummary>
- <DocsButton href={`${DOCS_URL}/guides/platform/database-size#disk-management`} />
- </PageSectionMeta>
- <PageSectionContent>
- {organization?.usage_billing_enabled === true ? (
- <div className="flex flex-col gap-3">
- <Panel className="m-0!">
- <Panel.Content>
- <div>
- <div>
- {currentDiskSize && (
- <span className="text-foreground-light flex gap-2 items-baseline">
- <h4 className="text-foreground">Current Disk Storage</h4>
- </span>
- )}
- <div className="grid grid-cols-2 items-center">
- <p className="text-sm text-lighter max-w-lg">
- Briven employs auto-scaling storage and allows for manual disk size
- adjustments when necessary
- </p>
- {!isAwsNimbus && (
- <ButtonTooltip
- type="default"
- className="w-min ml-auto"
- disabled={!canUpdateDiskSizeConfig || disabled}
- onClick={() => setShowIncreaseDiskSizeModal(true)}
- tooltip={{
- content: {
- side: 'bottom',
- text: !canUpdateDiskSizeConfig
- ? 'You need additional permissions to increase the disk size'
- : undefined,
- },
- }}
- >
- Increase disk size
- </ButtonTooltip>
- )}
- </div>
- <div className="grid grid-cols-12 gap-2 mt-12 items-start">
- <div className="col-span-4 grid grid-cols-2 gap-x-12 gap-y-4 items-start">
- <div className="grid gap-2 col-span-1">
- <h5>Space used</h5>
- <span className="text-lg">
- {formatBytes(databaseSizeBytesUsed, 2, 'GB')}
- </span>
- </div>
- <div className="grid gap-2 col-span-1">
- <h5>Total size</h5>
- <span className="text-lg">{currentDiskSize} GB</span>
- </div>
- {reportsAll && (
- <div className="col-span-2 mt-4">
- <Button asChild type="default" iconRight={<ExternalLink size={14} />}>
- <Link
- href={`/project/${projectRef}/reports/database#database-size-report`}
- >
- View detailed summary
- </Link>
- </Button>
- </div>
- )}
- </div>
- <div className="col-span-8">
- <Alert>
- <Info size={16} />
- <AlertTitle>Importing a lot of data?</AlertTitle>
- <AlertDescription>
- <Markdown
- className="max-w-full"
- content={`
- We auto-scale your disk as you need more storage, but can only do this once every 4 hours.
- If you upload more than 1.5x the current size of your storage, your database will go
- into read-only mode. If you know how big your database is going to be, you can
- manually increase the size here.
- 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).
- `}
- />
- </AlertDescription>
- </Alert>
- </div>
- </div>
- </div>
- </div>
- </Panel.Content>
- </Panel>
- </div>
- ) : (
- <Alert>
- <InfoIcon />
- <AlertTitle>
- {hasAccessToDiskSizeConfig === false
- ? 'Disk size configuration is not available for projects on the Free Plan'
- : 'Disk size configuration is only available when the spend cap has been disabled'}
- </AlertTitle>
- <AlertDescription>
- {hasAccessToDiskSizeConfig === false ? (
- <p>
- If you are intending to use more than 500MB of disk space, then you will need to
- upgrade to at least the Pro Plan.
- </p>
- ) : (
- <p>
- If you are intending to use more than 8GB of disk space, then you will need to
- disable your spend cap.
- </p>
- )}
- <Button asChild type="default" className="mt-3">
- <Link
- href={`/org/${organization?.slug}/billing?panel=${
- hasAccessToDiskSizeConfig === false ? 'subscriptionPlan' : 'costControl'
- }`}
- target="_blank"
- >
- {hasAccessToDiskSizeConfig === false
- ? 'Upgrade subscription'
- : 'Disable spend cap'}
- </Link>
- </Button>
- </AlertDescription>
- </Alert>
- )}
- </PageSectionContent>
- </PageSection>
- <DiskSizeConfigurationModal
- visible={showIncreaseDiskSizeModal}
- loading={isUpdatingDiskSize}
- hideModal={setShowIncreaseDiskSizeModal}
- />
- </>
- )
- }
|