OpenTsdb: migrate annotations from angular to react (#53856)

* remove annotation angular dependency and migrate annotations

* add nullish coalescing operator

* remove annotations angular partial

* make annotation queries code and errors more readable

* handle the betterer issue with '^ Unexpected any. Specify a different type' at top of file

* run precommits

* run prettier
This commit is contained in:
Brendan O'Handley 2022-08-26 13:44:10 -04:00 committed by GitHub
parent 2db6a199b8
commit 20d0aa9904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 129 additions and 27 deletions

View File

@ -7288,12 +7288,14 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "52"],
[0, 0, 0, "Unexpected any. Specify a different type.", "53"],
[0, 0, 0, "Unexpected any. Specify a different type.", "54"],
[0, 0, 0, "Unexpected any. Specify a different type.", "55"],
[0, 0, 0, "Do not use any type assertions.", "56"],
[0, 0, 0, "Do not use any type assertions.", "55"],
[0, 0, 0, "Unexpected any. Specify a different type.", "56"],
[0, 0, 0, "Unexpected any. Specify a different type.", "57"],
[0, 0, 0, "Unexpected any. Specify a different type.", "58"],
[0, 0, 0, "Unexpected any. Specify a different type.", "59"],
[0, 0, 0, "Unexpected any. Specify a different type.", "60"]
[0, 0, 0, "Unexpected any. Specify a different type.", "59"]
],
"public/app/plugins/datasource/opentsdb/migrations.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/opentsdb/query_ctrl.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],

View File

@ -0,0 +1,45 @@
import React, { useState } from 'react';
import { QueryEditorProps } from '@grafana/data';
import { InlineFormLabel, Input, InlineSwitch } from '@grafana/ui';
import OpenTsDatasource from '../datasource';
import { OpenTsdbQuery, OpenTsdbOptions } from '../types';
export const AnnotationEditor = (props: QueryEditorProps<OpenTsDatasource, OpenTsdbQuery, OpenTsdbOptions>) => {
const { query, onChange } = props;
const [target, setTarget] = useState<string>(query.target ?? '');
const [isGlobal, setIsGlobal] = useState<boolean>(query.isGlobal ?? false);
const updateValue = <K extends keyof OpenTsdbQuery, V extends OpenTsdbQuery[K]>(key: K, val: V) => {
onChange({
...query,
[key]: val,
fromAnnotations: true,
});
};
const updateIsGlobal = (isGlobal: boolean) => {
isGlobal = !isGlobal;
setIsGlobal(isGlobal);
updateValue('isGlobal', isGlobal);
};
return (
<div className="gf-form-group">
<div className="gf-form">
<InlineFormLabel width={12}>OpenTSDB metrics query</InlineFormLabel>
<Input
value={target}
onChange={(e) => setTarget(e.currentTarget.value ?? '')}
onBlur={() => updateValue('target', target)}
placeholder="events.eventname"
/>
</div>
<div className="gf-form">
<InlineFormLabel width={12}>Show Global Annotations?</InlineFormLabel>
<InlineSwitch value={isGlobal} onChange={(e) => updateIsGlobal(isGlobal)} />
</div>
</div>
);
};

View File

