Commit b9ff1923 by Ryan McKinley Committed by GitHub

QueryEditors: pass PanelData and filtered PanelData to each editor (#16692)

parent 2bc76471
...@@ -2,6 +2,7 @@ import { ComponentClass } from 'react'; ...@@ -2,6 +2,7 @@ import { ComponentClass } from 'react';
import { TimeRange } from './time'; import { TimeRange } from './time';
import { PluginMeta } from './plugin'; import { PluginMeta } from './plugin';
import { TableData, TimeSeries, SeriesData } from './data'; import { TableData, TimeSeries, SeriesData } from './data';
import { PanelData } from './panel';
export class DataSourcePlugin<TQuery extends DataQuery = DataQuery> { export class DataSourcePlugin<TQuery extends DataQuery = DataQuery> {
DataSourceClass: DataSourceConstructor<TQuery>; DataSourceClass: DataSourceConstructor<TQuery>;
...@@ -140,8 +141,8 @@ export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends D ...@@ -140,8 +141,8 @@ export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends D
query: TQuery; query: TQuery;
onRunQuery: () => void; onRunQuery: () => void;
onChange: (value: TQuery) => void; onChange: (value: TQuery) => void;
queryResponse?: SeriesData[]; panelData: PanelData; // The current panel data
queryError?: DataQueryError; queryResponse?: PanelData; // data filtered to only this query. Includes the error.
} }
export enum DataSourceStatus { export enum DataSourceStatus {
......
import { PanelData, LoadingState, DataQueryRequest } from '@grafana/ui';
import { filterPanelDataToQuery } from './QueryEditorRow';
function makePretendRequest(requestId: string, subRequests?: DataQueryRequest[]): DataQueryRequest {
return {
requestId,
// subRequests,
} as DataQueryRequest;
}
describe('filterPanelDataToQuery', () => {
const data = {
state: LoadingState.Done,
series: [
{ refId: 'A', fields: [{ name: 'AAA' }], rows: [], meta: {} },
{ refId: 'B', fields: [{ name: 'B111' }], rows: [], meta: {} },
{ refId: 'B', fields: [{ name: 'B222' }], rows: [], meta: {} },
{ refId: 'B', fields: [{ name: 'B333' }], rows: [], meta: {} },
{ refId: 'C', fields: [{ name: 'CCCC' }], rows: [], meta: { requestId: 'sub3' } },
],
error: {
refId: 'B',
message: 'Error!!',
},
request: makePretendRequest('111', [
makePretendRequest('sub1'),
makePretendRequest('sub2'),
makePretendRequest('sub3'),
]),
} as PanelData;
it('should not have an error unless the refId matches', () => {
const panelData = filterPanelDataToQuery(data, 'A');
expect(panelData.series.length).toBe(1);
expect(panelData.series[0].refId).toBe('A');
expect(panelData.error).toBeUndefined();
});
it('should match the error to the query', () => {
const panelData = filterPanelDataToQuery(data, 'B');
expect(panelData.series.length).toBe(3);
expect(panelData.series[0].refId).toBe('B');
expect(panelData.error!.refId).toBe('B');
});
});
...@@ -11,7 +11,7 @@ import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; ...@@ -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, DataQueryError, SeriesData, PanelData } from '@grafana/ui'; import { DataQuery, DataSourceApi, TimeRange, PanelData, LoadingState, DataQueryRequest } from '@grafana/ui';
import { DashboardModel } from '../state/DashboardModel'; import { DashboardModel } from '../state/DashboardModel';
interface Props { interface Props {
...@@ -32,8 +32,7 @@ interface State { ...@@ -32,8 +32,7 @@ interface State {
datasource: DataSourceApi | null; datasource: DataSourceApi | null;
isCollapsed: boolean; isCollapsed: boolean;
hasTextEditMode: boolean; hasTextEditMode: boolean;
queryError: DataQueryError | null; queryResponse?: PanelData;
queryResponse: SeriesData[] | null;
} }
export class QueryEditorRow extends PureComponent<Props, State> { export class QueryEditorRow extends PureComponent<Props, State> {
...@@ -46,7 +45,6 @@ export class QueryEditorRow extends PureComponent<Props, State> { ...@@ -46,7 +45,6 @@ export class QueryEditorRow extends PureComponent<Props, State> {
isCollapsed: false, isCollapsed: false,
loadedDataSourceValue: undefined, loadedDataSourceValue: undefined,
hasTextEditMode: false, hasTextEditMode: false,
queryError: null,
queryResponse: null, queryResponse: null,
}; };
...@@ -93,9 +91,7 @@ export class QueryEditorRow extends PureComponent<Props, State> { ...@@ -93,9 +91,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
const { data, query } = this.props; const { data, query } = this.props;
if (data !== prevProps.data) { if (data !== prevProps.data) {
const queryError = data.error && data.error.refId === query.refId ? data.error : null; this.setState({ queryResponse: filterPanelDataToQuery(data, query.refId) });
const queryResponse = data.series.filter(series => series.refId === query.refId);
this.setState({ queryResponse, queryError });
if (this.angularScope) { if (this.angularScope) {
this.angularScope.range = getTimeSrv().timeRange(); this.angularScope.range = getTimeSrv().timeRange();
...@@ -144,8 +140,8 @@ export class QueryEditorRow extends PureComponent<Props, State> { ...@@ -144,8 +140,8 @@ export class QueryEditorRow extends PureComponent<Props, State> {
}; };
renderPluginEditor() { renderPluginEditor() {
const { query, onChange } = this.props; const { query, data, onChange } = this.props;
const { datasource, queryResponse, queryError } = this.state; const { datasource, queryResponse } = this.state;
if (datasource.components.QueryCtrl) { if (datasource.components.QueryCtrl) {
return <div ref={element => (this.element = element)} />; return <div ref={element => (this.element = element)} />;
...@@ -161,7 +157,7 @@ export class QueryEditorRow extends PureComponent<Props, State> { ...@@ -161,7 +157,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
onChange={onChange} onChange={onChange}
onRunQuery={this.onRunQuery} onRunQuery={this.onRunQuery}
queryResponse={queryResponse} queryResponse={queryResponse}
queryError={queryError} panelData={data}
/> />
); );
} }
...@@ -284,3 +280,33 @@ export interface AngularQueryComponentScope { ...@@ -284,3 +280,33 @@ export interface AngularQueryComponentScope {
getCollapsedText?: () => string; getCollapsedText?: () => string;
range: TimeRange; range: TimeRange;
} }
/**
* Get a version of the PanelData limited to the query we are looking at
*/
export function filterPanelDataToQuery(data: PanelData, refId: string): PanelData | undefined {
const series = data.series.filter(series => series.refId === refId);
// No matching series
if (!series.length) {
return undefined;
}
// Don't pass the request if all requests are the same
const request: DataQueryRequest = undefined;
// TODO: look in sub-requets to match the info
// Only say this is an error if the error links to the query
let state = LoadingState.Done;
const error = data.error && data.error.refId === refId ? data.error : undefined;
if (error) {
state = LoadingState.Error;
}
return {
state,
series,
request,
error,
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment