ResourceContent.tsx 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. import { useParams } from 'common'
  2. import { Table2 } from 'lucide-react'
  3. import { DocSection } from './DocSection'
  4. import CodeSnippet from '@/components/interfaces/Docs/CodeSnippet'
  5. import Description from '@/components/interfaces/Docs/Description'
  6. import Param from '@/components/interfaces/Docs/Param'
  7. import Snippets from '@/components/interfaces/Docs/Snippets'
  8. import { InlineLink } from '@/components/ui/InlineLink'
  9. import { useProjectApiUrl } from '@/data/config/project-endpoint-query'
  10. import { useProjectJsonSchemaQuery } from '@/data/docs/project-json-schema-query'
  11. import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
  12. import { DOCS_URL } from '@/lib/constants'
  13. interface ResourceContentProps {
  14. resourceId: string
  15. resources: { [key: string]: { id: string; displayName: string; camelCase: string } }
  16. selectedLang: 'bash' | 'js'
  17. showApiKey: string
  18. refreshDocs: () => void
  19. }
  20. export const ResourceContent = ({
  21. resourceId,
  22. resources,
  23. selectedLang,
  24. showApiKey,
  25. refreshDocs,
  26. }: ResourceContentProps) => {
  27. const { ref } = useParams()
  28. const { realtimeAll: realtimeEnabled } = useIsFeatureEnabled(['realtime:all'])
  29. const { data: jsonSchema } = useProjectJsonSchemaQuery({ projectRef: ref })
  30. const { paths, definitions } = jsonSchema || {}
  31. const { data: endpoint = '' } = useProjectApiUrl({ projectRef: ref })
  32. const keyToShow = !!showApiKey ? showApiKey : 'BRIVEN_KEY'
  33. const resourcePaths = paths?.[`/${resourceId}`]
  34. const resourceDefinition = definitions?.[resourceId]
  35. const resourceMeta = resources[resourceId]
  36. const description = resourceDefinition?.description || ''
  37. const methods = Object.keys(resourcePaths ?? {}).map((x) => x.toUpperCase())
  38. const properties = Object.entries(resourceDefinition?.properties ?? []).map(([id, val]: any) => ({
  39. ...val,
  40. id,
  41. required: resourceDefinition?.required?.includes(id),
  42. }))
  43. if (!paths || !definitions) return null
  44. return (
  45. <div className="flex flex-col flex-1">
  46. <DocSection
  47. title={
  48. <span className="flex items-center gap-2 text-subTitle">
  49. <Table2 size={16} strokeWidth={1.5} />
  50. {resourceId}
  51. </span>
  52. }
  53. content={
  54. <>
  55. <label className="font-mono text-xs uppercase text-foreground-lighter inline-block mb-2">
  56. Description
  57. </label>
  58. <Description
  59. content={description}
  60. metadata={{ table: resourceId }}
  61. onChange={refreshDocs}
  62. />
  63. </>
  64. }
  65. />
  66. {properties.length > 0 && (
  67. <div className="flex flex-col flex-1">
  68. {properties.map((x) => (
  69. <DocSection
  70. key={x.id}
  71. title={null}
  72. content={
  73. <Param
  74. key={x.id}
  75. name={x.id}
  76. type={x.type}
  77. format={x.format}
  78. required={x.required}
  79. description={x.description}
  80. metadata={{
  81. table: resourceId,
  82. column: x.id,
  83. }}
  84. onDesciptionUpdated={refreshDocs}
  85. />
  86. }
  87. snippets={
  88. <CodeSnippet
  89. selectedLang={selectedLang}
  90. snippet={Snippets.readColumns({
  91. title: `Select ${x.id}`,
  92. resourceId,
  93. endpoint: endpoint,
  94. apiKey: keyToShow,
  95. columnName: x.id,
  96. })}
  97. />
  98. }
  99. />
  100. ))}
  101. </div>
  102. )}
  103. {methods.includes('GET') && (
  104. <DocSection
  105. title="Read rows"
  106. content={
  107. <>
  108. <p>
  109. To read rows in <code>{resourceId}</code>, use the <code>select</code> method.
  110. </p>
  111. <p>
  112. <InlineLink href={`${DOCS_URL}/reference/javascript/select`}>Learn more</InlineLink>
  113. </p>
  114. <h4 className="text-default">Filtering</h4>
  115. <p>Briven provides a wide range of filters.</p>
  116. <p>
  117. <InlineLink href={`${DOCS_URL}/reference/javascript/using-filters`}>
  118. Learn more
  119. </InlineLink>
  120. </p>
  121. </>
  122. }
  123. snippets={
  124. <>
  125. <CodeSnippet
  126. selectedLang={selectedLang}
  127. snippet={Snippets.readAll(resourceId, endpoint, keyToShow)}
  128. />
  129. <CodeSnippet
  130. selectedLang={selectedLang}
  131. snippet={Snippets.readColumns({
  132. resourceId,
  133. endpoint: endpoint,
  134. apiKey: keyToShow,
  135. })}
  136. />
  137. <CodeSnippet
  138. selectedLang={selectedLang}
  139. snippet={Snippets.readForeignTables(resourceId, endpoint, keyToShow)}
  140. />
  141. <CodeSnippet
  142. selectedLang={selectedLang}
  143. snippet={Snippets.readRange(resourceId, endpoint, keyToShow)}
  144. />
  145. <CodeSnippet
  146. selectedLang={selectedLang}
  147. snippet={Snippets.readFilters(resourceId, endpoint, keyToShow)}
  148. />
  149. </>
  150. }
  151. />
  152. )}
  153. {methods.includes('POST') && (
  154. <DocSection
  155. title="Insert rows"
  156. content={
  157. <>
  158. <p>
  159. <code>insert</code> lets you insert into your tables. You can also insert in bulk
  160. and do UPSERT.
  161. </p>
  162. <p>
  163. <code>insert</code> will also return the replaced values for UPSERT.
  164. </p>
  165. <p>
  166. <InlineLink href={`${DOCS_URL}/reference/javascript/insert`}>Learn more</InlineLink>
  167. </p>
  168. </>
  169. }
  170. snippets={
  171. <>
  172. <CodeSnippet
  173. selectedLang={selectedLang}
  174. snippet={Snippets.insertSingle(resourceId, endpoint, keyToShow)}
  175. />
  176. <CodeSnippet
  177. selectedLang={selectedLang}
  178. snippet={Snippets.insertMany(resourceId, endpoint, keyToShow)}
  179. />
  180. <CodeSnippet
  181. selectedLang={selectedLang}
  182. snippet={Snippets.upsert(resourceId, endpoint, keyToShow)}
  183. />
  184. </>
  185. }
  186. />
  187. )}
  188. {methods.includes('PATCH') && (
  189. <DocSection
  190. title="Update rows"
  191. content={
  192. <>
  193. <p>
  194. <code>update</code> lets you update rows. <code>update</code> will match all rows by
  195. default. You can update specific rows using horizontal filters, e.g. <code>eq</code>
  196. , <code>lt</code>, and <code>is</code>.
  197. </p>
  198. <p>
  199. <code>update</code> will also return the replaced values for UPDATE.
  200. </p>
  201. <p>
  202. <InlineLink href={`${DOCS_URL}/reference/javascript/update`}>Learn more</InlineLink>
  203. </p>
  204. </>
  205. }
  206. snippets={
  207. <CodeSnippet
  208. selectedLang={selectedLang}
  209. snippet={Snippets.update(resourceId, endpoint, keyToShow)}
  210. />
  211. }
  212. />
  213. )}
  214. {methods.includes('DELETE') && (
  215. <DocSection
  216. title="Delete rows"
  217. content={
  218. <>
  219. <p>
  220. <code>delete</code> lets you delete rows. <code>delete</code> will match all rows by
  221. default, so remember to specify your filters!
  222. </p>
  223. <p>
  224. <InlineLink href={`${DOCS_URL}/reference/javascript/delete`}>Learn more</InlineLink>
  225. </p>
  226. </>
  227. }
  228. snippets={
  229. <CodeSnippet
  230. selectedLang={selectedLang}
  231. snippet={Snippets.delete(resourceId, endpoint, keyToShow)}
  232. />
  233. }
  234. />
  235. )}
  236. {realtimeEnabled &&
  237. (methods.includes('DELETE') || methods.includes('POST') || methods.includes('PATCH')) && (
  238. <DocSection
  239. title="Subscribe to changes"
  240. content={
  241. <>
  242. <p>
  243. Briven provides realtime functionality and broadcasts database changes to
  244. authorized users depending on Row Level Security (RLS) policies.
  245. </p>
  246. <p>
  247. <InlineLink href={`${DOCS_URL}/reference/javascript/subscribe`}>
  248. Learn more
  249. </InlineLink>
  250. </p>
  251. </>
  252. }
  253. snippets={
  254. <>
  255. <CodeSnippet
  256. selectedLang={selectedLang}
  257. snippet={Snippets.subscribeAll(resourceMeta.camelCase, resourceId)}
  258. />
  259. <CodeSnippet
  260. selectedLang={selectedLang}
  261. snippet={Snippets.subscribeInserts(resourceMeta.camelCase, resourceId)}
  262. />
  263. <CodeSnippet
  264. selectedLang={selectedLang}
  265. snippet={Snippets.subscribeUpdates(resourceMeta.camelCase, resourceId)}
  266. />
  267. <CodeSnippet
  268. selectedLang={selectedLang}
  269. snippet={Snippets.subscribeDeletes(resourceMeta.camelCase, resourceId)}
  270. />
  271. <CodeSnippet
  272. selectedLang={selectedLang}
  273. snippet={Snippets.subscribeEq(
  274. resourceMeta.camelCase,
  275. resourceId,
  276. 'column_name',
  277. 'someValue'
  278. )}
  279. />
  280. </>
  281. }
  282. />
  283. )}
  284. </div>
  285. )
  286. }