@ -13,7 +13,7 @@ import {
map as _map,
toPairs,
} from 'lodash';
import { lastValueFrom, Observable, of } from 'rxjs';
import { lastValueFrom, merge, Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import {
@ -23,10 +23,13 @@ import {
DataSourceApi,
dateMath,
ScopedVars,
toDataFrame,
} from '@grafana/data';
import { FetchResponse, getBackendSrv } from '@grafana/runtime';
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
import { AnnotationEditor } from './components/AnnotationEditor';
import { prepareAnnotation } from './migrations';
import { OpenTsdbOptions, OpenTsdbQuery } from './types';
export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenTsdbOptions> {
@ -58,10 +61,39 @@ export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenT
this.aggregatorsPromise = null;
this.filterTypesPromise = null;
this.annotations = {
QueryEditor: AnnotationEditor,
prepareAnnotation,
};
}
// Called once per panel (graph)
query(options: DataQueryRequest<OpenTsdbQuery>): Observable<DataQueryResponse> {
// migrate annotations
if (options.targets.some((target: OpenTsdbQuery) => target.fromAnnotations)) {
const streams: Array<Observable<DataQueryResponse>> = [];
for (const annotation of options.targets) {
if (annotation.target) {
streams.push(
new Observable((subscriber) => {
this.annotationEvent(options, annotation)
.then((events) => subscriber.next({ data: [toDataFrame(events)] }))
.catch((ex) => {
// grafana fetch throws the error so for annotation consistency among datasources
// we return an empty array which displays as 'no events found'
// in the annnotation editor
return subscriber.next({ data: [toDataFrame([])] });
})
.finally(() => subscriber.complete());
})
);
}
}
return merge(...streams);
}
const start = this.convertToTSDBTime(options.range.raw.from, false, options.timezone);
const end = this.convertToTSDBTime(options.range.raw.to, true, options.timezone);
const qs: any[] = [];
@ -124,13 +156,13 @@ export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenT
);
}
annotationQuery(options: any): Promise<AnnotationEvent[]> {
const start = this.convertToTSDBTime(options.rangeRaw.from, false, options.timezone);
const end = this.convertToTSDBTime(options.rangeRaw.to, true, options.timezone);
annotationEvent(options: DataQueryRequest, annotation: OpenTsdbQuery): Promise<AnnotationEvent[]> {
const start = this.convertToTSDBTime(options.range.raw.from, false, options.timezone);
const end = this.convertToTSDBTime(options.range.raw.to, true, options.timezone);
const qs = [];
const eventList: any[] = [];
qs.push({ aggregator: 'sum', metric: options.annotation.target });
qs.push({ aggregator: 'sum', metric: annotation.target });
const queries = compact(qs);
@ -139,15 +171,15 @@ export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenT
map((results) => {
if (results.data[0]) {
let annotationObject = results.data[0].annotations;
if (options.annotation.isGlobal) {
if (annotation.isGlobal) {
annotationObject = results.data[0].globalAnnotations;
}
if (annotationObject) {
each(annotationObject, (annotation) => {
each(annotationObject, (ann) => {
const event = {
text: annotation.description,
time: Math.floor(annotation.startTime) * 1000,
annotation: options.annotation,
text: ann.description,
time: Math.floor(ann.startTime) * 1000,
annotation: annotation,
};
eventList.push(event);

View File

@ -0,0 +1,23 @@
import { LegacyAnnotation } from './types';
// this becomes the target in the migrated annotations
const migrateLegacyAnnotation = (json: LegacyAnnotation) => {
// return the target annotation
const annotation: LegacyAnnotation = {
fromAnnotations: true,
target: json.target ?? '',
name: json.name ?? '',
isGlobal: json.isGlobal ?? false,
};
return annotation;
};
// eslint-ignore-next-line
export const prepareAnnotation = (json: any) => {
const resultingTarget = json.target && typeof json.target !== 'string' ? json.target : migrateLegacyAnnotation(json);
json.target = resultingTarget;
return json;
};

View File

@ -4,11 +4,6 @@ import { ConfigEditor } from './components/ConfigEditor';
import OpenTsDatasource from './datasource';
import { OpenTsQueryCtrl } from './query_ctrl';
class AnnotationsQueryCtrl {
static templateUrl = 'partials/annotations.editor.html';
}
export const plugin = new DataSourcePlugin(OpenTsDatasource)
.setQueryCtrl(OpenTsQueryCtrl)
.setConfigEditor(ConfigEditor)
.setAnnotationQueryCtrl(AnnotationsQueryCtrl);
.setConfigEditor(ConfigEditor);

View File

@ -1,7 +0,0 @@
<div class="gf-form-group">
<div class="gf-form">
<span class="gf-form-label width-13">OpenTSDB metrics query</span>
<input type="text" class="gf-form-input" ng-model='ctrl.annotation.target' placeholder="events.eventname"></input>
</div>
<gf-form-switch class="gf-form" label="Show Global Annotations?" checked="ctrl.annotation.isGlobal" switch-class="max-width-6" label-class="width-13"></gf-form-switch>
</div>

View File

@ -2,6 +2,11 @@ import { DataQuery, DataSourceJsonData } from '@grafana/data';
export interface OpenTsdbQuery extends DataQuery {
metric?: any;
// annotation attrs
fromAnnotations?: boolean;
isGlobal?: boolean;
target?: string;
name?: string;
}
export interface OpenTsdbOptions extends DataSourceJsonData {
@ -9,3 +14,10 @@ export interface OpenTsdbOptions extends DataSourceJsonData {
tsdbResolution: number;
lookupLimit: number;
}
export type LegacyAnnotation = {
fromAnnotations?: boolean;
isGlobal?: boolean;
target?: string;
name?: string;
};