Browse Source

feat(alerting): added clear history button to alert state history view, #6244

Torkel Ödegaard 9 years ago
parent
commit
c9d7eb0a7a

+ 16 - 0
pkg/api/annotations.go

@@ -44,3 +44,19 @@ func GetAnnotations(c *middleware.Context) Response {
 
 
 	return Json(200, result)
 	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")
+}

+ 1 - 0
pkg/api/api.go

@@ -269,6 +269,7 @@ func Register(r *macaron.Macaron) {
 		}, reqOrgAdmin)
 		}, reqOrgAdmin)
 
 
 		r.Get("/annotations", wrap(GetAnnotations))
 		r.Get("/annotations", wrap(GetAnnotations))
+		r.Post("/annotations/mass-delete", reqOrgAdmin, bind(dtos.DeleteAnnotationsCmd{}), wrap(DeleteAnnotations))
 
 
 		// error test
 		// error test
 		r.Get("/metrics/error", wrap(GenerateError))
 		r.Get("/metrics/error", wrap(GenerateError))

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

@@ -15,3 +15,9 @@ type Annotation struct {
 
 
 	Data *simplejson.Json `json:"data"`
 	Data *simplejson.Json `json:"data"`
 }
 }
+
+type DeleteAnnotationsCmd struct {
+	AlertId     int64 `json:"alertId"`
+	DashboardId int64 `json:"dashboardId"`
+	PanelId     int64 `json:"panelId"`
+}

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

@@ -5,6 +5,7 @@ import "github.com/grafana/grafana/pkg/components/simplejson"
 type Repository interface {
 type Repository interface {
 	Save(item *Item) error
 	Save(item *Item) error
 	Find(query *ItemQuery) ([]*Item, error)
 	Find(query *ItemQuery) ([]*Item, error)
+	Delete(params *DeleteParams) error
 }
 }
 
 
 type ItemQuery struct {
 type ItemQuery struct {
@@ -20,6 +21,12 @@ type ItemQuery struct {
 	Limit int64 `json:"alertId"`
 	Limit int64 `json:"alertId"`
 }
 }
 
 
+type DeleteParams struct {
+	AlertId     int64 `json:"alertId"`
+	DashboardId int64 `json:"dashboardId"`
+	PanelId     int64 `json:"panelId"`
+}
+
 var repositoryInstance Repository
 var repositoryInstance Repository
 
 
 func GetRepository() Repository {
 func GetRepository() Repository {

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

@@ -84,3 +84,17 @@ func (r *SqlAnnotationRepo) Find(query *annotations.ItemQuery) ([]*annotations.I
 
 
 	return items, nil
 	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
+	})
+}

+ 19 - 1
public/app/features/alerting/alert_tab_ctrl.ts

@@ -59,7 +59,7 @@ export class AlertTabCtrl {
       this.panelCtrl.render();
       this.panelCtrl.render();
     });
     });
 
 
-       // build notification model
+    // build notification model
     this.notifications = [];
     this.notifications = [];
     this.alertNotifications = [];
     this.alertNotifications = [];
     this.alertHistory = [];
     this.alertHistory = [];
@@ -352,6 +352,24 @@ export class AlertTabCtrl {
     this.evaluatorParamsChanged();
     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() {
   test() {
     this.testing = true;
     this.testing = true;
 
 

+ 10 - 1
public/app/features/alerting/partials/alert_tab.html

@@ -125,7 +125,16 @@
 		</div>
 		</div>
 
 
 		<div class="gf-form-group" style="max-width: 720px;" ng-if="ctrl.subTabIndex === 2">
 		<div class="gf-form-group" style="max-width: 720px;" ng-if="ctrl.subTabIndex === 2">
-      <h5 class="section-heading">State history <span class="muted small">(last 50 state changes)</span></h5>
+			<button class="btn btn-mini btn-danger pull-right" ng-click="ctrl.clearHistory()"><i class="fa fa-trash"></i>&nbsp;Clear history</button>
+      <h5 class="section-heading" style="whitespace: nowrap">
+				State history <span class="muted small">(last 50 state changes)</span>
+			</h5>
+
+      <div ng-show="ctrl.alertHistory.length === 0">
+        <br>
+        <i>No state changes recorded</i>
+      </div>
+
 			<section class="card-section card-list-layout-list">
 			<section class="card-section card-list-layout-list">
 				<ol class="card-list" >
 				<ol class="card-list" >
 					<li class="card-item-wrapper" ng-repeat="ah in ctrl.alertHistory">
 					<li class="card-item-wrapper" ng-repeat="ah in ctrl.alertHistory">

+ 5 - 1
public/app/plugins/panel/graph/graph.ts

@@ -392,17 +392,21 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
           position: 'BOTTOM',
           position: 'BOTTOM',
           markerSize: 5,
           markerSize: 5,
         };
         };
+
         types['$__ok'] = {
         types['$__ok'] = {
           color: 'rgba(11, 237, 50, 1)',
           color: 'rgba(11, 237, 50, 1)',
           position: 'BOTTOM',
           position: 'BOTTOM',
           markerSize: 5,
           markerSize: 5,
         };
         };
-        types['$__nodata'] = {
+
+        types['$__no_data'] = {
           color: 'rgba(150, 150, 150, 1)',
           color: 'rgba(150, 150, 150, 1)',
           position: 'BOTTOM',
           position: 'BOTTOM',
           markerSize: 5,
           markerSize: 5,
         };
         };
 
 
+        types['$__execution_error'] = ['$__no_data'];
+
         for (var i = 0; i < annotations.length; i++) {
         for (var i = 0; i < annotations.length; i++) {
           var item = annotations[i];
           var item = annotations[i];
           if (item.newState) {
           if (item.newState) {

+ 4 - 0
public/sass/components/edit_sidemenu.scss

@@ -4,6 +4,10 @@
   flex-direction: row;
   flex-direction: row;
 }
 }
 
 
+.edit-tab-content {
+  flex-grow: 1;
+}
+
 .edit-sidemenu-aside {
 .edit-sidemenu-aside {
   width: 16rem;
   width: 16rem;
 }
 }