import { useParams } from 'common' import dayjs from 'dayjs' import { RotateCcw } from 'lucide-react' import { UseFormReturn } from 'react-hook-form' import { Button, FormControl, FormField, FormInputGroupInput, InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, } 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 { DocsButton } from '@/components/ui/DocsButton' import { useDiskAttributesQuery } from '@/data/config/disk-attributes-query' import { useDiskUtilizationQuery } from '@/data/config/disk-utilization-query' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { DOCS_URL, GB } from '@/lib/constants' 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 { 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 { defaultValues, dirtyFields, isDirty, errors } = formState const diskSizePrice = calculateDiskSizePrice({ planId, oldSize: defaultValues?.totalSize || 0, oldStorageType: defaultValues?.storageType as DiskType, newSize: getValues('totalSize'), newStorageType: getValues('storageType') as DiskType, }) const mainDiskUsed = Math.round(((diskUtil?.metrics.fs_used_bytes ?? 0) / GB) * 100) / 100 return (
( e.currentTarget.blur()} onChange={(e) => { setValue('totalSize', e.target.valueAsNumber, { shouldDirty: true, shouldValidate: true, }) trigger('provisionedIOPS') trigger('throughput') }} min={includedDiskGB} /> GB {isDirty ? ( { resetField('totalSize') trigger('provisionedIOPS') }} title="Reset" > ) : null} )} />
{includedDiskGB > 0 && org?.plan.id && `Your plan includes up to ${includedDiskGB} GB of ${watchedStorageType} storage.`}
{ setValue('storageType', 'io2') trigger('provisionedIOPS') trigger('totalSize') setAdvancedSettingsOpenState(true) }} > Change to High Performance SSD } />
{isProjectNew ? ( ) : ( error && ( {error?.message} ) )}
) }