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); + }); + }); });