mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 06:41:49 +08:00
Alert panel filters (#11712)
alert list panel: filter alerts by name, dashboard, folder, tags
This commit is contained in:

committed by
Marcus Efraimsson

parent
13a9701581
commit
0c269d64d0
@ -35,10 +35,15 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
|
|||||||
|
|
||||||
`/api/alerts?dashboardId=1`
|
`/api/alerts?dashboardId=1`
|
||||||
|
|
||||||
- **dashboardId** – Return alerts for a specified dashboard.
|
- **dashboardId** – Limit response to alerts in specified dashboard(s). You can specify multiple dashboards, e.g. dashboardId=23&dashboardId=35.
|
||||||
- **panelId** – Return alerts for a specified panel on a dashboard.
|
- **panelId** – Limit response to alert for a specified panel on a dashboard.
|
||||||
- **limit** - Limit response to x number of alerts.
|
- **query** - Limit response to alerts having a name like this value.
|
||||||
- **state** - Return alerts with one or more of the following alert states: `ALL`,`no_data`, `paused`, `alerting`, `ok`, `pending`. To specify multiple states use the following format: `?state=paused&state=alerting`
|
- **state** - Return alerts with one or more of the following alert states: `ALL`,`no_data`, `paused`, `alerting`, `ok`, `pending`. To specify multiple states use the following format: `?state=paused&state=alerting`
|
||||||
|
- **limit** - Limit response to *X* number of alerts.
|
||||||
|
- **folderId** – Limit response to alerts of dashboards in specified folder(s). You can specify multiple folders, e.g. folderId=23&folderId=35.
|
||||||
|
- **dashboardQuery** - Limit response to alerts having a dashboard name like this value.
|
||||||
|
- **dashboardTag** - Limit response to alerts of dashboards with specified tags. To do an "AND" filtering with multiple tags, specify the tags parameter multiple times e.g. dashboardTag=tag1&dashboardTag=tag2.
|
||||||
|
|
||||||
|
|
||||||
**Example Response**:
|
**Example Response**:
|
||||||
|
|
||||||
|
@ -2,12 +2,14 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ValidateOrgAlert(c *m.ReqContext) {
|
func ValidateOrgAlert(c *m.ReqContext) {
|
||||||
@ -46,12 +48,64 @@ func GetAlertStatesForDashboard(c *m.ReqContext) Response {
|
|||||||
|
|
||||||
// GET /api/alerts
|
// GET /api/alerts
|
||||||
func GetAlerts(c *m.ReqContext) Response {
|
func GetAlerts(c *m.ReqContext) Response {
|
||||||
|
dashboardQuery := c.Query("dashboardQuery")
|
||||||
|
dashboardTags := c.QueryStrings("dashboardTag")
|
||||||
|
stringDashboardIDs := c.QueryStrings("dashboardId")
|
||||||
|
stringFolderIDs := c.QueryStrings("folderId")
|
||||||
|
|
||||||
|
dashboardIDs := make([]int64, 0)
|
||||||
|
for _, id := range stringDashboardIDs {
|
||||||
|
dashboardID, err := strconv.ParseInt(id, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
dashboardIDs = append(dashboardIDs, dashboardID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dashboardQuery != "" || len(dashboardTags) > 0 || len(stringFolderIDs) > 0 {
|
||||||
|
folderIDs := make([]int64, 0)
|
||||||
|
for _, id := range stringFolderIDs {
|
||||||
|
folderID, err := strconv.ParseInt(id, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
folderIDs = append(folderIDs, folderID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
searchQuery := search.Query{
|
||||||
|
Title: dashboardQuery,
|
||||||
|
Tags: dashboardTags,
|
||||||
|
SignedInUser: c.SignedInUser,
|
||||||
|
Limit: 1000,
|
||||||
|
OrgId: c.OrgId,
|
||||||
|
DashboardIds: dashboardIDs,
|
||||||
|
Type: string(search.DashHitDB),
|
||||||
|
FolderIds: folderIDs,
|
||||||
|
Permission: m.PERMISSION_EDIT,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := bus.Dispatch(&searchQuery)
|
||||||
|
if err != nil {
|
||||||
|
return Error(500, "List alerts failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range searchQuery.Result {
|
||||||
|
if d.Type == search.DashHitDB && d.Id > 0 {
|
||||||
|
dashboardIDs = append(dashboardIDs, d.Id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we didn't find any dashboards, return empty result
|
||||||
|
if len(dashboardIDs) == 0 {
|
||||||
|
return JSON(200, []*m.AlertListItemDTO{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query := m.GetAlertsQuery{
|
query := m.GetAlertsQuery{
|
||||||
OrgId: c.OrgId,
|
OrgId: c.OrgId,
|
||||||
DashboardId: c.QueryInt64("dashboardId"),
|
DashboardIDs: dashboardIDs,
|
||||||
PanelId: c.QueryInt64("panelId"),
|
PanelId: c.QueryInt64("panelId"),
|
||||||
Limit: c.QueryInt64("limit"),
|
Limit: c.QueryInt64("limit"),
|
||||||
User: c.SignedInUser,
|
User: c.SignedInUser,
|
||||||
|
Query: c.Query("query"),
|
||||||
}
|
}
|
||||||
|
|
||||||
states := c.QueryStrings("state")
|
states := c.QueryStrings("state")
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
|
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
@ -64,6 +65,60 @@ func TestAlertingApiEndpoint(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/alerts?dashboardId=1", "/api/alerts", m.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||||
|
var searchQuery *search.Query
|
||||||
|
bus.AddHandler("test", func(query *search.Query) error {
|
||||||
|
searchQuery = query
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var getAlertsQuery *m.GetAlertsQuery
|
||||||
|
bus.AddHandler("test", func(query *m.GetAlertsQuery) error {
|
||||||
|
getAlertsQuery = query
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
sc.handlerFunc = GetAlerts
|
||||||
|
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||||
|
|
||||||
|
So(searchQuery, ShouldBeNil)
|
||||||
|
So(getAlertsQuery, ShouldNotBeNil)
|
||||||
|
})
|
||||||
|
|
||||||
|
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/alerts?dashboardId=1&dashboardId=2&folderId=3&dashboardTag=abc&dashboardQuery=dbQuery&limit=5&query=alertQuery", "/api/alerts", m.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||||
|
var searchQuery *search.Query
|
||||||
|
bus.AddHandler("test", func(query *search.Query) error {
|
||||||
|
searchQuery = query
|
||||||
|
query.Result = search.HitList{
|
||||||
|
&search.Hit{Id: 1},
|
||||||
|
&search.Hit{Id: 2},
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var getAlertsQuery *m.GetAlertsQuery
|
||||||
|
bus.AddHandler("test", func(query *m.GetAlertsQuery) error {
|
||||||
|
getAlertsQuery = query
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
sc.handlerFunc = GetAlerts
|
||||||
|
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||||
|
|
||||||
|
So(searchQuery, ShouldNotBeNil)
|
||||||
|
So(searchQuery.DashboardIds[0], ShouldEqual, 1)
|
||||||
|
So(searchQuery.DashboardIds[1], ShouldEqual, 2)
|
||||||
|
So(searchQuery.FolderIds[0], ShouldEqual, 3)
|
||||||
|
So(searchQuery.Tags[0], ShouldEqual, "abc")
|
||||||
|
So(searchQuery.Title, ShouldEqual, "dbQuery")
|
||||||
|
|
||||||
|
So(getAlertsQuery, ShouldNotBeNil)
|
||||||
|
So(getAlertsQuery.DashboardIDs[0], ShouldEqual, 1)
|
||||||
|
So(getAlertsQuery.DashboardIDs[1], ShouldEqual, 2)
|
||||||
|
So(getAlertsQuery.Limit, ShouldEqual, 5)
|
||||||
|
So(getAlertsQuery.Query, ShouldEqual, "alertQuery")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,12 +161,13 @@ type SetAlertStateCommand struct {
|
|||||||
|
|
||||||
//Queries
|
//Queries
|
||||||
type GetAlertsQuery struct {
|
type GetAlertsQuery struct {
|
||||||
OrgId int64
|
OrgId int64
|
||||||
State []string
|
State []string
|
||||||
DashboardId int64
|
DashboardIDs []int64
|
||||||
PanelId int64
|
PanelId int64
|
||||||
Limit int64
|
Limit int64
|
||||||
User *SignedInUser
|
Query string
|
||||||
|
User *SignedInUser
|
||||||
|
|
||||||
Result []*AlertListItemDTO
|
Result []*AlertListItemDTO
|
||||||
}
|
}
|
||||||
|
@ -82,8 +82,16 @@ func HandleAlertsQuery(query *m.GetAlertsQuery) error {
|
|||||||
|
|
||||||
builder.Write(`WHERE alert.org_id = ?`, query.OrgId)
|
builder.Write(`WHERE alert.org_id = ?`, query.OrgId)
|
||||||
|
|
||||||
if query.DashboardId != 0 {
|
if len(strings.TrimSpace(query.Query)) > 0 {
|
||||||
builder.Write(` AND alert.dashboard_id = ?`, query.DashboardId)
|
builder.Write(" AND alert.name "+dialect.LikeStr()+" ?", "%"+query.Query+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(query.DashboardIDs) > 0 {
|
||||||
|
builder.sql.WriteString(` AND alert.dashboard_id IN (?` + strings.Repeat(",?", len(query.DashboardIDs)-1) + `) `)
|
||||||
|
|
||||||
|
for _, dbID := range query.DashboardIDs {
|
||||||
|
builder.AddParams(dbID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if query.PanelId != 0 {
|
if query.PanelId != 0 {
|
||||||
|
@ -3,10 +3,11 @@ package sqlstore
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func mockTimeNow() {
|
func mockTimeNow() {
|
||||||
@ -99,7 +100,7 @@ func TestAlertingDataAccess(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Can read properties", func() {
|
Convey("Can read properties", func() {
|
||||||
alertQuery := m.GetAlertsQuery{DashboardId: testDash.Id, PanelId: 1, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
alertQuery := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
||||||
err2 := HandleAlertsQuery(&alertQuery)
|
err2 := HandleAlertsQuery(&alertQuery)
|
||||||
|
|
||||||
alert := alertQuery.Result[0]
|
alert := alertQuery.Result[0]
|
||||||
@ -109,7 +110,7 @@ func TestAlertingDataAccess(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Viewer cannot read alerts", func() {
|
Convey("Viewer cannot read alerts", func() {
|
||||||
alertQuery := m.GetAlertsQuery{DashboardId: testDash.Id, PanelId: 1, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_VIEWER}}
|
alertQuery := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_VIEWER}}
|
||||||
err2 := HandleAlertsQuery(&alertQuery)
|
err2 := HandleAlertsQuery(&alertQuery)
|
||||||
|
|
||||||
So(err2, ShouldBeNil)
|
So(err2, ShouldBeNil)
|
||||||
@ -134,7 +135,7 @@ func TestAlertingDataAccess(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Alerts should be updated", func() {
|
Convey("Alerts should be updated", func() {
|
||||||
query := m.GetAlertsQuery{DashboardId: testDash.Id, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
query := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
||||||
err2 := HandleAlertsQuery(&query)
|
err2 := HandleAlertsQuery(&query)
|
||||||
|
|
||||||
So(err2, ShouldBeNil)
|
So(err2, ShouldBeNil)
|
||||||
@ -183,7 +184,7 @@ func TestAlertingDataAccess(t *testing.T) {
|
|||||||
Convey("Should save 3 dashboards", func() {
|
Convey("Should save 3 dashboards", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
queryForDashboard := m.GetAlertsQuery{DashboardId: testDash.Id, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
queryForDashboard := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
||||||
err2 := HandleAlertsQuery(&queryForDashboard)
|
err2 := HandleAlertsQuery(&queryForDashboard)
|
||||||
|
|
||||||
So(err2, ShouldBeNil)
|
So(err2, ShouldBeNil)
|
||||||
@ -197,7 +198,7 @@ func TestAlertingDataAccess(t *testing.T) {
|
|||||||
err = SaveAlerts(&cmd)
|
err = SaveAlerts(&cmd)
|
||||||
|
|
||||||
Convey("should delete the missing alert", func() {
|
Convey("should delete the missing alert", func() {
|
||||||
query := m.GetAlertsQuery{DashboardId: testDash.Id, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
query := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
||||||
err2 := HandleAlertsQuery(&query)
|
err2 := HandleAlertsQuery(&query)
|
||||||
So(err2, ShouldBeNil)
|
So(err2, ShouldBeNil)
|
||||||
So(len(query.Result), ShouldEqual, 2)
|
So(len(query.Result), ShouldEqual, 2)
|
||||||
@ -232,7 +233,7 @@ func TestAlertingDataAccess(t *testing.T) {
|
|||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
Convey("Alerts should be removed", func() {
|
Convey("Alerts should be removed", func() {
|
||||||
query := m.GetAlertsQuery{DashboardId: testDash.Id, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
query := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
|
||||||
err2 := HandleAlertsQuery(&query)
|
err2 := HandleAlertsQuery(&query)
|
||||||
|
|
||||||
So(testDash.Id, ShouldEqual, 1)
|
So(testDash.Id, ShouldEqual, 1)
|
||||||
|
@ -12,6 +12,7 @@ export class FolderPickerCtrl {
|
|||||||
enterFolderCreation: any;
|
enterFolderCreation: any;
|
||||||
exitFolderCreation: any;
|
exitFolderCreation: any;
|
||||||
enableCreateNew: boolean;
|
enableCreateNew: boolean;
|
||||||
|
enableReset: boolean;
|
||||||
rootName = 'General';
|
rootName = 'General';
|
||||||
folder: any;
|
folder: any;
|
||||||
createNewFolder: boolean;
|
createNewFolder: boolean;
|
||||||
@ -58,6 +59,10 @@ export class FolderPickerCtrl {
|
|||||||
result.unshift({ title: '-- New Folder --', id: -1 });
|
result.unshift({ title: '-- New Folder --', id: -1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.enableReset && query === '' && this.initialTitle !== '') {
|
||||||
|
result.unshift({ title: this.initialTitle, id: null });
|
||||||
|
}
|
||||||
|
|
||||||
return _.map(result, item => {
|
return _.map(result, item => {
|
||||||
return { text: item.title, value: item.id };
|
return { text: item.title, value: item.id };
|
||||||
});
|
});
|
||||||
@ -65,7 +70,9 @@ export class FolderPickerCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onFolderChange(option) {
|
onFolderChange(option) {
|
||||||
if (option.value === -1) {
|
if (!option) {
|
||||||
|
option = { value: 0, text: this.rootName };
|
||||||
|
} else if (option.value === -1) {
|
||||||
this.createNewFolder = true;
|
this.createNewFolder = true;
|
||||||
this.enterFolderCreation();
|
this.enterFolderCreation();
|
||||||
return;
|
return;
|
||||||
@ -134,7 +141,7 @@ export class FolderPickerCtrl {
|
|||||||
this.onFolderLoad();
|
this.onFolderLoad();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (this.initialTitle) {
|
if (this.initialTitle && this.initialFolderId === null) {
|
||||||
this.folder = { text: this.initialTitle, value: null };
|
this.folder = { text: this.initialTitle, value: null };
|
||||||
} else {
|
} else {
|
||||||
this.folder = { text: this.rootName, value: 0 };
|
this.folder = { text: this.rootName, value: 0 };
|
||||||
@ -171,6 +178,7 @@ export function folderPicker() {
|
|||||||
enterFolderCreation: '&',
|
enterFolderCreation: '&',
|
||||||
exitFolderCreation: '&',
|
exitFolderCreation: '&',
|
||||||
enableCreateNew: '@',
|
enableCreateNew: '@',
|
||||||
|
enableReset: '@',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,30 @@
|
|||||||
</div>
|
</div>
|
||||||
<gf-form-switch class="gf-form" label="Alerts from this dashboard" label-class="width-18" checked="ctrl.panel.onlyAlertsOnDashboard" on-change="ctrl.updateStateFilter()"></gf-form-switch>
|
<gf-form-switch class="gf-form" label="Alerts from this dashboard" label-class="width-18" checked="ctrl.panel.onlyAlertsOnDashboard" on-change="ctrl.updateStateFilter()"></gf-form-switch>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section gf-form-group" ng-show="ctrl.panel.show === 'current'">
|
||||||
|
<h5 class="section-heading">Filter</h5>
|
||||||
|
<div class="gf-form">
|
||||||
|
<span class="gf-form-label width-8">Alert name</span>
|
||||||
|
<input type="text" class="gf-form-input max-width-15" ng-model="ctrl.panel.nameFilter" placeholder="Alert name query" ng-change="ctrl.onRefresh()" />
|
||||||
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<span class="gf-form-label width-8">Dashboard title</span>
|
||||||
|
<input type="text" class="gf-form-input" placeholder="Dashboard title query" ng-model="ctrl.panel.dashboardFilter" ng-change="ctrl.onRefresh()" ng-model-onblur>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<folder-picker initial-folder-id="ctrl.panel.folderId"
|
||||||
|
on-change="ctrl.onFolderChange($folder)"
|
||||||
|
label-class="width-8"
|
||||||
|
initial-title="'All'"
|
||||||
|
enable-reset="true" >
|
||||||
|
</folder-picker>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<span class="gf-form-label width-8">Dashboard tags</span>
|
||||||
|
<bootstrap-tagsinput ng-model="ctrl.panel.dashboardTags" tagclass="label label-tag" placeholder="add tags" on-tags-updated="ctrl.refresh()">
|
||||||
|
</bootstrap-tagsinput>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="section gf-form-group" ng-show="ctrl.panel.show === 'current'">
|
<div class="section gf-form-group" ng-show="ctrl.panel.show === 'current'">
|
||||||
<h5 class="section-heading">State filter</h5>
|
<h5 class="section-heading">State filter</h5>
|
||||||
<gf-form-switch class="gf-form" label="Ok" label-class="width-10" checked="ctrl.stateFilter['ok']" on-change="ctrl.updateStateFilter()"></gf-form-switch>
|
<gf-form-switch class="gf-form" label="Ok" label-class="width-10" checked="ctrl.stateFilter['ok']" on-change="ctrl.updateStateFilter()"></gf-form-switch>
|
||||||
|
@ -21,6 +21,7 @@ class AlertListPanel extends PanelCtrl {
|
|||||||
currentAlerts: any = [];
|
currentAlerts: any = [];
|
||||||
alertHistory: any = [];
|
alertHistory: any = [];
|
||||||
noAlertsMessage: string;
|
noAlertsMessage: string;
|
||||||
|
|
||||||
// Set and populate defaults
|
// Set and populate defaults
|
||||||
panelDefaults = {
|
panelDefaults = {
|
||||||
show: 'current',
|
show: 'current',
|
||||||
@ -28,6 +29,9 @@ class AlertListPanel extends PanelCtrl {
|
|||||||
stateFilter: [],
|
stateFilter: [],
|
||||||
onlyAlertsOnDashboard: false,
|
onlyAlertsOnDashboard: false,
|
||||||
sortOrder: 1,
|
sortOrder: 1,
|
||||||
|
dashboardFilter: '',
|
||||||
|
nameFilter: '',
|
||||||
|
folderId: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
@ -89,6 +93,11 @@ class AlertListPanel extends PanelCtrl {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onFolderChange(folder: any) {
|
||||||
|
this.panel.folderId = folder.id;
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
getStateChanges() {
|
getStateChanges() {
|
||||||
var params: any = {
|
var params: any = {
|
||||||
limit: this.panel.limit,
|
limit: this.panel.limit,
|
||||||
@ -110,6 +119,7 @@ class AlertListPanel extends PanelCtrl {
|
|||||||
al.info = alertDef.getAlertAnnotationInfo(al);
|
al.info = alertDef.getAlertAnnotationInfo(al);
|
||||||
return al;
|
return al;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.noAlertsMessage = this.alertHistory.length === 0 ? 'No alerts in current time range' : '';
|
this.noAlertsMessage = this.alertHistory.length === 0 ? 'No alerts in current time range' : '';
|
||||||
|
|
||||||
return this.alertHistory;
|
return this.alertHistory;
|
||||||
@ -121,10 +131,26 @@ class AlertListPanel extends PanelCtrl {
|
|||||||
state: this.panel.stateFilter,
|
state: this.panel.stateFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this.panel.nameFilter) {
|
||||||
|
params.query = this.panel.nameFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.panel.folderId >= 0) {
|
||||||
|
params.folderId = this.panel.folderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.panel.dashboardFilter) {
|
||||||
|
params.dashboardQuery = this.panel.dashboardFilter;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.panel.onlyAlertsOnDashboard) {
|
if (this.panel.onlyAlertsOnDashboard) {
|
||||||
params.dashboardId = this.dashboard.id;
|
params.dashboardId = this.dashboard.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.panel.dashboardTags) {
|
||||||
|
params.dashboardTag = this.panel.dashboardTags;
|
||||||
|
}
|
||||||
|
|
||||||
return this.backendSrv.get(`/api/alerts`, params).then(res => {
|
return this.backendSrv.get(`/api/alerts`, params).then(res => {
|
||||||
this.currentAlerts = this.sortResult(
|
this.currentAlerts = this.sortResult(
|
||||||
_.map(res, al => {
|
_.map(res, al => {
|
||||||
@ -135,6 +161,9 @@ class AlertListPanel extends PanelCtrl {
|
|||||||
return al;
|
return al;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
if (this.currentAlerts.length > this.panel.limit) {
|
||||||
|
this.currentAlerts = this.currentAlerts.slice(0, this.panel.limit);
|
||||||
|
}
|
||||||
this.noAlertsMessage = this.currentAlerts.length === 0 ? 'No alerts' : '';
|
this.noAlertsMessage = this.currentAlerts.length === 0 ? 'No alerts' : '';
|
||||||
|
|
||||||
return this.currentAlerts;
|
return this.currentAlerts;
|
||||||
|
Reference in New Issue
Block a user