@marklogic-community/grove-search-redux
Version:
Redux module to power MarkLogic search UIs
108 lines (70 loc) • 5.89 kB
Markdown
# MarkLogic Search Implemented in Redux
This is a Redux implementation of search. It forms part of the MarkLogic Grove project. It works well for search against MarkLogic, but any backend search system could be used, so long as a middle-tier marshalled the response into the shape specified by the [Grove Core API](https://github.com/marklogic-community/grove-core-api). See the [Grove React-Redux Template](https://github.com/marklogic-community/grove-react-template) for an example of using this library in practice.
## Install
npm install @marklogic-community/grove-search-redux --save
## Use
### Simple Use
In many cases, you will consume this library as part of a Grove Template, such as the [Grove React-Redux Template](https://github.com/marklogic-community/grove-react-template). The ui library in those templates, in turn, consume this library via the [grove-core-react-redux-containers library](https://github.com/marklogic-community/grove-core-react-redux-containers), which connects together React components with Redux modules like this one.
But the actions and selectors exposed by this library should also be passed along via grove-core-react-redux-containers's `<SearchContainer>`.
TODO: link to information in grove-cli about search filters.
#### Actions
- `runSearch(query)`. Runs a search based on the passed query. The query will most often be obtained by calling `selectors.getStagedQuery(state)`.
- `setQueryText(queryText)`. This sets a queryText filter in the staged search query.
- `addFilter(constraintName, constraintType, values, optional)`. This will by default append filter values with the given constraintName and a mode of 'and' in the staged search query. You can alternatively append to filter values with a mode of 'or' by passing `{boolean: 'or'}` as part of the `optional` argument. Note that values can be a single value or an array of values.
- `replaceFilter(constraintName, constraintType, values, optional)`: This will by default add or replace filter values with the given constraintName and a mode of 'and' in the staged search query. You can alternatively replace those with a mode of 'or' by passing `{boolean: 'or'}` as part of the `optional` argument. Note that values can be a single value or an array of values.
- `removeFilter(constraintName, values, optional)`. This will by default remove filter values with the given constraintName and a mode of 'and' in the staged search query. You can alternatively remove filter values with a mode of 'or' by passing `{boolean: 'or'}` as part of the `optional` argument. Note that values can be a single value or an array of values.
- `clearFilter(constraintName)`. This clears all filters for a given constraintName in the staged search query.
- `changePage(pageNumber)`. Changes the page in the staged search query.
#### Selectors
- Selectors getting information about the **staged** search:
- `getStagedQuery(state)`. Returns the currently staged query, as serialized in this Redux module and POSTed to a Grove middle-tier.
- `stagedFilters(state)`. Returns all currently staged filters, as serialized in this Redux module and POSTed to a Grove middle-tier.
- TODO: more, see `src/reducers/stagedSearch.js`
- Selectors getting information about the **executed** search:
- `getPage(state)`. Returns the page of the executed search query.
- `getPageLength(state)`. Returns the page length of the executed search query.
- TODO: more, see `src/reducers/executedSearch.js`
### Advanced Use Cases
The provided selectors only know about their slice of state, so your consuming code needs to wrap them to provide their particular slice of state. For example:
```javascript
import {
actions as searchActions,
selectors as searchSelectors
} from 'grove-search-redux';
const bindSelector = (selector, mountPoint) => {
return (state, ...args) => {
return selector(state[mountPoint], ...args)
}
}
const bindSelectors = (selectors, mountPoint) => {
return Object.keys(selectors).reduce((bound, key) => {
bound[key] = bindSelector(selectors[key], mountPoint)
return bound
}, {})
}
const boundSearchSelectors = bindSelectors(searchSelectors, 'search');
```
A version of the `bindSelectors()` function is available as an export from the `grove-core-react-redux-containers` library, in case you are already using it.
Also, you will need to provide a searchQuery to the `runSearch` action. This is done for you already if you are using the default ML-Treehouse React components. In other cases, this can be done with something like:
```javascript
import { searchActions } from 'grove-search-redux';
// Using `wrappedSearchSelectors` from the code above
// `state` imported most likely using the React-Redux Provider
searchActions.runSearch(wrappedSearchSelectors.getStagedQuery(state));
```
## 'Ducks' architecture
This roughly follows [the architecture laid out in the re-ducks proposal]( https://github.com/alexnm/re-ducks/blob/f28ecc59d43542b8353948ede0cd3a059ca177dd/README.md):
Specifically, the actionCreators and selectors are the primary external UI. State and reducers should be an implementation detail.
## Contributing
You will need to install the devDependencies:
npm install
### Building
This project uses [Webpack](https://webpack.js.org/) for building.
npm run build
### Testing
This project uses [Jest](https://facebook.github.io/jest/) for testing.
npm test
Or, if you want it to watch for file changes and automatically re-run the tests:
npm run test:watch
### Linting
This project uses the [Javascript Standard Style](https://standardjs.com/). It will be checked automatically when you run tests, but you will have a greatly improved experience if you [install an ESLint checker in your text editor](https://eslint.org/docs/user-guide/integrations#editors), so linting errors are highlighted immediately.