Browse Source

graph: initial Add Annotation flow #1286

Alexander Zobnin 8 years ago
parent
commit
32d34aed7a

+ 12 - 0
public/app/features/annotations/annotations_srv.ts

@@ -126,6 +126,18 @@ export class AnnotationsSrv {
     return this.globalAnnotationsPromise;
   }
 
+  postAnnotation(annotation) {
+    console.log("POST /api/annotations\n", annotation);
+
+    // Not implemented yet
+    let implemented = false;
+    if (implemented) {
+      return this.backendSrv.post('/api/annotations', annotation);
+    } else {
+      return Promise.resolve("Not implemented");
+    }
+  }
+
   translateQueryResult(annotation, results) {
     for (var item of results) {
       item.source = annotation;

+ 49 - 0
public/app/features/dashboard/addAnnotationModalCtrl.ts

@@ -0,0 +1,49 @@
+///<reference path="../../headers/common.d.ts" />
+
+import angular from 'angular';
+import moment from 'moment';
+
+export class AddAnnotationModalCtrl {
+  annotationTime: any;
+  annotationTimeFormat = 'YYYY-MM-DD HH:mm:ss';
+  annotation: any;
+  graphCtrl: any;
+
+  /** @ngInject */
+  constructor(private $scope) {
+    this.graphCtrl = $scope.ctrl;
+    $scope.ctrl = this;
+
+    this.annotation = {
+      time: null,
+      title: "",
+      text: ""
+    };
+
+    this.annotationTime = moment(this.$scope.annotationTimeUnix).format(this.annotationTimeFormat);
+  }
+
+  addAnnotation() {
+    let time = moment(this.annotationTime, this.annotationTimeFormat);
+    this.annotation.time = time.valueOf();
+
+    this.graphCtrl.pushAnnotation(this.annotation)
+    .then(response => {
+      console.log(response);
+      this.close();
+    })
+    .catch(error => {
+      console.log(error);
+      this.close();
+    });
+  }
+
+  close() {
+    this.graphCtrl.inAddAnnotationMode = false;
+    this.$scope.dismiss();
+  }
+}
+
+angular
+  .module('grafana.controllers')
+  .controller('AddAnnotationModalCtrl', AddAnnotationModalCtrl);

+ 1 - 0
public/app/features/dashboard/all.js

@@ -7,6 +7,7 @@ define([
   './saveDashboardAsCtrl',
   './shareModalCtrl',
   './shareSnapshotCtrl',
+  './addAnnotationModalCtrl',
   './dashboard_srv',
   './viewStateSrv',
   './time_srv',

+ 62 - 0
public/app/features/dashboard/partials/addAnnotationModal.html

@@ -0,0 +1,62 @@
+<div class="modal-body" ng-controller="AddAnnotationModalCtrl">
+
+  <div class="modal-header">
+    <h2 class="modal-header-title">
+      Add Annotation
+    </h2>
+
+    <a class="modal-header-close" ng-click="ctrl.close()">
+      <i class="fa fa-remove"></i>
+    </a>
+  </div>
+
+
+  <div class="modal-content">
+    <div class="share-modal-body">
+      <div class="share-modal-header">
+
+        <div class="share-modal-big-icon">
+          <i class="fa fa-tag"></i>
+        </div>
+
+        <div class="share-modal-content">
+
+          <div class="gf-form-group share-modal-options">
+            <p class="share-modal-info-text">
+              Add annotation details.
+            </p>
+
+            <div class="gf-form">
+              <span class="gf-form-label width-7">Title</span>
+              <input type="text" ng-model="ctrl.annotation.title" class="gf-form-input max-width-20">
+            </div>
+            <div class="gf-form">
+              <span class="gf-form-label width-7">Time</span>
+              <input type="text" ng-model="ctrl.annotationTime" class="gf-form-input max-width-20">
+            </div>
+          </div>
+
+          <div>
+            <h6>
+              Description
+            </h6>
+          </div>
+          <div class="gf-form-group share-modal-options">
+            <div class="gf-form">
+              <textarea rows="3" class="gf-form-input width-27" ng-model="ctrl.annotation.text"></textarea>
+            </div>
+          </div>
+
+          <div class="gf-form-button-row">
+            <button class="btn gf-form-btn width-10 btn-success" ng-click="ctrl.addAnnotation()">
+              <i class="fa fa-pencil"></i>
+              Add Annotation
+            </button>
+          </div>
+        </div>
+
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 8 - 0
public/app/plugins/panel/graph/graph.ts

@@ -79,6 +79,14 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv) {
         }
       }, scope);
 
+      appEvents.on('graph-click', (event) => {
+
+        // Select time for new annotation
+        if (ctrl.inAddAnnotationMode) {
+          ctrl.showAddAnnotationModal(event);
+        }
+      }, scope);
+
       function getLegendHeight(panelHeight) {
         if (!panel.legend.show || panel.legend.rightSide) {
           return 0;

+ 23 - 0
public/app/plugins/panel/graph/module.ts

@@ -24,6 +24,7 @@ class GraphCtrl extends MetricsPanelCtrl {
   dataList: any = [];
   annotations: any = [];
   alertState: any;
+  inAddAnnotationMode = false;
 
   annotationsPromise: any;
   dataWarning: any;
@@ -144,6 +145,7 @@ class GraphCtrl extends MetricsPanelCtrl {
     actions.push({text: 'Export CSV (series as rows)', click: 'ctrl.exportCsv()'});
     actions.push({text: 'Export CSV (series as columns)', click: 'ctrl.exportCsvColumns()'});
     actions.push({text: 'Toggle legend', click: 'ctrl.toggleLegend()'});
+    actions.push({ text: 'Add Annotation', click: 'ctrl.enableAddAnnotationMode()' });
   }
 
   issueQueries(datasource) {
@@ -300,6 +302,27 @@ class GraphCtrl extends MetricsPanelCtrl {
     this.refresh();
   }
 
+  enableAddAnnotationMode() {
+    // TODO: notify user about time selection mode
+    this.inAddAnnotationMode = true;
+  }
+
+  // Get annotation info from dialog and push it to backend
+  pushAnnotation(annotation) {
+    return this.annotationsSrv.postAnnotation(annotation);
+  }
+
+  showAddAnnotationModal(event) {
+    let addAnnotationScope = this.$scope.$new();
+    let annotationTimeUnix = Math.round(event.pos.x);
+    addAnnotationScope.annotationTimeUnix = annotationTimeUnix;
+
+    this.publishAppEvent('show-modal', {
+      src: 'public/app/features/dashboard/partials/addAnnotationModal.html',
+      scope: addAnnotationScope
+    });
+  }
+
   legendValuesOptionChanged() {
     var legend = this.panel.legend;
     legend.values = legend.min || legend.max || legend.avg || legend.current || legend.total;