Prometheus: Move to new annotation support as the old one is deprecated (#104578)

* remove deprecated annotation support and introduce the new one

* create annotations.test.ts

* convert the old annotations to new format

* don't override query if it has necessary fields

* a better implementation

* remove comment

* fix

* fix react errors

* unit tests for annotation query editor

* two more tests
This commit is contained in:
ismail simsek
2025-05-08 13:32:42 +02:00
committed by GitHub
parent 7042e73343
commit 9156149960
6 changed files with 1088 additions and 479 deletions
@@ -1,4 +1,7 @@
// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/components/AnnotationQueryEditor.tsx
import { memo } from 'react';
import { AnnotationQuery } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { EditorField, EditorRow, EditorRows, EditorSwitch } from '@grafana/plugin-ui';
@@ -14,26 +17,58 @@ type Props = PromQueryEditorProps & {
onAnnotationChange?: (annotation: AnnotationQuery<PromQuery>) => void;
};
export function AnnotationQueryEditor(props: Props) {
// This is because of problematic typing. See AnnotationQueryEditorProps in grafana-data/annotations.ts.
const annotation = props.annotation!;
const onAnnotationChange = props.onAnnotationChange!;
const query = { expr: annotation.expr, refId: annotation.name, interval: annotation.step };
const PLACEHOLDER_TITLE = '{{alertname}}';
const PLACEHOLDER_TEXT = '{{instance}}';
const PLACEHOLDER_TAGS = 'label1,label2';
/**
* AnnotationQueryEditor component for Prometheus datasource.
* Allows users to configure annotation queries with options for title, tags, text format,
* and timestamp settings.
*/
export const AnnotationQueryEditor = memo(function AnnotationQueryEditor(props: Props) {
const { annotation, onAnnotationChange, onChange, onRunQuery, query } = props;
if (!annotation || !onAnnotationChange) {
return <h3>annotation data load error!</h3>;
}
const handleMinStepChange = (value: string) => {
onChange({ ...query, interval: value });
};
const handleTitleChange = (value: string) => {
onAnnotationChange({
...annotation,
titleFormat: value,
});
};
const handleTagsChange = (value: string) => {
onAnnotationChange({
...annotation,
tagKeys: value,
});
};
const handleTextChange = (value: string) => {
onAnnotationChange({
...annotation,
textFormat: value,
});
};
const handleUseValueForTimeChange = (checked: boolean) => {
onAnnotationChange({
...annotation,
useValueForTime: checked,
});
};
return (
<>
<EditorRows>
<PromQueryCodeEditor
{...props}
query={query}
showExplain={false}
onChange={(query) => {
onAnnotationChange({
...annotation,
expr: query.expr,
});
}}
/>
<PromQueryCodeEditor {...props} query={query} showExplain={false} onRunQuery={onRunQuery} onChange={onChange} />
<EditorRow>
<EditorField
label="Min step"
@@ -49,13 +84,8 @@ export function AnnotationQueryEditor(props: Props) {
aria-label="Set lower limit for the step parameter"
placeholder={'auto'}
minWidth={10}
onCommitChange={(ev) => {
onAnnotationChange({
...annotation,
step: ev.currentTarget.value,
});
}}
defaultValue={query.interval}
value={query.interval ?? ''}
onChange={(e) => handleMinStepChange(e.currentTarget.value)}
id={selectors.components.DataSource.Prometheus.annotations.minStep}
/>
</EditorField>
@@ -71,28 +101,18 @@ export function AnnotationQueryEditor(props: Props) {
>
<Input
type="text"
placeholder="{{alertname}}"
value={annotation.titleFormat}
onChange={(event) => {
onAnnotationChange({
...annotation,
titleFormat: event.currentTarget.value,
});
}}
placeholder={PLACEHOLDER_TITLE}
value={annotation.titleFormat ?? ''}
onChange={(event) => handleTitleChange(event.currentTarget.value)}
data-testid={selectors.components.DataSource.Prometheus.annotations.title}
/>
</EditorField>
<EditorField label="Tags">
<Input
type="text"
placeholder="label1,label2"
value={annotation.tagKeys}
onChange={(event) => {
onAnnotationChange({
...annotation,
tagKeys: event.currentTarget.value,
});
}}
placeholder={PLACEHOLDER_TAGS}
value={annotation.tagKeys ?? ''}
onChange={(event) => handleTagsChange(event.currentTarget.value)}
data-testid={selectors.components.DataSource.Prometheus.annotations.tags}
/>
</EditorField>
@@ -104,14 +124,9 @@ export function AnnotationQueryEditor(props: Props) {
>
<Input
type="text"
placeholder="{{instance}}"
value={annotation.textFormat}
onChange={(event) => {
onAnnotationChange({
...annotation,
textFormat: event.currentTarget.value,
});
}}
placeholder={PLACEHOLDER_TEXT}
value={annotation.textFormat ?? ''}
onChange={(event) => handleTextChange(event.currentTarget.value)}
data-testid={selectors.components.DataSource.Prometheus.annotations.text}
/>
</EditorField>
@@ -122,17 +137,12 @@ export function AnnotationQueryEditor(props: Props) {
}
>
<EditorSwitch
value={annotation.useValueForTime}
onChange={(event) => {
onAnnotationChange({
...annotation,
useValueForTime: event.currentTarget.value,
});
}}
value={annotation.useValueForTime ?? false}
onChange={(event) => handleUseValueForTimeChange(event.currentTarget.checked)}
data-testid={selectors.components.DataSource.Prometheus.annotations.seriesValueAsTimestamp}
/>
</EditorField>
</EditorRow>
</>
);
}
});