grafana/public/app/features/annotations/annotations_srv.ts
kay delaney cf2cc71393 Chore: Remove angular dependency from backendSrv (#20999)
* Chore: Remove angular dependency from backendSrv

* Refactor: Naive soultion for logging out unauthorized users

* Refactor: Restructures to different streams

* Refactor: Restructures datasourceRequest

* Refactor: Flipped back if statement

* Refactor: Extracted getFromFetchStream

* Refactor: Extracts toFailureStream operation

* Refactor: Fixes issue when options.params contains arrays

* Refactor: Fixes broken test (but we need a lot more)

* Refactor: Adds explaining comments

* Refactor: Adds latest RxJs version so cancellations work

* Refactor: Cleans up the takeUntil code

* Refactor: Adds tests for request function

* Refactor: Separates into smaller functions

* Refactor: Adds last error tests

* Started to changed so we require getBackendSrv from the @grafana-runtime when applicable.

* Using the getBackendSrv from @grafana/runtime.

* Changed so we use the getBackendSrv from the @grafana-runtime when possible.

* Fixed so Server Admin -> Orgs works again.

* Removed unused dependency.

* Fixed digest issues on the Server Admin -> Users page.

* Fix: Fixes digest problems in Playlists

* Fix: Fixes digest issues in VersionHistory

* Tests: Fixes broken tests

* Fix: Fixes digest issues in Alerting => Notification channels

* Fixed digest issues on the Intive page.

* Fixed so we run digest after password reset email sent.

* Fixed digest issue when trying to sign up account.

* Fixed so the Server Admin -> Edit Org works with backendSrv

* Fixed so Server Admin -> Users works with backend srv.

* Fixed digest issues in Server Admin -> Orgs

* Fix: Fixes digest issues in DashList plugin

* Fixed digest issues on Server Admin -> users.

* Fix: Fixes digest issues with Snapshots

* Fixed digest issue when deleting a user.

* Fix: Fixes digest issues with dashLink

* Chore: Changes RxJs version to 6.5.4 which includes the same cancellation fix

* Fix: Fixes digest issue when toggling folder in manage dashboards

* Fix: Fixes bug in executeInOrder

* Fix: Fixes digest issue with CreateFolderCtrl and FolderDashboardsCtrl

* Fix: Fixes tslint error in test

* Refactor: Changes default behaviour for emitted messages as before migration

* Fix: Fixes various digest issues when saving, starring or deleting dashboards

* Fix: Fixes digest issues with FolderPickerCtrl

* Fixed digest issue.

* Fixed digest issues.

* Fixed issues with angular digest.

* Removed the this.digest pattern.

Co-authored-by: Hugo Häggmark <hugo.haggmark@gmail.com>
Co-authored-by: Marcus Andersson <systemvetaren@gmail.com>
2020-01-21 10:08:07 +01:00

178 lines
5.5 KiB
TypeScript

// Libaries
import flattenDeep from 'lodash/flattenDeep';
import cloneDeep from 'lodash/cloneDeep';
// Components
import './editor_ctrl';
import coreModule from 'app/core/core_module';
// Utils & Services
import { dedupAnnotations } from './events_processing';
// Types
import { DashboardModel } from '../dashboard/state/DashboardModel';
import { DataSourceApi, PanelEvents, AnnotationEvent, AppEvents, PanelModel, TimeRange } from '@grafana/data';
import { appEvents } from 'app/core/core';
import { getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
import { getTimeSrv } from '../dashboard/services/TimeSrv';
export class AnnotationsSrv {
globalAnnotationsPromise: any;
alertStatesPromise: any;
datasourcePromises: any;
init(dashboard: DashboardModel) {
// always clearPromiseCaches when loading new dashboard
this.clearPromiseCaches();
// clear promises on refresh events
dashboard.on(PanelEvents.refresh, this.clearPromiseCaches.bind(this));
}
clearPromiseCaches() {
this.globalAnnotationsPromise = null;
this.alertStatesPromise = null;
this.datasourcePromises = null;
}
getAnnotations(options: { dashboard: DashboardModel; panel: PanelModel; range: TimeRange }) {
return Promise.all([this.getGlobalAnnotations(options), this.getAlertStates(options)])
.then(results => {
// combine the annotations and flatten results
let annotations: AnnotationEvent[] = flattenDeep(results[0]);
// filter out annotations that do not belong to requesting panel
annotations = annotations.filter(item => {
// if event has panel id and query is of type dashboard then panel and requesting panel id must match
if (item.panelId && item.source.type === 'dashboard') {
return item.panelId === options.panel.id;
}
return true;
});
annotations = dedupAnnotations(annotations);
// look for alert state for this panel
const alertState: any = results[1].find((res: any) => res.panelId === options.panel.id);
return {
annotations: annotations,
alertState: alertState,
};
})
.catch(err => {
if (!err.message && err.data && err.data.message) {
err.message = err.data.message;
}
console.log('AnnotationSrv.query error', err);
appEvents.emit(AppEvents.alertError, ['Annotation Query Failed', err.message || err]);
return [];
});
}
getAlertStates(options: any) {
if (!options.dashboard.id) {
return Promise.resolve([]);
}
// ignore if no alerts
if (options.panel && !options.panel.alert) {
return Promise.resolve([]);
}
if (options.range.raw.to !== 'now') {
return Promise.resolve([]);
}
if (this.alertStatesPromise) {
return this.alertStatesPromise;
}
this.alertStatesPromise = getBackendSrv().get('/api/alerts/states-for-dashboard', {
dashboardId: options.dashboard.id,
});
return this.alertStatesPromise;
}
getGlobalAnnotations(options: { dashboard: DashboardModel; panel: PanelModel; range: TimeRange }) {
const dashboard = options.dashboard;
if (this.globalAnnotationsPromise) {
return this.globalAnnotationsPromise;
}
const range = getTimeSrv().timeRange();
const promises = [];
const dsPromises = [];
for (const annotation of dashboard.annotations.list) {
if (!annotation.enable) {
continue;
}
if (annotation.snapshotData) {
return this.translateQueryResult(annotation, annotation.snapshotData);
}
const datasourcePromise = getDataSourceSrv().get(annotation.datasource);
dsPromises.push(datasourcePromise);
promises.push(
datasourcePromise
.then((datasource: DataSourceApi) => {
// issue query against data source
return datasource.annotationQuery({
range,
rangeRaw: range.raw,
annotation: annotation,
dashboard: dashboard,
});
})
.then(results => {
// store response in annotation object if this is a snapshot call
if (dashboard.snapshot) {
annotation.snapshotData = cloneDeep(results);
}
// translate result
return this.translateQueryResult(annotation, results);
})
);
}
this.datasourcePromises = Promise.all(dsPromises);
this.globalAnnotationsPromise = Promise.all(promises);
return this.globalAnnotationsPromise;
}
saveAnnotationEvent(annotation: AnnotationEvent) {
this.globalAnnotationsPromise = null;
return getBackendSrv().post('/api/annotations', annotation);
}
updateAnnotationEvent(annotation: AnnotationEvent) {
this.globalAnnotationsPromise = null;
return getBackendSrv().put(`/api/annotations/${annotation.id}`, annotation);
}
deleteAnnotationEvent(annotation: AnnotationEvent) {
this.globalAnnotationsPromise = null;
const deleteUrl = `/api/annotations/${annotation.id}`;
return getBackendSrv().delete(deleteUrl);
}
translateQueryResult(annotation: any, results: any) {
// if annotation has snapshotData
// make clone and remove it
if (annotation.snapshotData) {
annotation = cloneDeep(annotation);
delete annotation.snapshotData;
}
for (const item of results) {
item.source = annotation;
item.isRegion = item.timeEnd && item.time !== item.timeEnd;
}
return results;
}
}
coreModule.service('annotationsSrv', AnnotationsSrv);