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';
import { TimeRange } from './time';
import { PluginMeta } from './plugin';
import { TableData, TimeSeries, SeriesData } from './data';
import { PanelData } from './panel';
export class DataSourcePlugin<TQuery extends DataQuery = DataQuery> {
DataSourceClass: DataSourceConstructor<TQuery>;
......@@ -140,8 +141,8 @@ export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends D
query: TQuery;
onRunQuery: () => void;
onChange: (value: TQuery) => void;
queryResponse?: SeriesData[];
queryError?: DataQueryError;
panelData: PanelData; // The current panel data
queryResponse?: PanelData; // data filtered to only this query. Includes the error.
}
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';
// Types
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';
interface Props {
......@@ -32,8 +32,7 @@ interface State {
datasource: DataSourceApi | null;
isCollapsed: boolean;
hasTextEditMode: boolean;
queryError: DataQueryError | null;
queryResponse: SeriesData[] | null;
queryResponse?: PanelData;
}
export class QueryEditorRow extends PureComponent<Props, State> {
......@@ -46,7 +45,6 @@ export class QueryEditorRow extends PureComponent<Props, State> {
isCollapsed: false,
loadedDataSourceValue: undefined,
hasTextEditMode: false,
queryError: null,
queryResponse: null,
};
......@@ -93,9 +91,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
const { data, query } = this.props;
if (data !== prevProps.data) {
const queryError = data.error && data.error.refId === query.refId ? data.error : null;
const queryResponse = data.series.filter(series => series.refId === query.refId);
this.setState({ queryResponse, queryError });
this.setState({ queryResponse: filterPanelDataToQuery(data, query.refId) });
if (this.angularScope) {
this.angularScope.range = getTimeSrv().timeRange();
......@@ -144,8 +140,8 @@ export class QueryEditorRow extends PureComponent<Props, State> {
};
renderPluginEditor() {
const { query, onChange } = this.props;
const { datasource, queryResponse, queryError } = this.state;
const { query, data, onChange } = this.props;
const { datasource, queryResponse } = this.state;
if (datasource.components.QueryCtrl) {
return <div ref={element => (this.element = element)} />;
......@@ -161,7 +157,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
onChange={onChange}
onRunQuery={this.onRunQuery}
queryResponse={queryResponse}
queryError={queryError}
panelData={data}
/>
);
}
......@@ -284,3 +280,33 @@ export interface AngularQueryComponentScope {
getCollapsedText?: () => string;
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