diff --git a/pkg/api/annotations.go b/pkg/api/annotations.go index 2803aa46435..48bf6c327ad 100644 --- a/pkg/api/annotations.go +++ b/pkg/api/annotations.go @@ -44,3 +44,19 @@ func GetAnnotations(c *middleware.Context) Response { return Json(200, result) } + +func DeleteAnnotations(c *middleware.Context, cmd dtos.DeleteAnnotationsCmd) Response { + repo := annotations.GetRepository() + + err := repo.Delete(&annotations.DeleteParams{ + AlertId: cmd.PanelId, + DashboardId: cmd.DashboardId, + PanelId: cmd.PanelId, + }) + + if err != nil { + return ApiError(500, "Failed to delete annotations", err) + } + + return ApiSuccess("Annotations deleted") +} diff --git a/pkg/api/api.go b/pkg/api/api.go index 5609536e213..71adc7da063 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -269,6 +269,7 @@ func Register(r *macaron.Macaron) { }, reqOrgAdmin) r.Get("/annotations", wrap(GetAnnotations)) + r.Post("/annotations/mass-delete", reqOrgAdmin, bind(dtos.DeleteAnnotationsCmd{}), wrap(DeleteAnnotations)) // error test r.Get("/metrics/error", wrap(GenerateError)) diff --git a/pkg/api/dtos/annotations.go b/pkg/api/dtos/annotations.go index a5d5823e1a4..45415978ee1 100644 --- a/pkg/api/dtos/annotations.go +++ b/pkg/api/dtos/annotations.go @@ -15,3 +15,9 @@ type Annotation struct { Data *simplejson.Json `json:"data"` } + +type DeleteAnnotationsCmd struct { + AlertId int64 `json:"alertId"` + DashboardId int64 `json:"dashboardId"` + PanelId int64 `json:"panelId"` +} diff --git a/pkg/services/annotations/annotations.go b/pkg/services/annotations/annotations.go index 189c3d823cf..3fc3bafe5c5 100644 --- a/pkg/services/annotations/annotations.go +++ b/pkg/services/annotations/annotations.go @@ -5,6 +5,7 @@ import "github.com/grafana/grafana/pkg/components/simplejson" type Repository interface { Save(item *Item) error Find(query *ItemQuery) ([]*Item, error) + Delete(params *DeleteParams) error } type ItemQuery struct { @@ -20,6 +21,12 @@ type ItemQuery struct { Limit int64 `json:"alertId"` } +type DeleteParams struct { + AlertId int64 `json:"alertId"` + DashboardId int64 `json:"dashboardId"` + PanelId int64 `json:"panelId"` +} + var repositoryInstance Repository func GetRepository() Repository { diff --git a/pkg/services/sqlstore/annotation.go b/pkg/services/sqlstore/annotation.go index 3ea8647d3fa..e219f48d2fe 100644 --- a/pkg/services/sqlstore/annotation.go +++ b/pkg/services/sqlstore/annotation.go @@ -84,3 +84,17 @@ func (r *SqlAnnotationRepo) Find(query *annotations.ItemQuery) ([]*annotations.I return items, nil } + +func (r *SqlAnnotationRepo) Delete(params *annotations.DeleteParams) error { + return inTransaction(func(sess *xorm.Session) error { + + sql := "DELETE FROM annotation WHERE dashboard_id = ? AND panel_id = ?" + + _, err := sess.Exec(sql, params.DashboardId, params.PanelId) + if err != nil { + return err + } + + return nil + }) +} diff --git a/public/app/features/alerting/alert_tab_ctrl.ts b/public/app/features/alerting/alert_tab_ctrl.ts index b7e0e4ac218..61c4d658ed1 100644 --- a/public/app/features/alerting/alert_tab_ctrl.ts +++ b/public/app/features/alerting/alert_tab_ctrl.ts @@ -59,7 +59,7 @@ export class AlertTabCtrl { this.panelCtrl.render(); }); - // build notification model + // build notification model this.notifications = []; this.alertNotifications = []; this.alertHistory = []; @@ -352,6 +352,24 @@ export class AlertTabCtrl { this.evaluatorParamsChanged(); } + clearHistory() { + appEvents.emit('confirm-modal', { + title: 'Delete Alert History', + text: 'Are you sure you want to remove all history & annotations for this alert?', + icon: 'fa-trash', + yesText: 'Yes', + onConfirm: () => { + this.backendSrv.post('/api/annotations/mass-delete', { + dashboardId: this.panelCtrl.dashboard.id, + panelId: this.panel.id, + }).then(res => { + this.alertHistory = []; + this.panelCtrl.refresh(); + }); + } + }); + } + test() { this.testing = true; diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html index 07ff28dcddb..4dd5516945b 100644 --- a/public/app/features/alerting/partials/alert_tab.html +++ b/public/app/features/alerting/partials/alert_tab.html @@ -125,7 +125,16 @@
-
State history (last 50 state changes)
+ +
+ State history (last 50 state changes) +
+ +
+
+ No state changes recorded +
+
  1. diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 7e19d00251f..6a3e49b8455 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -392,17 +392,21 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) { position: 'BOTTOM', markerSize: 5, }; + types['$__ok'] = { color: 'rgba(11, 237, 50, 1)', position: 'BOTTOM', markerSize: 5, }; - types['$__nodata'] = { + + types['$__no_data'] = { color: 'rgba(150, 150, 150, 1)', position: 'BOTTOM', markerSize: 5, }; + types['$__execution_error'] = ['$__no_data']; + for (var i = 0; i < annotations.length; i++) { var item = annotations[i]; if (item.newState) { diff --git a/public/sass/components/edit_sidemenu.scss b/public/sass/components/edit_sidemenu.scss index d6c56fcc521..aa6f1c3535d 100644 --- a/public/sass/components/edit_sidemenu.scss +++ b/public/sass/components/edit_sidemenu.scss @@ -4,6 +4,10 @@ flex-direction: row; } +.edit-tab-content { + flex-grow: 1; +} + .edit-sidemenu-aside { width: 16rem; }