diff --git a/README.md b/README.md index 73fb5b8..747c51d 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,12 @@ Hooks for building **lightweight, fast and extendable datagrids** for React - + + + + + + @@ -118,7 +123,6 @@ Hooks for building **lightweight, fast and extendable datagrids** for React -
Nicholas Kaufmann
Pekka
Jon Eickmeier
diff --git a/src/hooks/useTable.js b/src/hooks/useTable.js index 5c486b4..be5fe2f 100755 --- a/src/hooks/useTable.js +++ b/src/hooks/useTable.js @@ -189,7 +189,7 @@ export const useTable = (props, ...plugins) => { // Create the cells and values row.values = {} - instanceRef.current.columns.forEach(column => { + columns.forEach(column => { row.values[column.id] = column.accessor ? column.accessor(originalRow, i, { subRows, depth, data }) : undefined @@ -203,7 +203,7 @@ export const useTable = (props, ...plugins) => { if (process.env.NODE_ENV === 'development' && debug) console.timeEnd('getAccessedRows') return [accessedData, rowPaths, flatRows] - }, [debug, data, subRowsKey]) + }, [debug, data, columns, subRowsKey]) instanceRef.current.rows = rows instanceRef.current.rowPaths = rowPaths diff --git a/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap b/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap index 721aea5..20eb419 100644 --- a/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap +++ b/src/plugin-hooks/tests/__snapshots__/useRowSelect.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders a table with seletable rows 1`] = ` +exports[`renders a table with selectable rows 1`] = ` Snapshot Diff: - First value + Second value @@ -57,7 +57,227 @@ Snapshot Diff: -@@ -314,15 +314,20 @@ +@@ -333,11 +333,11 @@ + + +
+- Not Selected ++ Selected +
+ + +@@ -389,11 +389,11 @@ + + +
+- Not Selected ++ Selected +
+ + +@@ -426,15 +426,22 @@ + + + + +

+- Selected Rows: 0 ++ Selected Rows: 6 +

+
+      
+        {
+-   "selectedRows": []
++   "selectedRows": [
++     "0",
++     "1",
++     "2",
++     "2.0",
++     "2.1",
++     "3"
++   ]
+  }
+      
+    
+ +`; + +exports[`renders a table with selectable rows 2`] = ` +Snapshot Diff: +- First value ++ Second value + +@@ -109,11 +109,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -165,11 +165,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -221,11 +221,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -277,11 +277,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -333,11 +333,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -389,11 +389,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -426,22 +426,15 @@ + + + + +

+- Selected Rows: 6 ++ Selected Rows: 0 +

+
+      
+        {
+-   "selectedRows": [
+-     "0",
+-     "1",
+-     "2",
+-     "2.0",
+-     "2.1",
+-     "3"
+-   ]
++   "selectedRows": []
+  }
+      
+    
+ +`; + +exports[`renders a table with selectable rows 3`] = ` +Snapshot Diff: +- First value ++ Second value + +@@ -109,11 +109,11 @@ + + +
+- Not Selected ++ Selected +
+ + +@@ -221,11 +221,11 @@ + + +
+- Not Selected ++ Selected +
+ + +@@ -277,11 +277,11 @@ + + +
+- Not Selected ++ Selected +
+ + +@@ -333,11 +333,11 @@ + + +
+- Not Selected ++ Selected +
+ + +@@ -426,15 +426,20 @@ @@ -72,9 +292,9 @@ Snapshot Diff: - "selectedRows": [] + "selectedRows": [ + "0", -+ "1", + "2", -+ "3" ++ "2.0", ++ "2.1" + ] } @@ -82,37 +302,11 @@ Snapshot Diff: `; -exports[`renders a table with seletable rows 2`] = ` +exports[`renders a table with selectable rows 4`] = ` Snapshot Diff: - First value + Second value -@@ -109,11 +109,11 @@ - - -
-- Selected -+ Not Selected -
- - -@@ -165,11 +165,11 @@ - - -
-- Selected -+ Not Selected -
- - @@ -221,11 +221,11 @@ -@@ -314,20 +314,15 @@ +@@ -333,11 +333,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -426,20 +426,17 @@

- Selected Rows: 4 -+ Selected Rows: 0 ++ Selected Rows: 1

       
         {
--   "selectedRows": [
+    "selectedRows": [
 -     "0",
--     "1",
 -     "2",
--     "3"
--   ]
-+   "selectedRows": []
+-     "2.0",
+-     "2.1"
++     "0"
+    ]
   }
       
     
`; -exports[`renders a table with seletable rows 3`] = ` +exports[`renders a table with selectable rows 5`] = ` Snapshot Diff: - First value + Second value -@@ -109,11 +109,11 @@ +@@ -277,11 +277,11 @@ +@@ -426,17 +426,18 @@ + + + + +

