Skip to content

Commit

Permalink
breaking(search) - Generalize the search interface
Browse files Browse the repository at this point in the history
You should pass an `operation` to search now. This decouples search from
*searchtabular*.
  • Loading branch information
bebraw committed Dec 16, 2016
1 parent 0af87e6 commit 6b56b8c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
==================

* Feature - Add `tree.wrap = ({ operations: [rows => rows], idField = 'id' }) => (rows) => [<operatedRow>]`.
* Breaking - `tree.search` does not depend on *selectabular* directly anymore. Instead you have to pass the search `operation` to it. The new signature is `tree.search = ({ operation: (rows) => [<row>], idField = 'id', parentField = 'parent' }) => (rows) => [<searchedRow>]`.
* Breaking - `tree.sort` has been dropped. Use `tree.wrap` instead. Example:

```javascript
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ Returns parents based on given `rows` and `index`.

Returns a boolean based on whether or not the row at the given `index` has children.

**`tree.search = ({ columns, query, idField = 'id', parentField = 'parent' }) => (rows) => [<searchedRow>]`**
**`tree.search = ({ operation: (rows) => [<row>], idField = 'id', parentField = 'parent' }) => (rows) => [<searchedRow>]`**

Searches against a tree structure while matching against children too. If children are found, associated parents are returned as well.
Searches against a tree structure using `operation` while matching against children too. If children are found, associated parents are returned as well. This has been designed to [searchtabular](https://www.npmjs.com/package/searchtabular) `multipleColumns` and `singleColumn`, but as long as the passed operation follows the interface, it should fit in.

> This depends on [resolve.index](https://www.npmjs.com/package/table-resolver#resolveindex)!
Expand Down Expand Up @@ -261,7 +261,9 @@ class TreeTable extends React.Component {
})
]
}),
tree.search({ columns, query })
tree.search({
operation: search.multipleColumns({ columns, query })
})
)(this.state.rows);

return (
Expand Down
40 changes: 33 additions & 7 deletions __tests__/search-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { multipleColumns } from 'searchtabular';
import { search } from '../src';

describe('tree.search', function () {
it('returns empty rows if empty rows are passed', function () {
expect(search({ columns: [], query: {} })([])).toEqual([]);
expect(search({
operation: multipleColumns({
columns: [],
query: {}
})
})([])).toEqual([]);
});

it('returns matching rows', function () {
Expand All @@ -20,7 +26,11 @@ describe('tree.search', function () {
foo: 'bar'
};

expect(search({ columns, query })(given)).toEqual(given);
expect(
search({
operation: multipleColumns({ columns, query })
})(given)
).toEqual(given);
});

it('matches children', function () {
Expand All @@ -46,7 +56,9 @@ describe('tree.search', function () {
foo: 'zoo'
};

expect(search({ columns, query })(given)).toEqual(given);
expect(search({
operation: multipleColumns({ columns, query })
})(given)).toEqual(given);
});

it('matches multiple children', function () {
Expand Down Expand Up @@ -78,7 +90,9 @@ describe('tree.search', function () {
foo: 'zoo'
};

expect(search({ columns, query })(given)).toEqual(given);
expect(search({
operation: multipleColumns({ columns, query })
})(given)).toEqual(given);
});

it('returns the same structure with an empty query', function () {
Expand Down Expand Up @@ -108,7 +122,9 @@ describe('tree.search', function () {
];
const query = {};

expect(search({ columns, query })(given)).toEqual(given);
expect(search({
operation: multipleColumns({ columns, query })
})(given)).toEqual(given);
});

it('returns the same structure with an empty all query', function () {
Expand Down Expand Up @@ -140,7 +156,9 @@ describe('tree.search', function () {
all: ''
};

expect(search({ columns, query })(given)).toEqual(given);
expect(search({
operation: multipleColumns({ columns, query })
})(given)).toEqual(given);
});

it('retains children on match', function () {
Expand Down Expand Up @@ -191,6 +209,14 @@ describe('tree.search', function () {
}
];

expect(search({ columns, query })(given)).toEqual(expected);
expect(search({
operation: multipleColumns({ columns, query })
})(given)).toEqual(expected);
});

/* TODO: test idField/parentField */

it('throws an error if operation is not passed', function () {
expect(search.bind(null, {})).toThrow(Error);
});
});
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
"lodash": ">= 3.0.0 < 5.0.0",
"react": ">= 15.0.0 < 16.0.0",
"reactabular-dnd": ">= 8.0.0 < 9.0.0",
"searchtabular": ">= 1.0.0 < 2.0.0",
"redux": ">= 3.0.0 < 4.0.0"
},
"pre-push": [
Expand Down
19 changes: 7 additions & 12 deletions src/search.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
import { uniq } from 'lodash';
import { multipleColumns } from 'searchtabular';
import getChildren from './get-children';
import getParents from './get-parents';

function searchTree({
columns,
query,
idField = 'id',
parentField = 'parent'
parentField = 'parent',
operation
} = {}) {
if (!operation) {
throw new Error('tree.search - Missing operation!');
}

return (rows) => {
// Track fetched parents to get them into the results only once
const fetchedParents = {};

if (!Object.keys(query).length) {
return rows;
}

return uniq([].concat(
...multipleColumns({
columns,
query
})(rows).map((row) => {
...operation(rows).map((row) => {
const rowParent = row[parentField];

if (fetchedParents[rowParent]) {
Expand Down

0 comments on commit 6b56b8c

Please sign in to comment.