From e43968c6849ee82d8e2ee7404ec82387435e1444 Mon Sep 17 00:00:00 2001 From: tannerlinsley Date: Thu, 3 Oct 2019 14:08:34 -0600 Subject: [PATCH] feat(userowselect): add selectedFlatRows, rename state.selectedRows Added instance.selectedFlatRows to know which row objects are currently selecte --- docs/api.md | 4 +- examples/kitchen-sink-controlled/src/App.js | 6 +- examples/kitchen-sink/src/App.js | 6 +- examples/row-selection/src/App.js | 18 +++++- .../__snapshots__/useRowSelect.test.js.snap | 20 +++--- src/plugin-hooks/tests/useRowSelect.test.js | 6 +- src/plugin-hooks/useRowSelect.js | 61 +++++++++++++------ 7 files changed, 83 insertions(+), 38 deletions(-) diff --git a/docs/api.md b/docs/api.md index ca1a4b9..add4e88 100644 --- a/docs/api.md +++ b/docs/api.md @@ -780,7 +780,7 @@ The following values are provided to the table `instance`: The following options are supported via the main options object passed to `useTable(options)` -- `state[0].selectedRows: Array` +- `state[0].selectedRowsPaths: Array` - Optional - Defaults to `[]` - If a row's path key (eg. a row path of `[1, 3, 2]` would have a path key of `1.3.2`) is found in this array, it will have a selected state. @@ -809,6 +809,8 @@ The following values are provided to the table `instance`: - `isAllRowsSelected: Bool` - Will be `true` if all rows are selected. - If at least one row is not selected, will be `false` +- `selectedFlatRows: Array` + - The flat array of rows that are currently selected ### Row Properties diff --git a/examples/kitchen-sink-controlled/src/App.js b/examples/kitchen-sink-controlled/src/App.js index 953c728..ef26d54 100644 --- a/examples/kitchen-sink-controlled/src/App.js +++ b/examples/kitchen-sink-controlled/src/App.js @@ -285,7 +285,9 @@ function Table({ columns, data, updateMyData, disablePageResetOnDataChange }) { nextPage, previousPage, setPageSize, - state: [{ pageIndex, pageSize, groupBy, expanded, filters, selectedRows }], + state: [ + { pageIndex, pageSize, groupBy, expanded, filters, selectedRowPaths }, + ], } = useTable( { columns, @@ -438,7 +440,7 @@ function Table({ columns, data, updateMyData, disablePageResetOnDataChange }) { groupBy, expanded, filters, - selectedRows, + selectedRowPaths, }, null, 2 diff --git a/examples/kitchen-sink/src/App.js b/examples/kitchen-sink/src/App.js index 3b63c24..a2aca89 100644 --- a/examples/kitchen-sink/src/App.js +++ b/examples/kitchen-sink/src/App.js @@ -285,7 +285,9 @@ function Table({ columns, data, updateMyData, disablePageResetOnDataChange }) { nextPage, previousPage, setPageSize, - state: [{ pageIndex, pageSize, groupBy, expanded, filters, selectedRows }], + state: [ + { pageIndex, pageSize, groupBy, expanded, filters, selectedRowPaths }, + ], } = useTable( { columns, @@ -438,7 +440,7 @@ function Table({ columns, data, updateMyData, disablePageResetOnDataChange }) { groupBy, expanded, filters, - selectedRows, + selectedRowPaths, }, null, 2 diff --git a/examples/row-selection/src/App.js b/examples/row-selection/src/App.js index 2d3d3da..650e2da 100644 --- a/examples/row-selection/src/App.js +++ b/examples/row-selection/src/App.js @@ -41,7 +41,8 @@ function Table({ columns, data }) { headerGroups, rows, prepareRow, - state: [{ selectedRows }], + selectedFlatRows, + state: [{ selectedRowPaths }], } = useTable( { columns, @@ -78,9 +79,20 @@ function Table({ columns, data }) { )} -

Selected Rows: {selectedRows.length}

+

Selected Rows: {selectedRowPaths.length}

