diff --git a/public/app/features/dashboard/dashgrid/QueriesTab.tsx b/public/app/features/dashboard/dashgrid/QueriesTab.tsx index b7dbb87b9ed..db5bcc44f2d 100644 --- a/public/app/features/dashboard/dashgrid/QueriesTab.tsx +++ b/public/app/features/dashboard/dashgrid/QueriesTab.tsx @@ -1,4 +1,4 @@ -import React, { PureComponent } from 'react'; +import React, { SFC, PureComponent } from 'react'; import DataSourceOption from './DataSourceOption'; import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; import { EditorTabBody } from './EditorTabBody'; @@ -27,12 +27,23 @@ interface Help { helpHtml: any; } +interface DsQuery { + isLoading: boolean; + response: {}; +} + interface State { currentDatasource: DataSourceSelectItem; help: Help; - dsQuery: {}; + dsQuery: DsQuery; } +interface LoadingPlaceholderProps { + text: string; +} + +const LoadingPlaceholder: SFC = ({ text }) =>

{text}

; + export class QueriesTab extends PureComponent { element: any; component: AngularComponent; @@ -44,14 +55,18 @@ export class QueriesTab extends PureComponent { const { panel } = props; this.state = { - dsQuery: {}, currentDatasource: this.datasources.find(datasource => datasource.value === panel.datasource), help: { isLoading: false, helpHtml: null, }, + dsQuery: { + isLoading: false, + response: {}, + }, }; appEvents.on('ds-request-response', this.onDataSourceResponse); + panel.events.on('refresh', this.onPanelRefresh); } componentDidMount() { @@ -74,13 +89,25 @@ export class QueriesTab extends PureComponent { } componentWillUnmount() { + const { panel } = this.props; appEvents.off('ds-request-response', this.onDataSourceResponse); + panel.events.off('refresh', this.onPanelRefresh); if (this.component) { this.component.destroy(); } } + onPanelRefresh = () => { + this.setState(prevState => ({ + ...prevState, + dsQuery: { + isLoading: true, + response: {}, + }, + })); + }; + onDataSourceResponse = (response: any = {}) => { // ignore if closed // if (!this.isOpen) { @@ -94,6 +121,7 @@ export class QueriesTab extends PureComponent { // this.isLoading = false; // data = _.cloneDeep(data); + response = { ...response }; // clone if (response.headers) { delete response.headers; @@ -132,7 +160,10 @@ export class QueriesTab extends PureComponent { } this.setState(prevState => ({ ...prevState, - dsQuery: response, + dsQuery: { + isLoading: false, + response: response, + }, })); }; @@ -260,14 +291,24 @@ export class QueriesTab extends PureComponent { }); }; + loadQueryInspector = () => { + const { panel } = this.props; + panel.refresh(); + }; + renderQueryInspector = () => { - const { dsQuery } = this.state; - return ; + const { response, isLoading } = this.state.dsQuery; + return isLoading ? : ; + }; + + renderHelp = () => { + const { helpHtml, isLoading } = this.state.help; + return isLoading ? : helpHtml; }; render() { const { currentDatasource } = this.state; - const { helpHtml } = this.state.help; + const { hasQueryHelp, queryOptions } = currentDatasource.meta; const hasQueryOptions = !!queryOptions; const dsInformation = { @@ -286,6 +327,7 @@ export class QueriesTab extends PureComponent { const queryInspector = { title: 'Query Inspector', + onClick: this.loadQueryInspector, render: this.renderQueryInspector, }; @@ -294,7 +336,7 @@ export class QueriesTab extends PureComponent { icon: 'fa fa-question', disabled: !hasQueryHelp, onClick: this.loadHelp, - render: () => helpHtml, + render: this.renderHelp, }; const options = {