Simplify alert UI
This commit is contained in:
parent
8f2aaff1db
commit
152df94088
4
api.go
4
api.go
|
@ -38,7 +38,7 @@ type API struct {
|
|||
config string
|
||||
uptime time.Time
|
||||
|
||||
groups func() []*UIGroup
|
||||
groups func() []*UIGroups
|
||||
|
||||
// context is an indirection for testing.
|
||||
context func(r *http.Request) context.Context
|
||||
|
@ -46,7 +46,7 @@ type API struct {
|
|||
}
|
||||
|
||||
// NewAPI returns a new API.
|
||||
func NewAPI(alerts provider.Alerts, silences provider.Silences, gf func() []*UIGroup) *API {
|
||||
func NewAPI(alerts provider.Alerts, silences provider.Silences, gf func() []*UIGroups) *API {
|
||||
return &API{
|
||||
context: route.Context,
|
||||
alerts: alerts,
|
||||
|
|
33
dispatch.go
33
dispatch.go
|
@ -59,14 +59,19 @@ func (d *Dispatcher) Run() {
|
|||
// UIGroup is the representation of a group of alerts as provided by
|
||||
// the API.
|
||||
type UIGroup struct {
|
||||
Matchers types.Matchers `json:"matchers"`
|
||||
RouteOpts *RouteOpts `json:"routeOpts"`
|
||||
Labels model.LabelSet `json:"labels"`
|
||||
Alerts model.Alerts `json:"alerts"`
|
||||
RouteOpts *RouteOpts `json:"routeOpts"`
|
||||
Alerts model.Alerts `json:"alerts"`
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Groups() []*UIGroup {
|
||||
var groups []*UIGroup
|
||||
type UIGroups struct {
|
||||
Labels model.LabelSet `json:"labels"`
|
||||
Groups []*UIGroup `json:"groups"`
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Groups() []*UIGroups {
|
||||
var groups []*UIGroups
|
||||
|
||||
seen := map[model.Fingerprint]*UIGroups{}
|
||||
|
||||
for route, ags := range d.aggrGroups {
|
||||
for _, ag := range ags {
|
||||
|
@ -75,14 +80,18 @@ func (d *Dispatcher) Groups() []*UIGroup {
|
|||
alerts = append(alerts, a)
|
||||
}
|
||||
|
||||
uig := &UIGroup{
|
||||
Matchers: route.SquashMatchers(),
|
||||
Labels: ag.labels,
|
||||
RouteOpts: &route.RouteOpts,
|
||||
Alerts: types.Alerts(alerts...),
|
||||
uig, ok := seen[ag.labels.Fingerprint()]
|
||||
if !ok {
|
||||
uig = &UIGroups{Labels: ag.labels}
|
||||
|
||||
seen[ag.labels.Fingerprint()] = uig
|
||||
groups = append(groups, uig)
|
||||
}
|
||||
|
||||
groups = append(groups, uig)
|
||||
uig.Groups = append(uig.Groups, &UIGroup{
|
||||
RouteOpts: &route.RouteOpts,
|
||||
Alerts: types.Alerts(alerts...),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
main.go
2
main.go
|
@ -66,7 +66,7 @@ func main() {
|
|||
)
|
||||
defer disp.Stop()
|
||||
|
||||
api := NewAPI(alerts, silences, func() []*UIGroup {
|
||||
api := NewAPI(alerts, silences, func() []*UIGroups {
|
||||
return disp.Groups()
|
||||
})
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ angular.module('am.directives').directive('alert',
|
|||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
a: '='
|
||||
alert: '=',
|
||||
hiddenLabels: '='
|
||||
},
|
||||
templateUrl: '/app/partials/alert.html'
|
||||
};
|
||||
|
@ -202,11 +203,11 @@ angular.module('am.controllers').controller('AlertCtrl',
|
|||
$scope.silence = {
|
||||
matchers: []
|
||||
}
|
||||
angular.forEach($scope.a.labels, function(value, key) {
|
||||
angular.forEach($scope.alert.labels, function(value, key) {
|
||||
this.push({
|
||||
name: key,
|
||||
value: value,
|
||||
isRegex: false,
|
||||
isRegex: false
|
||||
});
|
||||
}, $scope.silence.matchers);
|
||||
|
||||
|
@ -219,11 +220,25 @@ angular.module('am.controllers').controller('AlertCtrl',
|
|||
angular.module('am.controllers').controller('AlertsCtrl',
|
||||
function($scope, AlertGroups) {
|
||||
$scope.groups = null;
|
||||
$scope.allDestinations = [];
|
||||
|
||||
$scope.refresh = function() {
|
||||
AlertGroups.query({},
|
||||
function(data) {
|
||||
$scope.groups = data.data;
|
||||
|
||||
$scope.allDestinations = [];
|
||||
angular.forEach($scope.groups, function(group) {
|
||||
angular.forEach(group.groups, function(g) {
|
||||
if ($scope.allDestinations.indexOf(g.routeOpts.sendTo) < 0) {
|
||||
$scope.allDestinations.push(g.routeOpts.sendTo);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (!$scope.destinations) {
|
||||
$scope.destinations = angular.copy($scope.allDestinations);
|
||||
}
|
||||
},
|
||||
function(data) {
|
||||
$scope.error = data.data;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="alert-item" ng-controller="AlertCtrl">
|
||||
<div class="overview group">
|
||||
<div class="labels left" ng-click="toggleDetails()">
|
||||
<span ng-repeat="(name, value) in a.labels | orderBy:name">
|
||||
<span class="lbl {{ name == 'alertname' ? 'lbl-highlight' : '' }}" outline>
|
||||
<span ng-repeat="(name, value) in alert.labels | orderBy:name">
|
||||
<span ng-hide="hiddenLabels.indexOf(name) >= 0" class="lbl {{ name == 'alertname' ? 'lbl-highlight' : '' }}" outline>
|
||||
{{ name }} = '{{ value }}'
|
||||
</span>
|
||||
</span>
|
||||
|
@ -23,12 +23,12 @@
|
|||
<tr>
|
||||
<td>active</td>
|
||||
<td>
|
||||
<span>{{ a.startsAt | date:'yyyy-MM-dd HH:mm' }}</span>
|
||||
<span>{{ alert.startsAt | date:'yyyy-MM-dd HH:mm' }}</span>
|
||||
–
|
||||
<span ng-hide="a.endsAt == '0001-01-01T00:00:00Z'">
|
||||
<span class="date">{{ a.endsAt | date:'yyyy-MM-dd' }},</span> <span class="time">{{ a.endsAt | date:'HH:mm' }}</span>
|
||||
<span class="date">{{ alert.endsAt | date:'yyyy-MM-dd' }},</span> <span class="time">{{ alert.endsAt | date:'HH:mm' }}</span>
|
||||
</span>
|
||||
<span ng-show="a.endsAt == '0001-01-01T00:00:00Z'">
|
||||
<span ng-show="alert.endsAt == '0001-01-01T00:00:00Z'">
|
||||
<span class="time">now</span>
|
||||
</span>
|
||||
</td>
|
||||
|
@ -38,7 +38,7 @@
|
|||
<td>
|
||||
<table class="table-flat">
|
||||
<tbody>
|
||||
<tr ng-repeat="(name, val) in a.annotations | orderBy:name">
|
||||
<tr ng-repeat="(name, val) in alert.annotations | orderBy:name">
|
||||
<td style="padding-right: 3em"><em>{{ name }}</em></td>
|
||||
<td style="white-space: pre-line;">{{ val }}</td>
|
||||
</tr>
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
<div>
|
||||
<select class="select" ng-model="destinations" multiple>
|
||||
<option ng-repeat="dest in allDestinations" value="{{ dest }}">{{ dest }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="alert-groups" ng-controller="AlertsCtrl">
|
||||
<div ng-repeat="group in groups">
|
||||
<div class="alert-group" ng-show"group.alerts">
|
||||
<div class="route-header group">
|
||||
<div class="route-matchers left">
|
||||
<span ng-repeat="m in group.matchers" class="lbl lbl-outline">
|
||||
{{ m.name }} =<span ng-show="m.isRegex">~</span> '{{ m.value }}'
|
||||
</span>
|
||||
<div class="alert-group-header group">
|
||||
<span ng-repeat="(ln, lv) in group.labels" class="lbl lbl-outline">
|
||||
{{ ln }} = '{{ lv }}'
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="g in group.groups">
|
||||
<div ng-show="destinations.indexOf(g.routeOpts.sendTo) >= 0" class="alert-group" ng-show"g.alerts">
|
||||
<div ng-repeat="a in g.alerts">
|
||||
<alert class="list-item" alert="a" hiddenLabels="Object.keys(group.labels)"></alert>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert-group-header group">
|
||||
<span ng-repeat="(ln, lv) in group.labels" class="lbl lbl-outline">
|
||||
{{ ln }} = '{{ lv }}'
|
||||
</span>
|
||||
</div>
|
||||
<div ng-repeat="a in group.alerts">
|
||||
<alert class="list-item" a="a"></alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -34,7 +34,7 @@
|
|||
<row>
|
||||
<column cols="2">
|
||||
<label>Creator</label>
|
||||
<input ng-model="silence.createdBy" type="email" required>
|
||||
<input ng-model="silence.createdBy" type="email" ng-required>
|
||||
</column>
|
||||
<column cols="4">
|
||||
<label>Comment</label>
|
||||
|
|
Loading…
Reference in New Issue