import { UseFormReturn } from 'react-hook-form' import { InputVariants } from '@ui/components/shadcn/ui/input' import { useParams } from 'common' import { DocsButton } from 'components/ui/DocsButton' import { useDiskAttributesQuery } from 'data/config/disk-attributes-query' import { useDiskUtilizationQuery } from 'data/config/disk-utilization-query' import dayjs from 'dayjs' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { DOCS_URL, GB } from 'lib/constants' import { Button, FormControl_Shadcn_, FormField_Shadcn_, Input_Shadcn_, Skeleton, cn } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { DiskStorageSchemaType } from '../DiskManagement.schema' import { calculateDiskSizePrice } from '../DiskManagement.utils' import { BillingChangeBadge } from '../ui/BillingChangeBadge' import { DiskType, PLAN_DETAILS } from '../ui/DiskManagement.constants' import { DiskManagementDiskSizeReadReplicas } from '../ui/DiskManagementReadReplicas' import { DiskSpaceBar } from '../ui/DiskSpaceBar' import { DiskTypeRecommendationSection } from '../ui/DiskTypeRecommendationSection' import FormMessage from '../ui/FormMessage' import { InputPostTab } from '../ui/InputPostTab' import { InputResetButton } from '../ui/InputResetButton' type DiskSizeFieldProps = { form: UseFormReturn disableInput: boolean setAdvancedSettingsOpenState: (state: boolean) => void } export function DiskSizeField({ form, disableInput, setAdvancedSettingsOpenState, }: DiskSizeFieldProps) { const { ref: projectRef } = useParams() const { control, formState, setValue, trigger, getValues, resetField, watch } = form const { data: org } = useSelectedOrganizationQuery() const { data: project } = useSelectedProjectQuery() const { isLoading: isLoadingDiskAttributes, error: diskAttributesError, isError: isDiskAttributesError, } = useDiskAttributesQuery( { projectRef }, { enabled: project && project.cloud_provider !== 'FLY' } ) const { data: diskUtil, error: diskUtilError, isError: isDiskUtilizationError, } = useDiskUtilizationQuery( { projectRef: projectRef, }, { enabled: project && project.cloud_provider !== 'FLY' } ) const error = diskUtilError || diskAttributesError const isError = isDiskUtilizationError || isDiskAttributesError // coming up typically takes 5 minutes, and the request is cached for 5 mins // so doing less than 10 mins to account for both const isProjectNew = dayjs.utc().diff(dayjs.utc(project?.inserted_at), 'minute') < 10 || project?.status === 'COMING_UP' const watchedStorageType = watch('storageType') const watchedTotalSize = watch('totalSize') const planId = org?.plan.id ?? 'free' const { includedDiskGB: includedDiskGBMeta } = PLAN_DETAILS?.[planId as keyof typeof PLAN_DETAILS] ?? {} const includedDiskGB = includedDiskGBMeta[watchedStorageType] const diskSizePrice = calculateDiskSizePrice({ planId, oldSize: formState.defaultValues?.totalSize || 0, oldStorageType: formState.defaultValues?.storageType as DiskType, newSize: getValues('totalSize'), newStorageType: getValues('storageType') as DiskType, }) const isAllocatedStorageDirty = !!formState.dirtyFields.totalSize const mainDiskUsed = Math.round(((diskUtil?.metrics.fs_used_bytes ?? 0) / GB) * 100) / 100 return (
(
{isLoadingDiskAttributes ? (
) : ( e.currentTarget.blur()} onChange={(e) => { setValue('totalSize', e.target.valueAsNumber, { shouldDirty: true, shouldValidate: true, }) trigger('provisionedIOPS') trigger('throughput') }} min={includedDiskGB} /> )}
{ resetField('totalSize') trigger('provisionedIOPS') }} />
)} />
{includedDiskGB > 0 && org?.plan.id && `Your plan includes ${includedDiskGB} GB of disk size for ${watchedStorageType}.`}
{ setValue('storageType', 'io2') trigger('provisionedIOPS') trigger('totalSize') setAdvancedSettingsOpenState(true) }} > Change to High Performance SSD } />
{isProjectNew ? ( ) : ( error && ( {error?.message} ) )}
) }