blob: c47cabe1fb1b8136ba7920aebd8fdf28516f577a [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { PureComponent } from 'react';
import { Select, Spin } from 'antd';
import debounce from 'lodash.debounce';
import request from '../../../utils/request';
const { Option } = Select;
export default class Search extends PureComponent {
constructor(props) {
super(props);
this.lastFetchId = 0;
this.originFetchServer = this.fetchServer;
this.fetchServer = debounce(this.fetchServer, 800);
}
state = {
data: [],
fetching: false,
};
componentDidMount() {
if (this.props.variables && Object.keys(this.props.variables).length > 0) {
this.originFetchServer('', this.props.value.key);
}
}
componentDidUpdate(prevProps) {
if (prevProps.variables !== this.props.variables) {
this.originFetchServer('', this.props.value.key);
}
}
fetchServer = (value, key) => {
if (value === undefined) {
return;
}
const { url, query, variables = {}, transform } = this.props;
this.lastFetchId += 1;
const fetchId = this.lastFetchId;
this.setState({ data: [], fetching: true });
request(`/api${url}`, {
method: 'POST',
body: {
variables: {
...variables,
keyword: value,
},
query,
},
}).then(body => {
if (!body.data || fetchId !== this.lastFetchId) {
// for fetch callback order
return;
}
const list = body.data[Object.keys(body.data)[0]];
this.setState({ data: transform ? list.map(transform) : list, fetching: false });
if (this.state.data.length < 1) {
return;
}
if (!key) {
this.handleSelect(this.state.data[0]);
return;
}
const option = this.state.data.find(_ => _.key === key);
if (!option) {
this.handleSelect(this.state.data[0]);
}
});
};
handleSelect = value => {
const { onSelect } = this.props;
const selected = this.state.data.find(_ => _.key === value.key);
onSelect(selected);
};
render() {
const { placeholder, value } = this.props;
return (
<Select
showSearch
style={{ width: 600 }}
placeholder={placeholder}
notFoundContent={this.state.fetching ? <Spin size="small" /> : null}
filterOption={false}
labelInValue
onSelect={this.handleSelect.bind(this)}
onSearch={this.fetchServer}
value={value}
>
{this.state.data.map(_ => {
return (
<Option key={_.key} value={_.key}>
{_.label}
</Option>
);
})}
</Select>
);
}
}