+- Selected Rows: 1 ++ Selected Rows: 2 +

+
+      
+        {
+    "selectedRows": [
+-     "0"
++     "0",
++     "2.0"
+    ]
+  }
+      
+    
+ +`; + +exports[`renders a table with selectable rows 6`] = ` +Snapshot Diff: +- First value ++ Second value + @@ -221,11 +221,11 @@ -@@ -314,15 +314,18 @@ +@@ -333,11 +333,11 @@ + + +
+- Not Selected ++ Selected +
+ + +@@ -426,18 +426,20 @@

-- Selected Rows: 0 -+ Selected Rows: 2 +- Selected Rows: 2 ++ Selected Rows: 4

       
         {
--   "selectedRows": []
-+   "selectedRows": [
-+     "0",
+    "selectedRows": [
+      "0",
+-     "2.0"
++     "2.0",
++     "2.1",
 +     "2"
-+   ]
+    ]
+  }
+      
+    
+ +`; + +exports[`renders a table with selectable rows 7`] = ` +Snapshot Diff: +- First value ++ Second value + +@@ -221,11 +221,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -333,11 +333,11 @@ + + +
+- Selected ++ Not Selected +
+ + +@@ -426,20 +426,18 @@ + + + + +

+- Selected Rows: 4 ++ Selected Rows: 2 +

+
+      
+        {
+    "selectedRows": [
+      "0",
+-     "2.0",
+-     "2.1",
+-     "2"
++     "2.0"
+    ]
   }
       
     
