1
1
import { DirectiveNode , DocumentNode , OperationTypeNode , parse } from "graphql" ;
2
- import { ReactNode , useCallback , useContext , useMemo } from "react" ;
2
+ import { ReactNode , useContext , useMemo } from "react" ;
3
3
import { findDirective , parseDirectiveArguments } from "@directive" ;
4
4
import { ViewRenderer } from "@renderers/fields" ;
5
5
import { FormRenderer } from "@renderers/form" ;
@@ -185,57 +185,25 @@ export type FabrixComponentProps = FabrixComponentCommonProps & {
185
185
186
186
type FabrixComponentChildrenExtraProps = { key ?: string ; className ?: string } ;
187
187
188
- type FabrixGetComponentFn = (
189
- /**
190
- * The name that corresponds to the GQL query.
191
- */
192
- name : string ,
193
- extraProps ?: FabrixComponentChildrenExtraProps ,
194
- fieldsRenderer ?: FabrixComponentFieldsRenderer ,
195
- ) => ReactNode ;
196
-
197
- export type FabrixGetOperationFn = <
198
- T extends Record < string , unknown > = Record < string , unknown > ,
199
- > (
200
- indexOrName : number | string ,
201
- renderer ?: ( props : {
202
- data : T ;
203
- getComponent : FabrixGetComponentFn ;
204
- } ) => ReactNode ,
205
- ) => ReactNode ;
206
-
207
188
export type FabrixComponentChildrenProps = {
208
189
/**
209
- * Get the operation result by operation name or index
210
- *
211
- * ```tsx
212
- * <FabrixComponent query={getUsersQuery}>
213
- * {({ getOperation }) => (
214
- * {getOperation("getUsers", ({ data, getComponent }) => (
215
- * <>
216
- * <h2>{data.users.size} users</h2>
217
- * {getComponent("users")}
218
- * </>
219
- * ))}
220
- * )}
221
- * </FabrixComponent>
222
- * ```
190
+ * The data fetched from the query
223
191
*/
224
- getOperation : FabrixGetOperationFn ;
192
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
+ data : any ;
225
194
226
195
/**
227
196
* Get the component by root field name
228
197
*
229
198
* ```tsx
230
199
* <FabrixComponent query={getUsersQuery}>
231
200
* {({ getComponent }) => (
232
- * {getComponent("getUsers", " users")}
201
+ * {getComponent("users")}
233
202
* )}
234
203
* </FabrixComponent>
235
204
* ```
236
205
*/
237
206
getComponent : (
238
- operationIndexOrName : number | string ,
239
207
rootFieldName : string ,
240
208
extraProps ?: FabrixComponentChildrenExtraProps ,
241
209
fieldsRenderer ?: FabrixComponentFieldsRenderer ,
@@ -306,48 +274,41 @@ export const getComponentRendererFn = (
306
274
props : FabrixComponentProps ,
307
275
getComponent : ReturnType < typeof getComponentFn > ,
308
276
) => {
277
+ const context = useContext ( FabrixContext ) ;
309
278
const { fieldConfigs } = useFieldConfigs ( props . query ) ;
310
- const getOperation : FabrixComponentChildrenProps [ "getOperation" ] =
311
- useCallback (
312
- ( indexOrName , renderer ) => {
313
- const fieldConfig =
314
- typeof indexOrName === "number"
315
- ? fieldConfigs [ indexOrName ]
316
- : fieldConfigs . find ( ( { name } ) => name == indexOrName ) ;
317
- if ( ! fieldConfig ) {
318
- throw new Error ( `No operation found for indexOrName: ${ indexOrName } ` ) ;
319
- }
320
-
321
- return (
322
- < OperationRenderer
323
- key = { `fabrix-operation${ typeof indexOrName === "number" ? `-${ indexOrName } ` : "" } -${ fieldConfig . name } ` }
324
- operation = { fieldConfig }
325
- variables = { props . variables }
326
- getComponentFn = { getComponent }
327
- renderer = { renderer as Parameters < FabrixGetOperationFn > [ 1 ] }
328
- />
329
- ) ;
330
- } ,
331
- [ fieldConfigs , props . variables ] ,
332
- ) ;
279
+ const fieldConfig = fieldConfigs [ 0 ] ;
280
+ if ( ! fieldConfig ) {
281
+ throw new Error ( `No operation found` ) ;
282
+ }
333
283
334
284
return ( ) => {
285
+ const { fetching, error, data } = useDataFetch ( {
286
+ query : fieldConfig . document ,
287
+ variables : props . variables ,
288
+ pause : fieldConfig . type !== OperationTypeNode . QUERY ,
289
+ } ) ;
290
+
291
+ if ( fetching ) {
292
+ return < Loader /> ;
293
+ }
294
+
295
+ if ( error ) {
296
+ throw error ;
297
+ }
298
+
299
+ const component = getComponent ( fieldConfig , data , context ) ;
335
300
if ( props . children ) {
336
301
return props . children ( {
337
- getOperation,
338
- getComponent : (
339
- operationIndexOrName ,
340
- rootFieldName ,
341
- extraProps ,
342
- fieldsRenderer ,
343
- ) =>
344
- getOperation ( operationIndexOrName , ( { getComponent } ) =>
345
- getComponent ( rootFieldName , extraProps , fieldsRenderer ) ,
346
- ) ,
302
+ data,
303
+ getComponent : component ,
347
304
} ) ;
348
305
}
349
306
350
- return fieldConfigs . map ( ( _ , i ) => getOperation ( i ) ) ;
307
+ return fieldConfig . fields . map ( ( field ) =>
308
+ component ( field . name , {
309
+ key : `fabrix-${ fieldConfig . name } -${ field . name } ` ,
310
+ } ) ,
311
+ ) ;
351
312
} ;
352
313
} ;
353
314
@@ -362,7 +323,7 @@ export const getComponentFn =
362
323
( props : FabrixComponentProps , rendererFn : RendererFn ) =>
363
324
(
364
325
fieldConfig : FieldConfigs ,
365
- data : FabrixComponentData ,
326
+ data : FabrixComponentData | undefined ,
366
327
context : FabrixContextType ,
367
328
) =>
368
329
(
@@ -375,81 +336,14 @@ export const getComponentFn =
375
336
throw new Error ( `No root field found for name: ${ name } ` ) ;
376
337
}
377
338
339
+ const dataByName = data ? ( name in data ? data [ name ] : { } ) : { } ;
340
+
378
341
return (
379
342
< div
380
343
key = { extraProps ?. key }
381
344
className = { `fabrix renderer container ${ props . containerClassName ?? "" } ${ extraProps ?. className ?? "" } ` }
382
345
>
383
- { rendererFn ( field , data [ name ] , context , componentFieldsRenderer ) }
346
+ { rendererFn ( field , dataByName , context , componentFieldsRenderer ) }
384
347
</ div >
385
348
) ;
386
349
} ;
387
-
388
- type GetComponentFn = (
389
- op : FieldConfigs ,
390
- data : FabrixComponentData ,
391
- context : FabrixContextType ,
392
- ) => FabrixGetComponentFn ;
393
-
394
- type RendererCommonProps = {
395
- key : string ;
396
- operation : FieldConfigs ;
397
- variables : Record < string , unknown > | undefined ;
398
- renderer ?: Parameters < FabrixGetOperationFn > [ 1 ] ;
399
- getComponentFn : GetComponentFn ;
400
- extraClassName ?: string ;
401
- } ;
402
-
403
- const OperationRenderer = ( props : RendererCommonProps ) => {
404
- return props . operation . type === OperationTypeNode . MUTATION ? (
405
- < MutateOperationRenderer { ...props } />
406
- ) : (
407
- < QueryOperationRenderer { ...props } />
408
- ) ;
409
- } ;
410
-
411
- const QueryOperationRenderer = ( {
412
- operation,
413
- variables,
414
- renderer,
415
- getComponentFn,
416
- } : RendererCommonProps ) => {
417
- const context = useContext ( FabrixContext ) ;
418
- const { fetching, error, data } = useDataFetch ( {
419
- query : operation . document ,
420
- variables,
421
- } ) ;
422
-
423
- if ( fetching || ! data ) {
424
- return < Loader /> ;
425
- }
426
-
427
- if ( error ) {
428
- throw error ;
429
- }
430
-
431
- const getComponent = getComponentFn ( operation , data , context ) ;
432
- return renderer
433
- ? renderer ( { data, getComponent } )
434
- : operation . fields . map ( ( field ) =>
435
- getComponent ( field . name , {
436
- key : `fabrix-query-${ operation . name } -${ field . name } ` ,
437
- } ) ,
438
- ) ;
439
- } ;
440
-
441
- const MutateOperationRenderer = ( {
442
- operation,
443
- renderer,
444
- getComponentFn,
445
- } : RendererCommonProps ) => {
446
- const context = useContext ( FabrixContext ) ;
447
- const getComponent = getComponentFn ( operation , { } , context ) ;
448
- return renderer
449
- ? renderer ( { data : { } , getComponent } )
450
- : operation . fields . map ( ( field ) =>
451
- getComponent ( field . name , {
452
- key : `fabrix-mutation-${ operation . name } -${ field . name } ` ,
453
- } ) ,
454
- ) ;
455
- } ;
0 commit comments