浏览代码

Merge remote-tracking branch 'upstream/create-annotations' into create-annotations

Alexander Zobnin 8 年之前
父节点
当前提交
eeb998d712

+ 22 - 3
pkg/api/annotations.go

@@ -39,6 +39,8 @@ func GetAnnotations(c *middleware.Context) Response {
 			Text:      item.Text,
 			Metric:    item.Metric,
 			Title:     item.Title,
+			PanelId:   item.PanelId,
+			RegionId:  item.RegionId,
 		})
 	}
 
@@ -55,14 +57,31 @@ func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response
 		Epoch:       cmd.Time / 1000,
 		Title:       cmd.Title,
 		Text:        cmd.Text,
+		CategoryId:  cmd.CategoryId,
+		NewState:    cmd.FillColor,
+		Type:        annotations.EventType,
 	}
 
-	err := repo.Save(&item)
-
-	if err != nil {
+	if err := repo.Save(&item); err != nil {
 		return ApiError(500, "Failed to save annotation", err)
 	}
 
+	// handle regions
+	if cmd.IsRegion {
+		item.RegionId = item.Id
+
+		if err := repo.Update(&item); err != nil {
+			return ApiError(500, "Failed set regionId on annotation", err)
+		}
+
+		item.Id = 0
+		item.Epoch = cmd.EndTime
+
+		if err := repo.Save(&item); err != nil {
+			return ApiError(500, "Failed save annotation for region end time", err)
+		}
+	}
+
 	return ApiSuccess("Annotation added")
 }
 

+ 4 - 2
pkg/api/api.go

@@ -277,8 +277,10 @@ func (hs *HttpServer) registerRoutes() {
 		}, reqEditorRole)
 
 		r.Get("/annotations", wrap(GetAnnotations))
-		r.Post("/annotations", bind(dtos.PostAnnotationsCmd{}), wrap(PostAnnotation))
-		r.Post("/annotations/mass-delete", reqOrgAdmin, bind(dtos.DeleteAnnotationsCmd{}), wrap(DeleteAnnotations))
+
+		r.Group("/annotations", func() {
+			r.Post("/", bind(dtos.PostAnnotationsCmd{}), wrap(PostAnnotation))
+		}, reqEditorRole)
 
 		// error test
 		r.Get("/metrics/error", wrap(GenerateError))

+ 6 - 0
pkg/api/dtos/annotations.go

@@ -12,6 +12,7 @@ type Annotation struct {
 	Title       string `json:"title"`
 	Text        string `json:"text"`
 	Metric      string `json:"metric"`
+	RegionId    int64  `json:"regionId"`
 
 	Data *simplejson.Json `json:"data"`
 }
@@ -19,9 +20,14 @@ type Annotation struct {
 type PostAnnotationsCmd struct {
 	DashboardId int64  `json:"dashboardId"`
 	PanelId     int64  `json:"panelId"`
+	CategoryId  int64  `json:"categoryId"`
 	Time        int64  `json:"time"`
 	Title       string `json:"title"`
 	Text        string `json:"text"`
+
+	FillColor string `json:"fillColor"`
+	IsRegion  bool   `json:"isRegion"`
+	EndTime   int64  `json:"endTime"`
 }
 
 type DeleteAnnotationsCmd struct {

+ 3 - 0
pkg/services/annotations/annotations.go

@@ -4,6 +4,7 @@ import "github.com/grafana/grafana/pkg/components/simplejson"
 
 type Repository interface {
 	Save(item *Item) error
+	Update(item *Item) error
 	Find(query *ItemQuery) ([]*Item, error)
 	Delete(params *DeleteParams) error
 }
@@ -49,6 +50,7 @@ type ItemType string
 
 const (
 	AlertType ItemType = "alert"
+	EventType ItemType = "event"
 )
 
 type Item struct {
@@ -57,6 +59,7 @@ type Item struct {
 	DashboardId int64    `json:"dashboardId"`
 	PanelId     int64    `json:"panelId"`
 	CategoryId  int64    `json:"categoryId"`
+	RegionId    int64    `json:"regionId"`
 	Type        ItemType `json:"type"`
 	Title       string   `json:"title"`
 	Text        string   `json:"text"`

+ 11 - 0
pkg/services/sqlstore/annotation.go

@@ -23,6 +23,17 @@ func (r *SqlAnnotationRepo) Save(item *annotations.Item) error {
 	})
 }
 
+func (r *SqlAnnotationRepo) Update(item *annotations.Item) error {
+	return inTransaction(func(sess *xorm.Session) error {
+
+		if _, err := sess.Table("annotation").Id(item.Id).Update(item); err != nil {
+			return err
+		}
+
+		return nil
+	})
+}
+
 func (r *SqlAnnotationRepo) Find(query *annotations.ItemQuery) ([]*annotations.Item, error) {
 	var sql bytes.Buffer
 	params := make([]interface{}, 0)

+ 4 - 0
pkg/services/sqlstore/migrations/annotation_mig.go

@@ -54,4 +54,8 @@ func addAnnotationMig(mg *Migrator) {
 		{Name: "new_state", Type: DB_NVarchar, Length: 25, Nullable: false},
 		{Name: "data", Type: DB_Text, Nullable: false},
 	}))
+
+	mg.AddMigration("Add column region_id to annotation table", NewAddColumnMigration(table, &Column{
+		Name: "region_id", Type: DB_BigInt, Nullable: true, Default: "0",
+	}))
 }

