diff --git a/superset/assets/javascripts/SqlLab/components/RunQueryActionButton.jsx b/superset/assets/javascripts/SqlLab/components/RunQueryActionButton.jsx new file mode 100644 index 0000000000000..d117318460b59 --- /dev/null +++ b/superset/assets/javascripts/SqlLab/components/RunQueryActionButton.jsx @@ -0,0 +1,71 @@ +import React, { PropTypes } from 'react'; +import Button from '../../components/Button'; + +const propTypes = { + allowAsync: PropTypes.bool.isRequired, + dbId: PropTypes.number.isRequired, + queryState: PropTypes.string.isRequired, + runQuery: PropTypes.func.isRequired, + selectedText: PropTypes.string, + stopQuery: PropTypes.func.isRequired, +}; + +export default function RunQueryActionButton(props) { + const runBtnText = props.selectedText ? 'Run Selected Query' : 'Run Query'; + const btnStyle = props.selectedText ? 'warning' : 'primary'; + const shouldShowStopBtn = ['running', 'pending'].indexOf(props.queryState) > -1; + const asyncToolTip = 'Run query asynchronously'; + + const commonBtnProps = { + bsSize: 'small', + bsStyle: btnStyle, + disabled: !(props.dbId), + }; + + const syncBtn = ( + + ); + + const asyncBtn = ( + + ); + + const stopBtn = ( + + ); + + let button; + if (shouldShowStopBtn) { + button = stopBtn; + } else if (props.allowAsync) { + button = asyncBtn; + } else { + button = syncBtn; + } + + return ( +
+ {button} +
+ ); +} + +RunQueryActionButton.propTypes = propTypes; diff --git a/superset/assets/javascripts/SqlLab/components/SqlEditor.jsx b/superset/assets/javascripts/SqlLab/components/SqlEditor.jsx index 6daba5857e7ed..aacb21681257f 100644 --- a/superset/assets/javascripts/SqlLab/components/SqlEditor.jsx +++ b/superset/assets/javascripts/SqlLab/components/SqlEditor.jsx @@ -1,7 +1,5 @@ import React from 'react'; import { - Button as BootstrapButton, - ButtonGroup, Col, FormGroup, InputGroup, @@ -21,6 +19,7 @@ import Timer from '../../components/Timer'; import SqlEditorLeftBar from './SqlEditorLeftBar'; import AceEditorWrapper from './AceEditorWrapper'; import { STATE_BSSTYLE_MAP } from '../constants.js'; +import RunQueryActionButton from './RunQueryActionButton'; const propTypes = { actions: React.PropTypes.object.isRequired, @@ -104,64 +103,6 @@ class SqlEditor extends React.PureComponent { } render() { - let runButtons = []; - let runText = 'Run Query'; - let btnStyle = 'primary'; - if (this.props.queryEditor.selectedText) { - runText = 'Run Selection'; - btnStyle = 'warning'; - } - if (this.props.database && this.props.database.allow_run_sync) { - runButtons.push( - - {runText} - - ); - } - if (this.props.database && this.props.database.allow_run_async) { - const asyncToolTip = 'Run query asynchronously'; - runButtons.push( - - ); - } - runButtons = ( - - {runButtons} - - ); - if ( - this.props.latestQuery && - ['running', 'pending'].indexOf(this.props.latestQuery.state) > -1) { - runButtons = ( - - - Stop - - - ); - } let limitWarning = null; if (this.props.latestQuery && this.props.latestQuery.limit_reached) { const tooltip = ( @@ -208,7 +149,14 @@ class SqlEditor extends React.PureComponent {
- {runButtons} + {ctasControls}
diff --git a/superset/assets/spec/javascripts/explorev2/components/RunQueryActionButton_spec.js b/superset/assets/spec/javascripts/explorev2/components/RunQueryActionButton_spec.js new file mode 100644 index 0000000000000..509caa969eca9 --- /dev/null +++ b/superset/assets/spec/javascripts/explorev2/components/RunQueryActionButton_spec.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { expect } from 'chai'; +import { describe, it, beforeEach } from 'mocha'; +import { shallow } from 'enzyme'; + +import RunQueryActionButton + from '../../../../javascripts/SqlLab/components/RunQueryActionButton'; +import Button from '../../../../javascripts/components/Button'; + +describe('RunQueryActionButton', () => { + let wrapper; + const defaultProps = { + allowAsync: false, + dbId: 1, + queryState: 'pending', + runQuery: () => {}, // eslint-disable-line + selectedText: null, + stopQuery: () => {}, // eslint-disable-line + }; + + beforeEach(() => { + wrapper = shallow(); + }); + + it('is a valid react element', () => { + expect( + React.isValidElement() + ).to.equal(true); + }); + + it('renders a single Button', () => { + expect(wrapper.find(Button)).to.have.lengthOf(1); + }); +});