mirror of
https://github.com/ascribe/onion.git
synced 2024-11-15 01:25:17 +01:00
Add documentation for SearchBar and put threshold into AppConstants
This commit is contained in:
parent
c59f5267ce
commit
6d36be5311
@ -6,6 +6,8 @@ import PieceListToolbarFilterWidget from './piece_list_toolbar_filter_widget';
|
|||||||
import PieceListToolbarOrderWidget from './piece_list_toolbar_order_widget';
|
import PieceListToolbarOrderWidget from './piece_list_toolbar_order_widget';
|
||||||
import SearchBar from '../search_bar';
|
import SearchBar from '../search_bar';
|
||||||
|
|
||||||
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
|
|
||||||
let PieceListToolbar = React.createClass({
|
let PieceListToolbar = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@ -76,7 +78,7 @@ let PieceListToolbar = React.createClass({
|
|||||||
className="pull-right search-bar ascribe-input-glyph"
|
className="pull-right search-bar ascribe-input-glyph"
|
||||||
searchFor={searchFor}
|
searchFor={searchFor}
|
||||||
searchQuery={searchQuery}
|
searchQuery={searchQuery}
|
||||||
threshold={500}/>
|
threshold={AppConstants.searchThreshold}/>
|
||||||
<span className="pull-right">
|
<span className="pull-right">
|
||||||
{this.getOrderWidget()}
|
{this.getOrderWidget()}
|
||||||
{this.getFilterWidget()}
|
{this.getFilterWidget()}
|
||||||
|
@ -12,12 +12,16 @@ const { update } = React.addons;
|
|||||||
|
|
||||||
const SearchBar = React.createClass({
|
const SearchBar = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
// a function that accepts a string as a search query and updates the
|
||||||
|
// propagated `searchQuery` after successfully retrieving the
|
||||||
|
// request from the server
|
||||||
searchFor: func.isRequired,
|
searchFor: func.isRequired,
|
||||||
searchQuery: string.isRequired,
|
searchQuery: string.isRequired,
|
||||||
|
|
||||||
className: string,
|
className: string,
|
||||||
|
|
||||||
// in milliseconds
|
// the number of milliseconds the component
|
||||||
|
// should wait before requesting search results from the server
|
||||||
threshold: number.isRequired
|
threshold: number.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -25,7 +29,7 @@ const SearchBar = React.createClass({
|
|||||||
return {
|
return {
|
||||||
timers: [],
|
timers: [],
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
searching: false
|
loading: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -33,16 +37,44 @@ const SearchBar = React.createClass({
|
|||||||
const searchQueryProps = this.props.searchQuery;
|
const searchQueryProps = this.props.searchQuery;
|
||||||
const searchQueryPrevProps = prevProps.searchQuery;
|
const searchQueryPrevProps = prevProps.searchQuery;
|
||||||
const searchQueryState = this.state.searchQuery;
|
const searchQueryState = this.state.searchQuery;
|
||||||
const { searching } = this.state;
|
const { loading } = this.state;
|
||||||
|
|
||||||
if(searching && (searchQueryProps && searchQueryState && searchQueryProps === searchQueryState || !searchQueryPrevProps && searchQueryProps === searchQueryState)) {
|
/**
|
||||||
this.setState({ searching: false });
|
* 1. Condition: `loading` must be true, which implies that `evaluateTimer`,
|
||||||
|
* has already been called
|
||||||
|
*
|
||||||
|
* AND
|
||||||
|
*
|
||||||
|
* 2. Condition: `searchQueryProps` and `searchQueryState` are true and equal
|
||||||
|
* (which means that the search query has been propagated to the inner
|
||||||
|
* fetch method of `fetchPieceList`, which in turn means that a fetch
|
||||||
|
* has completed)
|
||||||
|
*
|
||||||
|
* OR
|
||||||
|
*
|
||||||
|
* 3. Condition: `searchQueryProps` and `searchQueryState` can be any value (`true` or
|
||||||
|
* `false`, as long as they're equal). This case only occurs when the user
|
||||||
|
* has entered a `searchQuery` and deletes the query in one go, reseting
|
||||||
|
* `searchQueryProps` to empty string ('' === false) again.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const firstCondition = !!loading;
|
||||||
|
const secondCondition = searchQueryProps && searchQueryState && searchQueryProps === searchQueryState;
|
||||||
|
const thirdCondition = !searchQueryPrevProps && searchQueryProps === searchQueryState;
|
||||||
|
|
||||||
|
if(firstCondition && (secondCondition || thirdCondition)) {
|
||||||
|
this.setState({ loading: false });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
startTimers(searchQuery) {
|
startTimers(searchQuery) {
|
||||||
const { timers } = this.state;
|
const { timers } = this.state;
|
||||||
const { threshold } = this.props;
|
const { threshold } = this.props;
|
||||||
|
|
||||||
|
// the timer waits for the specified threshold time in milliseconds
|
||||||
|
// and then calls `evaluateTimer`, that checks if another letter
|
||||||
|
// has been added to the query (by checking if there are newer
|
||||||
|
// timers on the stack aka. `this.state.timers`)
|
||||||
const timer = {
|
const timer = {
|
||||||
searchQuery,
|
searchQuery,
|
||||||
cb: setTimeout(this.evaluateTimer(timers.length, searchQuery), threshold)
|
cb: setTimeout(this.evaluateTimer(timers.length, searchQuery), threshold)
|
||||||
@ -56,9 +88,14 @@ const SearchBar = React.createClass({
|
|||||||
return () => {
|
return () => {
|
||||||
const { timers } = this.state;
|
const { timers } = this.state;
|
||||||
|
|
||||||
|
// If there have been no timers added to `this.state.timers`,
|
||||||
|
// while the `threshold` was passed, we start loading
|
||||||
|
// by querying the server.
|
||||||
if(timers.length <= timerIndex + 1) {
|
if(timers.length <= timerIndex + 1) {
|
||||||
// clean the timers array
|
// However, we're doing that only after setting `this.state.loading`
|
||||||
this.setState({ timers: [], searching: true }, () => {
|
// to `true`, as we want to display a little spinner while loading.
|
||||||
|
// We also clean the now worthless `timers` array.
|
||||||
|
this.setState({ timers: [], loading: true }, () => {
|
||||||
// search for the query
|
// search for the query
|
||||||
this.props.searchFor(searchQuery);
|
this.props.searchFor(searchQuery);
|
||||||
});
|
});
|
||||||
@ -67,6 +104,9 @@ const SearchBar = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleChange({ target: { value }}) {
|
handleChange({ target: { value }}) {
|
||||||
|
// On each letter entry we're updating the state of the component
|
||||||
|
// and start a timer, which we're also pushing to the state
|
||||||
|
// of the component
|
||||||
this.startTimers(value);
|
this.startTimers(value);
|
||||||
this.setState({ searchQuery: value });
|
this.setState({ searchQuery: value });
|
||||||
},
|
},
|
||||||
@ -74,9 +114,9 @@ const SearchBar = React.createClass({
|
|||||||
render() {
|
render() {
|
||||||
let searchIcon = <Glyphicon glyph='search' className="filter-glyph"/>;
|
let searchIcon = <Glyphicon glyph='search' className="filter-glyph"/>;
|
||||||
const { className } = this.props;
|
const { className } = this.props;
|
||||||
const { searching } = this.state;
|
const { loading } = this.state;
|
||||||
|
|
||||||
if(searching) {
|
if(loading) {
|
||||||
searchIcon = <span className="glyph-ascribe-spool-chunked ascribe-color spin"/>;
|
searchIcon = <span className="glyph-ascribe-spool-chunked ascribe-color spin"/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,8 @@ let constants = {
|
|||||||
'copyrightAssociations': ['ARS', 'DACS', 'Bildkunst', 'Pictoright', 'SODRAC', 'Copyright Agency/Viscopy', 'SAVA',
|
'copyrightAssociations': ['ARS', 'DACS', 'Bildkunst', 'Pictoright', 'SODRAC', 'Copyright Agency/Viscopy', 'SAVA',
|
||||||
'Bildrecht GmbH', 'SABAM', 'AUTVIS', 'CREAIMAGEN', 'SONECA', 'Copydan', 'EAU', 'Kuvasto', 'GCA', 'HUNGART',
|
'Bildrecht GmbH', 'SABAM', 'AUTVIS', 'CREAIMAGEN', 'SONECA', 'Copydan', 'EAU', 'Kuvasto', 'GCA', 'HUNGART',
|
||||||
'IVARO', 'SIAE', 'JASPAR-SPDA', 'AKKA/LAA', 'LATGA-A', 'SOMAAP', 'ARTEGESTION', 'CARIER', 'BONO', 'APSAV',
|
'IVARO', 'SIAE', 'JASPAR-SPDA', 'AKKA/LAA', 'LATGA-A', 'SOMAAP', 'ARTEGESTION', 'CARIER', 'BONO', 'APSAV',
|
||||||
'SPA', 'GESTOR', 'VISaRTA', 'RAO', 'LITA', 'DALRO', 'VeGaP', 'BUS', 'ProLitteris', 'AGADU', 'AUTORARTE', 'BUBEDRA', 'BBDA', 'BCDA', 'BURIDA', 'ADAVIS', 'BSDA']
|
'SPA', 'GESTOR', 'VISaRTA', 'RAO', 'LITA', 'DALRO', 'VeGaP', 'BUS', 'ProLitteris', 'AGADU', 'AUTORARTE', 'BUBEDRA', 'BBDA', 'BCDA', 'BURIDA', 'ADAVIS', 'BSDA'],
|
||||||
|
'searchThreshold': 500
|
||||||
};
|
};
|
||||||
|
|
||||||
export default constants;
|
export default constants;
|
||||||
|
Loading…
Reference in New Issue
Block a user