diff options
Diffstat (limited to 'scraper/client/common/autocomplete.component.js')
| -rw-r--r-- | scraper/client/common/autocomplete.component.js | 118 |
1 files changed, 62 insertions, 56 deletions
diff --git a/scraper/client/common/autocomplete.component.js b/scraper/client/common/autocomplete.component.js index 12419cf1..03039b1c 100644 --- a/scraper/client/common/autocomplete.component.js +++ b/scraper/client/common/autocomplete.component.js @@ -47,29 +47,33 @@ class Autocomplete extends Component { this.handleCancel = this.handleCancel.bind(this) } - componentWillMount() { + componentDidMount() { // build index based on what's in the hierarchy - const { nodes } = this.props.hierarchy + const { entities, lookup } = this.props.institutions let index = [] this.index = index - Object.keys(nodes).forEach(key => { - const node = nodes[key] - if (!key || !node || !node.name || !node.parent) return - let { name } = node - let prefixName = name - if (node.is_attribute) { - const parent = nodes[node.parent] - if (parent) { - prefixName = parent.name + " (" + name + ")" - } - } - index.push([sanitizeForAutocomplete(prefixName), name, node.id]) - node.synonyms - .split("\n") - .map(word => word = word.trim()) - .filter(word => !!word) - .forEach(word => index.push([prefixName, name, node.id])) + Object.keys(entities).forEach(name => { + if (!name) return + index.push([sanitizeForAutocomplete(name), name]) + }) + Object.keys(lookup).forEach(name => { + if (!name) return + index.push([sanitizeForAutocomplete(name), lookup[name]]) }) + // console.log(index) + // node.synonyms + // .split("\n") + // .map(word => word = word.trim()) + // .filter(word => !!word) + // .forEach(word => index.push([prefixName, name, node.id])) + } + + componentDidUpdate(oldProps) { + if (this.props.vetting !== oldProps.vetting) { + this.handleChange({ target: { value: this.props.vetting }}) + } else if (this.props.value !== oldProps.value) { + this.handleChange({ target: { value: this.props.value }}) + } } handleKeyDown(e) { @@ -101,6 +105,7 @@ class Autocomplete extends Component { default: break } + return null } handleChange(e) { @@ -115,31 +120,42 @@ class Autocomplete extends Component { }) return } - const re = new RegExp(value) - let matches = [] let seen = {} - this.index.forEach(pair => { - if (seen[pair[2]]) return - if (pair[0].match(re)) { - seen[pair[2]] = true - if (pair[1].indexOf(value) === 0) { - matches.unshift(pair[2]) - } else { - matches.push(pair[2]) + let matches = [] + value.split(' ').forEach(word => { + const re = new RegExp(word) + this.index.forEach(([synonym, term]) => { + if (synonym.match(re)) { + if (synonym.indexOf(value) === 0) { + if (term in seen) { + seen[term] += 4 + } else { + seen[term] = 4 + } + } else if (term in seen) { + seen[term] += 1 + } else { + seen[term] = 1 + } } - } + }) + matches = Object.keys(seen) + .map(term => [seen[term], term]) + .sort((a, b) => { + return b[0] - a[0] + }) + .slice(0, 100) + .map(pair => pair[1]) }) this.setState({ q, selected: 0, - matches: matches.slice(0, 10), + matches, }) } - handleSelect(id) { - const { nodes } = this.props.hierarchy - const node = nodes[id] - if (this.props.onSelect) this.props.onSelect(node) + handleSelect(name) { + if (this.props.onSelect) this.props.onSelect(name) this.setState({ q: "", selected: 0, matches: [] }) } @@ -149,28 +165,14 @@ class Autocomplete extends Component { } render() { - // const suggestions = this.state.suggestions.map((suggestion)) - const { nodes } = this.props.hierarchy const { q, selected } = this.state const matches = this.state.matches.map((match, i) => { - const node = nodes[match] - const parent = nodes[node.parent] - let label - if (node.is_attribute) { - label = ( - <span> - {formatLabel(parent.name, q)} - {' '}<small>{'('}{formatLabel(node.name, q)}{')'}</small> - </span> - ) - } else { - label = formatLabel(node.name, q) - } + const label = formatLabel(match, q) return ( <div key={i} className={selected === i ? 'selected' : ''} - onClick={() => this.handleSelect(node.id)} + onClick={() => this.handleSelect(match)} onMouseEnter={() => this.setState({ selected: i })} > {label} @@ -185,14 +187,17 @@ class Autocomplete extends Component { value={this.state.q} onKeyDown={this.handleKeyDown} onChange={this.handleChange} - autoFocus + autoFocus={this.props.autoFocus} autoCapitalize="off" autoComplete="off" - placeholder="Start typing a name" + placeholder={this.props.placeholder} + ref={ref => this._el = ref} /> - <div className="matches"> - {matches} - </div> + {!!matches.length && + <div className="matches"> + {matches} + </div> + } </div> ) } @@ -200,6 +205,7 @@ class Autocomplete extends Component { const mapStateToProps = (state, ownProps) => ({ onSelect: ownProps.onSelect, + institutions: state.api.institutions, }) const mapDispatchToProps = (dispatch) => ({ |
