Skip to content

Commit

Permalink
feat(DataTable): add batch actions select all button addition (#14476)
Browse files Browse the repository at this point in the history
* feat(DataTable): render select all button is onSelectAll is provided

* fix(DataTable): update onSelectAll type

* chore: update test snapshot

---------

Co-authored-by: Guilherme Datilio Ribeiro <[email protected]>
  • Loading branch information
matthewgallo and guidari authored Aug 24, 2023
1 parent d9a3ae9 commit db61c68
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 41 deletions.
14 changes: 14 additions & 0 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1888,9 +1888,15 @@ Map {
"isRequired": true,
"type": "func",
},
"onSelectAll": Object {
"type": "func",
},
"shouldShowBatchActions": Object {
"type": "bool",
},
"totalCount": Object {
"type": "number",
},
"totalSelected": Object {
"isRequired": true,
"type": "number",
Expand All @@ -1903,6 +1909,7 @@ Map {
"carbon.table.batch.cancel",
"carbon.table.batch.items.selected",
"carbon.table.batch.item.selected",
"carbon.table.batch.selectAll",
],
},
"TableBody": Object {
Expand Down Expand Up @@ -7748,9 +7755,15 @@ Map {
"isRequired": true,
"type": "func",
},
"onSelectAll": Object {
"type": "func",
},
"shouldShowBatchActions": Object {
"type": "bool",
},
"totalCount": Object {
"type": "number",
},
"totalSelected": Object {
"isRequired": true,
"type": "number",
Expand All @@ -7763,6 +7776,7 @@ Map {
"carbon.table.batch.cancel",
"carbon.table.batch.items.selected",
"carbon.table.batch.item.selected",
"carbon.table.batch.selectAll",
],
},
"TableBody" => Object {
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/components/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
[key: string]: unknown;
}) => {
onCancel: () => void;
onSelectAll?: () => void | undefined;
shouldShowBatchActions: boolean;
totalCount: number;
totalSelected: number;
[key: string]: unknown;
};
Expand Down Expand Up @@ -678,6 +680,8 @@ class DataTable<RowType, ColTypes extends any[]> extends React.Component<
const { shouldShowBatchActions } = this.state;
const totalSelected = this.getSelectedRows().length;
return {
onSelectAll: undefined,
totalCount: this.state.rowIds.length || 0,
...props,
shouldShowBatchActions: shouldShowBatchActions && totalSelected > 0,
totalSelected,
Expand Down
29 changes: 29 additions & 0 deletions packages/react/src/components/DataTable/TableBatchActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ const translationKeys = {
'carbon.table.batch.cancel': 'Cancel',
'carbon.table.batch.items.selected': 'items selected',
'carbon.table.batch.item.selected': 'item selected',
'carbon.table.batch.selectAll': 'Select all',
};

const translateWithId = (id, state) => {
if (id === 'carbon.table.batch.cancel') {
return translationKeys[id];
}
if (id === 'carbon.table.batch.selectAll') {
return `${translationKeys[id]} (${state.totalCount})`;
}
return `${state.totalSelected} ${translationKeys[id]}`;
};

Expand All @@ -31,7 +35,9 @@ const TableBatchActions = ({
children,
shouldShowBatchActions,
totalSelected,
totalCount,
onCancel,
onSelectAll,
translateWithId: t,
...rest
}) => {
Expand Down Expand Up @@ -65,6 +71,16 @@ const TableBatchActions = ({
: t('carbon.table.batch.item.selected', { totalSelected })}
</Text>
</p>
{onSelectAll && (
<>
<span className={`${prefix}--batch-summary__divider`}>&#x7c;</span>
<Button
onClick={onSelectAll}
tabIndex={shouldShowBatchActions ? 0 : -1}>
{t('carbon.table.batch.selectAll', { totalCount })}
</Button>
</>
)}
</div>
<TableActionList>
{children}
Expand All @@ -91,12 +107,25 @@ TableBatchActions.propTypes = {
*/
onCancel: PropTypes.func.isRequired,

/**
* Hook required to listen for when the user initiates a select all
* request through this component. This _only_ controls the rendering
* of the `Select All` button and does not include built in functionality
*/
onSelectAll: PropTypes.func,

/**
* Boolean specifier for whether or not the batch action bar should be
* displayed
*/
shouldShowBatchActions: PropTypes.bool,

/**
* Numeric representation of the total number of items in a table.
* This number is used in the select all button text
*/
totalCount: PropTypes.number,

/**
* Numeric representation of the total number of items selected in a table.
* This number is used to derive the selection message
Expand Down
55 changes: 37 additions & 18 deletions packages/react/src/components/DataTable/__tests__/DataTable-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,32 @@ import { render, screen, within } from '@testing-library/react';
const getLastCallFor = (mocker) =>
mocker.mock.calls[mocker.mock.calls.length - 1];

const onSelectAllFn = jest.fn();

const rows = [
{
id: 'b',
fieldA: 'Field 2:A',
fieldB: 'Field 2:B',
},
{
id: 'a',
fieldA: 'Field 1:A',
fieldB: 'Field 1:B',
},
{
id: 'c',
fieldA: 'Field 3:A',
fieldB: 'Field 3:B',
},
];

describe('DataTable', () => {
let mockProps;

beforeEach(() => {
mockProps = {
rows: [
{
id: 'b',
fieldA: 'Field 2:A',
fieldB: 'Field 2:B',
},
{
id: 'a',
fieldA: 'Field 1:A',
fieldB: 'Field 1:B',
},
{
id: 'c',
fieldA: 'Field 3:A',
fieldB: 'Field 3:B',
},
],
rows,
headers: [
{
key: 'fieldA',
Expand Down Expand Up @@ -334,7 +338,10 @@ describe('DataTable', () => {
}) => (
<TableContainer title="DataTable with selection">
<TableToolbar>
<TableBatchActions {...getBatchActionProps()}>
<TableBatchActions
{...getBatchActionProps({
onSelectAll: onSelectAllFn,
})}>
<TableBatchAction onClick={jest.fn()}>
Ghost
</TableBatchAction>
Expand Down Expand Up @@ -452,6 +459,18 @@ describe('DataTable', () => {
const { selectedRows } = getLastCallFor(mockProps.render)[0];
expect(selectedRows.length).toBe(0);
});

it('should call the onSelectAll prop if supplied to TableBatchAction component', async () => {
render(<DataTable {...mockProps} />);
const selectAllCheckbox = screen.getAllByRole('checkbox')[0];

await userEvent.click(selectAllCheckbox);
expect(selectAllCheckbox).toBeChecked();

const selectAllButton = screen.getByText(`Select all (${rows.length})`);
await userEvent.click(selectAllButton);
expect(onSelectAllFn).toHaveBeenCalledTimes(1);
});
});

describe('selection with filtering', () => {
Expand Down
Loading

0 comments on commit db61c68

Please sign in to comment.