Files
redash/client/app/components/QueryBasedParameterInput.jsx
Rafael Wendel fa2b57a209 Remove unwanted props from Select component (#5277)
* Explicitly selected props so as to avoid errors from non-wanted props

* Simplified approach

* Ran prettier 😬

* Fixed minor issues
2020-11-22 13:07:56 -03:00

102 lines
2.9 KiB
JavaScript

import { find, isArray, get, first, map, intersection, isEqual, isEmpty } from "lodash";
import React from "react";
import PropTypes from "prop-types";
import SelectWithVirtualScroll from "@/components/SelectWithVirtualScroll";
export default class QueryBasedParameterInput extends React.Component {
static propTypes = {
parameter: PropTypes.any, // eslint-disable-line react/forbid-prop-types
value: PropTypes.any, // eslint-disable-line react/forbid-prop-types
mode: PropTypes.oneOf(["default", "multiple"]),
queryId: PropTypes.number,
onSelect: PropTypes.func,
className: PropTypes.string,
};
static defaultProps = {
value: null,
mode: "default",
parameter: null,
queryId: null,
onSelect: () => {},
className: "",
};
constructor(props) {
super(props);
this.state = {
options: [],
value: null,
loading: false,
};
}
componentDidMount() {
this._loadOptions(this.props.queryId);
}
componentDidUpdate(prevProps) {
if (this.props.queryId !== prevProps.queryId) {
this._loadOptions(this.props.queryId);
}
if (this.props.value !== prevProps.value) {
this.setValue(this.props.value);
}
}
setValue(value) {
const { options } = this.state;
if (this.props.mode === "multiple") {
value = isArray(value) ? value : [value];
const optionValues = map(options, option => option.value);
const validValues = intersection(value, optionValues);
this.setState({ value: validValues });
return validValues;
}
const found = find(options, option => option.value === this.props.value) !== undefined;
value = found ? value : get(first(options), "value");
this.setState({ value });
return value;
}
async _loadOptions(queryId) {
if (queryId && queryId !== this.state.queryId) {
this.setState({ loading: true });
const options = await this.props.parameter.loadDropdownValues();
// stale queryId check
if (this.props.queryId === queryId) {
this.setState({ options, loading: false }, () => {
const updatedValue = this.setValue(this.props.value);
if (!isEqual(updatedValue, this.props.value)) {
this.props.onSelect(updatedValue);
}
});
}
}
}
render() {
const { className, mode, onSelect, queryId, value, ...otherProps } = this.props;
const { loading, options } = this.state;
return (
<span>
<SelectWithVirtualScroll
className={className}
disabled={loading}
loading={loading}
mode={mode}
value={this.state.value}
onChange={onSelect}
options={map(options, ({ value, name }) => ({ label: String(name), value }))}
optionFilterProp="children"
showSearch
showArrow
notFoundContent={isEmpty(options) ? "No options available" : null}
{...otherProps}
/>
</span>
);
}
}