203 lines
6.2 KiB
JavaScript
203 lines
6.2 KiB
JavaScript
const $ = window.$ = require('jquery');
|
|
import React from 'react';
|
|
|
|
import { bindActionCreators } from 'redux';
|
|
import { connect } from 'react-redux';
|
|
import * as Actions from '../actions';
|
|
import shortid from 'shortid';
|
|
import Select from 'react-select';
|
|
import { Label, Button } from 'react-bootstrap';
|
|
import TableElement from './TableElement';
|
|
|
|
|
|
class SqlEditorTopToolbar extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
databaseLoading: false,
|
|
databaseOptions: [],
|
|
schemaLoading: false,
|
|
schemaOptions: [],
|
|
tableLoading: false,
|
|
tableOptions: [],
|
|
};
|
|
}
|
|
componentWillMount() {
|
|
this.fetchDatabaseOptions();
|
|
this.fetchSchemas();
|
|
this.fetchTables();
|
|
}
|
|
resetState() {
|
|
this.props.actions.resetState();
|
|
}
|
|
fetchTables(dbId, schema) {
|
|
const actualDbId = dbId || this.props.queryEditor.dbId;
|
|
if (actualDbId) {
|
|
const actualSchema = schema || this.props.queryEditor.schema;
|
|
this.setState({ tableLoading: true });
|
|
this.setState({ tableOptions: [] });
|
|
const url = `/caravel/tables/${actualDbId}/${actualSchema}`;
|
|
$.get(url, (data) => {
|
|
let tableOptions = data.tables.map((s) => ({ value: s, label: s }));
|
|
const views = data.views.map((s) => ({ value: s, label: '[view] ' + s }));
|
|
tableOptions = [...tableOptions, ...views];
|
|
this.setState({ tableOptions });
|
|
this.setState({ tableLoading: false });
|
|
});
|
|
}
|
|
}
|
|
changeSchema(schemaOpt) {
|
|
const schema = (schemaOpt) ? schemaOpt.value : null;
|
|
this.props.actions.queryEditorSetSchema(this.props.queryEditor, schema);
|
|
this.fetchTables(this.props.queryEditor.dbId, schema);
|
|
}
|
|
fetchSchemas(dbId) {
|
|
const actualDbId = dbId || this.props.queryEditor.dbId;
|
|
if (actualDbId) {
|
|
this.setState({ schemaLoading: true });
|
|
const url = `/databasetablesasync/api/read?_flt_0_id=${actualDbId}`;
|
|
$.get(url, (data) => {
|
|
const schemas = data.result[0].all_schema_names;
|
|
const schemaOptions = schemas.map((s) => ({ value: s, label: s }));
|
|
this.setState({ schemaOptions });
|
|
this.setState({ schemaLoading: false });
|
|
});
|
|
}
|
|
}
|
|
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';
|
|
$.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();
|
|
}
|
|
changeTable(tableOpt) {
|
|
const tableName = tableOpt.value;
|
|
const qe = this.props.queryEditor;
|
|
const url = `/caravel/table/${qe.dbId}/${tableName}/${qe.schema}/`;
|
|
$.get(url, (data) => {
|
|
this.props.actions.addTable({
|
|
id: shortid.generate(),
|
|
dbId: this.props.queryEditor.dbId,
|
|
queryEditorId: this.props.queryEditor.id,
|
|
name: data.name,
|
|
schema: qe.schema,
|
|
columns: data.columns,
|
|
expanded: true,
|
|
});
|
|
})
|
|
.fail(() => {
|
|
this.props.actions.addAlert({
|
|
msg: 'Error occurred while fetching metadata',
|
|
bsStyle: 'danger',
|
|
});
|
|
});
|
|
}
|
|
render() {
|
|
let networkAlert = null;
|
|
if (!this.props.networkOn) {
|
|
networkAlert = <p><Label bsStyle="danger">OFFLINE</Label></p>;
|
|
}
|
|
const tables = this.props.tables.filter((t) => (t.queryEditorId === this.props.queryEditor.id));
|
|
const shouldShowReset = window.location.search === '?reset=1';
|
|
return (
|
|
<div className="clearfix sql-toolbar">
|
|
{networkAlert}
|
|
<div>
|
|
<Select
|
|
name="select-db"
|
|
placeholder={`Select a database (${this.state.databaseOptions.length})`}
|
|
options={this.state.databaseOptions}
|
|
value={this.props.queryEditor.dbId}
|
|
isLoading={this.state.databaseLoading}
|
|
autosize={false}
|
|
onChange={this.changeDb.bind(this)}
|
|
/>
|
|
</div>
|
|
<div className="m-t-5">
|
|
<Select
|
|
name="select-schema"
|
|
placeholder={`Select a schema (${this.state.schemaOptions.length})`}
|
|
options={this.state.schemaOptions}
|
|
value={this.props.queryEditor.schema}
|
|
isLoading={this.state.schemaLoading}
|
|
autosize={false}
|
|
onChange={this.changeSchema.bind(this)}
|
|
/>
|
|
</div>
|
|
<div className="m-t-5">
|
|
<Select
|
|
name="select-table"
|
|
ref="selectTable"
|
|
isLoading={this.state.tableLoading}
|
|
placeholder={`Add a table (${this.state.tableOptions.length})`}
|
|
autosize={false}
|
|
value={this.state.tableName}
|
|
onChange={this.changeTable.bind(this)}
|
|
options={this.state.tableOptions}
|
|
/>
|
|
</div>
|
|
<hr />
|
|
<div className="m-t-5">
|
|
{tables.map((table) => (
|
|
<TableElement table={table} queryEditor={this.props.queryEditor} />
|
|
))}
|
|
</div>
|
|
{shouldShowReset &&
|
|
<Button bsSize="small" bsStyle="danger" onClick={this.resetState.bind(this)}>
|
|
<i className="fa fa-bomb" /> Reset State
|
|
</Button>
|
|
}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
SqlEditorTopToolbar.propTypes = {
|
|
queryEditor: React.PropTypes.object,
|
|
tables: React.PropTypes.array,
|
|
actions: React.PropTypes.object,
|
|
networkOn: React.PropTypes.bool,
|
|
};
|
|
|
|
SqlEditorTopToolbar.defaultProps = {
|
|
tables: [],
|
|
};
|
|
|
|
function mapStateToProps(state) {
|
|
return {
|
|
tables: state.tables,
|
|
networkOn: state.networkOn,
|
|
};
|
|
}
|
|
|
|
function mapDispatchToProps(dispatch) {
|
|
return {
|
|
actions: bindActionCreators(Actions, dispatch),
|
|
};
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(SqlEditorTopToolbar);
|