From ea187ff77c277d886d6abcb098a266179c8a8991 Mon Sep 17 00:00:00 2001 From: Matthias Klass Date: Tue, 1 Aug 2023 14:57:07 +0200 Subject: [PATCH] Enable editing upon row click --- __tests__/demo/demo-components/index.js | 55 +++++++++++++++++-------- __tests__/detailPanel.test.js | 2 +- __tests__/editRow.test.js | 28 +++++++++++++ src/components/MTableBodyRow/index.js | 26 ++++++++---- src/components/m-table-body.js | 1 + src/material-table.js | 18 +++++--- types/index.d.ts | 3 +- 7 files changed, 99 insertions(+), 34 deletions(-) diff --git a/__tests__/demo/demo-components/index.js b/__tests__/demo/demo-components/index.js index 1d769c48..c5b09bef 100644 --- a/__tests__/demo/demo-components/index.js +++ b/__tests__/demo/demo-components/index.js @@ -290,29 +290,48 @@ export function BulkEditWithDetailPanel() { } export function EditableRow(props) { - const [isEditing, setIsEditing] = useState(false); + const [canEdit, setCanEdit] = useState(true); + const [clickRowToEdit, setClickRowToEdit] = useState(false); return (
-

I am the parent

- +
+
+ setClickRowToEdit(event.target.checked)} + /> + +
+
+ setCanEdit(event.target.checked)} + /> + +
+
+ { - if (isEditing) { - return ; - } else { - return ; - } - } - }} + key={`table_${canEdit}`} + onRowClick={ + clickRowToEdit + ? (event, data, openDetails, enableEditMode) => enableEditMode() + : undefined + } editable={{ - onRowUpdate: (newData, oldData) => { - console.log({ newData, oldData }); - return new Promise((reject, resolve) => resolve()); - } + onRowUpdate: canEdit + ? (newData, oldData) => { + console.log({ newData, oldData }); + return new Promise((reject, resolve) => resolve()); + } + : undefined }} data={[ { name: 'jack', id: 1 }, diff --git a/__tests__/detailPanel.test.js b/__tests__/detailPanel.test.js index 32629abd..379135be 100644 --- a/__tests__/detailPanel.test.js +++ b/__tests__/detailPanel.test.js @@ -69,7 +69,7 @@ describe('Detailpanel render', () => { screen.getByRole('cell', { name: /one/i }); - const toggleButton = screen.getByRole('button', { + const toggleButton = await screen.findByRole('button', { name: /detail panel visibility toggle/i }); diff --git a/__tests__/editRow.test.js b/__tests__/editRow.test.js index 66636995..721d162b 100644 --- a/__tests__/editRow.test.js +++ b/__tests__/editRow.test.js @@ -259,6 +259,34 @@ describe('Edit Row Row Update', () => { expect(onRowUpdateCancelled.mock.calls.length).toBe(1); }); + test('clicking a row to start the edit mode', () => { + const onRowUpdate = jest.fn(); + const onRowUpdateCancelled = jest.fn(); + render( + + enableEditMode() + } + editable={{ + onRowUpdate, + onRowUpdateCancelled + }} + /> + ); + fireEvent.click(screen.getByText(data[0].id.toString())); + + screen.getByTestId('check'); + const cancelButton = screen.getByRole('button', { + name: /cancel/i + }); + fireEvent.click(cancelButton); + + expect(onRowUpdate.mock.calls.length).toBe(0); + expect(onRowUpdateCancelled.mock.calls.length).toBe(1); + }); + test('edit a row', async () => { const onRowUpdate = jest.fn(async () => {}); render( diff --git a/src/components/MTableBodyRow/index.js b/src/components/MTableBodyRow/index.js index 01e728d5..e654cc2c 100644 --- a/src/components/MTableBodyRow/index.js +++ b/src/components/MTableBodyRow/index.js @@ -27,6 +27,7 @@ function MTableBodyRow({ forwardedRef, ...props }) { getFieldValue, isTreeData, onRowSelected, + onRowEditStarted, onTreeExpandChanged, onToggleDetailPanel, onEditingCanceled, @@ -49,17 +50,24 @@ function MTableBodyRow({ forwardedRef, ...props }) { const columns = propColumns.filter((columnDef) => !columnDef.hidden); const onClick = (event, callback) => - callback(event, data, (panelIndex) => { - let panel = detailPanel; - if (Array.isArray(panel)) { - panel = panel[panelIndex || 0]; - if (typeof panel === 'function') { - panel = panel(data); + callback( + event, + data, + (panelIndex) => { + let panel = detailPanel; + if (Array.isArray(panel)) { + panel = panel[panelIndex || 0]; + if (typeof panel === 'function') { + panel = panel(data); + } + panel = panel.render; } - panel = panel.render; + onToggleDetailPanel(path, panel); + }, + () => { + onRowEditStarted(data); } - onToggleDetailPanel(path, panel); - }); + ); const handleOnRowClick = useDoubleClick( onRowClick ? (e) => onClick(e, onRowClick) : undefined, diff --git a/src/components/m-table-body.js b/src/components/m-table-body.js index c7cb34a6..5ace2cfe 100644 --- a/src/components/m-table-body.js +++ b/src/components/m-table-body.js @@ -123,6 +123,7 @@ function MTableBody(props) { cellEditable={props.cellEditable} onCellEditStarted={props.onCellEditStarted} onCellEditFinished={props.onCellEditFinished} + onRowEditStarted={props.onRowEditStarted} scrollWidth={props.scrollWidth} /> ); diff --git a/src/material-table.js b/src/material-table.js index 378071dc..12752f4d 100644 --- a/src/material-table.js +++ b/src/material-table.js @@ -338,11 +338,7 @@ export default class MaterialTable extends React.Component { calculatedProps.editable.isEditHidden && calculatedProps.editable.isEditHidden(rowData), onClick: (e, rowData) => { - this.dataManager.changeRowEditing(rowData, 'update'); - this.setState({ - ...this.dataManager.getRenderState(), - showAddRow: false - }); + this.onRowEditStarted(rowData); } })); } @@ -1046,6 +1042,7 @@ export default class MaterialTable extends React.Component { cellEditable={props.cellEditable} onCellEditStarted={this.onCellEditStarted} onCellEditFinished={this.onCellEditFinished} + onRowEditStarted={this.onRowEditStarted} bulkEditOpen={this.dataManager.bulkEditOpen} bulkEditChangedRows={this.dataManager.bulkEditChangedRows} onBulkEditRowChanged={this.dataManager.onBulkEditRowChanged} @@ -1054,6 +1051,17 @@ export default class MaterialTable extends React.Component { ); + onRowEditStarted = (rowData) => { + if (!this.props.editable?.onRowUpdate) { + return; + } + this.dataManager.changeRowEditing(rowData, 'update'); + this.setState({ + ...this.dataManager.getRenderState(), + showAddRow: false + }); + }; + getColumnsWidth = (props, count) => { const result = []; diff --git a/types/index.d.ts b/types/index.d.ts index d9cffa8f..f3890b3b 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -79,7 +79,8 @@ export interface MaterialTableProps { onRowClick?: ( event?: React.MouseEvent, rowData?: RowData, - toggleDetailPanel?: (panelIndex?: number) => void + toggleDetailPanel?: (panelIndex?: number) => void, + enableEditMode?: () => void ) => void; onRowDoubleClick?: ( event?: React.MouseEvent,