[explore] fix query text modal while loading (#2596)

* [explore] fix and clean

Currently it's not possible to view queries while they are running, the
spinner appears endlessly. I decided to rearrange things a bit while
debugging so I could see clearly through it.

* Adding NotImplemented methods to base classes

* Fixing

* Piling up
This commit is contained in:
Maxime Beauchemin
2017-04-13 15:46:57 -07:00
committed by GitHub
parent 2df6baa7a7
commit db02b33e09
9 changed files with 134 additions and 62 deletions

View File

@@ -228,7 +228,6 @@ class ChartContainer extends React.PureComponent {
return this.renderChart();
}
const queryResponse = this.props.queryResponse;
const query = queryResponse && queryResponse.query ? queryResponse.query : null;
return (
<div className="chart-container">
<Panel
@@ -266,14 +265,14 @@ class ChartContainer extends React.PureComponent {
{this.props.chartStatus === 'success' &&
this.props.queryResponse &&
this.props.queryResponse.is_cached &&
<TooltipWrapper
tooltip="Loaded from cache. Click to force refresh"
label="cache-desc"
>
<Label
style={{ fontSize: '10px', marginRight: '5px', cursor: 'pointer' }}
onClick={this.runQuery.bind(this)}
>
<TooltipWrapper
tooltip="Loaded from cache. Click to force refresh"
label="cache-desc"
>
<Label
style={{ fontSize: '10px', marginRight: '5px', cursor: 'pointer' }}
onClick={this.runQuery.bind(this)}
>
cached
</Label>
</TooltipWrapper>
@@ -288,7 +287,8 @@ class ChartContainer extends React.PureComponent {
<ExploreActionButtons
slice={this.state.mockSlice}
canDownload={this.props.can_download}
query={query}
chartStatus={this.props.chartStatus}
queryResponse={queryResponse}
queryEndpoint={getExploreUrl(this.props.latestQueryFormData, 'query')}
/>
</div>

View File

@@ -7,62 +7,91 @@ import ModalTrigger from './../../components/ModalTrigger';
const $ = window.$ = require('jquery');
const propTypes = {
query: PropTypes.string,
animation: PropTypes.bool,
queryResponse: PropTypes.object,
chartStatus: PropTypes.string,
queryEndpoint: PropTypes.string.isRequired,
};
const defaultProps = {
animation: true,
};
export default class DisplayQueryButton extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
modalBody: <pre />,
language: null,
query: null,
isLoading: false,
error: null,
};
this.beforeOpen = this.beforeOpen.bind(this);
this.fetchQuery = this.fetchQuery.bind(this);
}
fetchQuery() {
this.setState({ isLoading: true });
$.ajax({
type: 'GET',
url: this.props.queryEndpoint,
success: data => {
this.setState({
language: data.language,
query: data.query,
isLoading: false,
});
},
error: data => {
this.setState({
error: data.error,
isLoading: false,
});
},
});
}
setStateFromQueryResponse() {
const qr = this.props.queryResponse;
this.setState({
language: qr.language,
query: qr.query,
isLoading: false,
});
}
beforeOpen() {
this.setState({
modalBody:
(<img
className="loading"
alt="Loading..."
src="/static/assets/images/loading.gif"
/>),
});
if (this.props.query) {
const modalBody = (
<pre>{this.props.query}</pre>
);
this.setState({ modalBody });
if (this.props.chartStatus === 'loading' || this.props.chartStatus === null) {
this.fetchQuery();
} else {
$.ajax({
type: 'GET',
url: this.props.queryEndpoint,
success: (data) => {
const modalBody = data.language ?
(<SyntaxHighlighter language={data.language} style={github}>
{data.query}
</SyntaxHighlighter>)
:
<pre>{data.query}</pre>;
this.setState({ modalBody });
},
error(data) {
this.setState({ modalBody: (<pre>{data.error}</pre>) });
},
});
this.setStateFromQueryResponse();
}
}
renderModalBody() {
if (this.state.isLoading) {
return (<img
className="loading"
alt="Loading..."
src="/static/assets/images/loading.gif"
/>);
} else if (this.state.error) {
return <pre>{this.state.error}</pre>;
}
return (
<SyntaxHighlighter language={this.state.language} style={github}>
{this.state.query}
</SyntaxHighlighter>);
}
render() {
return (
<ModalTrigger
animation={this.props.animation}
isButton
triggerNode={<span>Query</span>}
modalTitle="Query"
bsSize="large"
beforeOpen={this.beforeOpen.bind(this)}
modalBody={this.state.modalBody}
beforeOpen={this.beforeOpen}
modalBody={this.renderModalBody()}
/>
);
}
}
DisplayQueryButton.propTypes = propTypes;
DisplayQueryButton.defaultProps = defaultProps;

View File

@@ -8,10 +8,12 @@ const propTypes = {
canDownload: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]).isRequired,
slice: PropTypes.object,
queryEndpoint: PropTypes.string,
query: PropTypes.string,
queryResponse: PropTypes.object,
chartStatus: PropTypes.string,
};
export default function ExploreActionButtons({ canDownload, slice, query, queryEndpoint }) {
export default function ExploreActionButtons({
chartStatus, canDownload, slice, queryResponse, queryEndpoint }) {
const exportToCSVClasses = cx('btn btn-default btn-sm', {
'disabled disabledButton': !canDownload,
});
@@ -43,8 +45,9 @@ export default function ExploreActionButtons({ canDownload, slice, query, queryE
</a>
<DisplayQueryButton
query={query}
queryResponse={queryResponse}
queryEndpoint={queryEndpoint}
chartStatus={chartStatus}
/>
</div>
);