mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge remote-tracking branch 'upstream/create-annotations' into create-annotations
This commit is contained in:
commit
eeb998d712
@ -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")
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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 {
|
||||
|
@ -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"`
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
}))
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -61,7 +61,6 @@ export class AddAnnotationModalCtrl {
|
||||
}
|
||||
|
||||
close() {
|
||||
this.graphCtrl.inAddAnnotationMode = false;
|
||||
this.$scope.dismiss();
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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({
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user