From 0f2f3e4eb7d57855d8a92b4e8decd7ccc2050b21 Mon Sep 17 00:00:00 2001 From: Monica Khoury <99693443+monicakh@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:17:06 +0300 Subject: [PATCH] fix: update storage size unit correctly after navigation (#48932) Fixes FE-4128. ## What is the current behavior? When updating the global Storage file size limit using a unit other than MB, the selected unit displays an incorrect value after navigating away from the Storage settings page and returning. The updated file size is persisted correctly by the API, but the unit selector does not always reflect the value derived from the persisted configuration. The Save button also remains enabled after successfully saving the updated configuration. ## What is the new behavior? The file size unit selector now correctly reflects the unit derived from the persisted global file size limit after saving and navigating between pages. The form state is also correctly synchronized with the latest Storage configuration after an update, so the Save button returns to its disabled state once the changes have been persisted. ## Additional context The Storage API persists the global file size limit in bytes rather than persisting the selected display unit separately. The dashboard derives the appropriate unit (MB/GB) from the stored byte value when loading the configuration. The issue was caused by the unit Select retaining stale internal state when the form values were reset after the Storage configuration was loaded/refetched. Ensuring the Select is refreshed when the controlled unit changes keeps the displayed unit synchronized with the form state. ## Summary by CodeRabbit * **Bug Fixes** * Improved storage settings form initialization when configuration and entitlements load. * Ensured storage unit selections and placeholders display consistently. * Improved form resetting to reflect the latest loaded settings. --- .../StorageSettings/StorageSettings.tsx | 53 ++++++------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/apps/studio/components/interfaces/Storage/StorageSettings/StorageSettings.tsx b/apps/studio/components/interfaces/Storage/StorageSettings/StorageSettings.tsx index d93c413405b..03143378f10 100644 --- a/apps/studio/components/interfaces/Storage/StorageSettings/StorageSettings.tsx +++ b/apps/studio/components/interfaces/Storage/StorageSettings/StorageSettings.tsx @@ -2,7 +2,7 @@ import { zodResolver } from '@hookform/resolvers/zod' import { PermissionAction } from '@supabase/shared-types/out/constants' import { IS_PLATFORM, useParams } from 'common' import { useEffect, useMemo, useState } from 'react' -import { SubmitHandler, useForm, useWatch } from 'react-hook-form' +import { SubmitHandler, useForm } from 'react-hook-form' import { toast } from 'sonner' import { Button, @@ -56,12 +56,6 @@ import { formatBytes } from '@/lib/helpers' const formId = 'storage-settings-form' -interface StorageSettingsState { - fileSizeLimit: number - unit: StorageSizeUnits - imageTransformationEnabled: boolean -} - export const StorageSettings = () => { const { ref: projectRef } = useParams() const { data: project } = useSelectedProjectQuery() @@ -112,11 +106,6 @@ export const StorageSettings = () => { !hasAccessToImageTransformations && !hasAccessToFileSizeConfiguration const [isUpdating, setIsUpdating] = useState(false) - const [initialValues, setInitialValues] = useState({ - fileSizeLimit: 0, - unit: StorageSizeUnits.MB, - imageTransformationEnabled: false, - }) const maxBytes = useMemo(() => { if (organization?.usage_billing_enabled || isEntitlementUnlimited()) { @@ -153,12 +142,15 @@ export const StorageSettings = () => { const form = useForm>({ resolver: zodResolver(FormSchema), - defaultValues: initialValues, + defaultValues: { + fileSizeLimit: 0, + unit: StorageSizeUnits.MB, + imageTransformationEnabled: false, + }, mode: 'onSubmit', reValidateMode: 'onSubmit', }) - const storageUnit = useWatch({ control: form.control, name: 'unit' }) const fileSizeLimitError = form.formState.errors.fileSizeLimit const { mutate: updateStorageConfig } = useProjectStorageConfigUpdateUpdateMutation({ @@ -225,27 +217,17 @@ export const StorageSettings = () => { } useEffect(() => { - if (isSuccess && config && !isLoading) { - const { fileSizeLimit, features } = config - const { value, unit } = convertFromBytes(fileSizeLimit ?? 0) - const imageTransformationEnabled = - features?.imageTransformation?.enabled ?? hasAccessToImageTransformations + if (!isSuccess || !config || isLoading) return - setInitialValues({ - fileSizeLimit: value, - unit: unit, - imageTransformationEnabled, - }) + const { value, unit } = convertFromBytes(config.fileSizeLimit ?? 0) - // Reset the form values when the config values load - form.reset({ - fileSizeLimit: value, - unit: unit, - imageTransformationEnabled, - }) - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isSuccess, config, isLoading, hasAccessToImageTransformations]) + form.reset({ + fileSizeLimit: value, + unit, + imageTransformationEnabled: + config.features?.imageTransformation?.enabled ?? hasAccessToImageTransformations, + }) + }, [isSuccess, config, isLoading, hasAccessToImageTransformations, form]) return ( @@ -355,6 +337,7 @@ export const StorageSettings = () => { name="unit" render={({ field: unitField }) => (