Skip to content

Commit

Permalink
Allow execution of highlighted subquery (#3288)
Browse files Browse the repository at this point in the history
* allow execution of selected subquery
* fix query save while highlighted
* don't modify queryText and update UI when running selected
* code style and transition
* Fix query selection execution background color
* make naming consistent
  • Loading branch information
chang authored and arikfr committed Jan 20, 2019
1 parent 84d5bec commit 8bc8e2d
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 9 deletions.
3 changes: 3 additions & 0 deletions client/app/components/QueryEditor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.editor__container[data-executing="true"] .ace_marker-layer .ace_selection {
background-color: rgb(255, 210, 181);
}
20 changes: 18 additions & 2 deletions client/app/components/QueryEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import AutocompleteToggle from '@/components/AutocompleteToggle';
import keywordBuilder from './keywordBuilder';
import { DataSource, Schema } from './proptypes';

import './QueryEditor.css';

const langTools = ace.acequire('ace/ext/language_tools');
const snippetsModule = ace.acequire('ace/snippets');

Expand Down Expand Up @@ -51,6 +53,7 @@ class QueryEditor extends React.Component {
queryExecuting: PropTypes.bool.isRequired,
saveQuery: PropTypes.func.isRequired,
updateQuery: PropTypes.func.isRequired,
updateSelectedQuery: PropTypes.func.isRequired,
listenForResize: PropTypes.func.isRequired,
listenForEditorCommand: PropTypes.func.isRequired,
};
Expand All @@ -64,6 +67,8 @@ class QueryEditor extends React.Component {
constructor(props) {
super(props);

this.refEditor = React.createRef();

this.state = {
schema: null, // eslint-disable-line react/no-unused-state
keywords: {
Expand All @@ -75,6 +80,7 @@ class QueryEditor extends React.Component {
liveAutocompleteDisabled: false,
// XXX temporary while interfacing with angular
queryText: props.queryText,
selectedQueryText: null,
};

const schemaCompleter = {
Expand Down Expand Up @@ -181,6 +187,15 @@ class QueryEditor extends React.Component {
});
};

updateSelectedQuery = (selection) => {
const { editor } = this.refEditor.current;
const doc = editor.getSession().doc;
const rawSelectedQueryText = doc.getTextRange(selection.getRange());
const selectedQueryText = (rawSelectedQueryText.length > 1) ? rawSelectedQueryText : null;
this.setState({ selectedQueryText });
this.props.updateSelectedQuery(selectedQueryText);
}

updateQuery = (queryText) => {
this.props.updateQuery(queryText);
this.setState({ queryText });
Expand Down Expand Up @@ -208,7 +223,7 @@ class QueryEditor extends React.Component {
return (
<section style={{ height: '100%' }} data-test="QueryEditor">
<div className="container p-15 m-b-10" style={{ height: '100%' }}>
<div style={{ height: 'calc(100% - 40px)', marginBottom: '0px' }} className="editor__container">
<div data-executing={this.props.queryExecuting} style={{ height: 'calc(100% - 40px)', marginBottom: '0px' }} className="editor__container">
<AceEditor
ref={this.refEditor}
theme="textmate"
Expand All @@ -229,6 +244,7 @@ class QueryEditor extends React.Component {
onLoad={this.onLoad}
onPaste={this.onPaste}
onChange={this.updateQuery}
onSelectionChange={this.updateSelectedQuery}
/>
</div>

Expand Down Expand Up @@ -292,7 +308,7 @@ class QueryEditor extends React.Component {
data-test="ExecuteButton"
>
<span className="zmdi zmdi-play" />
<span className="hidden-xs m-l-5">Execute</span>
<span className="hidden-xs m-l-5">{ (this.state.selectedQueryText == null) ? 'Execute' : 'Execute Selected' }</span>
</button>
</Tooltip>
</div>
Expand Down
1 change: 1 addition & 0 deletions client/app/pages/queries/query.html
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ <h3>
listen-for-editor-command="listenForEditorCommand"
save-query="saveQuery"
update-query="updateQuery"
update-selected-query="updateSelectedQuery"
add-new-parameter="addNewParameter"
data-data-source="dataSource"
data-data-sources="dataSources"></query-editor>
Expand Down
17 changes: 12 additions & 5 deletions client/app/pages/queries/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function QueryViewCtrl(
DataSource,
Visualization,
) {
function getQueryResult(maxAge) {
function getQueryResult(maxAge, selectedQueryText) {
if (maxAge === undefined) {
maxAge = $location.search().maxAge;
}
Expand All @@ -36,7 +36,7 @@ function QueryViewCtrl(
}

$scope.showLog = false;
$scope.queryResult = $scope.query.getQueryResult(maxAge);
$scope.queryResult = $scope.query.getQueryResult(maxAge, selectedQueryText);
}

function getDataSourceId() {
Expand Down Expand Up @@ -105,6 +105,10 @@ function QueryViewCtrl(
getSchema();
}

$scope.updateSelectedQuery = (selectedQueryText) => {
$scope.selectedQueryText = selectedQueryText;
};

$scope.executeQuery = () => {
if (!$scope.canExecuteQuery()) {
return;
Expand All @@ -114,7 +118,7 @@ function QueryViewCtrl(
return;
}

getQueryResult(0);
getQueryResult(0, $scope.selectedQueryText);
$scope.lockButton(true);
$scope.cancelling = false;
Events.record('execute', 'query', $scope.query.id);
Expand Down Expand Up @@ -372,8 +376,11 @@ function QueryViewCtrl(
}

if (status === 'done') {
$scope.query.latest_query_data_id = $scope.queryResult.getId();
$scope.query.queryResult = $scope.queryResult;
const ranSelectedQuery = $scope.query.query !== $scope.queryResult.query;
if (!ranSelectedQuery) {
$scope.query.latest_query_data_id = $scope.queryResult.getId();
$scope.query.queryResult = $scope.queryResult;
}

Notifications.showNotification('Redash', `${$scope.query.name} updated.`);
} else if (status === 'failed') {
Expand Down
4 changes: 2 additions & 2 deletions client/app/services/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,12 @@ function QueryResource(
return this.getParameters().isRequired();
};

Query.prototype.getQueryResult = function getQueryResult(maxAge) {
Query.prototype.getQueryResult = function getQueryResult(maxAge, selectedQueryText) {
if (!this.query) {
return new QueryResultError("Can't execute empty query.");
}
const queryText = this.query;

const queryText = selectedQueryText || this.query;
const parameters = this.getParameters();
const missingParams = parameters.getMissing();

Expand Down

0 comments on commit 8bc8e2d

Please sign in to comment.