UNPKG

@bigfishtv/cockpit

Version:

124 lines (107 loc) 3.46 kB
import PropTypes from 'prop-types' import React, { Component } from 'react' import keycode from 'keycode' import { titleCase } from '../../utils/stringUtils' import Button from '../button/Button' import AutosuggestInput from '../input/AutosuggestInput' import Icon from '../Icon' const DefaultCell = ({ defaultValue, model, onChange, onEdit }) => ( <div className="cell" onDoubleClick={onEdit}> <div className="cell-icon"> <Icon name="link" size="18" /> </div> <div className="cell-content">{defaultValue ? defaultValue : titleCase(model)}</div> <div className="cell-control"> <Button size="icon" onClick={() => onChange(null)}> <Icon name="close" size="18" /> </Button> </div> </div> ) export default class AutosuggestModelInput extends Component { static propTypes = { model: PropTypes.string.isRequired, queryUrl: PropTypes.string, onChange: PropTypes.func, autoSaveInput: PropTypes.bool, autoSaveTransform: PropTypes.func, } static defaultProps = { Cell: DefaultCell, onAdd: () => console.warn('[ModelAutosuggestInput] no onAdd prop provided'), onEdit: () => console.warn('[ModelAutosuggestInput] no onEdit prop provided'), renderSuggestion: (suggestion, input) => <div>{suggestion.name || suggestion.title || suggestion.toString()}</div>, autoSaveInput: false, autoSaveTransform: value => value, } constructor(props) { super(props) this.inputFocused = false this.suggestionsTotal = 0 this.state = { input: '' } } componentDidMount() { window.addEventListener('keydown', this.handleKeyDown) } handleKeyDown = event => { const { autoSaveInput } = this.props if (keycode(event) == 'enter' && autoSaveInput && this.inputFocused && this.state.input && !this.suggestionsTotal) { event.preventDefault() this.handleAdd() } } handleSuggestion(suggestion, event) { this.props.onChange(suggestion) } handleAdd = () => { Promise.resolve(this.props.autoSaveTransform(this.state.input)) .then(transformedInput => { this.handleSuggestion(transformedInput) this.props.onAdd(transformedInput) }) .catch(error => { alert(error.message) }) } handleRemove() { if ('formValue' in this.props) this.props.formValue.update(null) else console.warn('[ModelAutosuggestInput] no onRemove prop provided') } queryUrl(props) { return props.queryUrl ? props.queryUrl : props.model ? '/admin/' + props.model + '/search.json' : null } render() { const { Cell, model, onAdd, renderSuggestion, autoSaveInput, autoSaveTransform, onRemove, ...rest } = this.props if (!this.props.value) { return ( <div className="input-group"> <AutosuggestInput {...rest} queryUrl={this.queryUrl(this.props)} onChange={this.props.onChange} renderSuggestion={renderSuggestion} onSuggestionsChange={suggestions => (this.suggestionsTotal = suggestions.length)} onInputChange={input => this.setState({ input })} onInputFocus={() => (this.inputFocused = true)} onInputBlur={() => (this.inputFocused = false)} /> {autoSaveInput && this.state.input && !this.suggestionsTotal && ( <Button text="Add" onClick={this.handleAdd} /> )} </div> ) } if (model) { return ( <Cell value={this.props.value} model={model} onDoubleClick={this.props.onEdit} onRemove={onRemove ? onRemove : () => this.handleRemove()} {...rest} /> ) } return null } }