[SQL Lab] moving the db/schema/table select to the left (#1038)

This commit is contained in:
Maxime Beauchemin 2016-08-30 11:08:41 -07:00 committed by GitHub
parent fc1e63761c
commit 561828c2f8
10 changed files with 98 additions and 152 deletions

View File

@ -5,8 +5,6 @@ import { bindActionCreators } from 'redux';
import * as Actions from '../actions';
import QueryLink from './QueryLink';
import 'react-select/dist/react-select.css';
const LeftPane = (props) => {
let queryElements;
if (props.workspaceQueries.length > 0) {

View File

@ -5,9 +5,6 @@ import { bindActionCreators } from 'redux';
import * as Actions from '../actions';
import shortid from 'shortid';
// CSS
import 'react-select/dist/react-select.css';
class QueryLink extends React.Component {
popTab() {
const qe = {

View File

@ -1,4 +1,4 @@
import { Alert, Panel, Tab, Tabs } from 'react-bootstrap';
import { Alert, Tab, Tabs } from 'react-bootstrap';
import QueryHistory from './QueryHistory';
import ResultSet from './ResultSet';
import React from 'react';
@ -21,16 +21,12 @@ const SouthPane = function (props) {
return (
<Tabs bsStyle="tabs">
<Tab title="Results" eventKey={1}>
<Panel>
<div style={{ overflow: 'auto' }}>
{results}
</div>
</Panel>
<div style={{ overflow: 'auto' }}>
{results}
</div>
</Tab>
<Tab title="Query History" eventKey={2}>
<Panel>
<QueryHistory />
</Panel>
<QueryHistory />
</Tab>
</Tabs>
);

View File

@ -4,6 +4,7 @@ import React from 'react';
import {
Button,
ButtonGroup,
Col,
FormGroup,
InputGroup,
Form,
@ -12,6 +13,7 @@ import {
Label,
MenuItem,
OverlayTrigger,
Row,
Tooltip,
} from 'react-bootstrap';
@ -29,10 +31,7 @@ import ButtonWithTooltip from './ButtonWithTooltip';
import SouthPane from './SouthPane';
import Timer from './Timer';
import SqlEditorTopToolbar from './SqlEditorTopToolbar';
// CSS
import 'react-select/dist/react-select.css';
import SqlEditorLeft from './SqlEditorLeft';
class SqlEditor extends React.Component {
constructor(props) {
@ -246,23 +245,29 @@ class SqlEditor extends React.Component {
<div className="SqlEditor">
<div>
<div>
<SqlEditorTopToolbar queryEditor={this.props.queryEditor} />
<AceEditor
mode="sql"
name={this.props.queryEditor.id}
theme="github"
minLines={5}
maxLines={30}
onChange={this.textChange.bind(this)}
height="200px"
width="100%"
editorProps={{ $blockScrolling: true }}
enableBasicAutocompletion
value={this.props.queryEditor.sql}
/>
{editorBottomBar}
<br />
<SouthPane latestQuery={this.props.latestQuery} sqlEditor={this} />
<Row>
<Col md={3}>
<SqlEditorLeft queryEditor={this.props.queryEditor} />
</Col>
<Col md={9}>
<AceEditor
mode="sql"
name={this.props.queryEditor.id}
theme="github"
minLines={5}
maxLines={30}
onChange={this.textChange.bind(this)}
height="200px"
width="100%"
editorProps={{ $blockScrolling: true }}
enableBasicAutocompletion
value={this.props.queryEditor.sql}
/>
{editorBottomBar}
<br />
<SouthPane latestQuery={this.props.latestQuery} sqlEditor={this} />
</Col>
</Row>
</div>
</div>
</div>

View File

@ -1,16 +1,13 @@
const $ = window.$ = require('jquery');
import React from 'react';
import { Label, OverlayTrigger, Popover } from 'react-bootstrap';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as Actions from '../actions';
import shortid from 'shortid';
import Select from 'react-select';
import Link from './Link';
import TableElement from './TableElement';
// CSS
import 'react-select/dist/react-select.css';
class SqlEditorTopToolbar extends React.Component {
constructor(props) {
@ -123,7 +120,6 @@ class SqlEditorTopToolbar extends React.Component {
schema: qe.schema,
columns: data.columns,
expanded: true,
showPopup: true,
});
})
.fail(() => {
@ -135,76 +131,9 @@ class SqlEditorTopToolbar extends React.Component {
}
render() {
const tables = this.props.tables.filter((t) => (t.queryEditorId === this.props.queryEditor.id));
const tablesEls = tables.map((table) => {
let cols = [];
if (table.columns) {
cols = table.columns.map((col) => (
<div className="clearfix">
<div className="pull-left m-r-10">{col.name}</div>
<div className="pull-right text-muted"> {col.type}</div>
</div>
));
}
const popoverId = 'tblPopover_' + table.name;
const popoverTop = (
<div className="clearfix">
<div className="pull-left">
<Link
className="fa fa-pencil"
onClick={this.selectStar.bind(this, table)}
tooltip="Overwrite text in editor with a query on this table"
placement="left"
href="#"
/>
<Link
className="fa fa-plus-circle"
onClick={this.popTab.bind(this, table)}
tooltip="Run query in a new tab"
placement="left"
href="#"
/>
</div>
<div className="pull-right">
<Link
className="fa fa-close"
onClick={this.closePopover.bind(this, popoverId)}
href="#"
/>
</div>
</div>
);
const popover = (
<Popover
id={popoverId}
className="tablePopover"
title={popoverTop}
>
{cols}
</Popover>
);
return (
<Label className="m-r-5 table-label" style={{ fontSize: '100%' }}>
<OverlayTrigger
trigger="click"
placement="bottom"
overlay={popover}
ref={popoverId}
>
<span className="m-r-5" style={{ cursor: 'pointer' }}>
{table.name}
</span>
</OverlayTrigger>
<i
className="fa fa-close"
style={{ cursor: 'pointer' }}
onClick={this.props.actions.removeTable.bind(this, table)}
/>
</Label>
);
});
return (
<div className="clearfix sql-toolbar">
<div className="pull-left m-r-5">
<div>
<Select
name="select-db"
placeholder="[Database]"
@ -215,7 +144,7 @@ class SqlEditorTopToolbar extends React.Component {
onChange={this.changeDb.bind(this)}
/>
</div>
<div className="pull-left m-r-5">
<div className="m-t-5">
<Select
name="select-schema"
placeholder="[Schema]"
@ -226,7 +155,7 @@ class SqlEditorTopToolbar extends React.Component {
onChange={this.changeSchema.bind(this)}
/>
</div>
<div className="pull-left m-r-5">
<div className="m-t-5">
<Select
name="select-table"
ref="selectTable"
@ -238,8 +167,9 @@ class SqlEditorTopToolbar extends React.Component {
options={this.state.tableOptions}
/>
</div>
<div className="pull-left m-r-5">
{tablesEls}
<hr />
<div className="m-t-5">
{tables.map((table) => <TableElement table={table} />)}
</div>
</div>
);

View File

@ -6,10 +6,7 @@ import { bindActionCreators } from 'redux';
import * as Actions from '../actions';
import shortid from 'shortid';
// CSS
import 'react-select/dist/react-select.css';
class TableWorkspaceElement extends React.Component {
class TableElement extends React.Component {
selectStar() {
let cols = '';
this.props.table.columns.forEach((col, i) => {
@ -31,35 +28,37 @@ class TableWorkspaceElement extends React.Component {
render() {
let metadata = null;
let buttonToggle;
if (!this.props.table.expanded) {
buttonToggle = (
<Link
href="#"
onClick={this.props.actions.expandTable.bind(this, this.props.table)}
placement="right"
tooltip="Collapse the table's structure information"
>
<i className="fa fa-minus" /> {this.props.table.name}
</Link>
);
metadata = this.props.table.columns.map((col) =>
<div className="clearfix">
<span className="pull-left">{col.name}</span>
<span className="pull-right">{col.type}</span>
</div>
);
metadata = (
<div style={{ 'margin-bottom': '5px' }}>{metadata}</div>
);
} else {
if (this.props.table.expanded) {
buttonToggle = (
<Link
href="#"
onClick={this.props.actions.collapseTable.bind(this, this.props.table)}
placement="right"
tooltip="Collapse the table's structure information"
>
{this.props.table.name} <i className="fa fa-caret-up" />
</Link>
);
metadata = (
<div>
{this.props.table.columns.map((col) => (
<div className="clearfix">
<span className="pull-left m-l-5">{col.name}</span>
<span className="pull-right">{col.type}</span>
</div>
))}
<hr />
</div>
);
} else {
buttonToggle = (
<Link
href="#"
onClick={this.props.actions.expandTable.bind(this, this.props.table)}
placement="right"
tooltip="Expand the table's structure information"
>
<i className="fa fa-plus" /> {this.props.table.name}
{this.props.table.name} <i className="fa fa-caret-down" />
</Link>
);
}
@ -68,13 +67,19 @@ class TableWorkspaceElement extends React.Component {
{buttonToggle}
<ButtonGroup className="ws-el-controls pull-right">
<Link
className="fa fa-play"
className="fa fa-pencil m-l-2"
onClick={this.selectStar.bind(this)}
tooltip="Run query in a new tab"
href="#"
/>
<Link
className="fa fa-trash"
className="fa fa-plus-circle m-l-2"
onClick={this.selectStar.bind(this)}
tooltip="Run query in a new tab"
href="#"
/>
<Link
className="fa fa-trash m-l-2"
onClick={this.props.actions.removeTable.bind(this, this.props.table)}
tooltip="Remove from workspace"
href="#"
@ -85,11 +90,11 @@ class TableWorkspaceElement extends React.Component {
);
}
}
TableWorkspaceElement.propTypes = {
TableElement.propTypes = {
table: React.PropTypes.object,
actions: React.PropTypes.object,
};
TableWorkspaceElement.defaultProps = {
TableElement.defaultProps = {
table: null,
};
@ -98,5 +103,4 @@ function mapDispatchToProps(dispatch) {
actions: bindActionCreators(Actions, dispatch),
};
}
export default connect(null, mapDispatchToProps)(TableWorkspaceElement);
export default connect(null, mapDispatchToProps)(TableElement);

View File

@ -6,7 +6,6 @@ import React from 'react';
import { render } from 'react-dom';
import * as Actions from './actions';
import LeftPane from './components/LeftPane';
import TabbedSqlEditors from './components/TabbedSqlEditors';
import QueryAutoRefresh from './components/QueryAutoRefresh';
import Alerts from './components/Alerts';
@ -37,12 +36,9 @@ const App = function (props) {
<QueryAutoRefresh />
<Alerts alerts={props.alerts} />
<div className="row">
<div className="col-md-9">
<div className="col-md-12">
<TabbedSqlEditors />
</div>
<div className="col-md-3">
<LeftPane />
</div>
</div>
</div>
</div>

View File

@ -72,9 +72,18 @@ div.Workspace {
.m-l-1 {
margin-left: 1px;
}
.m-l-2 {
margin-left: 2px;
}
.m-r-10 {
margin-right: 10px;
}
.m-l-10 {
margin-left: 10px;
}
.m-l-5 {
margin-left: 5px;
}
.m-b-10 {
margin-bottom: 10px;
}
@ -132,7 +141,9 @@ div.Workspace {
max-height: 600px;
box-shadow: rgba(0, 0, 0, 0.8) 5px 5px 25px
}
.SqlLab {
font-size: 12px;
}
.SqlLab pre {
padding: 0px !important;
margin: 0px;
@ -217,7 +228,7 @@ div.tablePopover:hover {
.ace_editor {
border: 1px solid #ccc;
margin: 10px 0;
margin: 0px 0px 10px 0px;
}
.Select-menu-outer {
@ -227,3 +238,11 @@ div.tablePopover:hover {
.ace_content {
background-color: #f4f4f4;
}
.ws-el > .ws-el-controls {
opacity: 0;
transition: visibility 0s, opacity 0.3s linear;
}
.ws-el:hover > .ws-el-controls {
opacity: 1;
transition: visibility 0s, opacity 0.3s linear;
}

View File

@ -1 +1,2 @@
require('../stylesheets/less/index.less');
require('../stylesheets/react-select/select.less');

View File

@ -22,7 +22,7 @@
@select-input-border-radius: 4px;
@select-input-border-focus: @select-primary-color;
@select-input-border-width: 1px;
@select-input-height: 36px;
@select-input-height: 30px;
@select-input-internal-height: (@select-input-height - (@select-input-border-width * 2));
@select-input-placeholder: #aaa;
@select-text-color: #333;