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;