mirror of
https://github.com/apache/superset.git
synced 2026-04-20 08:34:37 +00:00
More improvements to SQL Lab (#1104)
* Handling timeouts * Fixing timer on non-utc server * Allowing async with results * [bugfix] database is not selected * Making sure the session is up and running * Cleaning up query results and query objects * Picking a groupby and metric field on visualize flow * Showing local time in query history * Using pull-left pull-right instead of grid layout for table metdata Long column name were looking weird and icons were wrapping oddly * Linting * Eliminating east buttons under the sql editor * Sort database dropdown by name * Linting * Allowing non-SELECT statements to run * Adding a db config * Making sqla checkout check cross-db
This commit is contained in:
committed by
GitHub
parent
8081080709
commit
e8088d5c9a
@@ -41,7 +41,7 @@ class QueryTable extends React.Component {
|
||||
if (q.endDttm) {
|
||||
q.duration = fDuration(q.startDttm, q.endDttm);
|
||||
}
|
||||
q.started = moment.utc(q.startDttm).format('HH:mm:ss');
|
||||
q.started = moment(q.startDttm).format('HH:mm:ss');
|
||||
const source = (q.ctas) ? q.executedSql : q.sql;
|
||||
q.sql = (
|
||||
<SqlShrink sql={source} />
|
||||
|
||||
@@ -60,7 +60,7 @@ class ResultSet extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (results && results.data.length > 0) {
|
||||
if (results && results.data && results.data.length > 0) {
|
||||
return (
|
||||
<div>
|
||||
<VisualizeModal
|
||||
|
||||
@@ -9,9 +9,7 @@ import {
|
||||
InputGroup,
|
||||
Form,
|
||||
FormControl,
|
||||
DropdownButton,
|
||||
Label,
|
||||
MenuItem,
|
||||
OverlayTrigger,
|
||||
Row,
|
||||
Tooltip,
|
||||
@@ -27,7 +25,6 @@ import { connect } from 'react-redux';
|
||||
import * as Actions from '../actions';
|
||||
|
||||
import shortid from 'shortid';
|
||||
import ButtonWithTooltip from './ButtonWithTooltip';
|
||||
import SouthPane from './SouthPane';
|
||||
import Timer from './Timer';
|
||||
|
||||
@@ -52,8 +49,8 @@ class SqlEditor extends React.Component {
|
||||
this.startQuery();
|
||||
}
|
||||
}
|
||||
runQuery() {
|
||||
this.startQuery();
|
||||
runQuery(runAsync = false) {
|
||||
this.startQuery(runAsync);
|
||||
}
|
||||
startQuery(runAsync = false, ctas = false) {
|
||||
const that = this;
|
||||
@@ -76,10 +73,10 @@ class SqlEditor extends React.Component {
|
||||
|
||||
const sqlJsonUrl = '/caravel/sql_json/';
|
||||
const sqlJsonRequest = {
|
||||
async: runAsync,
|
||||
client_id: query.id,
|
||||
database_id: this.props.queryEditor.dbId,
|
||||
json: true,
|
||||
runAsync,
|
||||
schema: this.props.queryEditor.schema,
|
||||
select_as_cta: ctas,
|
||||
sql: this.props.queryEditor.sql,
|
||||
@@ -149,17 +146,36 @@ class SqlEditor extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let runButtons = (
|
||||
<ButtonGroup bsSize="small" className="inline m-r-5 pull-left">
|
||||
let runButtons = [];
|
||||
if (this.props.database && this.props.database.allow_run_sync) {
|
||||
runButtons.push(
|
||||
<Button
|
||||
bsSize="small"
|
||||
bsStyle="primary"
|
||||
style={{ width: '100px' }}
|
||||
onClick={this.runQuery.bind(this)}
|
||||
onClick={this.runQuery.bind(this, false)}
|
||||
disabled={!(this.props.queryEditor.dbId)}
|
||||
>
|
||||
<i className="fa fa-table" /> Run Query
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
if (this.props.database && this.props.database.allow_run_async) {
|
||||
runButtons.push(
|
||||
<Button
|
||||
bsSize="small"
|
||||
bsStyle="primary"
|
||||
style={{ width: '100px' }}
|
||||
onClick={this.runQuery.bind(this, true)}
|
||||
disabled={!(this.props.queryEditor.dbId)}
|
||||
>
|
||||
<i className="fa fa-table" /> Run Async
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
runButtons = (
|
||||
<ButtonGroup bsSize="small" className="inline m-r-5 pull-left">
|
||||
{runButtons}
|
||||
</ButtonGroup>
|
||||
);
|
||||
if (this.props.latestQuery && this.props.latestQuery.state === 'running') {
|
||||
@@ -176,35 +192,6 @@ class SqlEditor extends React.Component {
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
const rightButtons = (
|
||||
<ButtonGroup className="inlineblock">
|
||||
<ButtonWithTooltip
|
||||
tooltip="Save this query in your workspace"
|
||||
placement="left"
|
||||
bsSize="small"
|
||||
onClick={this.addWorkspaceQuery.bind(this)}
|
||||
>
|
||||
<i className="fa fa-save" />
|
||||
</ButtonWithTooltip>
|
||||
<DropdownButton
|
||||
id="ddbtn-export"
|
||||
pullRight
|
||||
bsSize="small"
|
||||
title={<i className="fa fa-file-o" />}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={this.notImplemented}
|
||||
>
|
||||
<i className="fa fa-file-text-o" /> export to .csv
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={this.notImplemented}
|
||||
>
|
||||
<i className="fa fa-file-code-o" /> export to .json
|
||||
</MenuItem>
|
||||
</DropdownButton>
|
||||
</ButtonGroup>
|
||||
);
|
||||
let limitWarning = null;
|
||||
const rowLimit = 1000;
|
||||
if (this.props.latestQuery && this.props.latestQuery.rows === rowLimit) {
|
||||
@@ -256,7 +243,6 @@ class SqlEditor extends React.Component {
|
||||
<div className="pull-right">
|
||||
{limitWarning}
|
||||
<Timer query={this.props.latestQuery} />
|
||||
{rightButtons}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -77,7 +77,12 @@ class SqlEditorTopToolbar extends React.Component {
|
||||
}
|
||||
fetchDatabaseOptions() {
|
||||
this.setState({ databaseLoading: true });
|
||||
const url = '/databaseasync/api/read?_flt_0_expose_in_sqllab=1';
|
||||
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);
|
||||
|
||||
@@ -63,12 +63,12 @@ class TableElement extends React.Component {
|
||||
metadata = (
|
||||
<div>
|
||||
{this.props.table.columns.map((col) => (
|
||||
<div className="row">
|
||||
<div className="col-sm-8">
|
||||
<div className="m-l-5">{col.name}</div>
|
||||
<div className="clearfix">
|
||||
<div className="pull-left m-l-10">
|
||||
{col.name}
|
||||
</div>
|
||||
<div className="col-sm-4">
|
||||
<div className="pull-right text-muted"><small>{col.type}</small></div>
|
||||
<div className="pull-right text-muted">
|
||||
<small> {col.type}</small>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
@@ -88,11 +88,11 @@ class TableElement extends React.Component {
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div className="row">
|
||||
<div className="col-sm-9 m-b-10">
|
||||
<div className="clearfix">
|
||||
<div className="pull-left">
|
||||
{buttonToggle}
|
||||
</div>
|
||||
<div className="col-sm-3">
|
||||
<div className="pull-right">
|
||||
<ButtonGroup className="ws-el-controls pull-right">
|
||||
<Link
|
||||
className="fa fa-pencil pull-left m-l-2"
|
||||
|
||||
@@ -27,8 +27,8 @@ class Timer extends React.Component {
|
||||
}
|
||||
stopwatch() {
|
||||
if (this.props && this.props.query) {
|
||||
const since = this.props.query.endDttm || now();
|
||||
const clockStr = fDuration(this.props.query.startDttm, since);
|
||||
const endDttm = this.props.query.endDttm || now();
|
||||
const clockStr = fDuration(this.props.query.startDttm, endDttm);
|
||||
this.setState({ clockStr });
|
||||
if (this.props.query.state !== 'running') {
|
||||
this.stopTimer();
|
||||
|
||||
Reference in New Issue
Block a user