+ 10 - 14
public/app/features/annotations/annotations_srv.ts

@@ -35,6 +35,13 @@ export class AnnotationsSrv {
 
       // combine the annotations and flatten results
       var annotations = _.flattenDeep([results[0], results[1]]);
+      // filter out annotations that do not belong to requesting panel
+      annotations = _.filter(annotations, item => {
+        if (item.panelId && options.panel.id !== item.panelId) {
+          return false;
+        }
+        return true;
+      });
 
       // look for alert state for this panel
       var alertState = _.find(results[2], {panelId: options.panel.id});
@@ -127,20 +134,9 @@ export class AnnotationsSrv {
   }
 
   postAnnotation(annotations) {
-    console.log("POST /api/annotations\n", annotations);
-
-    // Not implemented yet
-    let implemented = true;
-    if (implemented) {
-      return Promise.all(_.map(annotations, annotation => {
-        return this.backendSrv.post('/api/annotations', annotation);
-      }))
-      .catch(error => {
-        console.log(error);
-      });
-    } else {
-      return Promise.resolve("Not implemented");
-    }
+    return Promise.all(_.map(annotations, annotation => {
+      return this.backendSrv.post('/api/annotations', annotation);
+    }));
   }
 
   translateQueryResult(annotation, results) {

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

@@ -61,7 +61,6 @@ export class AddAnnotationModalCtrl {
   }
 
   close() {
-    this.graphCtrl.inAddAnnotationMode = false;
     this.$scope.dismiss();
   }
 }

+ 1 - 1
public/app/plugins/datasource/grafana/partials/annotations.editor.html

@@ -4,7 +4,7 @@
 		<div class="gf-form">
 			<span class="gf-form-label width-7">Type</span>
 			<div class="gf-form-select-wrapper">
-				<select class="gf-form-input" ng-model="ctrl.annotation.type" ng-options="f.value as f.text for f in [{text: 'Alert', value: 'alert'}]">
+				<select class="gf-form-input" ng-model="ctrl.annotation.type" ng-options="f.value as f.text for f in [{text: 'Event', value: 'event'}, {text: 'Alert', value: 'alert'}]">
 				</select>
 			</div>
 		</div>

+ 2 - 4
public/app/plugins/panel/graph/graph.ts

@@ -84,7 +84,7 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv) {
         let thisPanelEvent = event.panel.id === ctrl.panel.id;
 
         // Select time for new annotation
-        let createAnnotation = ctrl.inAddAnnotationMode || event.pos.ctrlKey || event.pos.metaKey;
+        let createAnnotation = event.pos.ctrlKey || event.pos.metaKey;
         if (createAnnotation && thisPanelEvent) {
           let timeRange = {
             from: event.pos.x,
@@ -92,7 +92,6 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv) {
           };
 
           ctrl.showAddAnnotationModal(timeRange);
-          ctrl.inAddAnnotationMode = false;
         }
       }, scope);
 
@@ -656,12 +655,11 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv) {
       }
 
       elem.bind("plotselected", function (event, ranges) {
-        if (ctrl.inAddAnnotationMode || ranges.ctrlKey || ranges.metaKey) {
+        if (ranges.ctrlKey || ranges.metaKey) {
           // Create new annotation from time range
           let timeRange = ranges.xaxis;
           ctrl.showAddAnnotationModal(timeRange);
           plot.clearSelection();
-          ctrl.inAddAnnotationMode = false;
         } else {
           scope.$apply(function() {
             timeSrv.setTime({

+ 2 - 3
public/app/plugins/panel/graph/module.ts

@@ -24,7 +24,6 @@ class GraphCtrl extends MetricsPanelCtrl {
   dataList: any = [];
   annotations: any = [];
   alertState: any;
-  inAddAnnotationMode = false;
 
   annotationsPromise: any;
   dataWarning: any;
@@ -303,8 +302,8 @@ class GraphCtrl extends MetricsPanelCtrl {
   }
 
   enableAddAnnotationMode() {
-    // TODO: notify user about time selection mode
-    this.inAddAnnotationMode = true;
+    // placehoder for some other way to teach users
+    alert('selection region while holding down CTRL or CMD');
   }
 
   // Get annotation info from dialog and push it to backend