Skip to content
This repository was archived by the owner on Oct 19, 2021. It is now read-only.

Commit 12d9915

Browse files
authored
fix(DataTable): handle no rows in DataTable case for selection (#665)
* fix(DataTable): handle no rows in DataTable case for selection * chore(test): update snapshots
1 parent f961d8d commit 12d9915

File tree

3 files changed

+797
-2
lines changed

3 files changed

+797
-2
lines changed

src/components/DataTable/DataTable.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,12 @@ export default class DataTable extends React.Component {
190190
}
191191

192192
// Otherwise, we're working on `TableSelectAll` which handles toggling the
193-
// selection state of all rows
194-
const checked = this.getSelectedRows().length === this.state.rowIds.length;
193+
// selection state of all rows. If we have no rows, then this value defaults
194+
// to false.
195+
const checked =
196+
this.state.rowIds.length > 0
197+
? this.getSelectedRows().length === this.state.rowIds.length
198+
: false;
195199
const translationKey = checked
196200
? translationKeys.unselectAll
197201
: translationKeys.selectAll;

src/components/DataTable/__tests__/DataTable-test.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import DataTable, {
88
TableHead,
99
TableHeader,
1010
TableRow,
11+
TableSelectAll,
12+
TableSelectRow,
1113
TableToolbar,
1214
TableToolbarAction,
1315
TableToolbarContent,
@@ -16,9 +18,15 @@ import DataTable, {
1618
import { sortStates } from '../state/sorting';
1719
import { mount } from 'enzyme';
1820

21+
// Test helpers
1922
const getHeaderAt = (wrapper, index) =>
2023
wrapper.find('TableHeader button').at(index);
24+
const getRowAt = (wrapper, index) => wrapper.find('tbody tr').at(index);
2125
const getFilterInput = wrapper => wrapper.find('TableToolbarSearch input');
26+
const getSelectAll = wrapper =>
27+
wrapper.find('TableSelectAll input[type="checkbox"]');
28+
const getLastCallFor = mocker =>
29+
mocker.mock.calls[mocker.mock.calls.length - 1];
2230

2331
describe('DataTable', () => {
2432
let mockProps;
@@ -164,4 +172,107 @@ describe('DataTable', () => {
164172
);
165173
});
166174
});
175+
176+
describe('selection', () => {
177+
let mockProps;
178+
179+
beforeEach(() => {
180+
mockProps = {
181+
rows: [
182+
{
183+
id: 'b',
184+
fieldA: 'Field 2:A',
185+
fieldB: 'Field 2:B',
186+
},
187+
{
188+
id: 'a',
189+
fieldA: 'Field 1:A',
190+
fieldB: 'Field 1:B',
191+
},
192+
{
193+
id: 'c',
194+
fieldA: 'Field 3:A',
195+
fieldB: 'Field 3:B',
196+
},
197+
],
198+
headers: [
199+
{
200+
key: 'fieldA',
201+
header: 'Field A',
202+
},
203+
{
204+
key: 'fieldB',
205+
header: 'Field B',
206+
},
207+
],
208+
locale: 'en',
209+
render: jest.fn(
210+
({ rows, headers, getHeaderProps, getSelectionProps }) => (
211+
<TableContainer title="DataTable with selection">
212+
<Table>
213+
<TableHead>
214+
<TableRow>
215+
<TableSelectAll {...getSelectionProps()} />
216+
{headers.map(header => (
217+
<TableHeader {...getHeaderProps({ header })}>
218+
{header.header}
219+
</TableHeader>
220+
))}
221+
</TableRow>
222+
</TableHead>
223+
<TableBody>
224+
{rows.map(row => (
225+
<TableRow key={row.id}>
226+
<TableSelectRow {...getSelectionProps({ row })} />
227+
{row.cells.map(cell => (
228+
<TableCell key={cell.id}>{cell.value}</TableCell>
229+
))}
230+
</TableRow>
231+
))}
232+
</TableBody>
233+
</Table>
234+
</TableContainer>
235+
)
236+
),
237+
};
238+
});
239+
240+
it('should render', () => {
241+
const wrapper = mount(<DataTable {...mockProps} />);
242+
expect(wrapper).toMatchSnapshot();
243+
});
244+
245+
it('should have select-all default to un-checked if no rows are present', () => {
246+
const wrapper = mount(<DataTable {...mockProps} rows={[]} />);
247+
expect(wrapper).toMatchSnapshot();
248+
});
249+
250+
it('should select all rows if a user interacts with select all', () => {
251+
const wrapper = mount(<DataTable {...mockProps} />);
252+
expect(getSelectAll(wrapper).prop('checked')).toBe(false);
253+
254+
getSelectAll(wrapper).simulate('click');
255+
256+
expect(getSelectAll(wrapper).prop('checked')).toBe(true);
257+
258+
const { selectedRows } = getLastCallFor(mockProps.render)[0];
259+
expect(selectedRows.length).toBe(mockProps.rows.length);
260+
});
261+
262+
it('should select a specific row when a user interacts with select row', () => {
263+
const wrapper = mount(<DataTable {...mockProps} />);
264+
expect(getSelectAll(wrapper).prop('checked')).toBe(false);
265+
266+
const beforeInput = getRowAt(wrapper, 0).find('input[type="checkbox"]');
267+
expect(beforeInput.prop('checked')).toBe(false);
268+
269+
beforeInput.simulate('click');
270+
271+
const afterInput = getRowAt(wrapper, 0).find('input[type="checkbox"]');
272+
expect(afterInput.prop('checked')).toBe(true);
273+
274+
const { selectedRows } = getLastCallFor(mockProps.render)[0];
275+
expect(selectedRows.length).toBe(1);
276+
});
277+
});
167278
});

0 commit comments

Comments
 (0)