/* Copyright © 2016 Kuali, Inc. - All Rights Reserved
* You may use and modify this code under the terms of the Kuali, Inc.
* Pre-Release License Agreement. You may not distribute it.
*
* You should have received a copy of the Kuali, Inc. Pre-Release License
* Agreement with this file. If not, please write to license@kuali.co.
*/
import { map, omit, partial, pick } from 'lodash'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import Autocomplete from 'react-md/lib/Autocompletes'
import Chip from 'react-md/lib/Chips'
import styles from './styles.css'
import Fetch from '../fetch'
const expectedProps = [
'ariaLabel',
'getAll',
'getById',
'notFoundMsg',
'onChange',
'placeholder',
'searchByName',
'value',
]
export default class _Typeahead extends Component {
static displayName = 'Typeahead';
static propTypes = {
ariaLabel: PropTypes.string.isRequired,
getAll: PropTypes.func.isRequired,
getById: PropTypes.func.isRequired,
notFoundMsg: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
placeholder: PropTypes.string,
searchByName: PropTypes.func.isRequired,
value: PropTypes.string,
};
constructor(props) {
super(props)
this.state = { text: '', dataSource: [] }
}
componentDidMount() {
this.handleChange('')
}
handleSelect = (_name, i, matches) => {
if (i === -1) return
this.props.onChange(matches[i].id)
this.setState({ text: '', dataSource: [] })
}
handleChange = (text) => {
this.setState({ text })
const promise = text ? this.props.searchByName(text) : this.props.getAll()
return promise.then((items) => {
const dataSource = map(items, (item) => pick(item, ['id', 'name']))
this.setState({ dataSource })
return
})
}
renderView() {
return (
<Fetch loadFn={partial(this.props.getById, this.props.value)}>
{(loading, error, item) => {
const label = loading ? '...' : error ? this.props.notFoundMsg : item.name || '--'
return (
<Chip
className={error && styles.notFound}
removable
onClick={() => this.props.onChange(null)}
label={label}
/>
)
}}
</Fetch>
)
}
render() {
if (this.props.value) return this.renderView()
const otherProps = omit(this.props, expectedProps)
return (
<Autocomplete
{...otherProps}
aria-label={this.props.ariaLabel}
data={this.state.dataSource}
dataLabel="name"
dataValue="id"
filter={null}
placeholder={this.props.placeholder}
onChange={this.handleChange}
onAutocomplete={this.handleSelect}
value={this.state.text}
/>
)
}
}
|