diff --git a/public/app/features/dashboard/dashgrid/QueriesTab.tsx b/public/app/features/dashboard/dashgrid/QueriesTab.tsx index d35e55f591d..9a679832048 100644 --- a/public/app/features/dashboard/dashgrid/QueriesTab.tsx +++ b/public/app/features/dashboard/dashgrid/QueriesTab.tsx @@ -13,7 +13,6 @@ import { QueryInspector } from './QueryInspector'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv'; import { DataSourceSelectItem } from 'app/types'; -import appEvents from 'app/core/app_events'; import Remarkable from 'remarkable'; @@ -27,15 +26,9 @@ interface Help { helpHtml: any; } -interface DsQuery { - isLoading: boolean; - response: {}; -} - interface State { currentDatasource: DataSourceSelectItem; help: Help; - dsQuery: DsQuery; } interface LoadingPlaceholderProps { @@ -60,13 +53,7 @@ export class QueriesTab extends PureComponent { isLoading: false, helpHtml: null, }, - dsQuery: { - isLoading: false, - response: {}, - }, }; - appEvents.on('ds-request-response', this.onDataSourceResponse); - panel.events.on('refresh', this.onPanelRefresh); } componentDidMount() { @@ -89,84 +76,11 @@ 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) { - // return; - // } - - // if (this.isMocking) { - // this.handleMocking(data); - // return; - // } - - // this.isLoading = false; - // data = _.cloneDeep(data); - response = { ...response }; // clone - - if (response.headers) { - delete response.headers; - } - - if (response.config) { - response.request = response.config; - delete response.config; - delete response.request.transformRequest; - delete response.request.transformResponse; - delete response.request.paramSerializer; - delete response.request.jsonpCallbackParam; - delete response.request.headers; - delete response.request.requestId; - delete response.request.inspect; - delete response.request.retry; - delete response.request.timeout; - } - - if (response.data) { - response.response = response.data; - - // if (response.status === 200) { - // // if we are in error state, assume we automatically opened - // // and auto close it again - // if (this.hasError) { - // this.hasError = false; - // this.isOpen = false; - // } - // } - - delete response.data; - delete response.status; - delete response.statusText; - delete response.$$config; - } - this.setState(prevState => ({ - ...prevState, - dsQuery: { - isLoading: false, - response: response, - }, - })); - }; - onChangeDataSource = datasource => { const { panel } = this.props; const { currentDatasource } = this.state; @@ -291,18 +205,9 @@ export class QueriesTab extends PureComponent { }); }; - loadQueryInspector = () => { - const { panel } = this.props; - panel.refresh(); - }; - renderQueryInspector = () => { - const { response, isLoading } = this.state.dsQuery; - return isLoading ? ( - - ) : ( - - ); + const { panel } = this.props; + return ; }; renderHelp = () => { @@ -331,7 +236,6 @@ export class QueriesTab extends PureComponent { const queryInspector = { title: 'Query Inspector', - onClick: this.loadQueryInspector, render: this.renderQueryInspector, }; diff --git a/public/app/features/dashboard/dashgrid/QueryInspector.tsx b/public/app/features/dashboard/dashgrid/QueryInspector.tsx index 9733ae58263..08da527c035 100644 --- a/public/app/features/dashboard/dashgrid/QueryInspector.tsx +++ b/public/app/features/dashboard/dashgrid/QueryInspector.tsx @@ -3,12 +3,21 @@ import { JSONFormatter } from 'app/core/components/JSONFormatter/JSONFormatter'; import appEvents from 'app/core/app_events'; import { CopyToClipboard } from 'app/core/components/CopyToClipboard/CopyToClipboard'; +interface DsQuery { + isLoading: boolean; + response: {}; +} + interface Props { - response: any; + panel: any; + LoadingPlaceholder: any; } interface State { allNodesExpanded: boolean; + isMocking: boolean; + mockedResponse: string; + dsQuery: DsQuery; } export class QueryInspector extends PureComponent { @@ -17,12 +26,112 @@ export class QueryInspector extends PureComponent { constructor(props) { super(props); - this.state = { allNodesExpanded: null, + isMocking: false, + mockedResponse: '', + dsQuery: { + isLoading: false, + response: {}, + }, }; } + componentDidMount() { + const { panel } = this.props; + panel.events.on('refresh', this.onPanelRefresh); + appEvents.on('ds-request-response', this.onDataSourceResponse); + panel.refresh(); + } + + componentWillUnmount() { + const { panel } = this.props; + appEvents.off('ds-request-response', this.onDataSourceResponse); + panel.events.off('refresh', this.onPanelRefresh); + } + + handleMocking(response) { + const { mockedResponse } = this.state; + let mockedData; + try { + mockedData = JSON.parse(mockedResponse); + } catch (err) { + appEvents.emit('alert-error', ['R: Failed to parse mocked response']); + return; + } + + response.data = mockedData; + } + + onPanelRefresh = () => { + this.setState(prevState => ({ + ...prevState, + dsQuery: { + isLoading: true, + response: {}, + }, + })); + }; + + onDataSourceResponse = (response: any = {}) => { + // ignore if closed + // if (!this.isOpen) { + // return; + // } + + if (this.state.isMocking) { + this.handleMocking(response); + return; + } + + // this.isLoading = false; + // data = _.cloneDeep(data); + response = { ...response }; // clone + + if (response.headers) { + delete response.headers; + } + + if (response.config) { + response.request = response.config; + delete response.config; + delete response.request.transformRequest; + delete response.request.transformResponse; + delete response.request.paramSerializer; + delete response.request.jsonpCallbackParam; + delete response.request.headers; + delete response.request.requestId; + delete response.request.inspect; + delete response.request.retry; + delete response.request.timeout; + } + + if (response.data) { + response.response = response.data; + + // if (response.status === 200) { + // // if we are in error state, assume we automatically opened + // // and auto close it again + // if (this.hasError) { + // this.hasError = false; + // this.isOpen = false; + // } + // } + + delete response.data; + delete response.status; + delete response.statusText; + delete response.$$config; + } + this.setState(prevState => ({ + ...prevState, + dsQuery: { + isLoading: false, + response: response, + }, + })); + }; + setFormattedJson = formattedJson => { this.formattedJson = formattedJson; }; @@ -42,56 +151,92 @@ export class QueryInspector extends PureComponent { })); }; + onToggleMocking = () => { + this.setState(prevState => ({ + ...prevState, + isMocking: !this.state.isMocking, + })); + }; + getNrOfOpenNodes = () => { if (this.state.allNodesExpanded === null) { - return 3; + return 3; // 3 is default, ie when state is null } else if (this.state.allNodesExpanded) { return 20; } return 1; }; + setMockedResponse = evt => { + const mockedResponse = evt.target.value; + this.setState(prevState => ({ + ...prevState, + mockedResponse, + })); + }; + render() { - const { response } = this.props; - const { allNodesExpanded } = this.state; + const { response, isLoading } = this.state.dsQuery; + const { LoadingPlaceholder } = this.props; + const { allNodesExpanded, isMocking } = this.state; const openNodes = this.getNrOfOpenNodes(); + + if (isLoading) { + return ; + } + return ( <> {/*
Mock Response - - Expand All - - - Collapse All - - Copy to Clipboard + */} +
+ + -
*/} - {/* - */} - + +
- - <> - Copy to Clipboard - - - + {!isMocking && } + {isMocking && ( +
+
+ */} +
+
+ )} ); } diff --git a/public/sass/components/_buttons.scss b/public/sass/components/_buttons.scss index dcb4686701d..87947965fc3 100644 --- a/public/sass/components/_buttons.scss +++ b/public/sass/components/_buttons.scss @@ -172,6 +172,12 @@ padding-right: 20px; } +// No horizontal padding +.btn-p-x-0 { + padding-left: 0; + padding-right: 0; +} + // External services // Usage: //