diff --git a/superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx b/superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx
index efde76fa482f0..ff6da18651ca1 100644
--- a/superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx
+++ b/superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx
@@ -155,6 +155,7 @@ class SqlEditorLeftBar extends React.PureComponent {
)}
mutator={this.dbMutator.bind(this)}
placeholder="Select a database"
+ autoSelect
/>
diff --git a/superset/assets/javascripts/components/AsyncSelect.jsx b/superset/assets/javascripts/components/AsyncSelect.jsx
index 3269a98ae5463..53ecfda3c8f02 100644
--- a/superset/assets/javascripts/components/AsyncSelect.jsx
+++ b/superset/assets/javascripts/components/AsyncSelect.jsx
@@ -11,6 +11,7 @@ const propTypes = {
value: PropTypes.number,
valueRenderer: PropTypes.func,
placeholder: PropTypes.string,
+ autoSelect: PropTypes.bool,
};
const defaultProps = {
@@ -37,6 +38,10 @@ class AsyncSelect extends React.PureComponent {
const mutator = this.props.mutator;
$.get(this.props.dataEndpoint, (data) => {
this.setState({ options: mutator ? mutator(data) : data, isLoading: false });
+
+ if (this.props.autoSelect && this.state.options.length) {
+ this.onChange(this.state.options[0]);
+ }
});
}
render() {
diff --git a/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx b/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx
index b415d27f885e2..79c63739b65d3 100644
--- a/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx
+++ b/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx
@@ -4,6 +4,7 @@ import { shallow } from 'enzyme';
import { describe, it } from 'mocha';
import { expect } from 'chai';
import sinon from 'sinon';
+import $ from 'jquery';
import AsyncSelect from '../../../javascripts/components/AsyncSelect';
@@ -11,7 +12,10 @@ describe('AsyncSelect', () => {
const mockedProps = {
dataEndpoint: '/slicemodelview/api/read',
onChange: sinon.spy(),
- mutator: () => {},
+ mutator: () => [
+ { value: 1, label: 'main' },
+ { value: 2, label: 'another' },
+ ],
};
it('is valid element', () => {
expect(
@@ -33,4 +37,33 @@ describe('AsyncSelect', () => {
wrapper.find(Select).simulate('change', { value: 1 });
expect(mockedProps.onChange).to.have.property('callCount', 1);
});
+
+ describe('auto select', () => {
+ let stub;
+ beforeEach(() => {
+ stub = sinon.stub($, 'get');
+ stub.yields();
+ });
+ afterEach(() => {
+ stub.restore();
+ });
+ it('should be off by default', () => {
+ const wrapper = shallow(
+
,
+ );
+ const spy = sinon.spy(wrapper.instance(), 'onChange');
+
+ wrapper.instance().fetchOptions();
+ expect(spy.callCount).to.equal(0);
+ });
+ it('should auto select first option', () => {
+ const wrapper = shallow(
+
,
+ );
+ const spy = sinon.spy(wrapper.instance(), 'onChange');
+
+ wrapper.instance().fetchOptions();
+ expect(spy.calledWith(wrapper.instance().state.options[0])).to.equal(true);
+ });
+ });
});