useSchemaQueryState.ts44 lines · main
1import { LOCAL_STORAGE_KEYS, useParams } from 'common'
2import { parseAsString, useQueryState } from 'nuqs'
3import { 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 */
9const 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
23export 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}