import { useQueryClient } from '@tanstack/react-query'; import { useNotify } from '../../notification'; import { useDataProvider, UseGetListOptions } from '../../dataProvider'; import { useRecordSelection } from './useRecordSelection'; import { useResourceContext } from '../../core'; import { useEvent } from '../../util'; import type { FilterPayload, RaRecord, SortPayload } from '../../types'; /** * Get a callback to select all records of a resource (capped by the limit parameter) * * @param {Object} params The hook parameters { resource, sort, filter } * @returns {Function} handleSelectAll A function to select all items of a list * * @example * import { List, Datagrid, BulkActionsToolbar, BulkDeleteButton, useListContext, useSelectAll } from 'react-admin'; * * const MySelectAllButton = () => { * const { sort, filter } = useListContext(); * const handleSelectAll = useSelectAll({ resource: 'posts', sort, filter }); * const handleClick = () => handleSelectAll({ * queryOptions: { meta: { foo: 'bar' } }, * limit: 250, * }); * return ; * }; * * const PostBulkActionsToolbar = () => ( * }> * * * ); * * export const PostList = () => ( * * }> * ... * * * ); */ export const useSelectAll = ( params: UseSelectAllParams ): UseSelectAllResult => { const { sort, filter, storeKey, disableSyncWithStore } = params; const resource = useResourceContext(params); if (!resource) { throw new Error( 'useSelectAll should be used inside a ResourceContextProvider or passed a resource prop' ); } const dataProvider = useDataProvider(); const queryClient = useQueryClient(); const [, { select }] = useRecordSelection({ resource, storeKey, disableSyncWithStore, }); const notify = useNotify(); const handleSelectAll = useEvent( async ({ queryOptions = {}, limit = 250, }: HandleSelectAllParams = {}) => { const { meta, onSuccess, onError, ...otherQueryOptions } = queryOptions; try { const results = await queryClient.fetchQuery({ queryKey: [ resource, 'getList', { pagination: { page: 1, perPage: limit }, sort, filter, meta, }, ], queryFn: () => dataProvider.getList(resource, { pagination: { page: 1, perPage: limit, }, sort, filter, meta, }), ...otherQueryOptions, }); const allIds = results.data?.map(({ id }) => id) || []; select(allIds); if (allIds.length === limit) { notify('ra.message.select_all_limit_reached', { messageArgs: { max: limit }, type: 'warning', }); } if (onSuccess) { onSuccess(results); } return results.data; } catch (error) { if (onError) { onError(error); } else { notify('ra.notification.http_error', { type: 'warning' }); } } } ); return handleSelectAll; }; export interface UseSelectAllParams { resource?: string; sort?: SortPayload; filter?: FilterPayload; storeKey?: string; disableSyncWithStore?: boolean; } export interface HandleSelectAllParams { limit?: number; queryOptions?: UseGetListOptions; } export type UseSelectAllResult = (options?: HandleSelectAllParams) => void;