Skip to content

Commit

Permalink
feat: added useselectionactions (openedx#853)
Browse files Browse the repository at this point in the history
  • Loading branch information
manny-m authored Oct 28, 2021
1 parent d1a7c1e commit 79d8f21
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/DataTable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,16 @@ To enable proper selection behavior with backend pagination (i.e., when ``isSele
buttonText: 'Download CSV',
handleClick: (data) => console.log('Download CSV', data),
},
// custom button function that utilizes clearSelection function provided by the table instance
({tableInstance})=>{
return {
buttonText: `Clear Selection`,
handleClick: () => {
console.log('Clear selection');
tableInstance.clearSelection()
},
}
},
]}
/>
);
Expand Down Expand Up @@ -316,10 +326,10 @@ You can pass a function to render custom components for bulk actions and table a
]}
bulkActions={[
// Function defined button
(data)=>{
({selectedFlatRows})=>{
return {
buttonText: `Enroll ${data.selectedFlatRows.length}`,
handleClick: () => console.log('Enroll', data),
buttonText: `Enroll ${selectedFlatRows.length}`,
handleClick: () => console.log('Enroll', selectedFlatRows),
}
},
{
Expand Down
26 changes: 26 additions & 0 deletions src/DataTable/hooks.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable import/prefer-default-export */
import { useContext } from 'react';
import DataTableContext from './DataTableContext';
import { clearSelectionAction } from './selection/data/actions';

export const useRows = () => {
const {
Expand All @@ -13,3 +14,28 @@ export const useRows = () => {
getTableProps, prepareRow, displayRows, headerGroups, getTableBodyProps,
};
};

/**
* Hook that provides selection state functionality
* @param {Object} param0 Table instance
* @param {Array} controlledTableSelections Selection Object and dispatch function
* @returns
*/
export const useSelectionActions = (
{ toggleAllRowsSelected },
controlledTableSelections,
) => {
const [{ selectedRows, isEntireTableSelected }, dispatch] = controlledTableSelections;

const clearSelection = () => {
// if using controlled selection component DataTable.ControlledSelectionStatus
if (selectedRows.length > 0 || isEntireTableSelected) {
dispatch(clearSelectionAction());
} else {
toggleAllRowsSelected(false);
}
};
return {
clearSelection,
};
};
4 changes: 4 additions & 0 deletions src/DataTable/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import ControlledSelect from './selection/ControlledSelect';
import ControlledSelectHeader from './selection/ControlledSelectHeader';
import DataTableLayout from './DataTableLayout';

import { useSelectionActions } from './hooks';
import selectionsReducer, { initialState as initialSelectionsState } from './selection/data/reducer';

function DataTable({
Expand Down Expand Up @@ -108,6 +109,8 @@ function DataTable({
}
}, [fetchData, JSON.stringify(tableStateWithoutSelections)]);

const selectionActions = useSelectionActions(instance, controlledTableSelections);

const enhancedInstance = {
...instance,
itemCount,
Expand All @@ -117,6 +120,7 @@ function DataTable({
controlledTableSelections,
showFiltersInSidebar,
...selectionProps,
...selectionActions,
...props,
};

Expand Down
44 changes: 44 additions & 0 deletions src/DataTable/tests/hooks.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useSelectionActions } from '../hooks';

const mockToggleAllRowsSelected = jest.fn();
const mockInstanceDispatcher = jest.fn();

const controlledTableSelectionsGenerator = (selectedRows = [], isEntireTableSelected = false) => ([
{ selectedRows, isEntireTableSelected },
mockInstanceDispatcher,
]);

describe('hooks', () => {
describe('useSelectionActions', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('calls toggleAllRowsSelected when controlled selection is empty', () => {
const { clearSelection } = useSelectionActions(
{ toggleAllRowsSelected: mockToggleAllRowsSelected },
controlledTableSelectionsGenerator([], false),
);
clearSelection();
expect(mockToggleAllRowsSelected.mock.calls.length).toBe(1);
expect(mockInstanceDispatcher.mock.calls.length).toBe(0);
});
it('calls dispatcher when all rows selected flagged', () => {
const { clearSelection } = useSelectionActions(
{ toggleAllRowsSelected: mockToggleAllRowsSelected },
controlledTableSelectionsGenerator([], true),
);
clearSelection();
expect(mockToggleAllRowsSelected.mock.calls.length).toBe(0);
expect(mockInstanceDispatcher.mock.calls.length).toBe(1);
});
it('calls dispatcher when some row is selected', () => {
const { clearSelection } = useSelectionActions(
{ toggleAllRowsSelected: mockToggleAllRowsSelected },
controlledTableSelectionsGenerator(['row'], true),
);
clearSelection();
expect(mockToggleAllRowsSelected.mock.calls.length).toBe(0);
expect(mockInstanceDispatcher.mock.calls.length).toBe(1);
});
});
});

0 comments on commit 79d8f21

Please sign in to comment.