Skip to content

Commit

Permalink
Wrapping up #7130 (#7633)
Browse files Browse the repository at this point in the history
* [SQL Lab] Adds autocomplete on table names and auto-add to schema browser

Closes #7059

* Wrapping up #7130

For more details see #7130, this PR addresses the merge conflicts.
  • Loading branch information
mistercrunch authored Jun 1, 2019
1 parent 722043c commit 687f205
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 5 deletions.
10 changes: 10 additions & 0 deletions superset/assets/src/SqlLab/actions/sqlLab.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export const EXPAND_TABLE = 'EXPAND_TABLE';
export const COLLAPSE_TABLE = 'COLLAPSE_TABLE';
export const QUERY_EDITOR_SETDB = 'QUERY_EDITOR_SETDB';
export const QUERY_EDITOR_SET_SCHEMA = 'QUERY_EDITOR_SET_SCHEMA';
export const QUERY_EDITOR_SET_SCHEMA_OPTIONS = 'QUERY_EDITOR_SET_SCHEMA_OPTIONS';
export const QUERY_EDITOR_SET_TABLE_OPTIONS = 'QUERY_EDITOR_SET_TABLE_OPTIONS';
export const QUERY_EDITOR_SET_TITLE = 'QUERY_EDITOR_SET_TITLE';
export const QUERY_EDITOR_SET_AUTORUN = 'QUERY_EDITOR_SET_AUTORUN';
export const QUERY_EDITOR_SET_SQL = 'QUERY_EDITOR_SET_SQL';
Expand Down Expand Up @@ -305,6 +307,14 @@ export function queryEditorSetSchema(queryEditor, schema) {
return { type: QUERY_EDITOR_SET_SCHEMA, queryEditor, schema };
}

export function queryEditorSetSchemaOptions(queryEditor, options) {
return { type: QUERY_EDITOR_SET_SCHEMA_OPTIONS, queryEditor, options };
}

export function queryEditorSetTableOptions(queryEditor, options) {
return { type: QUERY_EDITOR_SET_TABLE_OPTIONS, queryEditor, options };
}

