-
+
{
@@ -81,7 +81,7 @@ export function ComputeSizeField({ form }: ComputeSizeFieldProps) {
}
>
{
setValue('computeSize', value, {
shouldDirty: true,
@@ -99,7 +99,7 @@ export function ComputeSizeField({ form }: ComputeSizeFieldProps) {
.fill(0)
.map((_, i) => )
) : addonsError ? (
- Error loading compute options
+
) : (
availableOptions.map((compute: ComputeOption) => {
// @ts-expect-error
diff --git a/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx b/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx
index aa064aa869a..917da8c9633 100644
--- a/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx
@@ -16,6 +16,7 @@ import DiskSpaceBar from '../ui/DiskSpaceBar'
import { InputPostTab } from '../ui/InputPostTab'
import { InputResetButton } from '../ui/InputResetButton'
import FormMessage from '../ui/FormMessage'
+import { useDiskAttributesQuery } from 'data/config/disk-attributes-query'
type DiskSizeFieldProps = {
form: UseFormReturn
@@ -27,10 +28,16 @@ export function DiskSizeField({ form, disableInput }: DiskSizeFieldProps) {
const { control, formState, setValue, trigger, getValues, resetField, watch } = form
const org = useSelectedOrganization()
+ const {
+ isLoading: isLoadingDiskAttributes,
+ error: diskAttributesError,
+ isError: isDiskAttributesError,
+ } = useDiskAttributesQuery({ projectRef })
const {
data: subscription,
isLoading: isSubscriptionLoading,
error: subscriptionError,
+ isError: isSubscriptionError,
} = useOrgSubscriptionQuery({
orgSlug: org?.slug,
})
@@ -38,12 +45,14 @@ export function DiskSizeField({ form, disableInput }: DiskSizeFieldProps) {
data: diskUtil,
isLoading: isDiskUtilizationLoading,
error: diskUtilError,
+ isError: isDiskUtilizationError,
} = useDiskUtilizationQuery({
projectRef: projectRef,
})
- const isLoading = isSubscriptionLoading || isDiskUtilizationLoading
- const error = subscriptionError || diskUtilError
+ const isLoading = isSubscriptionLoading || isDiskUtilizationLoading || isLoadingDiskAttributes
+ const error = subscriptionError || diskUtilError || diskAttributesError
+ const isError = isSubscriptionError || isDiskUtilizationError || isDiskAttributesError
const watchedStorageType = watch('storageType')
const watchedTotalSize = watch('totalSize')
@@ -73,7 +82,6 @@ export function DiskSizeField({ form, disableInput }: DiskSizeFieldProps) {
control={control}
render={({ field }) => (
- {error && }
{isLoading ? (
@@ -90,7 +98,7 @@ export function DiskSizeField({ form, disableInput }: DiskSizeFieldProps) {
e.currentTarget.blur()}
onChange={(e) => {
@@ -136,13 +144,8 @@ export function DiskSizeField({ form, disableInput }: DiskSizeFieldProps) {
-
+
+ {error && }
@@ -21,12 +25,15 @@ type IOPSFieldProps = {
}
export function IOPSField({ form, disableInput }: IOPSFieldProps) {
+ const { ref: projectRef } = useParams()
const { control, formState, setValue, trigger, getValues, watch } = form
const watchedStorageType = watch('storageType')
const watchedComputeSize = watch('computeSize')
const watchedIOPS = watch('provisionedIOPS') ?? 0
+ const { isLoading, error, isError } = useDiskAttributesQuery({ projectRef })
+
const iopsPrice = calculateIOPSPrice({
oldStorageType: formState.defaultValues?.storageType as DiskType,
oldProvisionedIOPS: formState.defaultValues?.provisionedIOPS || 0,
@@ -47,8 +54,9 @@ export function IOPSField({ form, disableInput }: IOPSFieldProps) {
+
)}
-
+
}
labelOptional={
<>
@@ -98,29 +106,37 @@ export function IOPSField({ form, disableInput }: IOPSFieldProps) {
}
>
-
- {
- setValue('provisionedIOPS', e.target.valueAsNumber, {
- shouldDirty: true,
- shouldValidate: true,
- })
- }}
- />
-
+ {isLoading ? (
+
+
+
+ ) : (
+
+ {
+ setValue('provisionedIOPS', e.target.valueAsNumber, {
+ shouldDirty: true,
+ shouldValidate: true,
+ })
+ }}
+ />
+
+ )}
+ {error && }
)
}}
diff --git a/apps/studio/components/interfaces/DiskManagement/fields/StorageTypeField.tsx b/apps/studio/components/interfaces/DiskManagement/fields/StorageTypeField.tsx
index 96ce156c4a6..dca7310624b 100644
--- a/apps/studio/components/interfaces/DiskManagement/fields/StorageTypeField.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/fields/StorageTypeField.tsx
@@ -1,16 +1,23 @@
-import { FormField_Shadcn_, FormControl_Shadcn_ } from 'ui'
-import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
+import { useParams } from 'common'
+import { useDiskAttributesQuery } from 'data/config/disk-attributes-query'
+import { UseFormReturn } from 'react-hook-form'
import {
+ Badge,
+ FormControl_Shadcn_,
+ FormField_Shadcn_,
Select_Shadcn_,
- SelectTrigger_Shadcn_,
- SelectValue_Shadcn_,
SelectContent_Shadcn_,
SelectItem_Shadcn_,
+ SelectTrigger_Shadcn_,
+ SelectValue_Shadcn_,
+ Skeleton,
+ buttonVariants,
+ cn,
} from 'ui'
-import { Badge } from 'ui'
-import { UseFormReturn } from 'react-hook-form'
+import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { DiskStorageSchemaType } from '../DiskManagement.schema'
import { DISK_TYPE_OPTIONS } from '../ui/DiskManagement.constants'
+import FormMessage from '../ui/FormMessage'
type StorageTypeFieldProps = {
form: UseFormReturn
@@ -18,8 +25,11 @@ type StorageTypeFieldProps = {
}
export function StorageTypeField({ form, disableInput }: StorageTypeFieldProps) {
+ const { ref: projectRef } = useParams()
const { control, trigger } = form
+ const { isLoading, error, isError } = useDiskAttributesQuery({ projectRef })
+
return (
-
-
-
-
-
+ {isLoading ? (
+
+ ) : (
+
+
+
+
+
+ )}
<>
{DISK_TYPE_OPTIONS.map((item) => (
@@ -66,6 +85,7 @@ export function StorageTypeField({ form, disableInput }: StorageTypeFieldProps)
>
+ {error && }
)}
/>
diff --git a/apps/studio/components/interfaces/DiskManagement/fields/ThroughputField.tsx b/apps/studio/components/interfaces/DiskManagement/fields/ThroughputField.tsx
index a8c1a3a0ffd..0e335735529 100644
--- a/apps/studio/components/interfaces/DiskManagement/fields/ThroughputField.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/fields/ThroughputField.tsx
@@ -1,6 +1,6 @@
import { AnimatePresence, motion } from 'framer-motion'
import { UseFormReturn } from 'react-hook-form'
-import { FormControl_Shadcn_, FormField_Shadcn_, Input_Shadcn_ } from 'ui'
+import { cn, FormControl_Shadcn_, FormField_Shadcn_, Input_Shadcn_, Skeleton } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { BillingChangeBadge } from '../ui/BillingChangeBadge'
import {
@@ -14,6 +14,10 @@ import { DiskStorageSchemaType } from '../DiskManagement.schema'
import { DiskManagementThroughputReadReplicas } from '../ui/DiskManagementReadReplicas'
import { InputPostTab } from '../ui/InputPostTab'
import { useEffect } from 'react'
+import FormMessage from '../ui/FormMessage'
+import { useDiskAttributesQuery } from 'data/config/disk-attributes-query'
+import { useParams } from 'common'
+import { InputVariants } from '@ui/components/shadcn/ui/input'
type ThroughputFieldProps = {
form: UseFormReturn
@@ -21,6 +25,8 @@ type ThroughputFieldProps = {
}
export function ThroughputField({ form, disableInput }: ThroughputFieldProps) {
+ const { ref: projectRef } = useParams()
+
const { control, formState, setValue, getValues, watch } = form
const watchedStorageType = watch('storageType')
@@ -28,6 +34,8 @@ export function ThroughputField({ form, disableInput }: ThroughputFieldProps) {
const watchedComputeSize = watch('computeSize')
const throughput_mbps = formState.defaultValues?.throughput
+ const { isLoading, error } = useDiskAttributesQuery({ projectRef })
+
const throughputPrice = calculateThroughputPrice({
storageType: form.getValues('storageType') as DiskType,
newThroughput: form.getValues('throughput') || 0,
@@ -98,28 +106,40 @@ export function ThroughputField({ form, disableInput }: ThroughputFieldProps) {
}
>
-
- {
- setValue('throughput', e.target.valueAsNumber, {
- shouldDirty: true,
- shouldValidate: true,
- })
- }}
- className="flex-grow font-mono rounded-r-none max-w-32"
- disabled={disableInput || disableIopsInput || watchedStorageType === 'io2'}
- />
-
+ {isLoading ? (
+
+
+
+ ) : (
+
+ {
+ setValue('throughput', e.target.valueAsNumber, {
+ shouldDirty: true,
+ shouldValidate: true,
+ })
+ }}
+ className="flex-grow font-mono rounded-r-none max-w-32"
+ disabled={disableInput || disableIopsInput || watchedStorageType === 'io2'}
+ />
+
+ )}
+ {error && }
)}
/>
diff --git a/apps/studio/components/interfaces/DiskManagement/ui/ComputeSizeReccomendationSection.tsx b/apps/studio/components/interfaces/DiskManagement/ui/ComputeSizeReccomendationSection.tsx
index a3e86e82cd5..224ece65b32 100644
--- a/apps/studio/components/interfaces/DiskManagement/ui/ComputeSizeReccomendationSection.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/ui/ComputeSizeReccomendationSection.tsx
@@ -24,7 +24,7 @@ export function ComputeSizeReccomendationSection({
iops > maxIOPSforComputeSize && !RESTRICTED_COMPUTE_FOR_IOPS_ON_GP3.includes(computeSize)
return (
-
+
{isVisible && (
+
{isDirty && (
+
{isDirty && (
- {type === 'error' ? : }
- {message}
-
+
)
}