;
};
export interface ListControllerProps<
RecordType extends RaRecord = any,
ErrorType = Error,
> {
/**
* The debounce delay for filter queries in milliseconds. Defaults to 500ms.
*
* @see https://marmelab.com/react-admin/List.html#debounce
* @example
* // wait 1 seconds instead of 500 milliseconds befoce calling the dataProvider
* const PostList = () => (
*
* ...
*
* );
*/
debounce?: number;
/**
* Allow anonymous access to the list view. Defaults to false.
*
* @see https://marmelab.com/react-admin/List.html#disableauthentication
* @example
* import { List } from 'react-admin';
*
* const BoolkList = () => (
*
* ...
*
* );
*/
disableAuthentication?: boolean;
/**
* Whether to disable the synchronization of the list parameters with the current location (URL search parameters)
*
* @see https://marmelab.com/react-admin/List.html#disablesyncwithlocation
* @example
* const Dashboard = () => (
*
* // ...
*
*
* record.title}
* secondaryText={record => `${record.views} views`}
* tertiaryText={record => new Date(record.published_at).toLocaleDateString()}
* />
*
*
*
*
* record.title}
* secondaryText={record => `${record.views} views`}
* tertiaryText={record => new Date(record.published_at).toLocaleDateString()}
* />
*
*
*
* )
*/
disableSyncWithLocation?: boolean;
/**
* The function called when a user exports the list
*
* @see https://marmelab.com/react-admin/List.html#exporter
* @example
* import { List, downloadCSV } from 'react-admin';
* import jsonExport from 'jsonexport/dist';
*
* const exporter = posts => {
* const postsForExport = posts.map(post => {
* const { backLinks, author, ...postForExport } = post; // omit backLinks and author
* postForExport.author_name = post.author.name; // add a field
* return postForExport;
* });
* jsonExport(postsForExport, {
* headers: ['id', 'title', 'author_name', 'body'] // order fields in the export
* }, (err, csv) => {
* downloadCSV(csv, 'posts'); // download as 'posts.csv` file
* });
* };
*
* const PostList = () => (
*
* ...
*
* )
*/
exporter?: Exporter | false;
/**
* Permanent filter applied to all getList queries, regardless of the user selected filters.
*
* @see https://marmelab.com/react-admin/List.html#filter
* @example
* export const PostList = () => (
*
* ...
*
* );
*/
filter?: FilterPayload;
/**
* The filter to apply when calling getList if the filter is empty.
*
* @see https://marmelab.com/react-admin/List.html#filterdefaultvalues
* @example
* const postFilters = [
* ,
* ,
* ,
* ];
*
* export const PostList = () => (
*
* ...
*
* );
*/
filterDefaultValues?: object;
/**
* The number of results per page. Defaults to 10.
*
* @see https://marmelab.com/react-admin/List.html#perpage
* @example
* export const PostList = () => (
*
* ...
*
* );
*/
perPage?: number;
/**
* The options passed to react-query's useQuery when calling getList.
*
* @see https://marmelab.com/react-admin/List.html#queryoptions
* @example
* import { useNotify, useRedirect, List } from 'react-admin';
*
* const PostList = () => {
* const notify = useNotify();
* const redirect = useRedirect();
*
* const onError = (error) => {
* notify(`Could not load list: ${error.message}`, { type: 'error' });
* redirect('/dashboard');
* };
*
* return (
*
* ...
*
* );
* }
*/
queryOptions?: UseGetListOptions;
/**
* The resource name. Defaults to the resource from ResourceContext.
*
* @see https://marmelab.com/react-admin/List.html#resource
* @example
* import { List } from 'react-admin';
*
* const PostList = () => (
*
* ...
*
* );
*/
resource?: string;
/**
* The default sort field and order. Defaults to { field: 'id', order: 'ASC' }.
*
* @see https://marmelab.com/react-admin/List.html#sort
* @example
* export const PostList = () => (
*
* ...
*
* );
*/
sort?: SortPayload;
/**
* The key to use to store the current filter & sort. Pass false to disable.
*
* @see https://marmelab.com/react-admin/List.html#storekey
* @example
* const NewerBooks = () => (
*
* ...
*
* );
*/
storeKey?: string | false;
}
const defaultSort = {
field: 'id',
order: SORT_ASC,
} as const;
export const DEFAULT_MAX_RESULTS = 1000;
export const injectedProps = [
'sort',
'data',
'defaultTitle',
'displayedFilters',
'error',
'exporter',
'getData',
'filterValues',
'hasNextPage',
'hasPreviousPage',
'hideFilter',
'isFetching',
'isLoading',
'isPending',
'onSelect',
'onSelectAll',
'onToggleItem',
'onUnselectItems',
'page',
'perPage',
'refetch',
'refresh',
'resource',
'selectedIds',
'setFilters',
'setPage',
'setPerPage',
'setSort',
'showFilter',
'total',
'totalPages',
];
/**
* Select the props injected by the useListController hook
* to be passed to the List children need
* This is an implementation of pick()
*/
export const getListControllerProps = props =>
injectedProps.reduce((acc, key) => ({ ...acc, [key]: props[key] }), {});
/**
* Select the props not injected by the useListController hook
* to be used inside the List children to sanitize props injected by List
* This is an implementation of omit()
*/
export const sanitizeListRestProps = props =>
Object.keys(props)
.filter(propName => !injectedProps.includes(propName))
.reduce((acc, key) => ({ ...acc, [key]: props[key] }), {});
export interface GetDataOptions {
maxResults?: number;
meta?: any;
}
export interface ListControllerBaseResult {
sort: SortPayload;
defaultTitle?: string;
displayedFilters: any;
exporter?: Exporter | false;
// FIXME: make non-optional in next major
getData?: (options?: GetDataOptions) => Promise;
filter?: FilterPayload;
filterValues: any;
hideFilter: (filterName: string) => void;
onSelect: (ids: RecordType['id'][]) => void;
onSelectAll: (options?: {
limit?: number;
queryOptions?:
| UseGetListOptions
| UseReferenceArrayFieldControllerParams['queryOptions']
| UseReferenceManyFieldControllerParams['queryOptions'];
}) => void;
onToggleItem: (id: RecordType['id']) => void;
onUnselectItems: (fromAllStoreKeys?: boolean) => void;
page: number;
perPage: number;
refetch: (() => void) | UseGetListHookValue['refetch'];
resource: string;
selectedIds: RecordType['id'][];
setFilters: (
filters: any,
displayedFilters?: any,
debounce?: boolean
) => void;
setPage: (page: number) => void;
setPerPage: (page: number) => void;
setSort: (sort: SortPayload) => void;
showFilter: (filterName: string, defaultValue: any) => void;
hasNextPage?: boolean;
hasPreviousPage?: boolean;
isFetching?: boolean;
isLoading?: boolean;
isPaused?: boolean;
isPlaceholderData?: boolean;
}
export interface ListControllerLoadingResult
extends ListControllerBaseResult {
data: undefined;
total: undefined;
meta: undefined;
error: null;
isPending: true;
}
export interface ListControllerErrorResult<
RecordType extends RaRecord = any,
TError = Error,
> extends ListControllerBaseResult {
data: undefined;
total: undefined;
meta: undefined;
error: TError;
isPending: false;
}
export interface ListControllerRefetchErrorResult<
RecordType extends RaRecord = any,
TError = Error,
> extends ListControllerBaseResult {
data: RecordType[];
total: number;
meta?: any;
error: TError;
isPending: false;
}
export interface ListControllerSuccessResult
extends ListControllerBaseResult {
data: RecordType[];
total: number;
meta?: any;
error: null;
isPending: false;
}
export type ListControllerResult<
RecordType extends RaRecord = any,
ErrorType = Error,
> =
| ListControllerLoadingResult
| ListControllerErrorResult
| ListControllerRefetchErrorResult
| ListControllerSuccessResult;