event_editor.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { cloneDeep, isNumber } from 'lodash';
  2. import { AnnotationEvent, dateTime } from '@grafana/data';
  3. import { coreModule } from 'app/angular/core_module';
  4. import { MetricsPanelCtrl } from 'app/angular/panel/metrics_panel_ctrl';
  5. import { contextSrv } from '../../../core/services/context_srv';
  6. import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../../features/annotations/api';
  7. import { getDashboardQueryRunner } from '../../../features/query/state/DashboardQueryRunner/DashboardQueryRunner';
  8. export class EventEditorCtrl {
  9. // @ts-ignore initialized through Angular not constructor
  10. panelCtrl: MetricsPanelCtrl;
  11. // @ts-ignore initialized through Angular not constructor
  12. event: AnnotationEvent;
  13. timeRange?: { from: number; to: number };
  14. form: any;
  15. close: any;
  16. timeFormated?: string;
  17. /** @ngInject */
  18. constructor() {}
  19. $onInit() {
  20. this.event.panelId = this.panelCtrl.panel.id; // set correct id if in panel edit
  21. this.event.dashboardId = this.panelCtrl.dashboard.id;
  22. // Annotations query returns time as Unix timestamp in milliseconds
  23. this.event.time = tryEpochToMoment(this.event.time);
  24. if (this.event.isRegion) {
  25. this.event.timeEnd = tryEpochToMoment(this.event.timeEnd);
  26. }
  27. this.timeFormated = this.panelCtrl.dashboard.formatDate(this.event.time!);
  28. }
  29. canDelete(): boolean {
  30. if (contextSrv.accessControlEnabled()) {
  31. if (this.event.source.type === 'dashboard') {
  32. return !!this.panelCtrl.dashboard.meta.annotationsPermissions?.dashboard.canDelete;
  33. }
  34. return !!this.panelCtrl.dashboard.meta.annotationsPermissions?.organization.canDelete;
  35. }
  36. return true;
  37. }
  38. async save(): Promise<void> {
  39. if (!this.form.$valid) {
  40. return;
  41. }
  42. const saveModel = cloneDeep(this.event);
  43. saveModel.time = saveModel.time!.valueOf();
  44. saveModel.timeEnd = 0;
  45. if (saveModel.isRegion) {
  46. saveModel.timeEnd = this.event.timeEnd!.valueOf();
  47. if (saveModel.timeEnd < saveModel.time) {
  48. console.log('invalid time');
  49. return;
  50. }
  51. }
  52. let crudFunction = saveAnnotation;
  53. if (saveModel.id) {
  54. crudFunction = updateAnnotation;
  55. }
  56. try {
  57. await crudFunction(saveModel);
  58. } catch (err) {
  59. console.log(err);
  60. } finally {
  61. this.close();
  62. getDashboardQueryRunner().run({ dashboard: this.panelCtrl.dashboard, range: this.panelCtrl.range });
  63. }
  64. }
  65. async delete(): Promise<void> {
  66. try {
  67. await deleteAnnotation(this.event);
  68. } catch (err) {
  69. console.log(err);
  70. } finally {
  71. this.close();
  72. getDashboardQueryRunner().run({ dashboard: this.panelCtrl.dashboard, range: this.panelCtrl.range });
  73. }
  74. }
  75. }
  76. function tryEpochToMoment(timestamp: any) {
  77. if (timestamp && isNumber(timestamp)) {
  78. const epoch = Number(timestamp);
  79. return dateTime(epoch);
  80. } else {
  81. return timestamp;
  82. }
  83. }
  84. export function eventEditor() {
  85. return {
  86. restrict: 'E',
  87. controller: EventEditorCtrl,
  88. bindToController: true,
  89. controllerAs: 'ctrl',
  90. templateUrl: 'public/app/features/annotations/partials/event_editor.html',
  91. scope: {
  92. panelCtrl: '=',
  93. event: '=',
  94. close: '&',
  95. },
  96. };
  97. }
  98. coreModule.directive('eventEditor', eventEditor);