Refactor: fixes annotation queries

This commit is contained in:
Hugo Häggmark
2021-07-01 08:39:24 +02:00
parent e402f15297
commit 460ebabac7
5 changed files with 49 additions and 19 deletions
@@ -1,6 +1,7 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
import { GrafanaAnnotationType, GrafanaAnnotationQuery } from '../types';
import { render, screen } from '@testing-library/react';
import { GrafanaAnnotationQuery, GrafanaAnnotationType } from '../types';
import AnnotationQueryEditor from './AnnotationQueryEditor';
describe('AnnotationQueryEditor', () => {
@@ -12,6 +13,9 @@ describe('AnnotationQueryEditor', () => {
refId: 'Anno',
type: GrafanaAnnotationType.Tags,
limit: 100,
enable: true,
name: 'a name',
iconColor: 'a color',
};
});
@@ -1,7 +1,8 @@
import React from 'react';
import { FieldSet, InlineField, InlineFieldRow, InlineSwitch, Select } from '@grafana/ui';
import { TagFilter } from 'app/core/components/TagFilter/TagFilter';
import { SelectableValue } from '@grafana/data';
import { FieldSet, InlineField, InlineFieldRow, InlineSwitch, Select } from '@grafana/ui';
import { TagFilter } from 'app/core/components/TagFilter/TagFilter';
import { GrafanaAnnotationQuery, GrafanaAnnotationType } from '../types';
import { getAnnotationTags } from 'app/features/annotations/api';
@@ -48,7 +49,7 @@ interface Props {
}
export default function AnnotationQueryEditor({ query, onChange }: Props) {
const { limit = 100, matchAny = false, tags = [], type = GrafanaAnnotationType.Tags } = query;
const { limit = 100, matchAny = false, tags = [], type = GrafanaAnnotationType.Dashboard } = query;
const onFilterByChange = (newValue: SelectableValue<GrafanaAnnotationType>) =>
onChange({
@@ -1,8 +1,8 @@
import { DataSourceInstanceSettings, dateTime, AnnotationQueryRequest } from '@grafana/data';
import { AnnotationQueryRequest, DataSourceInstanceSettings, dateTime } from '@grafana/data';
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
import { GrafanaDatasource } from './datasource';
import { GrafanaQuery, GrafanaAnnotationQuery, GrafanaAnnotationType } from './types';
import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery } from './types';
jest.mock('@grafana/runtime', () => ({
...((jest.requireActual('@grafana/runtime') as unknown) as object),
@@ -37,7 +37,7 @@ describe('grafana data source', () => {
const options = setupAnnotationQueryOptions({ tags: ['tag1:$var'] });
beforeEach(() => {
return ds.annotationQuery(options);
return ds.getAnnotations(options);
});
it('should interpolate template variables in tags in query options', () => {
@@ -49,7 +49,7 @@ describe('grafana data source', () => {
const options = setupAnnotationQueryOptions({ tags: ['$var2'] });
beforeEach(() => {
return ds.annotationQuery(options);
return ds.getAnnotations(options);
});
it('should interpolate template variables in tags in query options', () => {
@@ -68,7 +68,7 @@ describe('grafana data source', () => {
);
beforeEach(() => {
return ds.annotationQuery(options);
return ds.getAnnotations(options);
});
it('should remove tags from query options', () => {
@@ -1,5 +1,7 @@
import { from, merge, Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { getBackendSrv, getGrafanaLiveSrv, getTemplateSrv, toDataQueryResponse } from '@grafana/runtime';
import {
AnnotationEvent,
AnnotationQueryRequest,
DataQueryRequest,
DataQueryResponse,
@@ -8,13 +10,12 @@ import {
isValidLiveChannelAddress,
parseLiveChannelAddress,
StreamingFrameOptions,
toDataFrame,
} from '@grafana/data';
import { GrafanaQuery, GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQueryType } from './types';
import { getBackendSrv, getGrafanaLiveSrv, getTemplateSrv, toDataQueryResponse } from '@grafana/runtime';
import { Observable, of, merge } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery, GrafanaQueryType } from './types';
import AnnotationQueryEditor from './components/AnnotationQueryEditor';
import { getDashboardSrv } from '../../../features/dashboard/services/DashboardSrv';
let counter = 100;
@@ -23,6 +24,18 @@ export class GrafanaDatasource extends DataSourceApi<GrafanaQuery> {
super(instanceSettings);
this.annotations = {
QueryEditor: AnnotationQueryEditor,
prepareAnnotation(json: any): GrafanaAnnotationQuery {
json.target = json.target ?? {
type: json.type,
limit: json.limit,
tags: json.tags,
matchAny: json.matchAny,
}; // using spread syntax caused an infinite loop in StandardAnnotationQueryEditor
return json;
},
prepareQuery(anno: GrafanaAnnotationQuery): GrafanaQuery {
return { ...anno, refId: anno.name, queryType: GrafanaQueryType.Annotations };
},
};
}
@@ -33,6 +46,16 @@ export class GrafanaDatasource extends DataSourceApi<GrafanaQuery> {
if (target.hide) {
continue;
}
if (target.queryType === GrafanaQueryType.Annotations) {
return from(
this.getAnnotations({
range: request.range,
rangeRaw: request.rangeRaw!,
annotation: target as any,
dashboard: getDashboardSrv().getCurrent(),
})
);
}
if (target.queryType === GrafanaQueryType.LiveMeasurements) {
let channel = templateSrv.replace(target.channel, request.scopedVars);
const { filter } = target;
@@ -84,7 +107,7 @@ export class GrafanaDatasource extends DataSourceApi<GrafanaQuery> {
return Promise.resolve([]);
}
annotationQuery(options: AnnotationQueryRequest<GrafanaQuery>): Promise<AnnotationEvent[]> {
async getAnnotations(options: AnnotationQueryRequest<GrafanaQuery>): Promise<DataQueryResponse> {
const templateSrv = getTemplateSrv();
const annotation = (options.annotation as unknown) as GrafanaAnnotationQuery;
const params: any = {
@@ -98,7 +121,7 @@ export class GrafanaDatasource extends DataSourceApi<GrafanaQuery> {
if (annotation.type === GrafanaAnnotationType.Dashboard) {
// if no dashboard id yet return
if (!options.dashboard.id) {
return Promise.resolve([]);
return Promise.resolve({ data: [] });
}
// filter by dashboard id
params.dashboardId = options.dashboard.id;
@@ -107,7 +130,7 @@ export class GrafanaDatasource extends DataSourceApi<GrafanaQuery> {
} else {
// require at least one tag
if (!Array.isArray(annotation.tags) || annotation.tags.length === 0) {
return Promise.resolve([]);
return Promise.resolve({ data: [] });
}
const delimiter = '__delimiter__';
const tags = [];
@@ -126,11 +149,12 @@ export class GrafanaDatasource extends DataSourceApi<GrafanaQuery> {
params.tags = tags;
}
return getBackendSrv().get(
const annotations = await getBackendSrv().get(
'/api/annotations',
params,
`grafana-data-source-annotations-${annotation.name}-${options.dashboard?.id}`
);
return { data: [toDataFrame(annotations)] };
}
testDatasource() {
@@ -8,6 +8,7 @@ import { LiveDataFilter } from '@grafana/runtime';
export enum GrafanaQueryType {
RandomWalk = 'randomWalk',
LiveMeasurements = 'measurements',
Annotations = 'annotations',
}
export interface GrafanaQuery extends DataQuery {