diff --git a/src/plugin-hooks/tests/useRowSelect.test.js b/src/plugin-hooks/tests/useRowSelect.test.js index 376a41e..418598a 100644 --- a/src/plugin-hooks/tests/useRowSelect.test.js +++ b/src/plugin-hooks/tests/useRowSelect.test.js @@ -2,6 +2,7 @@ import React from 'react' import { render, fireEvent } from '@testing-library/react' import { useTable } from '../../hooks/useTable' import { useRowSelect } from '../useRowSelect' +import { useExpanded } from '../useExpanded' const data = [ { @@ -27,6 +28,25 @@ const data = [ visits: 20, status: 'Complicated', progress: 10, + expanded: true, + subRows: [ + { + firstName: 'bob', + lastName: 'ross', + age: 52, + visits: 40, + status: 'In Relationship', + progress: 30, + }, + { + firstName: 'john', + lastName: 'smith', + age: 21, + visits: 30, + status: 'Single', + progress: 60, + }, + ], }, { firstName: 'jaylen', @@ -51,7 +71,8 @@ function Table({ columns, data }) { columns, data, }, - useRowSelect + useRowSelect, + useExpanded ) // Render the UI for your table @@ -164,7 +185,7 @@ function App() { return } -test('renders a table with seletable rows', () => { +test('renders a table with selectable rows', () => { const { getByLabelText, getAllByLabelText, asFragment } = render() const fragment1 = asFragment() @@ -182,7 +203,27 @@ test('renders a table with seletable rows', () => { const fragment4 = asFragment() + fireEvent.click(getAllByLabelText('Select Row')[2]) + + const fragment5 = asFragment() + + fireEvent.click(getAllByLabelText('Select Row')[3]) + + const fragment6 = asFragment() + fireEvent.click(getAllByLabelText('Select Row')[4]) + + const fragment7 = asFragment() + + fireEvent.click(getAllByLabelText('Select Row')[4]) + + const fragment8 = asFragment() + + expect(fragment1).toMatchDiffSnapshot(fragment2) expect(fragment2).toMatchDiffSnapshot(fragment3) expect(fragment3).toMatchDiffSnapshot(fragment4) + expect(fragment4).toMatchDiffSnapshot(fragment5) + expect(fragment5).toMatchDiffSnapshot(fragment6) + expect(fragment6).toMatchDiffSnapshot(fragment7) + expect(fragment7).toMatchDiffSnapshot(fragment8) }) diff --git a/src/plugin-hooks/useFilters.js b/src/plugin-hooks/useFilters.js index 075f6a9..ce6b971 100755 --- a/src/plugin-hooks/useFilters.js +++ b/src/plugin-hooks/useFilters.js @@ -146,14 +146,14 @@ function useMain(instance) { // Find the filters column const column = columns.find(d => d.id === columnID) - if (depth === 0) { - column.preFilteredRows = filteredSoFar - } - if (!column) { return filteredSoFar } + if (depth === 0) { + column.preFilteredRows = filteredSoFar + } + const filterMethod = getFilterMethod( column.filter, userFilterTypes || {}, diff --git a/src/plugin-hooks/useRowSelect.js b/src/plugin-hooks/useRowSelect.js index f594f97..72acc9a 100644 --- a/src/plugin-hooks/useRowSelect.js +++ b/src/plugin-hooks/useRowSelect.js @@ -50,6 +50,20 @@ function useMain(instance) { }, actions.toggleRowSelectedAll) } + const updateParentRow = (selectedRows, path) => { + const parentPath = path.slice(0, path.length - 1) + const parentKey = parentPath.join(".") + const selected = rowPaths.filter(path => + path !== parentKey && path.startsWith(parentKey) && !selectedRows.has(path) + ).length === 0 + if (selected) { + selectedRows.add(parentKey) + } else { + selectedRows.delete(parentKey) + } + if (parentPath.length > 1) updateParentRow(selectedRows, parentPath) + } + const toggleRowSelected = (path, set) => { const key = path.join('.') @@ -62,13 +76,21 @@ function useMain(instance) { let newSelectedRows = new Set(old.selectedRows) if (!exists && shouldExist) { - newSelectedRows.add(key) + rowPaths.forEach((rowPath) => { + if (rowPath.startsWith(key)) newSelectedRows.add(rowPath) + }) } else if (exists && !shouldExist) { - newSelectedRows.delete(key) + rowPaths.forEach((rowPath) => { + if (rowPath.startsWith(key)) newSelectedRows.delete(rowPath) + }) } else { return old } + // If the row is a subRow update + // its parent row to reflect changes + if (path.length > 1) updateParentRow(newSelectedRows, path) + return { ...old, selectedRows: [...newSelectedRows.values()], diff --git a/src/plugin-hooks/useSortBy.js b/src/plugin-hooks/useSortBy.js index ae0dcb9..b8385b0 100755 --- a/src/plugin-hooks/useSortBy.js +++ b/src/plugin-hooks/useSortBy.js @@ -210,15 +210,28 @@ function useMain(instance) { if (process.env.NODE_ENV === 'development' && debug) console.time('getSortedRows') + // Filter out sortBys that correspond to non existing columns + const availableSortBy = sortBy.filter(sort => + columns.find(col => col.id === sort.id) + ) + const sortData = rows => { // Use the orderByFn to compose multiple sortBy's together. // This will also perform a stable sorting using the row index // if needed. const sortedData = orderByFn( rows, - sortBy.map(sort => { + availableSortBy.map(sort => { // Support custom sorting methods for each column - const { sortType } = columns.find(d => d.id === sort.id) + const column = columns.find(d => d.id === sort.id) + + if (!column) { + throw new Error( + `React-Table: Could not find a column with id: ${sort.id} while sorting` + ) + } + + const { sortType } = column // Look up sortBy functions in this order: // column function @@ -238,11 +251,11 @@ function useMain(instance) { sortMethod(a.values[sort.id], b.values[sort.id], sort.desc) }), // Map the directions - sortBy.map(sort => { + availableSortBy.map(sort => { // Detect and use the sortInverted option - const { sortInverted } = columns.find(d => d.id === sort.id) + const column = columns.find(d => d.id === sort.id) - if (sortInverted) { + if (column && column.sortInverted) { return sort.desc }