DocsTab.tsx91 lines · main
| 1 | import { useParams } from 'common' |
| 2 | import { useMemo, useState } from 'react' |
| 3 | import { ShimmeringLoader } from 'ui-patterns' |
| 4 | |
| 5 | import type { ShowApiKey } from '../../Docs/Docs.types' |
| 6 | import { LangSelector } from '../../Docs/LangSelector' |
| 7 | import { DataApiDisabledState } from '@/components/interfaces/Integrations/DataApi/DataApiDisabledState' |
| 8 | import { DocsMenu } from '@/components/interfaces/Integrations/DataApi/DocsMenu' |
| 9 | import { DocsMobileNav } from '@/components/interfaces/Integrations/DataApi/DocsMobileNav' |
| 10 | import { DocView } from '@/components/interfaces/Integrations/DataApi/DocView' |
| 11 | import { generateDocsMenu, getActivePage } from '@/components/layouts/DocsLayout/DocsLayout.utils' |
| 12 | import { useOpenAPISpecQuery } from '@/data/open-api/api-spec-query' |
| 13 | import { useIsDataApiEnabled } from '@/hooks/misc/useIsDataApiEnabled' |
| 14 | import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' |
| 15 | import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' |
| 16 | import { PROJECT_STATUS } from '@/lib/constants' |
| 17 | |
| 18 | export 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 | } |