|
@@ -11,7 +11,7 @@ import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
|
|
|
|
|
|
|
// Types
|
|
// Types
|
|
|
import { PanelModel } from '../state/PanelModel';
|
|
import { PanelModel } from '../state/PanelModel';
|
|
|
-import { DataQuery, DataSourceApi, TimeRange } from '@grafana/ui';
|
|
|
|
|
|
|
+import { DataQuery, DataSourceApi, TimeRange, DataQueryError, SeriesData } from '@grafana/ui';
|
|
|
import { DashboardModel } from '../state/DashboardModel';
|
|
import { DashboardModel } from '../state/DashboardModel';
|
|
|
|
|
|
|
|
interface Props {
|
|
interface Props {
|
|
@@ -31,6 +31,8 @@ interface State {
|
|
|
datasource: DataSourceApi | null;
|
|
datasource: DataSourceApi | null;
|
|
|
isCollapsed: boolean;
|
|
isCollapsed: boolean;
|
|
|
hasTextEditMode: boolean;
|
|
hasTextEditMode: boolean;
|
|
|
|
|
+ queryError: DataQueryError | null;
|
|
|
|
|
+ queryResponse: SeriesData[] | null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export class QueryEditorRow extends PureComponent<Props, State> {
|
|
export class QueryEditorRow extends PureComponent<Props, State> {
|
|
@@ -43,6 +45,8 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|
|
isCollapsed: false,
|
|
isCollapsed: false,
|
|
|
loadedDataSourceValue: undefined,
|
|
loadedDataSourceValue: undefined,
|
|
|
hasTextEditMode: false,
|
|
hasTextEditMode: false,
|
|
|
|
|
+ queryError: null,
|
|
|
|
|
+ queryResponse: null,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
componentDidMount() {
|
|
@@ -50,26 +54,35 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|
|
this.props.panel.events.on('refresh', this.onPanelRefresh);
|
|
this.props.panel.events.on('refresh', this.onPanelRefresh);
|
|
|
this.props.panel.events.on('data-error', this.onPanelDataError);
|
|
this.props.panel.events.on('data-error', this.onPanelDataError);
|
|
|
this.props.panel.events.on('data-received', this.onPanelDataReceived);
|
|
this.props.panel.events.on('data-received', this.onPanelDataReceived);
|
|
|
|
|
+ this.props.panel.events.on('series-data-received', this.onSeriesDataReceived);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
componentWillUnmount() {
|
|
|
this.props.panel.events.off('refresh', this.onPanelRefresh);
|
|
this.props.panel.events.off('refresh', this.onPanelRefresh);
|
|
|
this.props.panel.events.off('data-error', this.onPanelDataError);
|
|
this.props.panel.events.off('data-error', this.onPanelDataError);
|
|
|
this.props.panel.events.off('data-received', this.onPanelDataReceived);
|
|
this.props.panel.events.off('data-received', this.onPanelDataReceived);
|
|
|
|
|
+ this.props.panel.events.off('series-data-received', this.onSeriesDataReceived);
|
|
|
|
|
|
|
|
if (this.angularQueryEditor) {
|
|
if (this.angularQueryEditor) {
|
|
|
this.angularQueryEditor.destroy();
|
|
this.angularQueryEditor.destroy();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- onPanelDataError = () => {
|
|
|
|
|
|
|
+ onPanelDataError = (error: DataQueryError) => {
|
|
|
// Some query controllers listen to data error events and need a digest
|
|
// Some query controllers listen to data error events and need a digest
|
|
|
if (this.angularQueryEditor) {
|
|
if (this.angularQueryEditor) {
|
|
|
// for some reason this needs to be done in next tick
|
|
// for some reason this needs to be done in next tick
|
|
|
setTimeout(this.angularQueryEditor.digest);
|
|
setTimeout(this.angularQueryEditor.digest);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // if error relates to this query store it in state and pass it on to query editor
|
|
|
|
|
+ if (error.refId === this.props.query.refId) {
|
|
|
|
|
+ this.setState({ queryError: error });
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // Only used by angular plugins
|
|
|
onPanelDataReceived = () => {
|
|
onPanelDataReceived = () => {
|
|
|
// Some query controllers listen to data error events and need a digest
|
|
// Some query controllers listen to data error events and need a digest
|
|
|
if (this.angularQueryEditor) {
|
|
if (this.angularQueryEditor) {
|
|
@@ -78,6 +91,15 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // Only used by the React Query Editors
|
|
|
|
|
+ onSeriesDataReceived = (data: SeriesData[]) => {
|
|
|
|
|
+ if (!this.angularQueryEditor) {
|
|
|
|
|
+ // only pass series related to this query to query editor
|
|
|
|
|
+ const filterByRefId = data.filter(series => series.refId === this.props.query.refId);
|
|
|
|
|
+ this.setState({ queryResponse: filterByRefId, queryError: null });
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
onPanelRefresh = () => {
|
|
onPanelRefresh = () => {
|
|
|
if (this.angularScope) {
|
|
if (this.angularScope) {
|
|
|
this.angularScope.range = getTimeSrv().timeRange();
|
|
this.angularScope.range = getTimeSrv().timeRange();
|
|
@@ -152,7 +174,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|
|
|
|
|
|
|
renderPluginEditor() {
|
|
renderPluginEditor() {
|
|
|
const { query, onChange } = this.props;
|
|
const { query, onChange } = this.props;
|
|
|
- const { datasource } = this.state;
|
|
|
|
|
|
|
+ const { datasource, queryResponse, queryError } = this.state;
|
|
|
|
|
|
|
|
if (datasource.pluginExports.QueryCtrl) {
|
|
if (datasource.pluginExports.QueryCtrl) {
|
|
|
return <div ref={element => (this.element = element)} />;
|
|
return <div ref={element => (this.element = element)} />;
|
|
@@ -160,7 +182,16 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|
|
|
|
|
|
|
if (datasource.pluginExports.QueryEditor) {
|
|
if (datasource.pluginExports.QueryEditor) {
|
|
|
const QueryEditor = datasource.pluginExports.QueryEditor;
|
|
const QueryEditor = datasource.pluginExports.QueryEditor;
|
|
|
- return <QueryEditor query={query} datasource={datasource} onChange={onChange} onRunQuery={this.onRunQuery} />;
|
|
|
|
|
|
|
+ return (
|
|
|
|
|
+ <QueryEditor
|
|
|
|
|
+ query={query}
|
|
|
|
|
+ datasource={datasource}
|
|
|
|
|
+ onChange={onChange}
|
|
|
|
|
+ onRunQuery={this.onRunQuery}
|
|
|
|
|
+ queryResponse={queryResponse}
|
|
|
|
|
+ queryError={queryError}
|
|
|
|
|
+ />
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return <div>Data source plugin does not export any Query Editor component</div>;
|
|
return <div>Data source plugin does not export any Query Editor component</div>;
|