From 5e4c790946dd02da396c2243150e6b8817cae5ed Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Tue, 30 Apr 2024 17:46:30 +0200 Subject: [PATCH 1/9] DatagridBody creates a RecordContextProvider instead of DatagridRow --- .../src/list/datagrid/DatagridBody.tsx | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx b/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx index 36ff48980cc..2179131787a 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx @@ -3,7 +3,7 @@ import { cloneElement, memo, FC, ReactElement } from 'react'; import PropTypes from 'prop-types'; import { SxProps, TableBody, TableBodyProps } from '@mui/material'; import clsx from 'clsx'; -import { Identifier, RaRecord } from 'ra-core'; +import { Identifier, RaRecord, RecordContextProvider } from 'ra-core'; import { DatagridClasses } from './useDatagridStyles'; import DatagridRow, { PureDatagridRow, RowClickFunction } from './DatagridRow'; @@ -34,31 +34,33 @@ const DatagridBody: FC = React.forwardRef( className={clsx('datagrid-body', className, DatagridClasses.tbody)} {...rest} > - {data.map((record, rowIndex) => - cloneElement( - row, - { - className: clsx(DatagridClasses.row, { - [DatagridClasses.rowEven]: rowIndex % 2 === 0, - [DatagridClasses.rowOdd]: rowIndex % 2 !== 0, - }), - expand, - hasBulkActions: hasBulkActions && !!selectedIds, - hover, - id: record.id ?? `row${rowIndex}`, - key: record.id ?? `row${rowIndex}`, - onToggleItem, - record, - resource, - rowClick, - selectable: !isRowSelectable || isRowSelectable(record), - selected: selectedIds?.includes(record.id), - sx: rowSx?.(record, rowIndex), - style: rowStyle?.(record, rowIndex), - }, - children - ) - )} + {data.map((record, rowIndex) => ( + + {cloneElement( + row, + { + className: clsx(DatagridClasses.row, { + [DatagridClasses.rowEven]: rowIndex % 2 === 0, + [DatagridClasses.rowOdd]: rowIndex % 2 !== 0, + }), + expand, + hasBulkActions: hasBulkActions && !!selectedIds, + hover, + id: record.id ?? `row${rowIndex}`, + key: record.id ?? `row${rowIndex}`, + onToggleItem, + resource, + rowClick, + selectable: + !isRowSelectable || isRowSelectable(record), + selected: selectedIds?.includes(record.id), + sx: rowSx?.(record, rowIndex), + style: rowStyle?.(record, rowIndex), + }, + children + )} + + ))} ) ); From f1b2020229c197d0088a12ccfd96984a9dc55bd5 Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Thu, 2 May 2024 17:46:09 +0200 Subject: [PATCH 2/9] remove RecordContextProvider from Datagrid row --- packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx index 215dea415f6..3f692e989f0 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx @@ -163,7 +163,7 @@ const DatagridRow: FC = React.forwardRef((props, ref) => { ); return ( - + <> = React.forwardRef((props, ref) => { )} - + ); }); From f3a9425e0a7e2184df156b60c6d04f3c169c7e91 Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Thu, 2 May 2024 17:49:20 +0200 Subject: [PATCH 3/9] remove useless import --- packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx index 3f692e989f0..ebe3326afdd 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx @@ -15,7 +15,6 @@ import { TableCell, TableRow, TableRowProps, Checkbox } from '@mui/material'; import { Identifier, RaRecord, - RecordContextProvider, shallowEqual, useExpanded, useResourceContext, From 0e4ed7ab8caa0a3ce05c37f5097e6e5a7bf0848a Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Mon, 6 May 2024 10:40:46 +0200 Subject: [PATCH 4/9] apply reviews --- docs/Upgrade.md | 4 ++++ .../ra-ui-materialui/src/list/datagrid/DatagridBody.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/Upgrade.md b/docs/Upgrade.md index ea3484350ba..6032c3a4c41 100644 --- a/docs/Upgrade.md +++ b/docs/Upgrade.md @@ -928,6 +928,10 @@ If you were using this prop, you can safely remove it. The `data-generator-retail` package has been updated to provide types for all its records. In the process, we renamed the `commands` resource to `orders`. Accordingly, the `nb_commands` property of the `customers` resource has been renamed to `nb_orders` and the `command_id` property of the `invoices` and `reviews` resources has been renamed to `order_id`. +## `` No Longer Provides `record` Prop To `` + +The `` component no longer provides a `record` prop to its `` children. Instead, it provides a `recordContext` for each row. See the [``](./Datagrid.md#body) documentation to learn how to create your own row component. + ## Upgrading to v4 If you are on react-admin v3, follow the [Upgrading to v4](https://marmelab.com/react-admin/doc/4.16/Upgrade.html) guide before upgrading to v5. diff --git a/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx b/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx index 2179131787a..d65847d0942 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/DatagridBody.tsx @@ -35,7 +35,10 @@ const DatagridBody: FC = React.forwardRef( {...rest} > {data.map((record, rowIndex) => ( - + {cloneElement( row, { @@ -47,7 +50,6 @@ const DatagridBody: FC = React.forwardRef( hasBulkActions: hasBulkActions && !!selectedIds, hover, id: record.id ?? `row${rowIndex}`, - key: record.id ?? `row${rowIndex}`, onToggleItem, resource, rowClick, From 047c57cf48f82be6f11d24a0fca502e7d7b97666 Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Mon, 6 May 2024 14:44:49 +0200 Subject: [PATCH 5/9] fix tests --- .../src/list/datagrid/DatagridRow.spec.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx index c67eab1f175..e86d8d34a74 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx @@ -10,6 +10,7 @@ import { ResourceDefinitionContextProvider, useRecordContext, TestMemoryRouter, + RecordContextProvider, } from 'ra-core'; import { AdminContext } from '../../AdminContext'; @@ -304,6 +305,7 @@ describe('', () => { it('should default to false if the resource has no show nor edit page', () => { let spy = jest.fn(); + const { record, ...rest } = defaultProps; render( ', () => { }, }} > - - - + + + + + ); From fc93cb1306658ef47dbb23ecdb52f1dc3a9efee1 Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Mon, 6 May 2024 15:54:03 +0200 Subject: [PATCH 6/9] fix DatagridRow.spec --- .../src/list/datagrid/DatagridRow.spec.tsx | 162 +++++++++++------- 1 file changed, 97 insertions(+), 65 deletions(-) diff --git a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx index e86d8d34a74..b0a623803dc 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx @@ -43,23 +43,26 @@ const render = element => describe('', () => { const defaultProps = { id: 15, - record: { id: 15, title: 'hello' }, resource: 'posts', }; + const defaultRecord = { id: 15, title: 'hello' }; + describe('isRowExpandable', () => { it('should show the expand button if it returns true', () => { const contextValue = { isRowExpandable: () => true }; const { queryAllByText, getByText } = render( - } - > - - + + } + > + + + ); expect(queryAllByText('expanded')).toHaveLength(0); @@ -72,13 +75,15 @@ describe('', () => { const { queryAllByText, getByText } = render( - } - > - - + + } + > + + + ); expect(queryAllByText('expanded')).toHaveLength(0); @@ -97,9 +102,11 @@ describe('', () => { let spy = jest.fn(); render( - - - + + + + + ); fireEvent.click(screen.getByText('hello')); @@ -112,9 +119,11 @@ describe('', () => { let spy = jest.fn(); render( - - - + + + + + ); fireEvent.click(screen.getByText('hello')); @@ -125,13 +134,15 @@ describe('', () => { it("should change the expand state if the 'expand' option is selected", () => { render( - } - > - - + + } + > + + + ); expect(screen.queryAllByText('expanded')).toHaveLength(0); fireEvent.click(screen.getByText('hello')); @@ -143,13 +154,15 @@ describe('', () => { it("should execute the onToggleItem function if the 'toggleSelection' option is selected", () => { const onToggleItem = jest.fn(); const { getByText } = render( - - - + + + + + ); fireEvent.click(getByText('hello')); expect(onToggleItem.mock.calls.length).toEqual(1); @@ -158,14 +171,16 @@ describe('', () => { it('should not execute the onToggleItem function if the row is not selectable', () => { const onToggleItem = jest.fn(); const { getByText } = render( - - - + + + + + ); fireEvent.click(getByText('hello')); expect(onToggleItem).not.toHaveBeenCalled(); @@ -176,9 +191,11 @@ describe('', () => { let spy = jest.fn(); render( - - - + + + + + ); fireEvent.click(screen.getByText('hello')); @@ -192,9 +209,14 @@ describe('', () => { let spy = jest.fn(); render( - - - + + + + + ); fireEvent.click(screen.getByText('hello')); @@ -210,9 +232,11 @@ describe('', () => { let spy = jest.fn(); render( - - - + + + + + ); fireEvent.click(screen.getByText('hello')); @@ -225,9 +249,11 @@ describe('', () => { let spy = jest.fn(); render( - - - + + + + + ); fireEvent.click(screen.getByText('hello')); @@ -245,9 +271,11 @@ describe('', () => { posts: { name: 'posts', hasEdit: true }, }} > - - - + + + + + ); @@ -266,9 +294,11 @@ describe('', () => { posts: { name: 'posts', hasShow: true }, }} > - - - + + + + + ); @@ -291,9 +321,11 @@ describe('', () => { }, }} > - - - + + + + + ); @@ -316,7 +348,7 @@ describe('', () => { }, }} > - + From c8a2efee18388f2e99741912de3e662067ce8af9 Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Tue, 7 May 2024 16:27:00 +0200 Subject: [PATCH 7/9] add diff for DatagridBody and DatagridRow --- docs/Upgrade.md | 58 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/docs/Upgrade.md b/docs/Upgrade.md index fa12b3bf491..305ea2c4a40 100644 --- a/docs/Upgrade.md +++ b/docs/Upgrade.md @@ -759,6 +759,60 @@ Besides, the buttons passed as `bulkActionButtons` no longer receive any prop. I The deprecated `` component was removed. +### `` No Longer Provides `record` Prop To `` + +The `` component no longer provides a `record` prop to its `` children. Instead, it provides a `recordContext` for each row: + +```diff +const DatagridBody: FC = React.forwardRef(({/*...*/}, ref) + => ( + +- {data.map((record, rowIndex) => +- cloneElement( ++ {data.map((record, rowIndex) => ( ++ ++ {cloneElement( + row, + { + //... + id: record.id ?? `row${rowIndex}`, +- key: record.id ?? `row${rowIndex}`, + onToggleItem, +- record, + resource, + //... + }, + children +- ) + )} ++ ++ ))} + + ) +); +``` + +Also, `` no longer provides a `` to its children: + +```diff +const DatagridRow: FC = React.forwardRef((props, ref) => { + return ( +- ++ <> + + {/*...*/} + +- ++ + ); + }); +``` + +See the [``](./Datagrid.md#body) documentation to learn how to create your own row component. + ## Show and Edit Pages ### Custom Edit or Show Actions No Longer Receive Any Props @@ -1206,10 +1260,6 @@ The deprecated `` prop was removed. Use the `ThemesContext. The `data-generator-retail` package has been updated to provide types for all its records. In the process, we renamed the `commands` resource to `orders`. Accordingly, the `nb_commands` property of the `customers` resource has been renamed to `nb_orders` and the `command_id` property of the `invoices` and `reviews` resources has been renamed to `order_id`. -## `` No Longer Provides `record` Prop To `` - -The `` component no longer provides a `record` prop to its `` children. Instead, it provides a `recordContext` for each row. See the [``](./Datagrid.md#body) documentation to learn how to create your own row component. - ## Upgrading to v4 If you are on react-admin v3, follow the [Upgrading to v4](https://marmelab.com/react-admin/doc/4.16/Upgrade.html) guide before upgrading to v5. From d13fbc8eb6d1c280fdefa767b6097b4aa4762b5a Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Mon, 13 May 2024 16:21:15 +0200 Subject: [PATCH 8/9] using a custom DatagridRow with useRecordContext in upgrade guide and doc --- docs/Datagrid.md | 53 +++++++++++++++---------------- docs/Upgrade.md | 81 +++++++++++++++++++++--------------------------- 2 files changed, 63 insertions(+), 71 deletions(-) diff --git a/docs/Datagrid.md b/docs/Datagrid.md index 4009f4665a8..a3cb180647e 100644 --- a/docs/Datagrid.md +++ b/docs/Datagrid.md @@ -89,38 +89,39 @@ import { import { TableCell, TableRow, Checkbox } from "@mui/material"; const MyDatagridRow = ({ - record, - id, onToggleItem, children, selected, selectable, -}: DatagridRowProps) => - id ? ( - - - {/* first column: selection checkbox */} - - {selectable && ( - { - if (onToggleItem) { - onToggleItem(id, event); - } - }} - /> - )} - - {/* data columns based on children */} - {React.Children.map(children, (field) => - React.isValidElement(field) && field.props.source ? ( - {field} - ) : null +}: DatagridRowProps) => { + const record = useRecordContext(); + return record ? ( + + {/* first column: selection checkbox */} + + {selectable && ( + { + if (onToggleItem) { + onToggleItem(record.id, event); + } + }} + /> )} - - + + {/* data columns based on children */} + {React.Children.map(children, field => + React.isValidElement(field) && + field.props.source ? ( + + {field} + + ) : null + )} + ) : null; +}; const MyDatagridBody = (props: DatagridBodyProps) => ( } /> diff --git a/docs/Upgrade.md b/docs/Upgrade.md index 305ea2c4a40..a57d086d7dc 100644 --- a/docs/Upgrade.md +++ b/docs/Upgrade.md @@ -764,51 +764,42 @@ The deprecated `` component was removed. The `` component no longer provides a `record` prop to its `` children. Instead, it provides a `recordContext` for each row: ```diff -const DatagridBody: FC = React.forwardRef(({/*...*/}, ref) - => ( - -- {data.map((record, rowIndex) => -- cloneElement( -+ {data.map((record, rowIndex) => ( -+ -+ {cloneElement( - row, - { - //... - id: record.id ?? `row${rowIndex}`, -- key: record.id ?? `row${rowIndex}`, - onToggleItem, -- record, - resource, - //... - }, - children -- ) - )} -+ -+ ))} - - ) -); -``` - -Also, `` no longer provides a `` to its children: - -```diff -const DatagridRow: FC = React.forwardRef((props, ref) => { - return ( -- -+ <> - - {/*...*/} - -- -+ - ); - }); +const MyDatagridRow = ({ +- record, +- id, + onToggleItem, + children, + selected, + selectable, +}: DatagridRowProps) => { ++ const record = useRecordContext(); ++ return record ? ( +- + + + {selectable && ( + { + if (onToggleItem) { +- onToggleItem(id, event); ++ onToggleItem(record.id, event); + } + }} + /> + )} + + {React.Children.map(children, field => + React.isValidElement(field) && + field.props.source ? ( +- {field} ++ {field} + ) : null + )} + +- + ) : null; +}; ``` See the [``](./Datagrid.md#body) documentation to learn how to create your own row component. From 5c3d1f21ca697b5b398b84b704d679452ddf7fd2 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Mon, 13 May 2024 17:47:36 +0200 Subject: [PATCH 9/9] Update docs/Upgrade.md --- docs/Upgrade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Upgrade.md b/docs/Upgrade.md index a57d086d7dc..c2e38bdca3f 100644 --- a/docs/Upgrade.md +++ b/docs/Upgrade.md @@ -761,7 +761,7 @@ The deprecated `` component was removed. ### `` No Longer Provides `record` Prop To `` -The `` component no longer provides a `record` prop to its `` children. Instead, it provides a `recordContext` for each row: +The `` component no longer provides a `record` prop to its `` children. Instead, it provides a `RecordContext` for each row: ```diff const MyDatagridRow = ({