From f24a1d9d23bffdd0e6c5e58bb93caea28566391a Mon Sep 17 00:00:00 2001 From: JulienM Date: Thu, 12 Mar 2020 19:02:52 +0100 Subject: [PATCH 1/7] Add a default order prop in Lists Fields --- examples/simple/src/posts/PostList.js | 7 ++++++- packages/ra-core/src/controller/useListController.ts | 2 +- packages/ra-core/src/controller/useListParams.ts | 9 ++++++--- packages/ra-core/src/controller/useSortState.ts | 5 +++-- .../ra-ui-materialui/src/field/ReferenceArrayField.tsx | 1 + packages/ra-ui-materialui/src/field/ReferenceField.tsx | 1 + .../ra-ui-materialui/src/field/ReferenceManyField.tsx | 1 + packages/ra-ui-materialui/src/field/sanitizeRestProps.ts | 1 + packages/ra-ui-materialui/src/field/types.ts | 2 ++ packages/ra-ui-materialui/src/input/ReferenceInput.tsx | 2 +- packages/ra-ui-materialui/src/list/Datagrid.js | 5 ++++- packages/ra-ui-materialui/src/list/DatagridHeaderCell.js | 1 + 12 files changed, 28 insertions(+), 9 deletions(-) diff --git a/examples/simple/src/posts/PostList.js b/examples/simple/src/posts/PostList.js index fa73cc50071..ab0374595d4 100644 --- a/examples/simple/src/posts/PostList.js +++ b/examples/simple/src/posts/PostList.js @@ -140,7 +140,12 @@ const PostList = props => { ) : ( - + { setFilters: (filters: any, displayedFilters: any) => void; setPage: (page: number) => void; setPerPage: (page: number) => void; - setSort: (sort: string) => void; + setSort: (sort: string, order?: string) => void; showFilter: (filterName: string, defaultValue: any) => void; total: number; version: number; diff --git a/packages/ra-core/src/controller/useListParams.ts b/packages/ra-core/src/controller/useListParams.ts index 4d11f70e564..ed86b70a943 100644 --- a/packages/ra-core/src/controller/useListParams.ts +++ b/packages/ra-core/src/controller/useListParams.ts @@ -40,7 +40,7 @@ interface Modifiers { changeParams: (action: any) => void; setPage: (page: number) => void; setPerPage: (pageSize: number) => void; - setSort: (sort: string) => void; + setSort: (sort: string, order?: string) => void; setFilters: (filters: any, displayedFilters: any) => void; hideFilter: (filterName: string) => void; showFilter: (filterName: string, defaultValue: any) => void; @@ -156,8 +156,11 @@ const useListParams = ({ }, requestSignature); // eslint-disable-line react-hooks/exhaustive-deps const setSort = useCallback( - (newSort: string) => - changeParams({ type: SET_SORT, payload: { sort: newSort } }), + (newSort: string, newOrder?: string) => + changeParams({ + type: SET_SORT, + payload: { sort: newSort, order: newOrder || undefined }, + }), requestSignature // eslint-disable-line react-hooks/exhaustive-deps ); diff --git a/packages/ra-core/src/controller/useSortState.ts b/packages/ra-core/src/controller/useSortState.ts index e13ce87f320..2747a14e14b 100644 --- a/packages/ra-core/src/controller/useSortState.ts +++ b/packages/ra-core/src/controller/useSortState.ts @@ -9,7 +9,7 @@ import { Sort } from '../types'; export interface SortProps { setSortField: (field: string) => void; setSortOrder: (order: string) => void; - setSort: (sort: Sort) => void; + setSort: (sort: Sort, order?: string) => void; sort: Sort; } @@ -116,7 +116,8 @@ export default (initialSort: Sort = defaultSort): SortProps => { return { setSort: useCallback( - (sort: Sort) => dispatch({ type: 'SET_SORT', payload: { sort } }), + (sort: Sort, order?: string) => + dispatch({ type: 'SET_SORT', payload: { sort, order } }), [dispatch] ), setSortField: useCallback( diff --git a/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx b/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx index 1a530c54e1e..3a27816d6f7 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx @@ -83,6 +83,7 @@ ReferenceArrayField.propTypes = { reference: PropTypes.string.isRequired, resource: PropTypes.string, sortBy: PropTypes.string, + sortByOrder: PropTypes.string, source: PropTypes.string.isRequired, }; diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.tsx b/packages/ra-ui-materialui/src/field/ReferenceField.tsx index fde215dd410..1138b218519 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceField.tsx @@ -118,6 +118,7 @@ ReferenceField.propTypes = { reference: PropTypes.string.isRequired, resource: PropTypes.string, sortBy: PropTypes.string, + sortByOrder: PropTypes.string, source: PropTypes.string.isRequired, translateChoice: PropTypes.func, linkType: PropTypes.oneOfType([ diff --git a/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx b/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx index 7c3e2e37e31..03841905062 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx @@ -138,6 +138,7 @@ ReferenceManyField.propTypes = { reference: PropTypes.string.isRequired, resource: PropTypes.string, sortBy: PropTypes.string, + sortByOrder: PropTypes.string, source: PropTypes.string.isRequired, sort: PropTypes.exact({ field: PropTypes.string, diff --git a/packages/ra-ui-materialui/src/field/sanitizeRestProps.ts b/packages/ra-ui-materialui/src/field/sanitizeRestProps.ts index 394b46ab5e9..d163631562c 100644 --- a/packages/ra-ui-materialui/src/field/sanitizeRestProps.ts +++ b/packages/ra-ui-materialui/src/field/sanitizeRestProps.ts @@ -18,6 +18,7 @@ export default (props: object): object => 'resource', 'sortable', 'sortBy', + 'sortByOrder', 'source', 'textAlign', 'translateChoice', diff --git a/packages/ra-ui-materialui/src/field/types.ts b/packages/ra-ui-materialui/src/field/types.ts index 59025e6bb37..df195d915be 100644 --- a/packages/ra-ui-materialui/src/field/types.ts +++ b/packages/ra-ui-materialui/src/field/types.ts @@ -5,6 +5,7 @@ type TextAlign = 'right' | 'left'; export interface FieldProps { addLabel?: boolean; sortBy?: string; + sortByOrder?: string; source?: string; label?: string; sortable?: boolean; @@ -25,6 +26,7 @@ export interface InjectedFieldProps { export const fieldPropTypes = { addLabel: PropTypes.bool, sortBy: PropTypes.string, + sortByOrder: PropTypes.string, source: PropTypes.string, label: PropTypes.string, sortable: PropTypes.bool, diff --git a/packages/ra-ui-materialui/src/input/ReferenceInput.tsx b/packages/ra-ui-materialui/src/input/ReferenceInput.tsx index 1fc31b786ab..0207efddad0 100644 --- a/packages/ra-ui-materialui/src/input/ReferenceInput.tsx +++ b/packages/ra-ui-materialui/src/input/ReferenceInput.tsx @@ -203,7 +203,7 @@ interface ReferenceInputViewProps { resource: string; setFilter: (v: string) => void; setPagination: (pagination: Pagination) => void; - setSort: (sort: Sort) => void; + setSort: (sort: Sort, order?: string) => void; source: string; warning?: string; } diff --git a/packages/ra-ui-materialui/src/list/Datagrid.js b/packages/ra-ui-materialui/src/list/Datagrid.js index 970c32efd29..693d03a0e9c 100644 --- a/packages/ra-ui-materialui/src/list/Datagrid.js +++ b/packages/ra-ui-materialui/src/list/Datagrid.js @@ -127,7 +127,10 @@ const Datagrid = props => { const updateSort = useCallback( event => { event.stopPropagation(); - setSort(event.currentTarget.dataset.sort); + setSort( + event.currentTarget.dataset.sort, + event.currentTarget.dataset.order + ); }, [setSort] ); diff --git a/packages/ra-ui-materialui/src/list/DatagridHeaderCell.js b/packages/ra-ui-materialui/src/list/DatagridHeaderCell.js index e5b3a16d7f6..c7d5c83b0a3 100644 --- a/packages/ra-ui-materialui/src/list/DatagridHeaderCell.js +++ b/packages/ra-ui-materialui/src/list/DatagridHeaderCell.js @@ -61,6 +61,7 @@ export const DatagridHeaderCell = props => { } direction={currentSort.order === 'ASC' ? 'asc' : 'desc'} data-sort={field.props.sortBy || field.props.source} + data-order={field.props.sortByOrder || 'ASC'} onClick={updateSort} classes={classes} > From f8bff0f7d2e74a8a67d50d1e887382474cfafc5d Mon Sep 17 00:00:00 2001 From: JulienM Date: Fri, 13 Mar 2020 10:27:29 +0100 Subject: [PATCH 2/7] fix types and doc --- docs/List.md | 29 +++++++++++++++++++ examples/simple/src/posts/PostList.js | 4 +-- .../src/field/ReferenceArrayField.tsx | 2 +- .../src/field/ReferenceField.tsx | 4 +-- .../src/field/ReferenceManyField.tsx | 4 +-- packages/ra-ui-materialui/src/field/types.ts | 5 ++-- .../src/list/DatagridHeaderCell.spec.js | 17 +++++++++++ 7 files changed, 56 insertions(+), 9 deletions(-) diff --git a/docs/List.md b/docs/List.md index abc885f95f2..b234bcc68cc 100644 --- a/docs/List.md +++ b/docs/List.md @@ -548,6 +548,35 @@ export const PostList = (props) => ( ``` {% endraw %} +### Specify Sort Order + +By default, a column is sorted by the `ASC` order property. You can use `DESC` via the `sortByOrder` property: + +{% raw %} +```jsx +// in src/posts.js +import React from 'react'; +import { List, Datagrid, TextField } from 'react-admin'; + +export const PostList = (props) => ( + + + + + + `${record.author.first_name} ${record.author.last_name}`} + /> + + + +); +``` +{% endraw %} + ### Permanent Filter You can choose to always filter the list, without letting the user disable this filter - for instance to display only published posts. Write the filter to be passed to the REST client in the `filter` props: diff --git a/examples/simple/src/posts/PostList.js b/examples/simple/src/posts/PostList.js index ab0374595d4..af018bc1ae4 100644 --- a/examples/simple/src/posts/PostList.js +++ b/examples/simple/src/posts/PostList.js @@ -144,10 +144,10 @@ const PostList = props => { source="title" cellClassName={classes.title} sortBy="title" - sortByOrder="DESC" /> @@ -156,7 +156,7 @@ const PostList = props => { label="resources.posts.fields.commentable_short" sortable={false} /> - + (['ASC', 'DESC']), source: PropTypes.string, label: PropTypes.string, sortable: PropTypes.bool, diff --git a/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js b/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js index c056d13f6f0..7a6ee16b2e3 100644 --- a/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js +++ b/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js @@ -48,6 +48,23 @@ describe('', () => { expect(getByTitle('ra.action.sort').dataset.sort).toBe('title'); }); + it('should be enabled when field has a sortByOrder props', () => { + const { getByTitle } = render( + + + + } + updateSort={() => true} + /> + + +
+ ); + expect(getByTitle('ra.action.sort').dataset.order).toBe('DESC'); + }); + it('should be disabled when field has no sortby and no source', () => { const { queryAllByTitle } = render( From e2d69aad5303138f2a5c8d54b3b295ab03d4a3c8 Mon Sep 17 00:00:00 2001 From: JulienM Date: Fri, 13 Mar 2020 10:29:27 +0100 Subject: [PATCH 3/7] tests --- .../src/list/DatagridHeaderCell.spec.js | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js b/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js index 7a6ee16b2e3..a89dc98f813 100644 --- a/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js +++ b/packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js @@ -48,14 +48,16 @@ describe('', () => { expect(getByTitle('ra.action.sort').dataset.sort).toBe('title'); }); - it('should be enabled when field has a sortByOrder props', () => { + it('should be change order when field has a sortByOrder props', () => { const { getByTitle } = render(
} + field={ + + } updateSort={() => true} /> @@ -65,6 +67,23 @@ describe('', () => { expect(getByTitle('ra.action.sort').dataset.order).toBe('DESC'); }); + it('should be keep ASC order when field has not sortByOrder props', () => { + const { getByTitle } = render( +
+ + + } + updateSort={() => true} + /> + + +
+ ); + expect(getByTitle('ra.action.sort').dataset.order).toBe('ASC'); + }); + it('should be disabled when field has no sortby and no source', () => { const { queryAllByTitle } = render( From a25a07d92172aabe6c394edbd228cb94570a8c6b Mon Sep 17 00:00:00 2001 From: JulienM Date: Fri, 13 Mar 2020 10:41:36 +0100 Subject: [PATCH 4/7] fix doc --- docs/List.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/List.md b/docs/List.md index b234bcc68cc..a82db8e1b58 100644 --- a/docs/List.md +++ b/docs/List.md @@ -550,7 +550,7 @@ export const PostList = (props) => ( ### Specify Sort Order -By default, a column is sorted by the `ASC` order property. You can use `DESC` via the `sortByOrder` property: +By default, a column is sorted by the `ASC` order. You can use `DESC` via the `sortByOrder` property: {% raw %} ```jsx From aad1d946343cf0374dfdf2cea2140f24c561c52b Mon Sep 17 00:00:00 2001 From: Francois Zaninotto Date: Fri, 8 May 2020 16:57:03 +0200 Subject: [PATCH 5/7] Update docs/List.md --- docs/List.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/List.md b/docs/List.md index a82db8e1b58..bcad93c2b47 100644 --- a/docs/List.md +++ b/docs/List.md @@ -550,7 +550,7 @@ export const PostList = (props) => ( ### Specify Sort Order -By default, a column is sorted by the `ASC` order. You can use `DESC` via the `sortByOrder` property: +By default, when the user clicks on a column header, the list becomes sorted in the ascending order. You change this behavior by setting the `sortByOrder` prop to `"DESC"`: {% raw %} ```jsx From 1491cd1e0969b03a9dd99cdb3e8652df9bfac5df Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Fri, 8 May 2020 16:59:04 +0200 Subject: [PATCH 6/7] Review --- docs/List.md | 2 -- packages/ra-core/src/controller/useListParams.ts | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/List.md b/docs/List.md index bcad93c2b47..2ea8abb4b78 100644 --- a/docs/List.md +++ b/docs/List.md @@ -552,7 +552,6 @@ export const PostList = (props) => ( By default, when the user clicks on a column header, the list becomes sorted in the ascending order. You change this behavior by setting the `sortByOrder` prop to `"DESC"`: -{% raw %} ```jsx // in src/posts.js import React from 'react'; @@ -575,7 +574,6 @@ export const PostList = (props) => ( ); ``` -{% endraw %} ### Permanent Filter diff --git a/packages/ra-core/src/controller/useListParams.ts b/packages/ra-core/src/controller/useListParams.ts index ed86b70a943..f453a99776e 100644 --- a/packages/ra-core/src/controller/useListParams.ts +++ b/packages/ra-core/src/controller/useListParams.ts @@ -156,10 +156,10 @@ const useListParams = ({ }, requestSignature); // eslint-disable-line react-hooks/exhaustive-deps const setSort = useCallback( - (newSort: string, newOrder?: string) => + (sort: string, order?: string) => changeParams({ type: SET_SORT, - payload: { sort: newSort, order: newOrder || undefined }, + payload: { sort, order }, }), requestSignature // eslint-disable-line react-hooks/exhaustive-deps ); From 664274cc857347e4543637ab4e01f5f294909bc8 Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Fri, 8 May 2020 17:03:06 +0200 Subject: [PATCH 7/7] Fix useless change --- examples/simple/src/posts/PostList.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/simple/src/posts/PostList.js b/examples/simple/src/posts/PostList.js index af018bc1ae4..12b0af22a32 100644 --- a/examples/simple/src/posts/PostList.js +++ b/examples/simple/src/posts/PostList.js @@ -140,11 +140,7 @@ const PostList = props => { ) : ( - +