Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions packages/ra-core/src/controller/list/useListController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const useListController = <
filterDefaultValues,
perPage = 10,
queryOptions = {},
selectionStoreKey,
sort = defaultSort,
storeKey,
} = props;
Expand Down Expand Up @@ -101,10 +102,19 @@ export const useListController = <
storeKey,
});

const [selectedIds, selectionModifiers] = useRecordSelection({
resource,
disableSyncWithStore: storeKey === false,
});
const [selectedIds, selectionModifiers] = useRecordSelection(
selectionStoreKey
? {
storeKey: selectionStoreKey,
}
: storeKey === false
? {
disableSyncWithStore: true,
}
: {
resource,
}
);

const {
data,
Expand Down Expand Up @@ -440,6 +450,23 @@ export interface ListControllerProps<
* );
*/
storeKey?: string | false;

/**
* The key to use to store selected items. Pass undefined to use default key.
*
* @see https://marmelab.com/react-admin/List.html#selectionStorekey
* @example
* const NewerBooks = () => (
* <List
* resource="books"
* selectionStoreKey="newerBooks"
* sort={{ field: 'year', order: 'DESC' }}
* >
* ...
* </List>
* );
*/
selectionStoreKey?: string;
}

const defaultSort = {
Expand Down
17 changes: 13 additions & 4 deletions packages/ra-core/src/controller/list/useRecordSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,24 @@ import { useCallback, useMemo, useState } from 'react';
import { useStore, useRemoveFromStore } from '../../store';
import { RaRecord } from '../../types';

type UseRecordSelectionWithStoreKeyArgs = {
storeKey: string;
resource?: string;
disableSyncWithStore?: false;
};
type UseRecordSelectionWithResourceArgs = {
storeKey?: string;
resource: string;
disableSyncWithStore?: false;
};
type UseRecordSelectionWithNoStoreArgs = {
storeKey?: string;
resource?: string;
disableSyncWithStore: true;
};

export type UseRecordSelectionArgs =
| UseRecordSelectionWithStoreKeyArgs
| UseRecordSelectionWithResourceArgs
| UseRecordSelectionWithNoStoreArgs;

Expand All @@ -29,6 +37,7 @@ export type UseRecordSelectionResult<RecordType extends RaRecord = any> = [
/**
* Get the list of selected items for a resource, and callbacks to change the selection
*
* @param args.storeKey The key to use to store the selected items
* @param args.resource The resource name, e.g. 'posts'
* @param args.disableSyncWithStore Controls the selection syncronization with the store
*
Expand All @@ -37,19 +46,19 @@ export type UseRecordSelectionResult<RecordType extends RaRecord = any> = [
export const useRecordSelection = <RecordType extends RaRecord = any>(
args: UseRecordSelectionArgs
): UseRecordSelectionResult<RecordType> => {
const { resource = '', disableSyncWithStore = false } = args;
const { storeKey, resource = '', disableSyncWithStore = false } = args;

const storeKey = `${resource}.selectedIds`;
const finalStoreKey = storeKey || `${resource}.selectedIds`;

const [localIds, setLocalIds] =
useState<RecordType['id'][]>(defaultSelection);
// As we can't conditionally call a hook, if the storeKey is false,
// we'll ignore the params variable later on and won't call setParams either.
const [storeIds, setStoreIds] = useStore<RecordType['id'][]>(
storeKey,
finalStoreKey,
defaultSelection
);
const resetStore = useRemoveFromStore(storeKey);
const resetStore = useRemoveFromStore(finalStoreKey);

const ids = disableSyncWithStore ? localIds : storeIds;
const setIds = disableSyncWithStore ? setLocalIds : setStoreIds;
Expand Down
2 changes: 2 additions & 0 deletions packages/ra-ui-materialui/src/list/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const List = <RecordType extends RaRecord = any>(
perPage = 10,
queryOptions,
resource,
selectionStoreKey,
sort,
storeKey,
render,
Expand Down Expand Up @@ -100,6 +101,7 @@ export const List = <RecordType extends RaRecord = any>(
perPage={perPage}
queryOptions={queryOptions}
resource={resource}
selectionStoreKey={selectionStoreKey}
sort={sort}
storeKey={storeKey}
// Disable offline support from ListBase as it is handled by ListView to keep the ListView container
Expand Down