From 02c695175ab19c4f3b234bdb07cfea67c2cf5176 Mon Sep 17 00:00:00 2001 From: Connor Riva Date: Wed, 8 Nov 2023 12:15:08 -0500 Subject: [PATCH] feat(UncontrolledTable): allow disabled attribute to be passed in with rows --- src/components/Table/SortableTable.js | 1 + src/components/Table/SortableTable.spec.js | 18 ++++++++++ src/components/Table/UncontrolledTable.js | 6 ++-- .../Table/UncontrolledTable.spec.js | 34 +++++++++++++++++++ .../Table/UncontrolledTable.stories.js | 2 ++ 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/components/Table/SortableTable.js b/src/components/Table/SortableTable.js index 98656579d..18239f1dd 100644 --- a/src/components/Table/SortableTable.js +++ b/src/components/Table/SortableTable.js @@ -86,6 +86,7 @@ function getSelectableCell(row, rowSelected, onSelect) { checked={rowSelected(row)} onClick={(e) => e.stopPropagation()} onChange={(e) => onSelect(row, e.target.checked)} + disabled={!!row.disabled} /> ); diff --git a/src/components/Table/SortableTable.spec.js b/src/components/Table/SortableTable.spec.js index 33ca8e179..abf29dd8b 100644 --- a/src/components/Table/SortableTable.spec.js +++ b/src/components/Table/SortableTable.spec.js @@ -377,6 +377,24 @@ describe('', () => { assert.equal(wrapper.find('input').length, 4, 'select checkbox missing'); }); + it('should disable select checkbox when specified', () => { + const rows = [ + { name: 'Alpha', disabled: false }, + { name: 'Bravo', disabled: true }, + { name: 'Charlie', disabled: true }, + { name: 'Delta', disabled: true }, + ]; + const wrapper = mount( + false} /> + ); + + const trs = wrapper.find('tr'); + assert.equal(trs.at(1).find('input').prop('disabled'), false); + assert.equal(trs.at(2).find('input').prop('disabled'), true); + assert.equal(trs.at(3).find('input').prop('disabled'), true); + assert.equal(trs.at(4).find('input').prop('disabled'), true); + }); + it('should call onSelect when clicked', () => { const onSelect = sinon.stub(); const wrapper = mount( diff --git a/src/components/Table/UncontrolledTable.js b/src/components/Table/UncontrolledTable.js index b143e09fa..3e82209fe 100644 --- a/src/components/Table/UncontrolledTable.js +++ b/src/components/Table/UncontrolledTable.js @@ -78,7 +78,8 @@ export default class UncontrolledTable extends React.Component { }; get allSelected() { - return this.props.rows.length && this.state.selected.length === this.props.rows.length; + const selectableRows = this.props.rows.filter((row) => !row.disabled); + return this.props.rows.length && this.state.selected.length === selectableRows.length; } selected(value) { @@ -97,7 +98,8 @@ export default class UncontrolledTable extends React.Component { }; toggleAll = () => { - const newSelection = this.allSelected ? [] : this.props.rows; + const selectableRows = this.props.rows.filter((row) => !row.disabled); + const newSelection = this.allSelected ? [] : selectableRows; this.setState({ selected: newSelection }, () => { this.props.onSelect(newSelection); diff --git a/src/components/Table/UncontrolledTable.spec.js b/src/components/Table/UncontrolledTable.spec.js index e9362058e..e95626443 100644 --- a/src/components/Table/UncontrolledTable.spec.js +++ b/src/components/Table/UncontrolledTable.spec.js @@ -302,6 +302,40 @@ describe('', () => { assert.equal(ths.length, columns.length + 1); // For selectable column }); + it('should disable select checkbox when specified', () => { + const columns = [{ header: 'Name', cell: (row) => row.name }]; + const rows = [ + { name: 'Alpha', disabled: true }, + { name: 'Bravo', disabled: false }, + { name: 'Charlie', disabled: false }, + { name: 'Delta' }, + ]; + const wrapper = mount(); + + const trs = wrapper.find('tr'); + assert.equal(trs.at(1).find('input').prop('disabled'), true); + assert.equal(trs.at(2).find('input').prop('disabled'), false); + assert.equal(trs.at(3).find('input').prop('disabled'), false); + assert.equal(trs.at(4).find('input').prop('disabled'), false); + }); + + it('should only select on selectable rows when selecting selectAll', () => { + const columns = [{ header: 'Name', cell: (row) => row.name }]; + const rows = [ + { name: 'Alpha', disabled: true }, + { name: 'Bravo', disabled: false }, + { name: 'Charlie', disabled: false }, + { name: 'Delta', disabled: false }, + ]; + const wrapper = mount(); + + wrapper + .find({ type: 'checkbox' }) + .first() + .simulate('change', { target: { checked: true } }); + assert.equal(wrapper.state().selected.length, 3); + }); + it('should call onSelect when selectable row picked', () => { const columns = [{ header: 'Name', cell: (row) => row }]; const rows = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel']; diff --git a/src/components/Table/UncontrolledTable.stories.js b/src/components/Table/UncontrolledTable.stories.js index 0026754dc..063b01228 100644 --- a/src/components/Table/UncontrolledTable.stories.js +++ b/src/components/Table/UncontrolledTable.stories.js @@ -77,6 +77,7 @@ const DATA = [ last: 'Turner', email: 'maxine.turner@example.com', dob: new Date(1961, 8, 19), + disabled: true, }, { key: '000', @@ -85,6 +86,7 @@ const DATA = [ last: 'Headroom', email: 'max.headroom@example.com', dob: new Date(1984, 6, 1), + disabled: true, }, ];