SecondLevelNav.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { useParams } from 'common'
  2. import { type ReactNode } from 'react'
  3. import { API_DOCS_CATEGORIES } from './ProjectAPIDocs.constants'
  4. import { SecondLevelNavLayout, type MenuItemFilter } from './SecondLevelNav.Layout'
  5. import { ResourcePickerList } from './SecondLevelNav.ResourcePicker'
  6. import { StorageResourceList } from './SecondLevelNav.StoragePicker'
  7. import { useEdgeFunctionsQuery } from '@/data/edge-functions/edge-functions-query'
  8. import { useOpenAPISpecQuery } from '@/data/open-api/api-spec-query'
  9. import { useBucketInfoQueryPreferCached } from '@/data/storage/buckets-query'
  10. import { DOCS_URL } from '@/lib/constants'
  11. import { useAppStateSnapshot } from '@/state/app-state'
  12. const OPEN_API_SPEC_STALE_TIME = 1000 * 60 * 10
  13. const EntitiesSecondLevelNav = () => {
  14. const { ref } = useParams()
  15. const { data } = useOpenAPISpecQuery({ projectRef: ref }, { staleTime: OPEN_API_SPEC_STALE_TIME })
  16. const tables = data?.tables ?? []
  17. return (
  18. <SecondLevelNavLayout
  19. category={API_DOCS_CATEGORIES.ENTITIES}
  20. title="Tables & Views"
  21. docsUrl={`${DOCS_URL}/reference/javascript/select`}
  22. renderResourceList={(props) => (
  23. <ResourcePickerList {...props} items={tables} emptyMessage="No tables available" />
  24. )}
  25. />
  26. )
  27. }
  28. const StoredProceduresSecondLevelNav = () => {
  29. const { ref } = useParams()
  30. const { data } = useOpenAPISpecQuery({ projectRef: ref }, { staleTime: OPEN_API_SPEC_STALE_TIME })
  31. const functions = data?.functions ?? []
  32. return (
  33. <SecondLevelNavLayout
  34. category={API_DOCS_CATEGORIES.STORED_PROCEDURES}
  35. title="Database Functions"
  36. docsUrl={`${DOCS_URL}/reference/javascript/rpc`}
  37. renderResourceList={(props) => (
  38. <ResourcePickerList
  39. {...props}
  40. items={functions}
  41. emptyMessage="No database functions available"
  42. />
  43. )}
  44. />
  45. )
  46. }
  47. const EdgeFunctionsSecondLevelNav = () => {
  48. const { ref } = useParams()
  49. const { data: edgeFunctions } = useEdgeFunctionsQuery({ projectRef: ref })
  50. return (
  51. <SecondLevelNavLayout
  52. category={API_DOCS_CATEGORIES.EDGE_FUNCTIONS}
  53. title="Edge Functions"
  54. docsUrl={`${DOCS_URL}/reference/javascript/functions-invoke`}
  55. renderResourceList={(props) => (
  56. <ResourcePickerList
  57. {...props}
  58. items={edgeFunctions ?? []}
  59. emptyMessage="No edge functions available"
  60. />
  61. )}
  62. />
  63. )
  64. }
  65. const StorageSecondLevelNav = () => {
  66. const { ref } = useParams()
  67. const snap = useAppStateSnapshot()
  68. const [, resource] = snap.activeDocsSection
  69. const selectedBucket = useBucketInfoQueryPreferCached(resource, ref)
  70. const menuItemFilter: MenuItemFilter | undefined = selectedBucket
  71. ? (item) => {
  72. if (!selectedBucket.public && item.key === 'retrieve-public-url') return false
  73. if (selectedBucket.public && item.key === 'create-signed-url') return false
  74. return true
  75. }
  76. : undefined
  77. return (
  78. <SecondLevelNavLayout
  79. category={API_DOCS_CATEGORIES.STORAGE}
  80. title="Storage"
  81. docsUrl={`${DOCS_URL}/reference/javascript/storage-createbucket`}
  82. menuItemFilter={menuItemFilter}
  83. renderResourceList={(props) => <StorageResourceList {...props} projectRef={ref} />}
  84. />
  85. )
  86. }
  87. const SECTION_COMPONENTS: Record<string, () => ReactNode> = {
  88. [API_DOCS_CATEGORIES.ENTITIES]: EntitiesSecondLevelNav,
  89. [API_DOCS_CATEGORIES.STORED_PROCEDURES]: StoredProceduresSecondLevelNav,
  90. [API_DOCS_CATEGORIES.STORAGE]: StorageSecondLevelNav,
  91. [API_DOCS_CATEGORIES.EDGE_FUNCTIONS]: EdgeFunctionsSecondLevelNav,
  92. }
  93. export const SecondLevelNav = () => {
  94. const snap = useAppStateSnapshot()
  95. const [section] = snap.activeDocsSection
  96. const SectionComponent = SECTION_COMPONENTS[section]
  97. if (!SectionComponent) return null
  98. return <SectionComponent key={section} />
  99. }