Skip to content

Commit

Permalink
Merge pull request #7076 from marmelab/currentsort-to-sort
Browse files Browse the repository at this point in the history
[BC Break] rename `currentSort` to `sort`
  • Loading branch information
djhi authored Jan 14, 2022
2 parents a5f8379 + 28b7d3c commit f35b672
Show file tree
Hide file tree
Showing 35 changed files with 163 additions and 135 deletions.
47 changes: 44 additions & 3 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,47 @@ const CommentGrid = () => {
};
```

## `currentSort` Renamed To `sort`

If one of your components displays the curent sort order, it probably uses the injected `currentSort` prop (or reads it from the `ListContext`). This prop has been renamed to `sort` in v4.

Upgrade your code by replacing `currentSort` with `sort`:

```diff
import { useListContext } from 'react-admin';

const BookListIterator = () => {
- const { data, loading, currentSort } = useListContext();
+ const { data, isLoading, sort } = useListContext();

if (loading) return <Loading />;
if (data.length === 0) return <p>No data</p>;

return (<>
- <div>Books sorted by {currentSort.field}</div>
+ <div>Books sorted by {sort.field}</div>
<ul>
{data.map(book =>
<li key={book.id}>{book.title}</li>
)}
</ul>
</>);
};
```

The same happens for `<Datagrid>`: when used in standalone, it used to accept a `currentSort` prop, but now it only accepts a `sort` prop.


```diff
-<Datagrid data={data} currentSort={{ field: 'id', order: 'DESC' }}>
+<Datagrid data={data} sort={{ field: 'id', order: 'DESC' }}>
<TextField source="id" />
<TextField source="title" />
<TextField source="author" />
<TextField source="year" />
</Datagrid>
```

## `setSort()` Signature Changed

Some react-admin components have access to a `setSort()` callback to sort the current list of items. This callback is also present in the `ListContext`. Its signature has changed:
Expand All @@ -1074,16 +1115,16 @@ This impacts your code if you built a custom sort component:

```diff
const SortButton = () => {
const { currentSort, setSort } = useListContext();
const { sort, setSort } = useListContext();
const handleChangeSort = (event) => {
const field = event.currentTarget.dataset.sort;
- setSort(
- field,
- field === currentSort.field ? inverseOrder(currentSort.order) : 'ASC',
- field === sort.field ? inverseOrder(sort.order) : 'ASC',
- });
+ setSort({
+ field,
+ order: field === currentSort.field ? inverseOrder(currentSort.order) : 'ASC',
+ order: field === sort.field ? inverseOrder(sort.order) : 'ASC',
+ });
setAnchorEl(null);
};
Expand Down
10 changes: 5 additions & 5 deletions docs/Datagrid.md
Original file line number Diff line number Diff line change
Expand Up @@ -890,20 +890,20 @@ You can use the `<Datagrid>` component to display data that you've fetched yours
```jsx
import { useGetList, Datagrid, TextField } from 'react-admin';

const currentSort = { field: 'id', order: 'DESC' };
const sort = { field: 'id', order: 'DESC' };

const MyCustomList = () => {
const { data, total, isLoading } = useGetList('books', {
pagination: { page: 1, perPage: 10 },
sort: currentSort,
sort,
});

return (
<Datagrid
data={data}
total={total}
isLoading={isLoading}
currentSort={currentSort}
sort={sort}
bulkActionButtons={false}
>
<TextField source="id" />
Expand All @@ -924,12 +924,12 @@ import {
TextField
} from 'react-admin';

const currentSort = { field: 'id', order: 'DESC' };
const sort = { field: 'id', order: 'DESC' };

const MyCustomList = () => {
const { data, isLoading } = useGetList('books', {
pagination: { page: 1, perPage: 10 },
sort: currentSort,
sort,
});
const listContext = useList({ data, isLoading });

Expand Down
28 changes: 14 additions & 14 deletions docs/ListTutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ const BookList = () => {
const [filter, setFilter] = useState('');
const [page, setPage] = useState(1);
const perPage = 10;
const currentSort = { field: 'id', order: 'ASC' };
const sort = { field: 'id', order: 'ASC' };
const { data, total, isLoading } = useGetList('books', {
filter: { q: filter },
pagination: { page, perPage },
sort: currentSort,
sort,
});
if (isLoading) {
return <div>Loading...</div>;
Expand All @@ -132,7 +132,7 @@ const BookList = () => {
margin="dense"
/>
<Card>
<Datagrid data={data} currentSort={currentSort}>
<Datagrid data={data} sort={sort}>
<TextField source="id" />
<TextField source="title" />
<TextField source="author" />
Expand Down Expand Up @@ -173,11 +173,11 @@ const BookList = () => {
const [filter, setFilter] = useState('');
const [page, setPage] = useState(1);
const perPage = 10;
const currentSort = { field: 'id', order: 'ASC' };
const sort = { field: 'id', order: 'ASC' };
const { data, total, isLoading } = useGetList('books', {
filter: { q: filter },
pagination: { page, perPage },
sort: currentSort,
sort,
});
if (isLoading) {
return <div>Loading...</div>;
Expand All @@ -186,7 +186,7 @@ const BookList = () => {
const filterValues = { q: filter };
const setFilters = filters => setFilter(filters.q);
return (
<ListContextProvider value={{ data, total, page, perPage, setPage, filterValues, setFilters, currentSort }}>
<ListContextProvider value={{ data, total, page, perPage, setPage, filterValues, setFilters, sort }}>
<div>
<Title title="Book list" />
<FilterForm filters={filters} />
Expand Down Expand Up @@ -534,7 +534,7 @@ const SortByViews = () => (

## Building a Custom Sort Control

When neither the `<Datagrid>` or the `<SortButton>` fit your UI needs, you have to write a custom sort control. As with custom filters, this boils down to grabbing the required data and callbacks from the `ListContext`. Let's use the `<SortButton>` source as an example usage of `currentSort` and `setSort`:
When neither the `<Datagrid>` or the `<SortButton>` fit your UI needs, you have to write a custom sort control. As with custom filters, this boils down to grabbing the required data and callbacks from the `ListContext`. Let's use the `<SortButton>` source as an example usage of `sort` and `setSort`:

```jsx
import * as React from 'react';
Expand All @@ -544,9 +544,9 @@ import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import { useListSortContext, useTranslate } from 'react-admin';

