useSchemaQueryState.ts44 lines · main
| 1 | import { LOCAL_STORAGE_KEYS, useParams } from 'common' |
| 2 | import { parseAsString, useQueryState } from 'nuqs' |
| 3 | import { useEffect, useMemo } from 'react' |
| 4 | |
| 5 | /** |
| 6 | * This hook wraps useQueryState because useQueryState imports app router for some reason which breaks the SSR in |
| 7 | * the playwright tests. I've localized the issue to "NODE_ENV='test'" in the playwright tests. |
| 8 | */ |
| 9 | const useIsomorphicUseQueryState = (defaultSchema: string) => { |
| 10 | if (typeof window === 'undefined') { |
| 11 | return [defaultSchema, () => {}] as const |
| 12 | } else { |
| 13 | // eslint-disable-next-line react-hooks/rules-of-hooks |
| 14 | return useQueryState( |
| 15 | 'schema', |
| 16 | parseAsString.withDefault(defaultSchema).withOptions({ |
| 17 | clearOnDefault: false, |
| 18 | }) |
| 19 | ) |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | export const useQuerySchemaState = () => { |
| 24 | const { ref } = useParams() |
| 25 | |
| 26 | const defaultSchema = |
| 27 | typeof window !== 'undefined' && !!window.localStorage && ref && ref.length > 0 |
| 28 | ? window.localStorage.getItem(LOCAL_STORAGE_KEYS.LAST_SELECTED_SCHEMA(ref)) || 'public' |
| 29 | : 'public' |
| 30 | |
| 31 | // cache the original default schema so that it's not changed by another tab and cause issues in the app (saving a |
| 32 | // table on the wrong schema) |
| 33 | const originalDefaultSchema = useMemo(() => defaultSchema, [ref]) |
| 34 | const [schema, setSelectedSchema] = useIsomorphicUseQueryState(originalDefaultSchema) |
| 35 | |
| 36 | useEffect(() => { |
| 37 | // Update the schema in local storage on every change |
| 38 | if (typeof window !== 'undefined' && !!window.localStorage && ref && ref.length > 0) { |
| 39 | window.localStorage.setItem(LOCAL_STORAGE_KEYS.LAST_SELECTED_SCHEMA(ref), schema) |
| 40 | } |
| 41 | }, [schema, ref]) |
| 42 | |
| 43 | return { selectedSchema: schema, setSelectedSchema } |
| 44 | } |