Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Datagrid requires too many props when used standalone #6115

Merged
merged 1 commit into from
Apr 2, 2021
Merged
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
49 changes: 22 additions & 27 deletions docs/List.md
Original file line number Diff line number Diff line change
Expand Up @@ -2819,15 +2819,13 @@ export const UserList = ({ permissions, ...props }) => {

### Rendering `<Datagrid>` With A Custom Query

You can use the `<Datagrid>` component with [custom queries](./Actions.md#usequery-hook), provided you pass the result to a `<ListContextProvider>`:
You can use the `<Datagrid>` component with [custom queries](./Actions.md#usequery-hook):

{% raw %}
```jsx
import keyBy from 'lodash/keyBy'
import {
useQuery,
ResourceContextProvider,
ListContextProvider,
Datagrid,
TextField,
Pagination,
Expand All @@ -2836,13 +2834,14 @@ import {

const CustomList = () => {
const [page, setPage] = useState(1);
const perPage = 50;
const [perPage, setPerPage] = useState(25);
const [sort, setSort] = useState({ field: 'id', order: 'ASC' })
const { data, total, loading, error } = useQuery({
type: 'getList',
resource: 'posts',
payload: {
pagination: { page, perPage },
sort: { field: 'id', order: 'ASC' },
sort,
filter: {},
}
});
Expand All @@ -2854,33 +2853,29 @@ const CustomList = () => {
return <p>ERROR: {error}</p>
}
return (
<ResourceContextProvider value="posts">
<ListContextProvider
value={{
basePath: '/posts',
data: keyBy(data, 'id'),
ids: data.map(({ id }) => id),
currentSort: { field: 'id', order: 'ASC' },
selectedIds: [],
}}
>
<Datagrid rowClick="edit">
<TextField source="id" />
<TextField source="title" />
</Datagrid>
<Pagination
page={page}
perPage={perPage}
setPage={setPage}
total={total}
/>
</ListContextProvider>
</ResourceContextProvider>
<Datagrid
data={keyBy(data, 'id')}
ids={data.map(({ id }) => id)}
currentSort={sort}
setSort={(field, order) => setSort({ field, order })}
>
<TextField source="id" />
<TextField source="title" />
</Datagrid>
<Pagination
page={page}
setPage={setPage}
perPage={perPage}
setPerPage={setPerPage}
total={total}
/>
);
}
```
{% endraw %}

**Tip**: If you use the `<Datagrid rowClick>` prop in this case, you must also set the `basePath` prop to let the `<Datagrid>` compute the link to the record pages.

## Third-Party Components

You can find components for react-admin in third-party repositories.
Expand Down
4 changes: 2 additions & 2 deletions examples/simple/src/customRouteLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ const CustomRouteLayout = () => {
Found <span className="total">{total}</span> posts !
</p>
<Datagrid
basePath=""
basePath="/posts"
currentSort={currentSort}
data={data}
ids={ids}
selectedIds={[]}
loaded={loaded}
total={total}
rowClick="edit"
>
<TextField source="id" sortable={false} />
<TextField source="title" sortable={false} />
Expand Down
18 changes: 10 additions & 8 deletions packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
isRowExpandable,
]);

const updateSort = useCallback(
const updateSortCallback = useCallback(
event => {
event.stopPropagation();
const newField = event.currentTarget.dataset.field;
Expand All @@ -163,6 +163,8 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
[currentSort.field, currentSort.order, setSort]
);

const updateSort = setSort ? updateSortCallback : null;

const handleSelectAll = useCallback(
event => {
if (event.target.checked) {
Expand All @@ -184,10 +186,10 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
const lastSelected = useRef(null);

useEffect(() => {
if (selectedIds.length === 0) {
if (!selectedIds || selectedIds.length === 0) {
lastSelected.current = null;
}
}, [selectedIds.length]);
}, [JSON.stringify(selectedIds)]); // eslint-disable-line react-hooks/exhaustive-deps

const handleToggleItem = useCallback(
(id, event) => {
Expand Down Expand Up @@ -276,7 +278,7 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
)}
/>
)}
{hasBulkActions && (
{hasBulkActions && selectedIds && (
<TableCell
padding="checkbox"
className={classes.headerCell}
Expand Down Expand Up @@ -346,9 +348,9 @@ Datagrid.propTypes = {
children: PropTypes.node.isRequired,
classes: PropTypes.object,
className: PropTypes.string,
currentSort: PropTypes.shape({
field: PropTypes.string,
order: PropTypes.string,
currentSort: PropTypes.exact({
field: PropTypes.string.isRequired,
order: PropTypes.string.isRequired,
}),
data: PropTypes.any,
// @ts-ignore
Expand Down Expand Up @@ -393,7 +395,7 @@ export interface DatagridProps<RecordType extends Record = Record>
size?: 'medium' | 'small';
// can be injected when using the component without context
basePath?: string;
currentsort?: SortPayload;
currentSort?: SortPayload;
data?: RecordMap<RecordType>;
ids?: Identifier[];
loaded?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const DatagridBody: FC<DatagridBodyProps> = React.forwardRef(
[classes.clickableRow]: rowClick,
}),
expand,
hasBulkActions,
hasBulkActions: hasBulkActions && selectedIds,
hover,
id,
key: id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export const DatagridHeaderCell = (
variant="head"
{...rest}
>
{field.props.sortable !== false &&
{updateSort &&
field.props.sortable !== false &&
(field.props.sortBy || field.props.source) ? (
<Tooltip
title={translate('ra.action.sort')}
Expand Down Expand Up @@ -103,7 +104,7 @@ DatagridHeaderCell.propTypes = {
}).isRequired,
isSorting: PropTypes.bool,
resource: PropTypes.string,
updateSort: PropTypes.func.isRequired,
updateSort: PropTypes.func,
};

export interface DatagridHeaderCellProps
Expand All @@ -114,7 +115,7 @@ export interface DatagridHeaderCellProps
isSorting?: boolean;
resource: string;
currentSort: SortPayload;
updateSort: (event: any) => void;
updateSort?: (event: any) => void;
}

export default memo(
Expand Down
9 changes: 6 additions & 3 deletions packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,16 @@ const DatagridRow: FC<DatagridRowProps> = React.forwardRef((props, ref) => {

const effect =
typeof rowClick === 'function'
? await rowClick(id, basePath, record)
? await rowClick(id, basePath || `/${resource}`, record)
: rowClick;
switch (effect) {
case 'edit':
history.push(linkToRecord(basePath, id));
history.push(linkToRecord(basePath || `/${resource}`, id));
return;
case 'show':
history.push(linkToRecord(basePath, id, 'show'));
history.push(
linkToRecord(basePath || `/${resource}`, id, 'show')
);
return;
case 'expand':
handleToggleExpand(event);
Expand All @@ -137,6 +139,7 @@ const DatagridRow: FC<DatagridRowProps> = React.forwardRef((props, ref) => {
handleToggleSelection,
id,
record,
resource,
rowClick,
]
);
Expand Down