import { useCallback , useEffect , useMemo , useState } from "react" ; import { Entity , EntitySchemaResolver , FilterValues } from "../../models" ; import { useDataSource } from "./useDataSource" ; category export interface CollectionFetchProps < M extends { [ Key ] : any ; } > { /**
     * Absolute collection path
     */ path : string ; /**
     * Schema of the entity displayed by this collection
     */ schemaResolver : EntitySchemaResolver < M > ; /**
     * Number of entities to fetch
     */ itemCount ? : number ; /**
     * List of entities that will be displayed on top, no matter the ordering.
     * This is used for reference fields selection
     */ entitiesDisplayedFirst ? : Entity < M > [ ] ; /**
     * Filter the fetched data by the property
     */ filterValues ? : FilterValues < M > ; /**
     * Sort the results by
     */ sortBy ? : [ Extract < keyof M , string > , "asc" | "desc" ] ; /**
     * Search string
     */ searchString ? : string ; } category export interface CollectionFetchResult < M extends { [ Key ] : any ; } > { data : Entity < M > [ ] ; dataLoading : boolean ; noMoreToLoad : boolean ; dataLoadingError ? : Error ; } param path param schemaResolver param filterValues param sortBy param itemCount param searchString param entitiesDisplayedFirst category export function useCollectionFetch < M > ( { path , schemaResolver , filterValues , sortBy , itemCount , searchString , entitiesDisplayedFirst } ) { const sortByProperty = sortBy ? sortBy [ 0 ] : undefined ; const currentSort = sortBy ? sortBy [ 1 ] : undefined ; const dataSource = useDataSource ( ) ; const initialEntities = useMemo ( ( ) => entitiesDisplayedFirst ? entitiesDisplayedFirst . filter ( e => ! ! e . values ) : [ ] , [ entitiesDisplayedFirst ] ) ; const [ data , setData ] = useState < Entity < M > [ ] > ( initialEntities ) ; const [ dataLoading , setDataLoading ] = useState < boolean > ( false ) ; const [ dataLoadingError , setDataLoadingError ] = useState < Error | undefined > ( ) ; const [ noMoreToLoad , setNoMoreToLoad ] = useState < boolean > ( false ) ; const updateData = useCallback ( ( entities ) => { if ( ! initialEntities ) { setData ( entities ) ; } else { const displayedFirstId = new Set ( initialEntities . map ( ( e ) => e . id ) ) ; setData ( [ ... initialEntities , ... entities . filter ( ( e ) => ! displayedFirstId . has ( e . id ) ) ] ) ; } } , [ initialEntities ] ) ; useEffect ( ( ) => { setDataLoading ( true ) ; const onEntitiesUpdate = ( entities ) => { setDataLoading ( false ) ; setDataLoadingError ( undefined ) ; updateData ( entities ) ; setNoMoreToLoad ( ! itemCount || entities . length < itemCount ) ; } ; const onError = ( error ) => { console . error ( "ERROR" , error ) ; setDataLoading ( false ) ; setData ( [ ] ) ; setDataLoadingError ( error ) ; } ; if ( dataSource . listenCollection ) { return dataSource . listenCollection < M > ( { path : path , schema : schemaResolver , onUpdate : onEntitiesUpdate , onError , searchString , filter : filterValues , limit : itemCount , startAfter : undefined , orderBy : sortByProperty , order : currentSort } ) ; } else { dataSource . fetchCollection < M > ( { path : path , schema : schemaResolver , searchString , filter : filterValues , limit : itemCount , startAfter : undefined , orderBy : sortByProperty , order : currentSort } ) . then ( onEntitiesUpdate ) . catch ( onError ) ; return ( ) => { } ; } } , [ path , itemCount , currentSort , sortByProperty , filterValues , searchString ] ) ; return { data , dataLoading , dataLoadingError , noMoreToLoad } ; }