useSchemaQueryState.ts 1.6 KB

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