-        {JSON.stringify({ selectedRows }, null, 2)}
+        
+          {JSON.stringify(
+            {
+              selectedRowPaths,
+              'selectedFlatRows[].original': selectedFlatRows.map(
+                d => d.original
+              ),
+            },
+            null,
+            2
+          )}
+        
       
) diff --git a/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap b/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap index 6df1a58..f3e5ade 100644 --- a/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap +++ b/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap @@ -485,8 +485,8 @@ Snapshot Diff:
       
         {
--   "selectedRows": []
-+   "selectedRows": [
+-   "selectedRowPaths": []
++   "selectedRowPaths": [
 +     "0",
 +     "1",
 +     "2",
@@ -1015,7 +1015,7 @@ Snapshot Diff:
     
       
         {
--   "selectedRows": [
+-   "selectedRowPaths": [
 -     "0",
 -     "1",
 -     "2",
@@ -1053,7 +1053,7 @@ Snapshot Diff:
 -     "22.1",
 -     "23"
 -   ]
-+   "selectedRows": []
++   "selectedRowPaths": []
   }
       
     
@@ -1129,8 +1129,8 @@ Snapshot Diff:
       
         {
--   "selectedRows": []
-+   "selectedRows": [
+-   "selectedRowPaths": []
++   "selectedRowPaths": [
 +     "0",
 +     "2",
 +     "2.0",
@@ -1198,7 +1198,7 @@ Snapshot Diff:
     
       
         {
-    "selectedRows": [
+    "selectedRowPaths": [
 -     "0",
 -     "2",
 -     "2.0",
@@ -1241,7 +1241,7 @@ Snapshot Diff:
     
       
         {
-    "selectedRows": [
+    "selectedRowPaths": [
 -     "0"
 +     "0",
 +     "2.0"
@@ -1282,7 +1282,7 @@ Snapshot Diff:
     
       
         {
-    "selectedRows": [
+    "selectedRowPaths": [
       "0",
 -     "2.0"
 +     "2.0",
@@ -1324,7 +1324,7 @@ Snapshot Diff:
     
       
         {
-    "selectedRows": [
+    "selectedRowPaths": [
       "0",
 -     "2.0",
 -     "2.1"
diff --git a/src/plugin-hooks/tests/useRowSelect.test.js b/src/plugin-hooks/tests/useRowSelect.test.js
index ce5a994..6122177 100644
--- a/src/plugin-hooks/tests/useRowSelect.test.js
+++ b/src/plugin-hooks/tests/useRowSelect.test.js
@@ -75,7 +75,7 @@ function Table({ columns, data }) {
     headerGroups,
     rows,
     prepareRow,
-    state: [{ selectedRows }],
+    state: [{ selectedRowPaths }],
   } = useTable(
     {
       columns,
@@ -113,9 +113,9 @@ function Table({ columns, data }) {
           )}
         
       
-      

Selected Rows: {selectedRows.length}

+

Selected Rows: {selectedRowPaths.length}

-        {JSON.stringify({ selectedRows }, null, 2)}
+        {JSON.stringify({ selectedRowPaths }, null, 2)}
       
) diff --git a/src/plugin-hooks/useRowSelect.js b/src/plugin-hooks/useRowSelect.js index 8851ae7..d8a6b6a 100644 --- a/src/plugin-hooks/useRowSelect.js +++ b/src/plugin-hooks/useRowSelect.js @@ -1,10 +1,11 @@ +import React from 'react' import PropTypes from 'prop-types' import { mergeProps, applyPropHooks, ensurePluginOrder } from '../utils' import { addActions, actions } from '../actions' import { defaultState } from '../hooks/useTableState' -defaultState.selectedRows = [] +defaultState.selectedRowPaths = [] addActions('toggleRowSelected', 'toggleRowSelectedAll') @@ -15,11 +16,41 @@ const propTypes = { export const useRowSelect = hooks => { hooks.getToggleRowSelectedProps = [] hooks.getToggleAllRowsSelectedProps = [] + hooks.useRows.push(useRows) hooks.useMain.push(useMain) } useRowSelect.pluginName = 'useRowSelect' +function useRows(rows, instance) { + PropTypes.checkPropTypes(propTypes, instance, 'property', 'useRowSelect') + + const { + state: [{ selectedRowPaths }], + } = instance + + instance.selectedFlatRows = React.useMemo(() => { + const selectedFlatRows = [] + rows.forEach(row => { + if (row.isAggregated) { + const subRowPaths = row.subRows.map(row => row.path) + row.isSelected = subRowPaths.every(path => + selectedRowPaths.includes(path.join('.')) + ) + } else { + row.isSelected = selectedRowPaths.includes(row.path.join('.')) + } + if (row.isSelected) { + selectedFlatRows.push(row) + } + }) + + return selectedFlatRows + }, [rows, selectedRowPaths]) + + return rows +} + function useMain(instance) { PropTypes.checkPropTypes(propTypes, instance, 'property', 'useRowSelect') @@ -28,7 +59,7 @@ function useMain(instance) { manualRowSelectedKey = 'isSelected', plugins, flatRows, - state: [{ selectedRows }, setState], + state: [{ selectedRowPaths }, setState], } = instance ensurePluginOrder( @@ -40,10 +71,10 @@ function useMain(instance) { const flatRowPaths = flatRows.map(d => d.path.join('.')) - let isAllRowsSelected = !!flatRowPaths.length && !!selectedRows.length + let isAllRowsSelected = !!flatRowPaths.length && !!selectedRowPaths.length if (isAllRowsSelected) { - if (flatRowPaths.some(d => !selectedRows.includes(d))) { + if (flatRowPaths.some(d => !selectedRowPaths.includes(d))) { isAllRowsSelected = false } } @@ -53,12 +84,12 @@ function useMain(instance) { const selectAll = typeof set !== 'undefined' ? set : !isAllRowsSelected return { ...old, - selectedRows: selectAll ? flatRowPaths : [], + selectedRowPaths: selectAll ? flatRowPaths : [], } }, actions.toggleRowSelectedAll) } - const updateParentRow = (selectedRows, path) => { + const updateParentRow = (selectedRowPaths, path) => { const parentPath = path.slice(0, path.length - 1) const parentKey = parentPath.join('.') const selected = @@ -67,15 +98,15 @@ function useMain(instance) { return ( path !== parentKey && path.startsWith(parentKey) && - !selectedRows.has(path) + !selectedRowPaths.has(path) ) }).length === 0 if (selected) { - selectedRows.add(parentKey) + selectedRowPaths.add(parentKey) } else { - selectedRows.delete(parentKey) + selectedRowPaths.delete(parentKey) } - if (parentPath.length > 1) updateParentRow(selectedRows, parentPath) + if (parentPath.length > 1) updateParentRow(selectedRowPaths, parentPath) } const toggleRowSelected = (path, set) => { @@ -86,9 +117,9 @@ function useMain(instance) { // Join the paths of deep rows // to make a key, then manage all of the keys // in a flat object - const exists = old.selectedRows.includes(key) + const exists = old.selectedRowPaths.includes(key) const shouldExist = typeof set !== 'undefined' ? set : !exists - let newSelectedRows = new Set(old.selectedRows) + let newSelectedRows = new Set(old.selectedRowPaths) if (!exists && shouldExist) { flatRowPaths.forEach(rowPath => { @@ -112,7 +143,7 @@ function useMain(instance) { return { ...old, - selectedRows: [...newSelectedRows.values()], + selectedRowPaths: [...newSelectedRows.values()], } }, actions.toggleRowSelected) } @@ -138,9 +169,6 @@ function useMain(instance) { // Aggregate rows have entirely different select logic if (row.isAggregated) { const subRowPaths = row.subRows.map(row => row.path) - row.isSelected = subRowPaths.every(path => - selectedRows.includes(path.join('.')) - ) row.toggleRowSelected = set => { set = typeof set !== 'undefined' ? set : !row.isSelected subRowPaths.forEach(path => { @@ -176,7 +204,6 @@ function useMain(instance) { ) } } else { - row.isSelected = selectedRows.includes(row.path.join('.')) row.toggleRowSelected = set => toggleRowSelected(row.path, set) row.getToggleRowSelectedProps = props => { let checked = false