/** * WordPress dependencies */ import apiFetch from '@safe-wordpress/api-fetch'; import { useDispatch } from '@safe-wordpress/data'; import { useCallback } from '@safe-wordpress/element'; import { addQueryArgs } from '@safe-wordpress/url'; /** * External dependencies */ import { store as NAB_DATA } from '@nab/data'; import type { EntityInstance, PaginatedResults } from '@nab/types'; /** * Internal dependencies */ import type { OptionLoaderProps, OptionResults } from './types'; type OptionLoader = ( query: string, _: unknown, args?: OptionResults[ 'additional' ] ) => Promise< OptionResults >; export const useOptionLoader = ( { type, perPage = 50, filter = () => true, }: OptionLoaderProps ): OptionLoader => { const { receiveEntityRecords } = useDispatch( NAB_DATA ); const cacheEntities = useCallback( ( entities: ReadonlyArray< EntityInstance > ): void => void ( entities.length && receiveEntityRecords( type, entities ) ), [ type, receiveEntityRecords ] ); return useCallback( ( query: string, _: unknown, args?: { page: number } ) => apiFetch< PaginatedResults< ReadonlyArray< EntityInstance > > >( { path: addQueryArgs( '/nab/v1/post/search', { query, type, page: args?.page ?? 1, per_page: perPage, } ), } ).then( ( data ): OptionResults => { cacheEntities( data.results ); const results = data.results.filter( filter ); return { options: results.map( ( option ) => ( { value: option.id, label: option.title, type, } ) ), hasMore: data.pagination.more, additional: { page: ( args?.page ?? 1 ) + 1, }, }; } ), [ filter, perPage, type, cacheEntities ] ); };