diff --git a/studio/components/interfaces/Database/Wrappers/EditWrapper.tsx b/studio/components/interfaces/Database/Wrappers/EditWrapper.tsx index 85519c91539..2286ec04c7f 100644 --- a/studio/components/interfaces/Database/Wrappers/EditWrapper.tsx +++ b/studio/components/interfaces/Database/Wrappers/EditWrapper.tsx @@ -16,7 +16,7 @@ import { import { PermissionAction } from '@supabase/shared-types/out/constants' import { VaultSecret } from 'types' -import { checkPermissions, useParams, useStore } from 'hooks' +import { checkPermissions, useImmutableValue, useParams, useStore } from 'hooks' import { useFDWsQuery } from 'data/fdw/fdws-query' import { useFDWUpdateMutation } from 'data/fdw/fdw-update-mutation' @@ -50,15 +50,18 @@ const EditWrapper = () => { projectRef: project?.ref, connectionString: project?.connectionString, }) + const wrappers = data?.result ?? [] - const wrapper = wrappers.find((w) => Number(w.id) === Number(id)) + const foundWrapper = wrappers.find((w) => Number(w.id) === Number(id)) + // this call to useImmutableValue should be removed if the redirect after update is also removed + const wrapper = useImmutableValue(foundWrapper) + const wrapperMeta = WRAPPERS.find((w) => w.handlerName === wrapper?.handler) - const { mutateAsync: updateFDW } = useFDWUpdateMutation() + const { mutateAsync: updateFDW, isLoading: isSaving } = useFDWUpdateMutation() const [wrapperTables, setWrapperTables] = useState([]) const [isEditingTable, setIsEditingTable] = useState(false) - const [isSaving, setIsSaving] = useState(false) const [selectedTableToEdit, setSelectedTableToEdit] = useState() const [formErrors, setFormErrors] = useState<{ [k: string]: string }>({}) @@ -142,7 +145,6 @@ const EditWrapper = () => { if (wrapperTables.length === 0) errors.tables = 'Please add at least one table' if (!isEmpty(errors)) return setFormErrors(errors) - setIsSaving(true) setSubmitting(true) try { await updateFDW({ @@ -167,7 +169,6 @@ const EditWrapper = () => { message: `Failed to create ${wrapperMeta.label} foreign data wrapper: ${error.message}`, }) } finally { - setIsSaving(false) setSubmitting(false) } } diff --git a/studio/components/interfaces/Database/Wrappers/Wrappers.tsx b/studio/components/interfaces/Database/Wrappers/Wrappers.tsx index 06ed9c800ed..92032b53870 100644 --- a/studio/components/interfaces/Database/Wrappers/Wrappers.tsx +++ b/studio/components/interfaces/Database/Wrappers/Wrappers.tsx @@ -56,7 +56,7 @@ const Wrappers = () => { - {isLoadingExtensions ? ( + {isLoadingExtensions || isLoading ? (
@@ -94,7 +94,7 @@ const Wrappers = () => { /> ) } else { - return <> + return null } })} diff --git a/studio/hooks/index.ts b/studio/hooks/index.ts index 53628ed64e5..587af606a57 100644 --- a/studio/hooks/index.ts +++ b/studio/hooks/index.ts @@ -1,6 +1,7 @@ export * from './misc/useStore' export * from './misc/withAuth' export * from './misc/useOptimisticSqlSnippetCreate' +export * from './misc/useImmutableValue' export * from './misc/useNotifications' export * from './misc/usePlatformStatus' export * from './misc/useParams' diff --git a/studio/hooks/misc/useImmutableValue.tsx b/studio/hooks/misc/useImmutableValue.tsx new file mode 100644 index 00000000000..433e0099fef --- /dev/null +++ b/studio/hooks/misc/useImmutableValue.tsx @@ -0,0 +1,14 @@ +import { useRef } from 'react' + +/** + * Once a non-undefined value is passed, it will never change. + */ +export function useImmutableValue(value: T | undefined): T | undefined { + const ref = useRef(value) + + if (!ref.current && value) { + ref.current = value + } + + return ref.current +}