This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 866f6f9 feat: [SQLLAB] add checkbox to control autocomplete (#9338)
866f6f9 is described below
commit 866f6f9330388b74f36fef0b3f3886b8f4b12845
Author: ʈᵃᵢ <[email protected]>
AuthorDate: Mon Mar 23 22:11:05 2020 -0700
feat: [SQLLAB] add checkbox to control autocomplete (#9338)
* [SQLLAB] add checkbox to control autocomplete
* autocomplete -> autocompleteEnabled
* fix defaultProps
* fix spec
---
.../spec/javascripts/sqllab/SqlEditor_spec.jsx | 10 +++
.../{AceEditorWrapper.jsx => AceEditorWrapper.tsx} | 93 +++++++++++++---------
.../src/SqlLab/components/SqlEditor.jsx | 16 ++++
3 files changed, 80 insertions(+), 39 deletions(-)
diff --git a/superset-frontend/spec/javascripts/sqllab/SqlEditor_spec.jsx
b/superset-frontend/spec/javascripts/sqllab/SqlEditor_spec.jsx
index cb1002f..a97cebd 100644
--- a/superset-frontend/spec/javascripts/sqllab/SqlEditor_spec.jsx
+++ b/superset-frontend/spec/javascripts/sqllab/SqlEditor_spec.jsx
@@ -18,6 +18,7 @@
*/
import React from 'react';
import { shallow } from 'enzyme';
+import { Checkbox } from 'react-bootstrap';
import { defaultQueryEditor, initialState, queries, table } from './fixtures';
import {
@@ -105,4 +106,13 @@ describe('SqlEditor', () => {
queryEditor.queryLimit,
);
});
+ it('allows toggling autocomplete', () => {
+ const wrapper = shallow(<SqlEditor {...mockedProps} />);
+ expect(wrapper.find(AceEditorWrapper).props().autocomplete).toBe(true);
+ wrapper
+ .find(Checkbox)
+ .props()
+ .onChange();
+ expect(wrapper.find(AceEditorWrapper).props().autocomplete).toBe(false);
+ });
});
diff --git a/superset-frontend/src/SqlLab/components/AceEditorWrapper.jsx
b/superset-frontend/src/SqlLab/components/AceEditorWrapper.tsx
similarity index 82%
rename from superset-frontend/src/SqlLab/components/AceEditorWrapper.jsx
rename to superset-frontend/src/SqlLab/components/AceEditorWrapper.tsx
index aa31827..370cdbc 100644
--- a/superset-frontend/src/SqlLab/components/AceEditorWrapper.jsx
+++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper.tsx
@@ -17,7 +17,6 @@
* under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
import AceEditor from 'react-ace';
import 'brace/mode/sql';
import 'brace/theme/github';
@@ -34,41 +33,53 @@ import {
const langTools = ace.acequire('ace/ext/language_tools');
-const propTypes = {
- actions: PropTypes.object.isRequired,
- onBlur: PropTypes.func,
- sql: PropTypes.string.isRequired,
- schemas: PropTypes.array,
- tables: PropTypes.array,
- functionNames: PropTypes.array,
- extendedTables: PropTypes.array,
- queryEditor: PropTypes.object.isRequired,
- height: PropTypes.string,
- hotkeys: PropTypes.arrayOf(
- PropTypes.shape({
- key: PropTypes.string.isRequired,
- descr: PropTypes.string.isRequired,
- func: PropTypes.func.isRequired,
- }),
- ),
- onChange: PropTypes.func,
+type HotKey = {
+ key: string;
+ descr: string;
+ name: string;
+ func: () => void;
};
-const defaultProps = {
- onBlur: () => {},
- onChange: () => {},
- schemas: [],
- tables: [],
- functionNames: [],
- extendedTables: [],
-};
+interface Props {
+ actions: {
+ queryEditorSetSelectedText: (edit: any, text: null | string) => void;
+ addTable: (queryEditor: any, value: any, schema: any) => void;
+ };
+ autocomplete: boolean;
+ onBlur: (sql: string) => void;
+ sql: string;
+ schemas: any[];
+ tables: any[];
+ functionNames: string[];
+ extendedTables: Array<{ name: string; columns: any[] }>;
+ queryEditor: any;
+ height: string;
+ hotkeys: HotKey[];
+ onChange: (sql: string) => void;
+}
+
+interface State {
+ sql: string;
+ selectedText: string;
+ words: any[];
+}
+
+class AceEditorWrapper extends React.PureComponent<Props, State> {
+ static defaultProps = {
+ onBlur: () => {},
+ onChange: () => {},
+ schemas: [],
+ tables: [],
+ functionNames: [],
+ extendedTables: [],
+ };
-class AceEditorWrapper extends React.PureComponent {
- constructor(props) {
+ constructor(props: Props) {
super(props);
this.state = {
sql: props.sql,
selectedText: '',
+ words: [],
};
this.onChange = this.onChange.bind(this);
}
@@ -77,7 +88,7 @@ class AceEditorWrapper extends React.PureComponent {
this.props.actions.queryEditorSetSelectedText(this.props.queryEditor,
null);
this.setAutoCompleter(this.props);
}
- UNSAFE_componentWillReceiveProps(nextProps) {
+ UNSAFE_componentWillReceiveProps(nextProps: Props) {
if (
!areArraysShallowEqual(this.props.tables, nextProps.tables) ||
!areArraysShallowEqual(this.props.schemas, nextProps.schemas) ||
@@ -98,7 +109,7 @@ class AceEditorWrapper extends React.PureComponent {
onAltEnter() {
this.props.onBlur(this.state.sql);
}
- onEditorLoad(editor) {
+ onEditorLoad(editor: any) {
editor.commands.addCommand({
name: 'runQuery',
bindKey: { win: 'Alt-enter', mac: 'Alt-enter' },
@@ -129,18 +140,24 @@ class AceEditorWrapper extends React.PureComponent {
}
});
}
- onChange(text) {
+ onChange(text: string) {
this.setState({ sql: text });
this.props.onChange(text);
}
- getCompletions(aceEditor, session, pos, prefix, callback) {
+ getCompletions(
+ aceEditor: any,
+ session: any,
+ pos: any,
+ prefix: string,
+ callback: (p0: any, p1: any[]) => void,
+ ) {
// If the prefix starts with a number, don't try to autocomplete with a
// table name or schema or anything else
if (!isNaN(parseInt(prefix, 10))) {
return;
}
const completer = {
- insertMatch: (editor, data) => {
+ insertMatch: (editor: any, data: any) => {
if (data.meta === 'table') {
this.props.actions.addTable(
this.props.queryEditor,
@@ -163,7 +180,7 @@ class AceEditorWrapper extends React.PureComponent {
});
callback(null, words);
}
- setAutoCompleter(props) {
+ setAutoCompleter(props: Props) {
// Loading schema, table and column names as auto-completable words
const schemas = props.schemas || [];
const schemaWords = schemas.map(s => ({
@@ -223,7 +240,7 @@ class AceEditorWrapper extends React.PureComponent {
const validationResult = this.props.queryEditor.validationResult;
const resultIsReady = validationResult && validationResult.completed;
if (resultIsReady && validationResult.errors.length > 0) {
- const errors = validationResult.errors.map(err => ({
+ const errors = validationResult.errors.map((err: any) => ({
type: 'error',
row: err.line_number - 1,
column: err.start_column - 1,
@@ -244,14 +261,12 @@ class AceEditorWrapper extends React.PureComponent {
onChange={this.onChange}
width="100%"
editorProps={{ $blockScrolling: true }}
- enableLiveAutocompletion
+ enableLiveAutocompletion={this.props.autocomplete}
value={this.state.sql}
annotations={this.getAceAnnotations()}
/>
);
}
}
-AceEditorWrapper.defaultProps = defaultProps;
-AceEditorWrapper.propTypes = propTypes;
export default AceEditorWrapper;
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor.jsx
b/superset-frontend/src/SqlLab/components/SqlEditor.jsx
index 138093f..11edbf7 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor.jsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor.jsx
@@ -20,6 +20,7 @@ import React from 'react';
import { CSSTransition } from 'react-transition-group';
import PropTypes from 'prop-types';
import {
+ Checkbox,
FormGroup,
InputGroup,
Form,
@@ -93,6 +94,7 @@ class SqlEditor extends React.PureComponent {
northPercent: props.queryEditor.northPercent || INITIAL_NORTH_PERCENT,
southPercent: props.queryEditor.southPercent || INITIAL_SOUTH_PERCENT,
sql: props.queryEditor.sql,
+ autocompleteEnabled: true,
};
this.sqlEditorRef = React.createRef();
this.northPaneRef = React.createRef();
@@ -245,6 +247,9 @@ class SqlEditor extends React.PureComponent {
handleWindowResize() {
this.setState({ height: this.getSqlEditorHeight() });
}
+ handleToggleAutocompleteEnabled = () => {
+ this.setState({ autocompleteEnabled: !this.state.autocompleteEnabled });
+ };
elementStyle(dimension, elementSize, gutterSize) {
return {
[dimension]: `calc(${elementSize}% - ${gutterSize +
@@ -337,6 +342,7 @@ class SqlEditor extends React.PureComponent {
<div ref={this.northPaneRef} className="north-pane">
<AceEditorWrapper
actions={this.props.actions}
+ autocomplete={this.state.autocompleteEnabled}
onBlur={this.setQueryEditorSql}
onChange={this.onSqlChanged}
queryEditor={this.props.queryEditor}
@@ -502,6 +508,16 @@ class SqlEditor extends React.PureComponent {
</Form>
</div>
<div className="rightItems">
+ <span>
+ <Checkbox
+ checked={this.state.autocompleteEnabled}
+ inline
+ title={t('Autocomplete')}
+ onChange={this.handleToggleAutocompleteEnabled}
+ >
+ {t('Autocomplete')}
+ </Checkbox>
+ </span>
<TemplateParamsEditor
language="json"
onChange={params => {