const SortButton = ({ fields }) => {
// currentSort is an object { field, order } containing the current sort
// sort is an object { field, order } containing the current sort
// setSort is a callback ({ field, order }) => void allowing to change the sort field and order
const { currentSort, setSort } = useListSortContext();
const { sort, setSort } = useListSortContext();
// rely on the translations to display labels like 'Sort by sales descending'
const translate = useTranslate();
// open/closed state for dropdown
Expand All @@ -563,15 +563,15 @@ const SortButton = ({ fields }) => {
const field = event.currentTarget.dataset.sort;
setSort({
field,
order: field === currentSort.field ? inverseOrder(currentSort.order) : 'ASC'
order: field === sort.field ? inverseOrder(sort.order) : 'ASC'
});
setAnchorEl(null);
};

// English stranslation is 'Sort by %{field} %{order}'
const buttonLabel = translate('ra.sort.sort_by', {
field: translate(`resources.products.fields.${currentSort.field}`),
order: translate(`ra.sort.${currentSort.order}`),
field: translate(`resources.products.fields.${sort.field}`),
order: translate(`ra.sort.${sort.order}`),
});

return (<>
Expand Down Expand Up @@ -603,8 +603,8 @@ const SortButton = ({ fields }) => {
{translate(`resources.products.fields.${field}`)}{' '}
{translate(
`ra.sort.${
currentSort.field === field
? inverseOrder(currentSort.order)
sort.field === field
? inverseOrder(sort.order)
: 'ASC'
}`
)}
Expand Down
2 changes: 1 addition & 1 deletion docs/useList.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ const {
setPage, // a callback to change the page, e.g. setPage(3)
setPerPage, // a callback to change the number of results per page, e.g. setPerPage(25)
// sorting
currentSort, // a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
sort, // a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
setSort, // a callback to change the sort, e.g. setSort({ field: 'name', order: 'ASC' })
// filtering
filterValues, // a dictionary of filter values, e.g. { title: 'lorem', nationality: 'fr' }
Expand Down
2 changes: 1 addition & 1 deletion docs/useListContext.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const {
setPage, // a callback to change the page, e.g. setPage(3)
setPerPage, // a callback to change the number of results per page, e.g. setPerPage(25)
// sorting
currentSort, // a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
sort, // a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
setSort, // a callback to change the sort, e.g. setSort({ field: 'name', orfer: 'ASC' })
// filtering
filterValues, // a dictionary of filter values, e.g. { title: 'lorem', nationality: 'fr' }
Expand Down
2 changes: 1 addition & 1 deletion docs/useListController.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const {
setPage, // a callback to change the page, e.g. setPage(3)
setPerPage, // a callback to change the number of results per page, e.g. setPerPage(25)
// sorting
currentSort, // a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
sort, // a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
setSort, // a callback to change the sort, e.g. setSort({ field: 'name', order: 'ASC' })
// filtering
filterValues, // a dictionary of filter values, e.g. { title: 'lorem', nationality: 'fr' }
Expand Down
6 changes: 3 additions & 3 deletions examples/simple/src/customRouteLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import {
Title,
} from 'react-admin';

const currentSort = { field: 'published_at', order: 'DESC' };
const sort = { field: 'published_at', order: 'DESC' };

const CustomRouteLayout = ({ title = 'Posts' }) => {
useAuthenticated();

const { data, total, isLoading } = useGetList('posts', {
pagination: { page: 1, perPage: 10 },
sort: currentSort,
sort,
});

return !isLoading ? (
Expand All @@ -25,7 +25,7 @@ const CustomRouteLayout = ({ title = 'Posts' }) => {
Found <span className="total">{total}</span> posts !
</p>
<Datagrid
currentSort={currentSort}
sort={sort}
data={data}
isLoading={isLoading}
total={total}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('<useReferenceArrayFieldController />', () => {
);
expect(children).toHaveBeenCalledWith(
expect.objectContaining({
currentSort: { field: 'id', order: 'ASC' },
sort: { field: 'id', order: 'ASC' },
isFetching: true,
isLoading: true,
data: undefined,
Expand Down Expand Up @@ -79,7 +79,7 @@ describe('<useReferenceArrayFieldController />', () => {
);
expect(children).toHaveBeenCalledWith(
expect.objectContaining({
currentSort: { field: 'id', order: 'ASC' },
sort: { field: 'id', order: 'ASC' },
isFetching: false,
isLoading: false,
data: [
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('<useReferenceArrayFieldController />', () => {
);
expect(children).toHaveBeenCalledWith(
expect.objectContaining({
currentSort: { field: 'id', order: 'ASC' },
sort: { field: 'id', order: 'ASC' },
isFetching: false,
isLoading: false,
data: [{ id: 1, title: 'bar1' }],
Expand Down Expand Up @@ -150,7 +150,7 @@ describe('<useReferenceArrayFieldController />', () => {
);
expect(children).toHaveBeenCalledWith(
expect.objectContaining({
currentSort: { field: 'id', order: 'ASC' },
sort: { field: 'id', order: 'ASC' },
isFetching: false,
isLoading: false,
data: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export const useReferenceManyFieldController = (
);

return {
currentSort: sort,
sort,
data,
defaultTitle: null,
displayedFilters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export const useReferenceArrayInputController = <

return {
choices: dataStatus.choices,
currentSort: sort,
sort,
data: matchingReferences,
displayedFilters,
error:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ describe('useReferenceInputController', () => {
expect(children).toHaveBeenCalledWith(
expect.objectContaining({
possibleValues: {
currentSort: {
sort: {
field: 'title',
order: 'ASC',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const useReferenceInputController = <RecordType extends Record = Record>(
setPage,
perPage,
setPerPage,
currentSort: sort,
sort,
setSort,
filterValues,
displayedFilters,
Expand Down
4 changes: 2 additions & 2 deletions packages/ra-core/src/controller/list/ListContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ListControllerResult } from './useListController';
* @prop {Function} setPage a callback to change the page, e.g. setPage(3)
* @prop {integer} perPage the number of results per page. Defaults to 25
* @prop {Function} setPerPage a callback to change the number of results per page, e.g. setPerPage(25)
* @prop {Object} currentSort a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
* @prop {Object} sort a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
* @prop {Function} setSort a callback to change the sort, e.g. setSort({ field: 'name', order: 'ASC' })
* @prop {Object} filterValues a dictionary of filter values, e.g. { title: 'lorem', nationality: 'fr' }
* @prop {Function} setFilters a callback to update the filters, e.g. setFilters(filters, displayedFilters)
Expand Down Expand Up @@ -53,7 +53,7 @@ import { ListControllerResult } from './useListController';
* };
*/
export const ListContext = createContext<ListControllerResult>({
currentSort: null,
sort: null,
data: null,
defaultTitle: null,
displayedFilters: null,
Expand Down
10 changes: 5 additions & 5 deletions packages/ra-core/src/controller/list/ListSortContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ListControllerResult } from './useListController';
* List components do in react-admin (e.g. <SortButton>).
*
* @typedef {Object} ListSortContextValue
* @prop {Object} currentSort a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
* @prop {Object} sort a sort object { field, order }, e.g. { field: 'date', order: 'DESC' }
* @prop {Function} setSort a callback to change the sort, e.g. setSort({ field: 'name', order: 'ASC' })
* @prop {string} resource the resource name, deduced from the location. e.g. 'posts'
*
Expand All @@ -35,23 +35,23 @@ import { ListControllerResult } from './useListController';
* };
*/
export const ListSortContext = createContext<ListSortContextValue>({
currentSort: null,
sort: null,
setSort: null,
resource: null,
});

export type ListSortContextValue = Pick<
ListControllerResult,
'currentSort' | 'setSort' | 'resource'
'sort' | 'setSort' | 'resource'
>;

export const usePickSortContext = (
context: ListControllerResult
): ListSortContextValue =>
useMemo(
() => pick(context, ['currentSort', 'setSort', 'resource']),
() => pick(context, ['sort', 'setSort', 'resource']),
// eslint-disable-next-line react-hooks/exhaustive-deps
[context.currentSort, context.setSort]
[context.sort, context.setSort]
);

ListSortContext.displayName = 'ListSortContext';
Loading

0 comments on commit f35b672

Please sign in to comment.