1
- import { useState } from 'react' ;
1
+ import { useEffect , useRef , useState } from 'react' ;
2
2
import { useQuery } from 'urql' ;
3
3
import { Page , TargetLayout } from '@/components/layouts/target' ;
4
4
import { BadgeRounded } from '@/components/ui/badge' ;
@@ -230,7 +230,6 @@ function ChecksPageContent(props: {
230
230
const [ paginationVariables , setPaginationVariables ] = useState < Array < string | null > > ( ( ) => [
231
231
null ,
232
232
] ) ;
233
- const [ hasSchemaChecks , setHasSchemaChecks ] = useState ( false ) ;
234
233
const navigate = useNavigate ( ) ;
235
234
const { schemaCheckId } = useParams ( {
236
235
strict : false /* allows to read the $schemaCheckId param of its child route */ ,
@@ -266,9 +265,17 @@ function ChecksPageContent(props: {
266
265
) ;
267
266
}
268
267
269
- if ( ! hasSchemaChecks && ! ! query . data ?. target ?. schemaChecks ?. edges ?. length ) {
270
- setHasSchemaChecks ( true ) ;
271
- }
268
+ const [ isLoading ] = useDebouncedLoader ( query . fetching || query . stale ) ;
269
+
270
+ const [ hasSchemaChecks , setHasSchemaChecks ] = useState (
271
+ ! ! query . data ?. target ?. schemaChecks ?. edges ?. length ,
272
+ ) ;
273
+ useEffect ( ( ) => {
274
+ if ( ! query . stale && ! query . fetching ) {
275
+ setHasSchemaChecks ( ! ! query . data ?. target ?. schemaChecks ?. edges ?. length ) ;
276
+ }
277
+ } , [ query . fetching , query . stale , ! query . data ?. target ?. schemaChecks ?. edges ?. length ] ) ;
278
+
272
279
const hasFilteredSchemaChecks = ! ! query . data ?. target ?. filteredSchemaChecks ?. edges ?. length ;
273
280
const hasActiveSchemaCheck = ! ! schemaCheckId ;
274
281
@@ -290,9 +297,11 @@ function ChecksPageContent(props: {
290
297
} ) ;
291
298
} ;
292
299
300
+ const loadMore = ( cursor : string ) => setPaginationVariables ( cursors => [ ...cursors , cursor ] ) ;
301
+
293
302
return (
294
303
< >
295
- < div >
304
+ < div className = { cn ( ! hasActiveSchemaCheck && ! hasSchemaChecks && 'w-full' ) } >
296
305
< div className = "w-[300px] py-6" >
297
306
< Title > Schema Checks</ Title >
298
307
< Subtitle > Recently checked schemas.</ Subtitle >
@@ -337,40 +346,46 @@ function ChecksPageContent(props: {
337
346
schemaCheckId = { schemaCheckId }
338
347
after = { cursor }
339
348
isLastPage = { index + 1 === paginationVariables . length }
340
- onLoadMore = { cursor => setPaginationVariables ( cursors => [ ... cursors , cursor ] ) }
349
+ onLoadMore = { loadMore }
341
350
key = { cursor ?? 'first' }
342
351
showOnlyChanged = { showOnlyChanged }
343
352
showOnlyFailed = { showOnlyFailed }
344
353
/>
345
354
) ) }
346
355
</ div >
347
- ) : query . fetching || query . stale ? (
348
- < Spinner />
349
356
) : (
350
- < div className = "my-4 cursor-default text-center text-sm text-gray-400" >
351
- No schema checks found with the current filters
352
- </ div >
357
+ ! query . fetching &&
358
+ ! query . stale && (
359
+ < div className = "my-4 cursor-default text-center text-sm text-gray-400" >
360
+ No schema checks found with the current filters
361
+ </ div >
362
+ )
353
363
) }
354
364
</ div >
355
- ) : query . fetching ? (
356
- < Spinner />
357
365
) : (
358
- < div >
359
- < div className = "cursor-default text-sm" >
360
- { hasActiveSchemaCheck ? (
361
- 'List is empty'
362
- ) : (
363
- < NoSchemaVersion
364
- projectType = { query . data ?. target ?. project . type ?? null }
365
- recommendedAction = "check"
366
- />
367
- ) }
366
+ ! query . fetching &&
367
+ ! query . stale && (
368
+ < div >
369
+ < div className = "cursor-default text-sm" >
370
+ { ! hasActiveSchemaCheck && (
371
+ < NoSchemaVersion
372
+ projectType = { query . data ?. target ?. project . type ?? null }
373
+ recommendedAction = "check"
374
+ />
375
+ ) }
376
+ </ div >
377
+ < DocsLink
378
+ href = "/features/schema-registry#check-a-schema"
379
+ className = "flex flex-row items-center"
380
+ >
381
+ Learn how to check your first schema
382
+ </ DocsLink >
368
383
</ div >
369
- < DocsLink href = "/features/schema-registry#check-a-schema" >
370
- { hasActiveSchemaCheck
371
- ? 'Check you first schema'
372
- : 'Learn how to check your first schema with Hive CLI' }
373
- </ DocsLink >
384
+ )
385
+ ) }
386
+ { isLoading && (
387
+ < div className = "mt-4 flex w-full grow flex-col items-center" >
388
+ < Spinner / >
374
389
</ div >
375
390
) }
376
391
</ div >
@@ -410,3 +425,28 @@ export function TargetChecksPage(props: {
410
425
</ >
411
426
) ;
412
427
}
428
+
429
+ const useDebouncedLoader = ( isLoading : boolean , delay = 500 ) => {
430
+ const [ showLoadingIcon , setShowLoadingIcon ] = useState ( false ) ;
431
+ const timerRef = useRef < ReturnType < typeof setTimeout > | undefined > ( undefined ) ;
432
+
433
+ useEffect ( ( ) => {
434
+ if ( isLoading ) {
435
+ // Start a timer to show the loading icon after the delay
436
+ timerRef . current = setTimeout ( ( ) => {
437
+ setShowLoadingIcon ( true ) ;
438
+ } , delay ) ;
439
+ } else {
440
+ // If loading finishes, clear any pending timer and hide the icon
441
+ clearTimeout ( timerRef . current ) ;
442
+ setShowLoadingIcon ( false ) ;
443
+ }
444
+
445
+ // Cleanup function to clear the timer on unmount or if isLoading changes
446
+ return ( ) => {
447
+ clearTimeout ( timerRef . current ) ;
448
+ } ;
449
+ } , [ isLoading , delay ] ) ;
450
+
451
+ return [ showLoadingIcon ] ;
452
+ } ;
0 commit comments