mirror of
https://github.com/grafana/grafana.git
synced 2024-11-24 09:50:29 -06:00
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:
parent
2db6a199b8
commit
20d0aa9904
@ -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.", "52"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "53"],
|
[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.", "54"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "55"],
|
[0, 0, 0, "Do not use any type assertions.", "55"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "56"],
|
[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.", "57"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "58"],
|
[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.", "59"]
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "60"]
|
],
|
||||||
|
"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": [
|
"public/app/plugins/datasource/opentsdb/query_ctrl.ts:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
|
@ -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>
|
||||||
|
);
|
||||||
|
};
|
@ -13,7 +13,7 @@ import {
|
|||||||
map as _map,
|
map as _map,
|
||||||
toPairs,
|
toPairs,
|
||||||
} from 'lodash';
|
} from 'lodash';
|
||||||
import { lastValueFrom, Observable, of } from 'rxjs';
|
import { lastValueFrom, merge, Observable, of } from 'rxjs';
|
||||||
import { catchError, map } from 'rxjs/operators';
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -23,10 +23,13 @@ import {
|
|||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
dateMath,
|
dateMath,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
|
toDataFrame,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { FetchResponse, getBackendSrv } from '@grafana/runtime';
|
import { FetchResponse, getBackendSrv } from '@grafana/runtime';
|
||||||
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
|
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
|
import { AnnotationEditor } from './components/AnnotationEditor';
|
||||||
|
import { prepareAnnotation } from './migrations';
|
||||||
import { OpenTsdbOptions, OpenTsdbQuery } from './types';
|
import { OpenTsdbOptions, OpenTsdbQuery } from './types';
|
||||||
|
|
||||||
export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenTsdbOptions> {
|
export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenTsdbOptions> {
|
||||||
@ -58,10 +61,39 @@ export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenT
|
|||||||
|
|
||||||
this.aggregatorsPromise = null;
|
this.aggregatorsPromise = null;
|
||||||
this.filterTypesPromise = null;
|
this.filterTypesPromise = null;
|
||||||
|
this.annotations = {
|
||||||
|
QueryEditor: AnnotationEditor,
|
||||||
|
prepareAnnotation,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called once per panel (graph)
|
// Called once per panel (graph)
|
||||||
query(options: DataQueryRequest<OpenTsdbQuery>): Observable<DataQueryResponse> {
|
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 start = this.convertToTSDBTime(options.range.raw.from, false, options.timezone);
|
||||||
const end = this.convertToTSDBTime(options.range.raw.to, true, options.timezone);
|
const end = this.convertToTSDBTime(options.range.raw.to, true, options.timezone);
|
||||||
const qs: any[] = [];
|
const qs: any[] = [];
|
||||||
@ -124,13 +156,13 @@ export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenT
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
annotationQuery(options: any): Promise<AnnotationEvent[]> {
|
annotationEvent(options: DataQueryRequest, annotation: OpenTsdbQuery): Promise<AnnotationEvent[]> {
|
||||||
const start = this.convertToTSDBTime(options.rangeRaw.from, false, options.timezone);
|
const start = this.convertToTSDBTime(options.range.raw.from, false, options.timezone);
|
||||||
const end = this.convertToTSDBTime(options.rangeRaw.to, true, options.timezone);
|
const end = this.convertToTSDBTime(options.range.raw.to, true, options.timezone);
|
||||||
const qs = [];
|
const qs = [];
|
||||||
const eventList: any[] = [];
|
const eventList: any[] = [];
|
||||||
|
|
||||||
qs.push({ aggregator: 'sum', metric: options.annotation.target });
|
qs.push({ aggregator: 'sum', metric: annotation.target });
|
||||||
|
|
||||||
const queries = compact(qs);
|
const queries = compact(qs);
|
||||||
|
|
||||||
@ -139,15 +171,15 @@ export default class OpenTsDatasource extends DataSourceApi<OpenTsdbQuery, OpenT
|
|||||||
map((results) => {
|
map((results) => {
|
||||||
if (results.data[0]) {
|
if (results.data[0]) {
|
||||||
let annotationObject = results.data[0].annotations;
|
let annotationObject = results.data[0].annotations;
|
||||||
if (options.annotation.isGlobal) {
|
if (annotation.isGlobal) {
|
||||||
annotationObject = results.data[0].globalAnnotations;
|
annotationObject = results.data[0].globalAnnotations;
|
||||||
}
|
}
|
||||||
if (annotationObject) {
|
if (annotationObject) {
|
||||||
each(annotationObject, (annotation) => {
|
each(annotationObject, (ann) => {
|
||||||
const event = {
|
const event = {
|
||||||
text: annotation.description,
|
text: ann.description,
|
||||||
time: Math.floor(annotation.startTime) * 1000,
|
time: Math.floor(ann.startTime) * 1000,
|
||||||
annotation: options.annotation,
|
annotation: annotation,
|
||||||
};
|
};
|
||||||
|
|
||||||
eventList.push(event);
|
eventList.push(event);
|
||||||
|
23
public/app/plugins/datasource/opentsdb/migrations.ts
Normal file
23
public/app/plugins/datasource/opentsdb/migrations.ts
Normal 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;
|
||||||
|
};
|
@ -4,11 +4,6 @@ import { ConfigEditor } from './components/ConfigEditor';
|
|||||||
import OpenTsDatasource from './datasource';
|
import OpenTsDatasource from './datasource';
|
||||||
import { OpenTsQueryCtrl } from './query_ctrl';
|
import { OpenTsQueryCtrl } from './query_ctrl';
|
||||||
|
|
||||||
class AnnotationsQueryCtrl {
|
|
||||||
static templateUrl = 'partials/annotations.editor.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const plugin = new DataSourcePlugin(OpenTsDatasource)
|
export const plugin = new DataSourcePlugin(OpenTsDatasource)
|
||||||
.setQueryCtrl(OpenTsQueryCtrl)
|
.setQueryCtrl(OpenTsQueryCtrl)
|
||||||
.setConfigEditor(ConfigEditor)
|
.setConfigEditor(ConfigEditor);
|
||||||
.setAnnotationQueryCtrl(AnnotationsQueryCtrl);
|
|
||||||
|
@ -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>
|
|
@ -2,6 +2,11 @@ import { DataQuery, DataSourceJsonData } from '@grafana/data';
|
|||||||
|
|
||||||
export interface OpenTsdbQuery extends DataQuery {
|
export interface OpenTsdbQuery extends DataQuery {
|
||||||
metric?: any;
|
metric?: any;
|
||||||
|
// annotation attrs
|
||||||
|
fromAnnotations?: boolean;
|
||||||
|
isGlobal?: boolean;
|
||||||
|
target?: string;
|
||||||
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenTsdbOptions extends DataSourceJsonData {
|
export interface OpenTsdbOptions extends DataSourceJsonData {
|
||||||
@ -9,3 +14,10 @@ export interface OpenTsdbOptions extends DataSourceJsonData {
|
|||||||
tsdbResolution: number;
|
tsdbResolution: number;
|
||||||
lookupLimit: number;
|
lookupLimit: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LegacyAnnotation = {
|
||||||
|
fromAnnotations?: boolean;
|
||||||
|
isGlobal?: boolean;
|
||||||
|
target?: string;
|
||||||
|
name?: string;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user