UI tweaks for the query history.
parent
1291841d98
commit
e2cbaaef71
|
@ -10,44 +10,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Shapes from '../../react_shapes';
|
import Shapes from '../../react_shapes';
|
||||||
import NonSelectableElementStyle from '../../styles/non_selectable';
|
|
||||||
import MessageHeaderStyle from '../../styles/header_label';
|
|
||||||
|
|
||||||
const containerStyle = {
|
|
||||||
flex: '2 2 0%',
|
|
||||||
flexDirection: 'column',
|
|
||||||
display: 'flex',
|
|
||||||
};
|
|
||||||
|
|
||||||
const messageContainerStyle = {
|
|
||||||
flex: '0 1 auto',
|
|
||||||
overflow: 'auto',
|
|
||||||
position: 'relative',
|
|
||||||
height: '100%',
|
|
||||||
};
|
|
||||||
|
|
||||||
const errorMessageStyle = {
|
|
||||||
border: '0',
|
|
||||||
paddingLeft: '0',
|
|
||||||
backgroundColor: '#ffffff',
|
|
||||||
fontSize: '13px',
|
|
||||||
position: 'absolute',
|
|
||||||
};
|
|
||||||
|
|
||||||
const messageLabelStyle = _.extend({flex: '0 0 auto'},
|
|
||||||
MessageHeaderStyle,
|
|
||||||
NonSelectableElementStyle);
|
|
||||||
|
|
||||||
export default class HistoryDetailMessage extends React.Component {
|
export default class HistoryDetailMessage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={containerStyle}>
|
<div className='message'>
|
||||||
<div style={messageLabelStyle}>
|
<div className='message-header'>
|
||||||
Messages
|
Messages
|
||||||
</div>
|
</div>
|
||||||
<div style={messageContainerStyle}>
|
<div className='content'>
|
||||||
<pre style={errorMessageStyle}>
|
<pre className='content-value'>
|
||||||
{this.props.historyEntry.message}
|
{this.props.historyEntry.message}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,18 +10,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import Shapes from '../../react_shapes';
|
import Shapes from '../../react_shapes';
|
||||||
import HeaderDescriptionStyle from '../../styles/header_label';
|
|
||||||
|
|
||||||
const queryMetaDataStyle = {
|
|
||||||
flex: 1,
|
|
||||||
};
|
|
||||||
const headerStyle = {
|
|
||||||
display: 'flex',
|
|
||||||
};
|
|
||||||
const headerValueStyle = {
|
|
||||||
display: 'block',
|
|
||||||
fontSize: '14px',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class HistoryDetailMetadata extends React.Component {
|
export default class HistoryDetailMetadata extends React.Component {
|
||||||
|
|
||||||
|
@ -30,18 +18,18 @@ export default class HistoryDetailMetadata extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
queryMetaData(data, description) {
|
queryMetaData(data, description) {
|
||||||
return <div style={queryMetaDataStyle}>
|
return <div className='item'>
|
||||||
<span style={headerValueStyle}>
|
<span className='value'>
|
||||||
{data}
|
{data}
|
||||||
</span>
|
</span>
|
||||||
<span style={HeaderDescriptionStyle}>
|
<span className='description'>
|
||||||
{description}
|
{description}
|
||||||
</span>
|
</span>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div style={headerStyle}>
|
return <div className='metadata'>
|
||||||
{this.queryMetaData(this.formatDate(this.props.historyEntry.start_time), 'Date')}
|
{this.queryMetaData(this.formatDate(this.props.historyEntry.start_time), 'Date')}
|
||||||
{this.queryMetaData(this.props.historyEntry.row_affected.toLocaleString(), 'Rows Affected')}
|
{this.queryMetaData(this.props.historyEntry.row_affected.toLocaleString(), 'Rows Affected')}
|
||||||
{this.queryMetaData(this.props.historyEntry.total_time, 'Duration')}
|
{this.queryMetaData(this.props.historyEntry.total_time, 'Duration')}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
/////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
import QueryHistoryVanillaEntry from './query_history_vanilla_entry';
|
|
||||||
import update from 'immutability-helper';
|
|
||||||
import {errorStyle} from '../../styles/history_entry_styles';
|
|
||||||
|
|
||||||
export default class QueryHistoryErrorEntry extends QueryHistoryVanillaEntry {
|
|
||||||
componentWillMount() {
|
|
||||||
this.setState({
|
|
||||||
outerDivStyle: update(this.state.outerDivStyle, {$merge: errorStyle}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
import QueryHistoryVanillaEntry from './query_history_vanilla_entry';
|
|
||||||
import update from 'immutability-helper';
|
|
||||||
import {selectedFontStyle, selectedOuterStyle} from '../../styles/history_entry_styles';
|
|
||||||
|
|
||||||
export default class QueryHistorySelectedEntry extends QueryHistoryVanillaEntry {
|
|
||||||
componentWillMount() {
|
|
||||||
this.setState({
|
|
||||||
outerDivStyle: update(this.state.outerDivStyle, {$merge: selectedOuterStyle}),
|
|
||||||
secondLineStyle: update(this.state.secondLineStyle, {$merge: selectedFontStyle}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
/////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
import QueryHistoryVanillaEntry from './query_history_vanilla_entry';
|
|
||||||
import update from 'immutability-helper';
|
|
||||||
import {selectedFontStyle, selectedOuterStyle, selectedErrorBgColor} from '../../styles/history_entry_styles';
|
|
||||||
|
|
||||||
export default class QueryHistorySelectedErrorEntry extends QueryHistoryVanillaEntry {
|
|
||||||
componentWillMount() {
|
|
||||||
let selectedErrorStyle = update(selectedOuterStyle, {$merge: selectedErrorBgColor});
|
|
||||||
this.setState({
|
|
||||||
outerDivStyle: update(this.state.outerDivStyle, {$merge: selectedErrorStyle}),
|
|
||||||
secondLineStyle: update(this.state.secondLineStyle, {$merge: selectedFontStyle}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
/////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import moment from 'moment';
|
|
||||||
import Shapes from '../../react_shapes';
|
|
||||||
import {plainOuterDivStyle, plainSecondLineStyle, sqlStyle, timestampStyle} from '../../styles/history_entry_styles';
|
|
||||||
|
|
||||||
export default class QueryHistoryVanillaEntry extends React.Component {
|
|
||||||
formatDate(date) {
|
|
||||||
return (moment(date).format('MMM D YYYY [–] HH:mm:ss'));
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
outerDivStyle: plainOuterDivStyle,
|
|
||||||
secondLineStyle: plainSecondLineStyle,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div style={this.state.outerDivStyle}>
|
|
||||||
<div style={sqlStyle}>
|
|
||||||
{this.props.historyEntry.query}
|
|
||||||
</div>
|
|
||||||
<div style={this.state.secondLineStyle}>
|
|
||||||
<div style={timestampStyle}>
|
|
||||||
{this.formatDate(this.props.historyEntry.start_time)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryHistoryVanillaEntry.propTypes = {
|
|
||||||
historyEntry: Shapes.historyDetail,
|
|
||||||
isSelected: React.PropTypes.bool,
|
|
||||||
};
|
|
|
@ -19,9 +19,6 @@ const queryEntryListDivStyle = {
|
||||||
const queryDetailDivStyle = {
|
const queryDetailDivStyle = {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
};
|
};
|
||||||
const liStyle = {
|
|
||||||
borderBottom: '1px solid #cccccc',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class QueryHistory extends React.Component {
|
export default class QueryHistory extends React.Component {
|
||||||
|
|
||||||
|
@ -75,11 +72,11 @@ export default class QueryHistory extends React.Component {
|
||||||
return (
|
return (
|
||||||
<SplitPane defaultSize="50%" split="vertical" pane1Style={queryEntryListDivStyle}
|
<SplitPane defaultSize="50%" split="vertical" pane1Style={queryEntryListDivStyle}
|
||||||
pane2Style={queryDetailDivStyle}>
|
pane2Style={queryDetailDivStyle}>
|
||||||
<div id='query_list'>
|
<div id='query_list' className="query-history">
|
||||||
<ul>
|
<ul>
|
||||||
{this.retrieveOrderedHistory()
|
{this.retrieveOrderedHistory()
|
||||||
.map((entry, index) =>
|
.map((entry, index) =>
|
||||||
<li key={index} style={liStyle} onClick={this.onClickHandler.bind(this, index)}>
|
<li key={index} className='list-item' onClick={this.onClickHandler.bind(this, index)}>
|
||||||
<QueryHistoryEntry historyEntry={entry} isSelected={index == this.state.selectedEntry}/>
|
<QueryHistoryEntry historyEntry={entry} isSelected={index == this.state.selectedEntry}/>
|
||||||
</li>)
|
</li>)
|
||||||
.value()
|
.value()
|
||||||
|
|
|
@ -13,54 +13,22 @@ import HistoryDetailQuery from './detail/history_detail_query';
|
||||||
import HistoryDetailMessage from './detail/history_detail_message';
|
import HistoryDetailMessage from './detail/history_detail_message';
|
||||||
import Shapes from '../react_shapes';
|
import Shapes from '../react_shapes';
|
||||||
|
|
||||||
const outerStyle = {
|
|
||||||
width: '100%',
|
|
||||||
paddingTop: '10px',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
};
|
|
||||||
|
|
||||||
const detailVerticalTop = {
|
|
||||||
flex: 1,
|
|
||||||
padding: '0 10px',
|
|
||||||
};
|
|
||||||
|
|
||||||
const detailVerticalMiddle = {
|
|
||||||
flex: 5,
|
|
||||||
marginLeft: '10px',
|
|
||||||
marginRight: '10px',
|
|
||||||
height: 0,
|
|
||||||
position: 'relative',
|
|
||||||
};
|
|
||||||
|
|
||||||
const hrStyle = {
|
|
||||||
borderColor: '#cccccc',
|
|
||||||
marginTop: '11px',
|
|
||||||
marginBottom: '8px',
|
|
||||||
};
|
|
||||||
|
|
||||||
const detailVerticalBottom = {
|
|
||||||
flex: 2,
|
|
||||||
display: 'flex',
|
|
||||||
paddingLeft: '10px',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class QueryHistoryDetail extends React.Component {
|
export default class QueryHistoryDetail extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!_.isUndefined(this.props.historyEntry)) {
|
if (!_.isUndefined(this.props.historyEntry)) {
|
||||||
return (
|
return (
|
||||||
<div id='query_detail' style={outerStyle}>
|
<div id='query_detail' className='query-detail'>
|
||||||
<div style={detailVerticalTop}>
|
<div className='metadata-block'>
|
||||||
<HistoryDetailMetadata {...this.props} />
|
<HistoryDetailMetadata {...this.props} />
|
||||||
</div>
|
</div>
|
||||||
<div style={detailVerticalMiddle}>
|
<div className='query-statement-block'>
|
||||||
<HistoryDetailQuery {...this.props}/>
|
<HistoryDetailQuery {...this.props}/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<hr style={hrStyle}/>
|
<hr className='block-divider'/>
|
||||||
</div>
|
</div>
|
||||||
<div style={detailVerticalBottom}>
|
<div className='message-block'>
|
||||||
<HistoryDetailMessage {...this.props}/>
|
<HistoryDetailMessage {...this.props}/>
|
||||||
</div>
|
</div>
|
||||||
</div>);
|
</div>);
|
||||||
|
|
|
@ -9,24 +9,40 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Shapes from '../react_shapes';
|
import Shapes from '../react_shapes';
|
||||||
import QueryHistoryErrorEntry from './entry/query_history_error_entry';
|
import moment from 'moment';
|
||||||
import QueryHistorySelectedErrorEntry from './entry/query_history_selected_error_entry';
|
|
||||||
import QueryHistorySelectedEntry from './entry/query_history_selected_entry';
|
|
||||||
import QueryHistoryVanillaEntry from './entry/query_history_vanilla_entry';
|
|
||||||
|
|
||||||
export default class QueryHistoryEntry extends React.Component {
|
export default class QueryHistoryEntry extends React.Component {
|
||||||
|
formatDate(date) {
|
||||||
|
return (moment(date).format('MMM D YYYY [–] HH:mm:ss'));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderWithClasses(outerDivStyle) {
|
||||||
|
return (
|
||||||
|
<div className={'entry ' + outerDivStyle}>
|
||||||
|
<div className='query'>
|
||||||
|
{this.props.historyEntry.query}
|
||||||
|
</div>
|
||||||
|
<div className='other-info'>
|
||||||
|
<div className='timestamp'>
|
||||||
|
{this.formatDate(this.props.historyEntry.start_time)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.hasError()) {
|
if (this.hasError()) {
|
||||||
if (this.props.isSelected) {
|
if (this.props.isSelected) {
|
||||||
return <QueryHistorySelectedErrorEntry {...this.props}/>;
|
return this.renderWithClasses('error selected');
|
||||||
} else {
|
} else {
|
||||||
return <QueryHistoryErrorEntry {...this.props}/>;
|
return this.renderWithClasses('error');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.props.isSelected) {
|
if (this.props.isSelected) {
|
||||||
return <QueryHistorySelectedEntry {...this.props}/>;
|
return this.renderWithClasses('selected');
|
||||||
} else {
|
} else {
|
||||||
return <QueryHistoryVanillaEntry {...this.props}/>;
|
return this.renderWithClasses('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
export default {
|
|
||||||
display: 'block',
|
|
||||||
fontSize: '12px',
|
|
||||||
color: '#888888',
|
|
||||||
};
|
|
|
@ -1,57 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
import update from 'immutability-helper';
|
|
||||||
|
|
||||||
export const plainOuterDivStyle = {
|
|
||||||
paddingLeft: '8px',
|
|
||||||
paddingRight: '18px',
|
|
||||||
paddingTop: '-2px',
|
|
||||||
paddingBottom: '-2px',
|
|
||||||
fontFamily: 'monospace',
|
|
||||||
fontSize: '14px',
|
|
||||||
backgroundColor: '#FFF',
|
|
||||||
border: '2px solid transparent',
|
|
||||||
marginLeft: '1px',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sqlStyle = {
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
overflow: 'hidden',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
userSelect: 'auto',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const plainSecondLineStyle = {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
fontSize: '13px',
|
|
||||||
color: '#888888',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const timestampStyle = {
|
|
||||||
alignSelf: 'flex-start',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const selectedFontStyle = {
|
|
||||||
color: '#2c76b4',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const selectedOuterStyle = update(selectedFontStyle, {
|
|
||||||
$merge: {
|
|
||||||
border: '2px solid #2c76b4',
|
|
||||||
backgroundColor: '#e7f2ff',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const errorStyle = {backgroundColor: '#F7D0D5'};
|
|
||||||
|
|
||||||
export const selectedErrorBgColor = {backgroundColor: '#DCC4D1'};
|
|
|
@ -1,18 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
export default {
|
|
||||||
WebkitTouchCallout: 'none',
|
|
||||||
WebkitUserSelect: 'none',
|
|
||||||
KhtmlUserSelect: 'none',
|
|
||||||
MozUserSelect: 'none',
|
|
||||||
msUserSelect: 'none',
|
|
||||||
userSelect: 'none',
|
|
||||||
cursor: 'default',
|
|
||||||
};
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*doc
|
||||||
|
---
|
||||||
|
title: Grays
|
||||||
|
name: Grays
|
||||||
|
category: colors
|
||||||
|
---
|
||||||
|
For text, avoid using black or #000 to lower the contrast between the background and text.
|
||||||
|
|
||||||
|
```html_example
|
||||||
|
<div class="row">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-6 col-md-3">
|
||||||
|
<div class="color-chip bg-gray-1">
|
||||||
|
#f9f9f9
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6 col-md-3">
|
||||||
|
<div class="color-chip bg-gray-2">
|
||||||
|
#e8e8e8
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6 col-md-3">
|
||||||
|
<div class="color-chip bg-gray-3">
|
||||||
|
#cccccc
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6 col-md-3">
|
||||||
|
<div class="color-chip bg-gray-4">
|
||||||
|
#888888
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6 col-md-3">
|
||||||
|
<div class="color-chip bg-gray-5 font-white">
|
||||||
|
#555555
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6 col-md-3">
|
||||||
|
<div class="color-chip bg-gray-6 font-white">
|
||||||
|
#333333
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.color-chip {
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: inset 0 -3px 0 0 rgba(0, 0, 0, .15);
|
||||||
|
color: rgba(0, 0, 0, .65);
|
||||||
|
display: flex;
|
||||||
|
font-size: 1.25em;
|
||||||
|
height: 100px;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 0 1em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
$color-gray-1: #f9f9f9;
|
||||||
|
$color-gray-2: #e8e8e8;
|
||||||
|
$color-gray-3: #cccccc;
|
||||||
|
$color-gray-4: #888888;
|
||||||
|
$color-gray-5: #555555;
|
||||||
|
$color-gray-6: #333333;
|
||||||
|
|
||||||
|
.bg-gray-1 {
|
||||||
|
background-color: $color-gray-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-2 {
|
||||||
|
background-color: $color-gray-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-3 {
|
||||||
|
background-color: $color-gray-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-4 {
|
||||||
|
background-color: $color-gray-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-5 {
|
||||||
|
background-color: $color-gray-5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-6 {
|
||||||
|
background-color: $color-gray-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-1 {
|
||||||
|
border-color: $color-gray-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-2 {
|
||||||
|
border-color: $color-gray-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-3 {
|
||||||
|
border-color: $color-gray-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-4 {
|
||||||
|
border-color: $color-gray-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-5 {
|
||||||
|
border-color: $color-gray-5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-6 {
|
||||||
|
border-color: $color-gray-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-gray-4 {
|
||||||
|
color: $color-gray-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-gray-6 {
|
||||||
|
color: $color-gray-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-white {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
|
@ -79,6 +79,10 @@ These colors should be used to highlight hover options in dropdown menus and cat
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-white-1 {
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
.bg-blue-1 {
|
.bg-blue-1 {
|
||||||
background-color: #e7f2ff;
|
background-color: #e7f2ff;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*doc
|
||||||
|
---
|
||||||
|
title: Primary blue
|
||||||
|
name: colors-primaryblue
|
||||||
|
category: colors
|
||||||
|
---
|
||||||
|
This color should be used to call attention to the main part of the app. Use sparingly.
|
||||||
|
|
||||||
|
```html_example
|
||||||
|
<div class="row">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-6 col-md-3">
|
||||||
|
<div class="color-chip bg-primary-blue font-white">
|
||||||
|
#2c76b4
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.color-chip {
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: inset 0 -3px 0 0 rgba(0, 0, 0, .15);
|
||||||
|
color: rgba(0, 0, 0, .65);
|
||||||
|
display: flex;
|
||||||
|
font-size: 1.25em;
|
||||||
|
height: 100px;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 0 1em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
$primary-blue: #2c76b4;
|
||||||
|
|
||||||
|
.bg-primary-blue {
|
||||||
|
background-color: $primary-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-primary-blue {
|
||||||
|
border-color: $primary-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-primary-blue {
|
||||||
|
color: $primary-blue;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
.not-selectable {
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
|
@ -1,6 +1,12 @@
|
||||||
$enable-flex: false;
|
$enable-flex: false;
|
||||||
|
|
||||||
@import 'alert';
|
@import 'alert';
|
||||||
|
@import 'primaryblue';
|
||||||
|
@import 'colorsgrey';
|
||||||
@import 'othercolors';
|
@import 'othercolors';
|
||||||
@import 'typography';
|
@import 'typography';
|
||||||
|
|
||||||
|
@import 'utils';
|
||||||
|
|
||||||
@import 'alertify.overrides';
|
@import 'alertify.overrides';
|
||||||
|
@import 'sqleditor/history';
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
.query-history {
|
||||||
|
.list-item {
|
||||||
|
border-bottom: 1px solid $color-gray-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
@extend .text-14;
|
||||||
|
@extend .bg-white-1;
|
||||||
|
padding: -2px 18px -2px 8px;
|
||||||
|
font-family: monospace;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
margin-left: 1px;
|
||||||
|
|
||||||
|
.other-info{
|
||||||
|
@extend .text-13;
|
||||||
|
@extend .font-gray-4;
|
||||||
|
font-family: monospace;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.timestamp {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.query {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
user-select: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry.error {
|
||||||
|
@extend .bg-red-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry.selected.error {
|
||||||
|
background-color: #d7d0d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry.selected {
|
||||||
|
@extend .font-primary-blue;
|
||||||
|
@extend .border-primary-blue;
|
||||||
|
@extend .bg-blue-1;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 2px solid;
|
||||||
|
|
||||||
|
.other-info{
|
||||||
|
@extend .font-primary-blue;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-label {
|
||||||
|
@extend .text-12;
|
||||||
|
@extend .font-gray-4;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.query-detail {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.metadata-block {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
.metadata {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.value {
|
||||||
|
@extend .text-14;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@extend .header-label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.query-statement-block {
|
||||||
|
flex: 5;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
height: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-divider {
|
||||||
|
@extend .border-gray-3;
|
||||||
|
margin-top: 11px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-block {
|
||||||
|
flex: 2;
|
||||||
|
display: flex;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
.message {
|
||||||
|
flex: 2 2 0%;
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
@extend .header-label;
|
||||||
|
@extend .not-selectable;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
overflow: auto;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.content-value {
|
||||||
|
@extend .bg-white-1;
|
||||||
|
@extend .text-13;
|
||||||
|
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||||
|
border: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -118,6 +118,7 @@
|
||||||
.sql-editor-history-container {
|
.sql-editor-history-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
border-top: 1px solid #cccccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sql-status-cell {
|
.sql-status-cell {
|
||||||
|
|
|
@ -94,12 +94,13 @@ describe('QueryHistory', () => {
|
||||||
|
|
||||||
it('renders the most recent query as selected', () => {
|
it('renders the most recent query as selected', () => {
|
||||||
expect(foundChildren.at(0).nodes.length).toBe(1);
|
expect(foundChildren.at(0).nodes.length).toBe(1);
|
||||||
expect(foundChildren.at(0).find('QueryHistorySelectedEntry').length).toBe(1);
|
expect(foundChildren.at(0).hasClass('selected')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the older query as not selected', () => {
|
it('renders the older query as not selected', () => {
|
||||||
expect(foundChildren.at(1).nodes.length).toBe(1);
|
expect(foundChildren.at(1).nodes.length).toBe(1);
|
||||||
expect(foundChildren.at(1).find('QueryHistoryErrorEntry').length).toBe(1);
|
expect(foundChildren.at(1).hasClass('selected')).toBeFalsy();
|
||||||
|
expect(foundChildren.at(1).hasClass('error')).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -143,12 +144,14 @@ describe('QueryHistory', () => {
|
||||||
|
|
||||||
it('renders the most recent query as selected in the left pane', () => {
|
it('renders the most recent query as selected in the left pane', () => {
|
||||||
expect(foundChildren.at(0).nodes.length).toBe(1);
|
expect(foundChildren.at(0).nodes.length).toBe(1);
|
||||||
expect(foundChildren.at(0).find('QueryHistoryVanillaEntry').length).toBe(1);
|
expect(foundChildren.at(0).hasClass('selected')).toBeFalsy();
|
||||||
|
expect(foundChildren.at(0).hasClass('error')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the older query as selected in the left pane', () => {
|
it('renders the older query as selected in the left pane', () => {
|
||||||
expect(foundChildren.at(1).nodes.length).toBe(1);
|
expect(foundChildren.at(1).nodes.length).toBe(1);
|
||||||
expect(foundChildren.at(1).find('QueryHistorySelectedErrorEntry').length).toBe(1);
|
expect(foundChildren.at(1).hasClass('selected')).toBeTruthy();
|
||||||
|
expect(foundChildren.at(1).hasClass('error')).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue