);
}
}
+QuerySearch.propTypes = {
+ queries: React.PropTypes.array,
+};
+QuerySearch.defaultProps = {
+ queries: [],
+};
+function mapStateToProps(state) {
+ return {
+ queries: state.queries,
+ };
+}
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators(Actions, dispatch),
+ };
+}
-export default QuerySearch;
+export default connect(mapStateToProps, mapDispatchToProps)(QuerySearch);
diff --git a/caravel/assets/javascripts/SqlLab/components/QueryTable.jsx b/caravel/assets/javascripts/SqlLab/components/QueryTable.jsx
index 0dbe38398e6ec..e9c35ea8c1cdb 100644
--- a/caravel/assets/javascripts/SqlLab/components/QueryTable.jsx
+++ b/caravel/assets/javascripts/SqlLab/components/QueryTable.jsx
@@ -123,7 +123,7 @@ QueryTable.propTypes = {
queries: React.PropTypes.array,
};
QueryTable.defaultProps = {
- columns: ['started', 'duration', 'rows'],
+ columns: ['state', 'started', 'duration', 'progress', 'rows', 'sql', 'actions'],
queries: [],
};
diff --git a/caravel/assets/javascripts/SqlLab/components/SqlEditorLeft.jsx b/caravel/assets/javascripts/SqlLab/components/SqlEditorLeft.jsx
index 25ca82d56cb59..25ea4fd723a02 100644
--- a/caravel/assets/javascripts/SqlLab/components/SqlEditorLeft.jsx
+++ b/caravel/assets/javascripts/SqlLab/components/SqlEditorLeft.jsx
@@ -8,13 +8,14 @@ import shortid from 'shortid';
import Select from 'react-select';
import { Label, Button } from 'react-bootstrap';
import TableElement from './TableElement';
-import DatabaseSelect from './DatabaseSelect';
class SqlEditorTopToolbar extends React.Component {
constructor(props) {
super(props);
this.state = {
+ databaseLoading: false,
+ databaseOptions: [],
schemaLoading: false,
schemaOptions: [],
tableLoading: false,
@@ -22,20 +23,10 @@ class SqlEditorTopToolbar extends React.Component {
};
}
componentWillMount() {
+ this.fetchDatabaseOptions();
this.fetchSchemas();
this.fetchTables();
}
- onChange(db) {
- const val = (db) ? db.value : null;
- this.setState({ schemaOptions: [] });
- this.props.actions.queryEditorSetDb(this.props.queryEditor, val);
- if (!(db)) {
- this.setState({ tableOptions: [] });
- } else {
- this.fetchTables(val, this.props.queryEditor.schema);
- this.fetchSchemas(val);
- }
- }
resetState() {
this.props.actions.resetState();
}
@@ -73,6 +64,37 @@ class SqlEditorTopToolbar extends React.Component {
});
}
}
+ changeDb(db) {
+ const val = (db) ? db.value : null;
+ this.setState({ schemaOptions: [] });
+ this.props.actions.queryEditorSetDb(this.props.queryEditor, val);
+ if (!(db)) {
+ this.setState({ tableOptions: [] });
+ return;
+ }
+ this.fetchTables(val, this.props.queryEditor.schema);
+ this.fetchSchemas(val);
+ }
+ fetchDatabaseOptions() {
+ this.setState({ databaseLoading: true });
+ const url = (
+ '/databaseasync/api/read?' +
+ '_flt_0_expose_in_sqllab=1&' +
+ '_oc_DatabaseAsync=database_name&' +
+ '_od_DatabaseAsync=asc'
+ );
+ $.get(url, (data) => {
+ const options = data.result.map((db) => ({ value: db.id, label: db.database_name }));
+ this.props.actions.setDatabases(data.result);
+ this.setState({ databaseOptions: options });
+ this.setState({ databaseLoading: false });
+
+ // Auto select if only one option
+ if (options.length === 1) {
+ this.changeDb(options[0]);
+ }
+ });
+ }
closePopover(ref) {
this.refs[ref].hide();
}
@@ -114,7 +136,15 @@ class SqlEditorTopToolbar extends React.Component {
{networkAlert}
-
+
+ );
+};
+
+App.propTypes = {
+ alerts: React.PropTypes.array,
+};
+
+function mapStateToProps(state) {
+ return {
+ alerts: state.alerts,
+ };
+}
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators(Actions, dispatch),
+ };
+}
+
+const ReduxedApp = connect(mapStateToProps, mapDispatchToProps)(App);
render(
-
+
,
document.getElementById('app')
);
diff --git a/caravel/assets/javascripts/SqlLab/reducers.js b/caravel/assets/javascripts/SqlLab/reducers.js
index d711d64525c4e..b7a850c982ae8 100644
--- a/caravel/assets/javascripts/SqlLab/reducers.js
+++ b/caravel/assets/javascripts/SqlLab/reducers.js
@@ -13,7 +13,6 @@ const defaultQueryEditor = {
dbId: null,
};
-// TODO(bkyryliuk): document the object schemas
export const initialState = {
alerts: [],
networkOn: true,
diff --git a/caravel/assets/spec/javascripts/sqllab/QuerySearch_spec.jsx b/caravel/assets/spec/javascripts/sqllab/QuerySearch_spec.jsx
deleted file mode 100644
index 076771129aaa7..0000000000000
--- a/caravel/assets/spec/javascripts/sqllab/QuerySearch_spec.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import Select from 'react-select';
-import { Button } from 'react-bootstrap';
-import QuerySearch from '../../../javascripts/SqlLab/components/QuerySearch';
-import { shallow } from 'enzyme';
-import { describe, it } from 'mocha';
-import { expect } from 'chai';
-
-describe('QuerySearch', () => {
- it('should render', () => {
- expect(
- React.isValidElement(
)
- ).to.equal(true);
- });
-
- it('should have two Select', () => {
- const wrapper = shallow(
);
- expect(wrapper.find(Select)).to.have.length(2);
- });
-
- it('should have one input for searchText', () => {
- const wrapper = shallow(
);
- expect(wrapper.find('input')).to.have.length(1);
- });
-
- it('should have one Button', () => {
- const wrapper = shallow(
);
- expect(wrapper.find(Button)).to.have.length(1);
- });
-});
diff --git a/caravel/config.py b/caravel/config.py
index 267a7777333a9..ca378d8cd6187 100644
--- a/caravel/config.py
+++ b/caravel/config.py
@@ -47,9 +47,6 @@
# SQLALCHEMY_DATABASE_URI = 'mysql://myapp@localhost/myapp'
# SQLALCHEMY_DATABASE_URI = 'postgresql://root:password@localhost/myapp'
-# The limit of queries fetched for query search
-QUERY_SEARCH_LIMIT = 1000
-
# Flask-WTF flag for CSRF
CSRF_ENABLED = True
diff --git a/caravel/utils.py b/caravel/utils.py
index 670c0694e02b3..f646a4342365e 100644
--- a/caravel/utils.py
+++ b/caravel/utils.py
@@ -217,7 +217,7 @@ def init(caravel):
'RoleModelView',
'Security',
'UserDBModelView',
- 'SQL Lab',
+ 'SQL Lab
alpha',
'AccessRequestsModelView',
])
diff --git a/caravel/views.py b/caravel/views.py
index 415a03571cf06..78d424523f490 100755
--- a/caravel/views.py
+++ b/caravel/views.py
@@ -1,3 +1,4 @@
+"""Flask web views for Caravel"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1863,41 +1864,6 @@ def queries(self, last_updated_ms):
status=200,
mimetype="application/json")
- @has_access
- @expose("/search_queries")
- @log_this
- def search_queries(self):
- """Search for queries."""
- query = db.session.query(models.Query)
- userId = request.args.get('userId')
- databaseId = request.args.get('databaseId')
- searchText = request.args.get('searchText')
- status = request.args.get('status')
-
- if userId != 'null':
- # Filter on db Id
- query = query.filter(models.Query.user_id == userId)
-
- if databaseId != 'null':
- # Filter on db Id
- query = query.filter(models.Query.database_id == databaseId)
-
- if status != 'null':
- # Filter on status
- query = query.filter(models.Query.status == status)
-
- if searchText != 'null':
- # Filter on search text
- query = query.filter(models.Query.sql.like('%{}%'.format(searchText)))
-
- sql_queries = query.limit(config.get("QUERY_SEARCH_LIMIT")).all()
-
- dict_queries = {q.client_id: q.to_dict() for q in sql_queries}
- return Response(
- json.dumps(dict_queries, default=utils.json_int_dttm_ser),
- status=200,
- mimetype="application/json")
-
@has_access
@expose("/refresh_datasources/")
def refresh_datasources(self):
@@ -1972,15 +1938,9 @@ class CssTemplateModelView(CaravelModelView, DeleteMixin):
category_icon='')
appbuilder.add_link(
- 'SQL Editor',
+ 'SQL Lab
alpha',
href='/caravel/sqllab',
- icon="fa-flask",
- category='SQL Lab')
-appbuilder.add_link(
- 'Query Search',
- href='/caravel/sqllab#search',
- icon="fa-flask",
- category='SQL Lab')
+ icon="fa-flask")
@app.after_request
diff --git a/tests/core_tests.py b/tests/core_tests.py
index af90591e31f7c..bb1ace23a8cd1 100644
--- a/tests/core_tests.py
+++ b/tests/core_tests.py
@@ -69,7 +69,7 @@ def assert_admin_view_menus_in(role_name, assert_func):
assert_func('RoleModelView', view_menus)
assert_func('Security', view_menus)
assert_func('UserDBModelView', view_menus)
- assert_func('SQL Lab',
+ assert_func('SQL Lab
alpha',
view_menus)
assert_func('AccessRequestsModelView', view_menus)
@@ -670,15 +670,6 @@ def test_queries_endpoint(self):
resp = self.client.get('/caravel/queries/{}'.format(0))
self.assertEquals(403, resp.status_code)
- def test_search_query_endpoint(self):
- userId = 'userId=null'
- databaseId = 'databaseId=null'
- searchText = 'searchText=null'
- status = 'status=success'
- params = [userId, databaseId, searchText, status]
- resp = self.client.get('/caravel/search_queries?'+'&'.join(params))
- self.assertEquals(200, resp.status_code)
-
def test_public_user_dashboard_access(self):
# Try access before adding appropriate permissions.
self.revoke_public_access('birth_names')