DocsTab.tsx91 lines · main
1import { useParams } from 'common'
2import { useMemo, useState } from 'react'
3import { ShimmeringLoader } from 'ui-patterns'
4
5import type { ShowApiKey } from '../../Docs/Docs.types'
6import { LangSelector } from '../../Docs/LangSelector'
7import { DataApiDisabledState } from '@/components/interfaces/Integrations/DataApi/DataApiDisabledState'
8import { DocsMenu } from '@/components/interfaces/Integrations/DataApi/DocsMenu'
9import { DocsMobileNav } from '@/components/interfaces/Integrations/DataApi/DocsMobileNav'
10import { DocView } from '@/components/interfaces/Integrations/DataApi/DocView'
11import { generateDocsMenu, getActivePage } from '@/components/layouts/DocsLayout/DocsLayout.utils'
12import { useOpenAPISpecQuery } from '@/data/open-api/api-spec-query'
13import { useIsDataApiEnabled } from '@/hooks/misc/useIsDataApiEnabled'
14import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
15import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
16import { PROJECT_STATUS } from '@/lib/constants'
17
18export const DataApiDocsTab = () => {
19 const DEFAULT_KEY = { name: 'hide', key: 'BRIVEN_KEY' }
20 const { ref: projectRef, page, resource, rpc } = useParams()
21 const { data: project } = useSelectedProjectQuery()
22 const { projectAuthAll: authEnabled } = useIsFeatureEnabled(['project_auth:all'])
23 const isPaused = project?.status === PROJECT_STATUS.INACTIVE
24
25 const [selectedLang, setSelectedLang] = useState<'js' | 'bash'>('js')
26 const [selectedApiKey, setSelectedApiKey] = useState<ShowApiKey>(DEFAULT_KEY)
27
28 const { isEnabled, isPending: isConfigLoading } = useIsDataApiEnabled({ projectRef })
29
30 const { data: openApiSpec } = useOpenAPISpecQuery(
31 { projectRef },
32 {
33 enabled: !!projectRef && !isPaused && isEnabled,
34 }
35 )
36
37 const tableNames = useMemo(
38 () => (openApiSpec?.tables ?? []).map((table) => table.name),
39 [openApiSpec]
40 )
41 const functionNames = useMemo(
42 () => (openApiSpec?.functions ?? []).map((fn) => fn.name),
43 [openApiSpec]
44 )
45
46 const activePage = useMemo(() => getActivePage({ page, resource, rpc }), [page, resource, rpc])
47
48 const docsBasePath = projectRef ? `/project/${projectRef}/integrations/data_api/docs` : undefined
49
50 const menu = useMemo(() => {
51 if (!projectRef) return []
52 return generateDocsMenu(projectRef, tableNames, functionNames, { authEnabled }, docsBasePath)
53 }, [projectRef, tableNames, functionNames, authEnabled, docsBasePath])
54
55 if (isConfigLoading) {
56 return (
57 <div className="flex w-full bg-surface-100 flex-1 items-stretch p-10">
58 <ShimmeringLoader className="w-full h-full" />
59 </div>
60 )
61 }
62
63 if (!isEnabled) {
64 return <DataApiDisabledState description="view the documentation" />
65 }
66
67 return (
68 <div className="flex w-full bg-surface-100 flex-1 items-stretch">
69 <aside className="hidden lg:flex flex-col gap-y-6 w-60 shrink-0 p-10">
70 <LangSelector
71 selectedLang={selectedLang}
72 selectedApiKey={selectedApiKey}
73 setSelectedLang={(lang: 'js' | 'bash') => setSelectedLang(lang)}
74 setSelectedApiKey={setSelectedApiKey}
75 />
76 <DocsMenu activePage={activePage} menu={menu} />
77 </aside>
78 <div className="flex-1 min-w-0 relative">
79 <DocsMobileNav
80 activePage={activePage}
81 menu={menu}
82 selectedLang={selectedLang}
83 selectedApiKey={selectedApiKey}
84 setSelectedLang={setSelectedLang}
85 setSelectedApiKey={setSelectedApiKey}
86 />
87 <DocView selectedLang={selectedLang} selectedApiKey={selectedApiKey} />
88 </div>
89 </div>
90 )
91}