export function queryEditorSetAutorun(queryEditor, autorun) {
return { type: QUERY_EDITOR_SET_AUTORUN, queryEditor, autorun };
}
Expand Down
28 changes: 24 additions & 4 deletions superset/assets/src/SqlLab/components/AceEditorWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ const propTypes = {
actions: PropTypes.object.isRequired,
onBlur: PropTypes.func,
sql: PropTypes.string.isRequired,
schemas: PropTypes.array,
tables: PropTypes.array,
extendedTables: PropTypes.array,
queryEditor: PropTypes.object.isRequired,
height: PropTypes.string,
hotkeys: PropTypes.arrayOf(PropTypes.shape({
Expand All @@ -62,7 +64,9 @@ const propTypes = {
const defaultProps = {
onBlur: () => {},
onChange: () => {},
schemas: [],
tables: [],
extendedTables: [],
};

class AceEditorWrapper extends React.PureComponent {
Expand All @@ -80,7 +84,9 @@ class AceEditorWrapper extends React.PureComponent {
this.setAutoCompleter(this.props);
}
componentWillReceiveProps(nextProps) {
if (!areArraysShallowEqual(this.props.tables, nextProps.tables)) {
if (!areArraysShallowEqual(this.props.tables, nextProps.tables) ||
!areArraysShallowEqual(this.props.schemas, nextProps.schemas) ||
!areArraysShallowEqual(this.props.extendedTables, nextProps.extendedTables)) {
this.setAutoCompleter(nextProps);
}
if (nextProps.sql !== this.props.sql) {
Expand Down Expand Up @@ -126,20 +132,34 @@ class AceEditorWrapper extends React.PureComponent {
getCompletions(aceEditor, session, pos, prefix, callback) {
const completer = {
insertMatch: (editor, data) => {
if (data.meta === 'table') {
this.props.actions.addTable(
this.props.queryEditor,
data.value,
this.props.queryEditor.schema,
);
}
editor.completer.insertMatch({ value: data.caption + ' ' });
},
};
const words = this.state.words.map(word => ({ ...word, completer }));
callback(null, words);
}
setAutoCompleter(props) {
// Loading table and column names as auto-completable words
// Loading schema, table and column names as auto-completable words
let words = [];
const schemas = props.schemas || [];
schemas.forEach((s) => {
words.push({ name: s.label, value: s.value, score: 60, meta: 'schema' });
});
const columns = {};
const tables = props.tables || [];
const extendedTables = props.extendedTables || [];
tables.forEach((t) => {
words.push({ name: t.name, value: t.name, score: 55, meta: 'table' });
const cols = t.columns || [];
const tableName = t.value.table;
words.push({ name: t.label, value: tableName, score: 55, meta: 'table' });
const extendedTable = extendedTables.find(et => et.name === tableName);
const cols = extendedTable && extendedTable.columns || [];
cols.forEach((col) => {
columns[col.name] = null; // using an object as a unique set
});
Expand Down
4 changes: 3 additions & 1 deletion superset/assets/src/SqlLab/components/SqlEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ class SqlEditor extends React.PureComponent {
onChange={this.onSqlChanged}
queryEditor={this.props.queryEditor}
sql={this.props.queryEditor.sql}
tables={this.props.tables}
schemas={this.props.queryEditor.schemaOptions}
tables={this.props.queryEditor.tableOptions}
extendedTables={this.props.tables}
height={`${aceEditorHeight}px`}
hotkeys={hotkeys}
/>
Expand Down
10 changes: 10 additions & 0 deletions superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,21 @@ export default class SqlEditorLeftBar extends React.PureComponent {
};
this.resetState = this.resetState.bind(this);
this.onSchemaChange = this.onSchemaChange.bind(this);
this.onSchemasLoad = this.onSchemasLoad.bind(this);
this.onTablesLoad = this.onTablesLoad.bind(this);
this.onDbChange = this.onDbChange.bind(this);
this.getDbList = this.getDbList.bind(this);
this.onTableChange = this.onTableChange.bind(this);
}
onSchemaChange(schema) {
this.props.actions.queryEditorSetSchema(this.props.queryEditor, schema);
}
onSchemasLoad(schemas) {
this.props.actions.queryEditorSetSchemaOptions(this.props.queryEditor, schemas);
}
onTablesLoad(tables) {
this.props.actions.queryEditorSetTableOptions(this.props.queryEditor, tables);
}
onDbChange(db) {
this.props.actions.queryEditorSetDb(this.props.queryEditor, db.id);
}
Expand Down Expand Up @@ -105,6 +113,8 @@ export default class SqlEditorLeftBar extends React.PureComponent {
schema={qe.schema}
onDbChange={this.onDbChange}
onSchemaChange={this.onSchemaChange}
onSchemasLoad={this.onSchemasLoad}
onTablesLoad={this.onTablesLoad}
getDbList={this.getDbList}
onTableChange={this.onTableChange}
tableNameSticky={false}
Expand Down
6 changes: 6 additions & 0 deletions superset/assets/src/SqlLab/reducers/sqlLab.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ export default function sqlLabReducer(state = {}, action) {
[actions.QUERY_EDITOR_SET_SCHEMA]() {
return alterInArr(state, 'queryEditors', action.queryEditor, { schema: action.schema });
},
[actions.QUERY_EDITOR_SET_SCHEMA_OPTIONS]() {
return alterInArr(state, 'queryEditors', action.queryEditor, { schemaOptions: action.options });
},
[actions.QUERY_EDITOR_SET_TABLE_OPTIONS]() {
return alterInArr(state, 'queryEditors', action.queryEditor, { tableOptions: action.options });
},
[actions.QUERY_EDITOR_SET_TITLE]() {
return alterInArr(state, 'queryEditors', action.queryEditor, { title: action.title });
},
Expand Down
6 changes: 6 additions & 0 deletions superset/assets/src/components/TableSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const propTypes = {
schema: PropTypes.string,
onSchemaChange: PropTypes.func,
onDbChange: PropTypes.func,
onSchemasLoad: PropTypes.func,
onTablesLoad: PropTypes.func,
getDbList: PropTypes.func,
onTableChange: PropTypes.func,
tableNameSticky: PropTypes.bool,
Expand All @@ -47,6 +49,8 @@ const propTypes = {
const defaultProps = {
onDbChange: () => {},
onSchemaChange: () => {},
onSchemasLoad: () => {},
onTablesLoad: () => {},
getDbList: () => {},
onTableChange: () => {},
onChange: () => {},
Expand Down Expand Up @@ -136,6 +140,7 @@ export default class TableSelector extends React.PureComponent {
title: o.label,
})),
}));
this.props.onTablesLoad(json.options);
})
.catch(() => {
this.setState(() => ({ tableLoading: false, tableOptions: [] }));
Expand All @@ -156,6 +161,7 @@ export default class TableSelector extends React.PureComponent {
.then(({ json }) => {
const schemaOptions = json.schemas.map(s => ({ value: s, label: s, title: s }));
this.setState({ schemaOptions, schemaLoading: false });
this.props.onSchemasLoad(schemaOptions);
})
.catch(() => {
this.setState({ schemaLoading: false, schemaOptions: [] });
Expand Down

0 comments on commit 687f205

Please sign in to comment.