Files
supabase/apps/studio/hooks/misc/useSchemaQueryState.ts
Ivan Vasilov b3c6992e56 feat: Make the protected schemas dynamic, namespace schemas are now protected (#37290)
* Add hooks for async protected schemas.

* Migrate the ProtectedSchemaWarning to support the new implementation.

* sq

* Migrate all uses of protected schemas to the new approach.

* Delete extra file.

* Refactor the import foreign schema dialog to forbid protected and exposed schemas.

* Add the type to the protected schema.

* Revert ImportForeignSchemaDialog, it'll be addressed in another PR.

* Update apps/studio/hooks/useProtectedSchemas.ts

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>

* Fix a bad commit.

* Minor fixes.

* Fix the FDW delete mutation to handle names with numbers.

* Simplify the logic to skip a fetch.

* Minor fixes.

* Make the useIcebergFdwSchemasQuery work for all iceberg FDWs.

* Fix the tab schemas to always show in the Table Editor.

* Apply suggestion from @joshenlim

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>

* Fix a minor typo.

* Refactor ProtectedSchemaWarning to use Admonition, and standardise input field for target schema iceberg

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-07-30 11:38:50 +02:00

46 lines
1.6 KiB
TypeScript

import { parseAsString, useQueryState } from 'nuqs'
import { useEffect, useMemo } from 'react'
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
/**
* This hook wraps useQueryState because useQueryState imports app router for some reason which breaks the SSR in
* the playwright tests. I've localized the issue to "NODE_ENV='test'" in the playwright tests.
*/
const useIsomorphicUseQueryState = (defaultSchema: string) => {
if (typeof window === 'undefined') {
return [defaultSchema, () => {}] as const
} else {
// eslint-disable-next-line react-hooks/rules-of-hooks
return useQueryState(
'schema',
parseAsString.withDefault(defaultSchema).withOptions({
clearOnDefault: false,
})
)
}
}
export const useQuerySchemaState = () => {
const { ref } = useParams()
const defaultSchema =
typeof window !== 'undefined' && ref && ref.length > 0
? window.localStorage.getItem(LOCAL_STORAGE_KEYS.LAST_SELECTED_SCHEMA(ref)) || 'public'
: 'public'
// cache the original default schema so that it's not changed by another tab and cause issues in the app (saving a
// table on the wrong schema)
const originalDefaultSchema = useMemo(() => defaultSchema, [ref])
const [schema, setSelectedSchema] = useIsomorphicUseQueryState(originalDefaultSchema)
useEffect(() => {
// Update the schema in local storage on every change
if (typeof window !== 'undefined' && ref && ref.length > 0) {
window.localStorage.setItem(LOCAL_STORAGE_KEYS.LAST_SELECTED_SCHEMA(ref), schema)
}
}, [schema, ref])
return { selectedSchema: schema, setSelectedSchema }
}