Annotations: Add frontend api wrapper (#111452)
This commit is contained in:
@@ -10,6 +10,10 @@ const get = jest.fn(() => {
|
||||
});
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
config: {
|
||||
namespace: 'default',
|
||||
featureToggles: {},
|
||||
},
|
||||
getBackendSrv: () => ({
|
||||
get,
|
||||
}),
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { annotationServer } from 'app/features/annotations/api';
|
||||
import { StateHistoryItem } from 'app/types/unified-alerting';
|
||||
|
||||
export function fetchAnnotations(alertUID: string): Promise<StateHistoryItem[]> {
|
||||
return getBackendSrv()
|
||||
.get('/api/annotations', {
|
||||
alertUID,
|
||||
})
|
||||
return annotationServer()
|
||||
.forAlert(alertUID)
|
||||
.then((result) => {
|
||||
return result?.sort(sortStateHistory);
|
||||
});
|
||||
|
||||
@@ -1,24 +1,57 @@
|
||||
import { AnnotationEvent } from '@grafana/data';
|
||||
import { AnnotationEvent, DataFrame, toDataFrame } from '@grafana/data';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { StateHistoryItem } from 'app/types/unified-alerting';
|
||||
|
||||
import { AnnotationTagsResponse } from './types';
|
||||
|
||||
export function saveAnnotation(annotation: AnnotationEvent) {
|
||||
return getBackendSrv().post('/api/annotations', annotation);
|
||||
export interface AnnotationServer {
|
||||
query(params: Record<string, unknown>, requestId: string): Promise<DataFrame>;
|
||||
forAlert(alertUID: string): Promise<StateHistoryItem[]>;
|
||||
save(annotation: AnnotationEvent): Promise<AnnotationEvent>;
|
||||
update(annotation: AnnotationEvent): Promise<unknown>;
|
||||
delete(annotation: AnnotationEvent): Promise<unknown>;
|
||||
tags(): Promise<Array<{ term: string; count: number }>>;
|
||||
}
|
||||
|
||||
export function updateAnnotation(annotation: AnnotationEvent) {
|
||||
return getBackendSrv().put(`/api/annotations/${annotation.id}`, annotation);
|
||||
class LegacyAnnotationServer implements AnnotationServer {
|
||||
query(params: unknown, requestId: string): Promise<DataFrame> {
|
||||
return getBackendSrv()
|
||||
.get('/api/annotations', params, requestId)
|
||||
.then((v) => toDataFrame(v));
|
||||
}
|
||||
|
||||
forAlert(alertUID: string) {
|
||||
return getBackendSrv().get('/api/annotations', {
|
||||
alertUID,
|
||||
});
|
||||
}
|
||||
|
||||
save(annotation: AnnotationEvent) {
|
||||
return getBackendSrv().post('/api/annotations', annotation);
|
||||
}
|
||||
|
||||
update(annotation: AnnotationEvent) {
|
||||
return getBackendSrv().put(`/api/annotations/${annotation.id}`, annotation);
|
||||
}
|
||||
|
||||
delete(annotation: AnnotationEvent) {
|
||||
return getBackendSrv().delete(`/api/annotations/${annotation.id}`);
|
||||
}
|
||||
|
||||
async tags() {
|
||||
const response = await getBackendSrv().get<AnnotationTagsResponse>('/api/annotations/tags');
|
||||
return response.result.tags.map(({ tag, count }) => ({
|
||||
term: tag,
|
||||
count,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
export function deleteAnnotation(annotation: AnnotationEvent) {
|
||||
return getBackendSrv().delete(`/api/annotations/${annotation.id}`);
|
||||
}
|
||||
let instance: AnnotationServer | null = null;
|
||||
|
||||
export async function getAnnotationTags() {
|
||||
const response: AnnotationTagsResponse = await getBackendSrv().get('/api/annotations/tags');
|
||||
return response.result.tags.map(({ tag, count }) => ({
|
||||
term: tag,
|
||||
count,
|
||||
}));
|
||||
export function annotationServer(): AnnotationServer {
|
||||
if (!instance) {
|
||||
instance = new LegacyAnnotationServer();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { config, getDataSourceSrv } from '@grafana/runtime';
|
||||
import { AdHocFiltersVariable, dataLayers, sceneGraph, sceneUtils, VizPanel } from '@grafana/scenes';
|
||||
import { DataSourceRef } from '@grafana/schema';
|
||||
import { AdHocFilterItem, PanelContext } from '@grafana/ui';
|
||||
import { deleteAnnotation, saveAnnotation, updateAnnotation } from 'app/features/annotations/api';
|
||||
import { annotationServer } from 'app/features/annotations/api';
|
||||
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
import { getDashboardSceneFor, getPanelIdForVizPanel, getQueryRunnerFor } from '../utils/utils';
|
||||
@@ -84,7 +84,7 @@ export function setDashboardPanelContext(vizPanel: VizPanel, context: PanelConte
|
||||
text: event.description,
|
||||
};
|
||||
|
||||
await saveAnnotation(anno);
|
||||
await annotationServer().save(anno);
|
||||
|
||||
reRunBuiltInAnnotationsLayer(dashboard);
|
||||
|
||||
@@ -106,7 +106,7 @@ export function setDashboardPanelContext(vizPanel: VizPanel, context: PanelConte
|
||||
text: event.description,
|
||||
};
|
||||
|
||||
await updateAnnotation(anno);
|
||||
await annotationServer().update(anno);
|
||||
|
||||
reRunBuiltInAnnotationsLayer(dashboard);
|
||||
|
||||
@@ -114,7 +114,7 @@ export function setDashboardPanelContext(vizPanel: VizPanel, context: PanelConte
|
||||
};
|
||||
|
||||
context.onAnnotationDelete = async (id: string) => {
|
||||
await deleteAnnotation({ id });
|
||||
await annotationServer().delete({ id });
|
||||
|
||||
reRunBuiltInAnnotationsLayer(getDashboardSceneFor(vizPanel));
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
import appEvents from 'app/core/app_events';
|
||||
import config from 'app/core/config';
|
||||
import { profiler } from 'app/core/profiler';
|
||||
import { annotationServer } from 'app/features/annotations/api';
|
||||
import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
|
||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { applyFilterFromTable } from 'app/features/variables/adhoc/actions';
|
||||
@@ -43,7 +44,6 @@ import { changeSeriesColorConfigFactory } from 'app/plugins/panel/timeseries/ove
|
||||
import { dispatch } from 'app/store/store';
|
||||
import { RenderEvent } from 'app/types/events';
|
||||
|
||||
import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../annotations/api';
|
||||
import { getDashboardQueryRunner } from '../../query/state/DashboardQueryRunner/DashboardQueryRunner';
|
||||
import { getTimeSrv, TimeSrv } from '../services/TimeSrv';
|
||||
import { DashboardModel } from '../state/DashboardModel';
|
||||
@@ -421,13 +421,13 @@ export class PanelStateWrapper extends PureComponent<Props, State> {
|
||||
tags: event.tags,
|
||||
text: event.description,
|
||||
};
|
||||
await saveAnnotation(anno);
|
||||
await annotationServer().save(anno);
|
||||
getDashboardQueryRunner().run({ dashboard: this.props.dashboard, range: this.timeSrv.timeRange() });
|
||||
this.state.context.eventBus.publish(new AnnotationChangeEvent(anno));
|
||||
};
|
||||
|
||||
onAnnotationDelete = async (id: string) => {
|
||||
await deleteAnnotation({ id });
|
||||
await annotationServer().delete({ id });
|
||||
getDashboardQueryRunner().run({ dashboard: this.props.dashboard, range: this.timeSrv.timeRange() });
|
||||
this.state.context.eventBus.publish(new AnnotationChangeEvent({ id }));
|
||||
};
|
||||
@@ -444,7 +444,7 @@ export class PanelStateWrapper extends PureComponent<Props, State> {
|
||||
tags: event.tags,
|
||||
text: event.description,
|
||||
};
|
||||
await updateAnnotation(anno);
|
||||
await annotationServer().update(anno);
|
||||
|
||||
getDashboardQueryRunner().run({ dashboard: this.props.dashboard, range: this.timeSrv.timeRange() });
|
||||
this.state.context.eventBus.publish(new AnnotationChangeEvent(anno));
|
||||
|
||||
@@ -6,7 +6,7 @@ import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { Field, FieldSet, Select, Switch, useStyles2 } from '@grafana/ui';
|
||||
import { TagFilter } from 'app/core/components/TagFilter/TagFilter';
|
||||
import { TimeRegionConfig } from 'app/core/utils/timeRegions';
|
||||
import { getAnnotationTags } from 'app/features/annotations/api';
|
||||
import { annotationServer } from 'app/features/annotations/api';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
|
||||
import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery, GrafanaQueryType } from '../types';
|
||||
@@ -146,7 +146,7 @@ export default function AnnotationQueryEditor({ query, onChange }: Props) {
|
||||
allowCustomValue
|
||||
inputId="grafana-annotations__tags"
|
||||
onChange={onTagsChange}
|
||||
tagOptions={getAnnotationTags}
|
||||
tagOptions={annotationServer().tags}
|
||||
tags={tags ?? []}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
@@ -13,19 +13,18 @@ import {
|
||||
isValidLiveChannelAddress,
|
||||
MutableDataFrame,
|
||||
parseLiveChannelAddress,
|
||||
toDataFrame,
|
||||
dataFrameFromJSON,
|
||||
LoadingState,
|
||||
} from '@grafana/data';
|
||||
import {
|
||||
DataSourceWithBackend,
|
||||
getBackendSrv,
|
||||
getDataSourceSrv,
|
||||
getGrafanaLiveSrv,
|
||||
getTemplateSrv,
|
||||
StreamingFrameOptions,
|
||||
} from '@grafana/runtime';
|
||||
import { DataSourceRef } from '@grafana/schema';
|
||||
import { annotationServer } from 'app/features/annotations/api';
|
||||
import { migrateDatasourceNameToRef } from 'app/features/dashboard/state/DashboardMigrator';
|
||||
|
||||
import { getDashboardSrv } from '../../../features/dashboard/services/DashboardSrv';
|
||||
@@ -241,12 +240,11 @@ export class GrafanaDatasource extends DataSourceWithBackend<GrafanaQuery> {
|
||||
params.tags = tags;
|
||||
}
|
||||
|
||||
const annotations = await getBackendSrv().get(
|
||||
'/api/annotations',
|
||||
const df = await annotationServer().query(
|
||||
params,
|
||||
`grafana-data-source-annotations-${annotation.name}-${options.dashboard?.uid}`
|
||||
);
|
||||
return { data: [toDataFrame(annotations)] };
|
||||
return { data: [df] };
|
||||
}
|
||||
|
||||
testDatasource(): Promise<TestDataSourceResponse> {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Trans, t } from '@grafana/i18n';
|
||||
import { Button, Field, Stack, TextArea, usePanelContext, useStyles2 } from '@grafana/ui';
|
||||
import { Form } from 'app/core/components/Form/Form';
|
||||
import { TagFilter } from 'app/core/components/TagFilter/TagFilter';
|
||||
import { getAnnotationTags } from 'app/features/annotations/api';
|
||||
import { annotationServer } from 'app/features/annotations/api';
|
||||
|
||||
interface Props {
|
||||
annoVals: Record<string, any[]>;
|
||||
@@ -109,7 +109,7 @@ export const AnnotationEditor2 = ({ annoVals, annoIdx, dismiss, timeZone, ...oth
|
||||
allowCustomValue
|
||||
placeholder={t('timeseries.annotation-editor2.placeholder-add-tags', 'Add tags')}
|
||||
onChange={onChange}
|
||||
tagOptions={getAnnotationTags}
|
||||
tagOptions={annotationServer().tags}
|
||||
tags={field.value}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user