|
|
@@ -1,5 +1,6 @@
|
|
|
import React from 'react';
|
|
|
import PropTypes from 'prop-types';
|
|
|
+import { AsyncTypeahead } from 'react-bootstrap-typeahead';
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
@@ -16,47 +17,58 @@ export default class PageTagForm extends React.Component {
|
|
|
super(props);
|
|
|
|
|
|
this.state = {
|
|
|
- pageTags: this.props.pageTags,
|
|
|
+ resultTags: [],
|
|
|
+ isLoading: false,
|
|
|
+ selected: [],
|
|
|
};
|
|
|
+ this.crowi = this.props.crowi;
|
|
|
|
|
|
- this.updateState = this.updateState.bind(this);
|
|
|
this.handleSubmit = this.handleSubmit.bind(this);
|
|
|
}
|
|
|
|
|
|
- componentWillReceiveProps(nextProps) {
|
|
|
- this.setState({
|
|
|
- pageTags: nextProps.pageTags
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
handleSubmit() {
|
|
|
- this.props.submitTags(this.state.pageTags);
|
|
|
- }
|
|
|
-
|
|
|
- updateState(value) {
|
|
|
- this.setState({pageTags: value});
|
|
|
+ this.props.handleSubmit(this.state.selected);
|
|
|
}
|
|
|
|
|
|
render() {
|
|
|
return (
|
|
|
- <div className="input-group-sm mx-1">
|
|
|
- <input className="form-control page-tag-form" type="text" value={this.state.pageTags} placeholder="tag name"
|
|
|
- data-toggle="popover"
|
|
|
- title="タグ"
|
|
|
- data-content="タグ付けによりページをカテゴライズすることができます。"
|
|
|
- data-trigger="focus"
|
|
|
- data-placement="right"
|
|
|
- onChange={e => this.updateState(e.target.value)}
|
|
|
+ <div className="tag-typeahead">
|
|
|
+ <AsyncTypeahead
|
|
|
+ allowNew={true}
|
|
|
+ caseSensitive={false}
|
|
|
+ defaultSelected={this.props.pageTags}
|
|
|
+ emptyLabel={''}
|
|
|
+ isLoading={this.state.isLoading}
|
|
|
+ labelKey="name"
|
|
|
+ minLength={1}
|
|
|
+ multiple={true}
|
|
|
+ newSelectionPrefix=""
|
|
|
onBlur={this.handleSubmit}
|
|
|
- />
|
|
|
+ onChange={(selected) => {
|
|
|
+ this.setState({ selected });
|
|
|
+ }}
|
|
|
+ onSearch={query => {
|
|
|
+ this.setState({ isLoading: true });
|
|
|
+ this.crowi.apiGet('/searchTag', { q: query })
|
|
|
+ .then(res => {
|
|
|
+ this.setState({
|
|
|
+ resultTags: Array.from(new Set([res.data, query])), // use Set for de-duplication
|
|
|
+ isLoading: false,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ options={this.state.resultTags} // Search result (Some tag names)
|
|
|
+ placeholder="tag name"
|
|
|
+ />
|
|
|
</div>
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
PageTagForm.propTypes = {
|
|
|
- pageTags: PropTypes.string,
|
|
|
- submitTags: PropTypes.func,
|
|
|
+ crowi: PropTypes.object.isRequired,
|
|
|
+ pageTags: PropTypes.array,
|
|
|
+ handleSubmit: PropTypes.func,
|
|
|
};
|
|
|
|
|
|
PageTagForm.defaultProps = {
|