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