UI tweaks for the query history.

This commit is contained in:
Matthew Kleiman
2017-07-06 13:08:29 +01:00
committed by Dave Page
parent 1291841d98
commit e2cbaaef71
20 changed files with 380 additions and 300 deletions

View File

@@ -10,44 +10,17 @@
import React from 'react';
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 {
render() {
return (
<div style={containerStyle}>
<div style={messageLabelStyle}>
<div className='message'>
<div className='message-header'>
Messages
</div>
<div style={messageContainerStyle}>
<pre style={errorMessageStyle}>
<div className='content'>
<pre className='content-value'>
{this.props.historyEntry.message}
</pre>
</div>

View File

@@ -10,18 +10,6 @@
import React from 'react';
import moment from 'moment';
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 {
@@ -30,18 +18,18 @@ export default class HistoryDetailMetadata extends React.Component {
}
queryMetaData(data, description) {
return <div style={queryMetaDataStyle}>
<span style={headerValueStyle}>
return <div className='item'>
<span className='value'>
{data}
</span>
<span style={HeaderDescriptionStyle}>
<span className='description'>
{description}
</span>
</div>;
}
render() {
return <div style={headerStyle}>
return <div className='metadata'>
{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.total_time, 'Duration')}

View File

@@ -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}),
});
}
}

View File

@@ -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}),
});
}
}

View File

@@ -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}),
});
}
}

View File

@@ -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,
};

View File

@@ -19,9 +19,6 @@ const queryEntryListDivStyle = {
const queryDetailDivStyle = {
display: 'flex',
};
const liStyle = {
borderBottom: '1px solid #cccccc',
};
export default class QueryHistory extends React.Component {
@@ -75,11 +72,11 @@ export default class QueryHistory extends React.Component {
return (
<SplitPane defaultSize="50%" split="vertical" pane1Style={queryEntryListDivStyle}
pane2Style={queryDetailDivStyle}>
<div id='query_list'>
<div id='query_list' className="query-history">
<ul>
{this.retrieveOrderedHistory()
.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}/>
</li>)
.value()

View File

@@ -13,54 +13,22 @@ import HistoryDetailQuery from './detail/history_detail_query';
import HistoryDetailMessage from './detail/history_detail_message';
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 {
render() {
if (!_.isUndefined(this.props.historyEntry)) {
return (
<div id='query_detail' style={outerStyle}>
<div style={detailVerticalTop}>
<div id='query_detail' className='query-detail'>
<div className='metadata-block'>
<HistoryDetailMetadata {...this.props} />
</div>
<div style={detailVerticalMiddle}>
<div className='query-statement-block'>
<HistoryDetailQuery {...this.props}/>
</div>
<div>
<hr style={hrStyle}/>
<hr className='block-divider'/>
</div>
<div style={detailVerticalBottom}>
<div className='message-block'>
<HistoryDetailMessage {...this.props}/>
</div>
</div>);

View File

@@ -9,24 +9,40 @@
import React from 'react';
import Shapes from '../react_shapes';
import QueryHistoryErrorEntry from './entry/query_history_error_entry';
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';
import moment from 'moment';
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() {
if (this.hasError()) {
if (this.props.isSelected) {
return <QueryHistorySelectedErrorEntry {...this.props}/>;
return this.renderWithClasses('error selected');
} else {
return <QueryHistoryErrorEntry {...this.props}/>;
return this.renderWithClasses('error');
}
} else {
if (this.props.isSelected) {
return <QueryHistorySelectedEntry {...this.props}/>;
return this.renderWithClasses('selected');
} else {
return <QueryHistoryVanillaEntry {...this.props}/>;
return this.renderWithClasses('');
}
}
}