зеркало из https://github.com/mozilla/treeherder.git
Merge pull request #1219 from wlach/1234621
Bug 1234621 - Add basic client-side filtering to perfherder alerts
This commit is contained in:
Коммит
696476c268
|
@ -21,6 +21,9 @@ class TestOptionsSerializer(serializers.JSONField):
|
|||
|
||||
|
||||
class PerformanceSignatureSerializer(serializers.ModelSerializer):
|
||||
framework_id = serializers.SlugRelatedField(
|
||||
slug_field="id", source="framework",
|
||||
queryset=PerformanceFramework.objects.all())
|
||||
option_collection_hash = serializers.SlugRelatedField(
|
||||
read_only=True, slug_field="option_collection_hash",
|
||||
source="option_collection")
|
||||
|
@ -32,9 +35,9 @@ class PerformanceSignatureSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = PerformanceSignature
|
||||
fields = ['signature_hash', 'machine_platform', 'suite', 'test',
|
||||
'lower_is_better', 'option_collection_hash',
|
||||
'test_options']
|
||||
fields = ['framework_id', 'signature_hash', 'machine_platform',
|
||||
'suite', 'test', 'lower_is_better',
|
||||
'option_collection_hash', 'test_options']
|
||||
|
||||
|
||||
class PerformanceDecimalField(serializers.DecimalField):
|
||||
|
|
|
@ -83,16 +83,16 @@ perf.controller(
|
|||
|
||||
perf.controller('AlertsCtrl', [
|
||||
'$state', '$stateParams', '$scope', '$rootScope', '$http', '$q', '$modal',
|
||||
'thUrl', 'ThRepositoryModel', 'ThOptionCollectionModel', 'ThResultSetModel',
|
||||
'thDefaultRepo', 'PhSeries', 'PhAlerts', 'phTimeRanges', 'phDefaultTimeRangeValue',
|
||||
'phAlertResolutionMap', 'dateFilter', 'thDateFormat',
|
||||
'thUrl', 'ThOptionCollectionModel', 'ThResultSetModel',
|
||||
'PhFramework', 'PhSeries', 'PhAlerts', 'phTimeRanges',
|
||||
'phDefaultTimeRangeValue', 'phAlertResolutionMap', 'dateFilter',
|
||||
'thDateFormat',
|
||||
function AlertsCtrl($state, $stateParams, $scope, $rootScope, $http, $q,
|
||||
$modal,
|
||||
thUrl, ThRepositoryModel, ThOptionCollectionModel,
|
||||
ThResultSetModel, thDefaultRepo, PhSeries, PhAlerts,
|
||||
phTimeRanges, phDefaultTimeRangeValue,
|
||||
phAlertResolutionMap, dateFilter, thDateFormat) {
|
||||
|
||||
$modal, thUrl, ThOptionCollectionModel,
|
||||
ThResultSetModel, PhFramework,
|
||||
PhSeries, PhAlerts, phTimeRanges,
|
||||
phDefaultTimeRangeValue, phAlertResolutionMap,
|
||||
dateFilter, thDateFormat) {
|
||||
$scope.alertSummaries = [];
|
||||
$scope.getMoreAlertSummariesHref = null;
|
||||
$scope.getCappedMagnitude = function(percent) {
|
||||
|
@ -102,7 +102,6 @@ perf.controller('AlertsCtrl', [
|
|||
};
|
||||
$scope.phAlertResolutionMap = phAlertResolutionMap;
|
||||
|
||||
// these methods
|
||||
$scope.changeAlertSummaryStatus = function(alertSummary, status) {
|
||||
PhAlerts.changeAlertSummaryStatus(
|
||||
alertSummary.id, status).then(function() {
|
||||
|
@ -110,6 +109,41 @@ perf.controller('AlertsCtrl', [
|
|||
});
|
||||
};
|
||||
|
||||
function updateAlertVisibility() {
|
||||
_.forEach($scope.alertSummaries, function(alertSummary) {
|
||||
_.forEach(alertSummary.alerts, function(alert) {
|
||||
// only show alert if it passes all filter criteria
|
||||
alert.visible =
|
||||
(alert.series_signature.framework_id === $scope.filterOptions.framework.id) &&
|
||||
(!$scope.filterOptions.hideImprovements || alert.is_regression) &&
|
||||
_.every($scope.filterOptions.filter.split(' '),
|
||||
function(matchText) {
|
||||
return !matchText ||
|
||||
alert.title.toLowerCase().indexOf(
|
||||
matchText.toLowerCase()) > (-1);
|
||||
});
|
||||
});
|
||||
alertSummary.anyVisible = _.any(alertSummary.alerts,
|
||||
'visible');
|
||||
});
|
||||
$scope.numFilteredAlertSummaries = _.filter($scope.alertSummaries, { anyVisible: false }).length;
|
||||
|
||||
}
|
||||
|
||||
$scope.filtersUpdated = function() {
|
||||
$state.transitionTo('alerts', {
|
||||
framework: $scope.filterOptions.framework.id,
|
||||
filter: $scope.filterOptions.filter,
|
||||
hideImprovements: Boolean($scope.filterOptions.hideImprovements) ? undefined : 0,
|
||||
}, {
|
||||
location: true,
|
||||
inherit: true,
|
||||
relative: $state.$current,
|
||||
notify: false
|
||||
});
|
||||
updateAlertVisibility();
|
||||
};
|
||||
|
||||
// these methods handle the business logic of alert selection and
|
||||
// unselection
|
||||
$scope.anySelected = function(alerts) {
|
||||
|
@ -274,6 +308,7 @@ perf.controller('AlertsCtrl', [
|
|||
})).then(function() {
|
||||
$scope.alertSummaries = _.union($scope.alertSummaries,
|
||||
alertSummaries);
|
||||
updateAlertVisibility();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -284,27 +319,33 @@ perf.controller('AlertsCtrl', [
|
|||
});
|
||||
};
|
||||
|
||||
ThRepositoryModel.get_list().then(function(response) {
|
||||
$scope.projects = response.data;
|
||||
$scope.selectedProject = _.findWhere($scope.projects, {
|
||||
name: thDefaultRepo ? thDefaultRepo : thDefaultRepo
|
||||
});
|
||||
ThOptionCollectionModel.get_map().then(
|
||||
function(optionCollectionMap) {
|
||||
$scope.optionCollectionMap = optionCollectionMap;
|
||||
if ($stateParams.id) {
|
||||
PhAlerts.getAlertSummary($stateParams.id).then(
|
||||
function(data) {
|
||||
addAlertSummaries([data], null);
|
||||
});
|
||||
} else {
|
||||
PhAlerts.getAlertSummaries().then(function(data) {
|
||||
addAlertSummaries(data.results, data.next);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$q.all([PhFramework.getFrameworkList().then(
|
||||
function(frameworks) {
|
||||
$scope.frameworks = frameworks.data;
|
||||
}),
|
||||
ThOptionCollectionModel.get_map().then(
|
||||
function(optionCollectionMap) {
|
||||
$scope.optionCollectionMap = optionCollectionMap;
|
||||
})]
|
||||
).then(function() {
|
||||
$scope.filterOptions = {
|
||||
framework: _.find($scope.frameworks, {
|
||||
id: parseInt($stateParams.framework)
|
||||
}) || $scope.frameworks[0],
|
||||
filter: $stateParams.filter || "",
|
||||
hideImprovements: $stateParams.hideImprovements === undefined ||
|
||||
parseInt($stateParams.hideImprovements)
|
||||
};
|
||||
if ($stateParams.id) {
|
||||
PhAlerts.getAlertSummary($stateParams.id).then(
|
||||
function(data) {
|
||||
addAlertSummaries([data], null);
|
||||
});
|
||||
} else {
|
||||
PhAlerts.getAlertSummaries().then(function(data) {
|
||||
addAlertSummaries(data.results, data.next);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
|
|
@ -12,7 +12,7 @@ perf.config(function($compileProvider, $httpProvider, $stateProvider, $urlRouter
|
|||
$stateProvider.state('alerts', {
|
||||
title: 'Perfherder Alerts',
|
||||
templateUrl: 'partials/perf/alertsctrl.html',
|
||||
url: '/alerts?id',
|
||||
url: '/alerts?id&framework&filter&hideImprovements',
|
||||
controller: 'AlertsCtrl'
|
||||
}).state('graphs', {
|
||||
title: 'Perfherder Graphs',
|
||||
|
|
|
@ -1,144 +1,164 @@
|
|||
<div class="container-fluid">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
Perfherder alerts are experimental and not to be trusted (yet)
|
||||
</div>
|
||||
<div class="alert alert-warning" ng-show="!user.is_staff" role="alert">
|
||||
You must be logged into perfherder/treeherder and be a sheriff to make changes
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="panel panel-default alert-summary" ng-repeat="alertSummary in alertSummaries">
|
||||
<div class="panel-heading">
|
||||
<a href="#/alerts?id={{alertSummary.id}}" ng-class="{'alert-title-invalid': alertSummary.status==4}" class="alert-title">
|
||||
Alert #{{alertSummary.id}} - {{alertSummary.title}} <span class="fa fa-external-link icon-superscript"/>
|
||||
</a>
|
||||
<ul class="list-unstyled alert-metadata">
|
||||
<li>{{alertSummary.platforms.join(' / ')}}</li>
|
||||
<li>{{alertSummary.resultSetMetadata.dateStr}}</li>
|
||||
<li ng-if="alertSummary.pushURL">
|
||||
<a href="{{alertSummary.pushURL}}">{{alertSummary.resultSetMetadata.revision}}…{{alertSummary.prevResultSetMetadata.revision}}</a>
|
||||
</li>
|
||||
<li ng-if="!alertSummary.pushURL">
|
||||
<!-- This shouldn't happen in production, only in development -->
|
||||
<span class="text-danger">Unknown revision(s)</span>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline">
|
||||
<div class="form-group">
|
||||
<select ng-model="filterOptions.framework"
|
||||
ng-options="framework.name for framework in frameworks track by framework.id"
|
||||
ng-change="filtersUpdated()"/>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h4>Detected changes</h4>
|
||||
<table class="table table-striped compare-table">
|
||||
<tr>
|
||||
<th style="width:16px;">
|
||||
<input type="checkbox" ng-disabled="!user.is_staff" ng-model="alertSummary.allSelected" ng-change="selectNoneOrSelectAll(alertSummary)"/><!-- select 'em all checkbox --></th>
|
||||
<!-- Manually specify table widths because it's just easier this way -->
|
||||
<th class="test-title">
|
||||
<span style=" word-wrap: break-word;">
|
||||
Test
|
||||
</span>
|
||||
</th>
|
||||
<th style="width: 140px;">Previous</th>
|
||||
<th style="width: 30px;"><!-- less than / greater than --></th>
|
||||
<th style="width: 140px;">New</th>
|
||||
<th style="width: 80px;">Delta</th>
|
||||
<th style="width: 120px"><!-- Graphical difference --></th>
|
||||
<th style="width: 100px;">Confidence</th>
|
||||
</tr>
|
||||
<tr ng-repeat="alert in alertSummary.alerts">
|
||||
<td>
|
||||
<input type="checkbox" ng-disabled="!user.is_staff" ng-model="alert.selected" ng-change="alertSelected(alertSummary)"/>
|
||||
</td>
|
||||
<td class="test-title">
|
||||
<span ng-class="{'alert-strike': (alert.revised_summary_id || alert.status === phAlertResolutionMap.INVALID)}">
|
||||
{{alert.title}}
|
||||
</span>
|
||||
<span ng-show="alert.status === phAlertResolutionMap.INVALID">
|
||||
(<span class="alert-invalid">invalid</span>)
|
||||
</span>
|
||||
<span ng-show="alert.status === phAlertResolutionMap.UNTRIAGED">
|
||||
(<span class="alert-untriaged">untriaged</span>)
|
||||
</span>
|
||||
<span ng-show="alert.bug_number">
|
||||
(<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{alert.bug_number}}">bug #{{alert.bug_number}}</a>)
|
||||
</span>
|
||||
<span ng-show="alert.revised_summary_id">
|
||||
(see
|
||||
<a href="#/alerts?id={{alert.revised_summary_id}}">alert #{{alert.revised_summary_id}}</a>)
|
||||
</span>
|
||||
<span class="result-links">
|
||||
<a href="#/graphs?timerange={{alertSummary.resultSetMetadata.timeRange}}&series=[{{alertSummary.repository}},{{alert.series_signature.signature_hash}},1]&highlightedRevisions={{alertSummary.resultSetMetadata.revision}}">graph</a>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{alert.prev_value}}</td>
|
||||
<td>
|
||||
<span ng-class="{'compare-improvement': !alert.is_regression, 'compare-regression': alert.is_regression}">
|
||||
<span ng-if="alert.prev_value < alert.new_value">
|
||||
<
|
||||
</span>
|
||||
<span ng-if="alert.prev_value > alert.new_value">
|
||||
>
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{alert.new_value}}</td>
|
||||
<td><span class="detail-hint" tooltip="Absolute difference: {{alert.amount_abs}}">{{alert.amount_pct}}%</span></td>
|
||||
<td>
|
||||
<div ng-if="alert.is_regression" style="margin: auto; width: 80%;"
|
||||
tooltip="Relative magnitude of change (scale from 0 - 20%+)">
|
||||
<div class="bar bar-scale"
|
||||
style="width: {{100 - getCappedMagnitude(alert.amount_pct)}}%; height: 1em; float: left;">
|
||||
</div>
|
||||
<div class="bar bar-regression"
|
||||
style="width: {{getCappedMagnitude(alert.amount_pct)}}%; float: left;">
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="!alert.is_regression" style="margin: auto; width: 80%;"
|
||||
tooltip="Relative magnitude of change (scale from 0 - 20%+)">
|
||||
<div class="bar bar-improvement"
|
||||
style="width: {{getCappedMagnitude(alert.amount_pct)}}%; float: left;">
|
||||
</div>
|
||||
<div class="bar bar-scale"
|
||||
style="width: {{100 - getCappedMagnitude(alert.amount_pct)}}%; float: left; ">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<div class="form-group">
|
||||
<input id="filter" type="text" class="form-control" ng-model="filterOptions.filter" placeholder="filter text e.g. linux tp5o" ng-change="filtersUpdated()"/>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="filterOptions.hideImprovements" ng-change="filtersUpdated()"/>
|
||||
Hide improvements
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
<hr/>
|
||||
<div class="panel panel-default alert-summary" ng-repeat="alertSummary in alertSummaries" ng-if="alertSummary.anyVisible">
|
||||
<div class="panel-heading">
|
||||
<a href="#/alerts?id={{alertSummary.id}}" ng-class="{'alert-title-invalid': alertSummary.status==4}" class="alert-title">
|
||||
Alert #{{alertSummary.id}} - {{alertSummary.title}} <span class="fa fa-external-link icon-superscript"/>
|
||||
</a>
|
||||
<ul class="list-unstyled alert-metadata">
|
||||
<li>{{alertSummary.platforms.join(' / ')}}</li>
|
||||
<li>{{alertSummary.resultSetMetadata.dateStr}}</li>
|
||||
<li ng-if="alertSummary.pushURL">
|
||||
<a href="{{alertSummary.pushURL}}">{{alertSummary.resultSetMetadata.revision}}…{{alertSummary.prevResultSetMetadata.revision}}</a>
|
||||
</li>
|
||||
<li ng-if="!alertSummary.pushURL">
|
||||
<!-- This shouldn't happen in production, only in development -->
|
||||
<span class="text-danger">Unknown revision(s)</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h4>Detected changes</h4>
|
||||
|
||||
<td>
|
||||
<span class="detail-hint"
|
||||
tooltip="Confidence value as calculated by Perfherder alerts. Note that this is NOT the same as the calculation used in the compare view"
|
||||
tooltip-placement="left">
|
||||
{{alert.t_value}}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="padding-left: 8px;" ng-show="anySelected(alertSummary.alerts)">
|
||||
<div ng-if="!anySelectedAndTriaged(alertSummary.alerts)" class="btn-group" role="group" aria-label="alert-actions">
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="markAlertsInvalid(alertSummary)" title="Mark as invalid">
|
||||
<span class="fa fa-ban"></span>
|
||||
</button>
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="fileBug(alertSummary)" title="File bug for selected alerts">
|
||||
<span class="fa fa-bug"></span>
|
||||
</button>
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="addBugNumberToAlerts(alertSummary)" title="Link alerts to existing bug">
|
||||
<span class="fa fa-link"></span>
|
||||
</button>
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="reassignAlerts(alertSummary)"
|
||||
title="Associate with another alert summary">
|
||||
<span class="fa fa-share"></span>
|
||||
<table class="table table-striped compare-table">
|
||||
<tr>
|
||||
<th style="width:16px;">
|
||||
<input type="checkbox" ng-disabled="!user.is_staff" ng-model="alertSummary.allSelected" ng-change="selectNoneOrSelectAll(alertSummary)"/><!-- select 'em all checkbox --></th>
|
||||
<!-- Manually specify table widths because it's just easier this way -->
|
||||
<th class="test-title">
|
||||
<span style=" word-wrap: break-word;">
|
||||
Test
|
||||
</span>
|
||||
</th>
|
||||
<th style="width: 140px;">Previous</th>
|
||||
<th style="width: 30px;"><!-- less than / greater than --></th>
|
||||
<th style="width: 140px;">New</th>
|
||||
<th style="width: 80px;">Delta</th>
|
||||
<th style="width: 120px"><!-- Graphical difference --></th>
|
||||
<th style="width: 100px;">Confidence</th>
|
||||
</tr>
|
||||
<tr ng-repeat="alert in alertSummary.alerts" ng-show="alert.visible">
|
||||
<td>
|
||||
<input type="checkbox" ng-disabled="!user.is_staff" ng-model="alert.selected" ng-change="alertSelected(alertSummary)"/>
|
||||
</td>
|
||||
<td class="test-title">
|
||||
<span ng-class="{'alert-strike': (alert.revised_summary_id || alert.status === phAlertResolutionMap.INVALID)}">
|
||||
{{alert.title}}
|
||||
</span>
|
||||
<span ng-show="alert.status === phAlertResolutionMap.INVALID">
|
||||
(<span class="alert-invalid">invalid</span>)
|
||||
</span>
|
||||
<span ng-show="alert.status === phAlertResolutionMap.UNTRIAGED">
|
||||
(<span class="alert-untriaged">untriaged</span>)
|
||||
</span>
|
||||
<span ng-show="alert.bug_number">
|
||||
(<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{alert.bug_number}}">bug #{{alert.bug_number}}</a>)
|
||||
</span>
|
||||
<span ng-show="alert.revised_summary_id">
|
||||
(see
|
||||
<a href="#/alerts?id={{alert.revised_summary_id}}">alert #{{alert.revised_summary_id}}</a>)
|
||||
</span>
|
||||
<span class="result-links">
|
||||
<a href="#/graphs?timerange={{alertSummary.resultSetMetadata.timeRange}}&series=[{{alertSummary.repository}},{{alert.series_signature.signature_hash}},1]&highlightedRevisions={{alertSummary.resultSetMetadata.revision}}">graph</a>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{alert.prev_value}}</td>
|
||||
<td>
|
||||
<span ng-class="{'compare-improvement': !alert.is_regression, 'compare-regression': alert.is_regression}">
|
||||
<span ng-if="alert.prev_value < alert.new_value">
|
||||
<
|
||||
</span>
|
||||
<span ng-if="alert.prev_value > alert.new_value">
|
||||
>
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{alert.new_value}}</td>
|
||||
<td><span class="detail-hint" tooltip="Absolute difference: {{alert.amount_abs}}">{{alert.amount_pct}}%</span></td>
|
||||
<td>
|
||||
<div ng-if="alert.is_regression" style="margin: auto; width: 80%;"
|
||||
tooltip="Relative magnitude of change (scale from 0 - 20%+)">
|
||||
<div class="bar bar-scale"
|
||||
style="width: {{100 - getCappedMagnitude(alert.amount_pct)}}%; height: 1em; float: left;">
|
||||
</div>
|
||||
<div class="bar bar-regression"
|
||||
style="width: {{getCappedMagnitude(alert.amount_pct)}}%; float: left;">
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="!alert.is_regression" style="margin: auto; width: 80%;"
|
||||
tooltip="Relative magnitude of change (scale from 0 - 20%+)">
|
||||
<div class="bar bar-improvement"
|
||||
style="width: {{getCappedMagnitude(alert.amount_pct)}}%; float: left;">
|
||||
</div>
|
||||
<div class="bar bar-scale"
|
||||
style="width: {{100 - getCappedMagnitude(alert.amount_pct)}}%; float: left; ">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<span class="detail-hint"
|
||||
tooltip="Confidence value as calculated by Perfherder alerts. Note that this is NOT the same as the calculation used in the compare view"
|
||||
tooltip-placement="left">
|
||||
{{alert.t_value}}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="padding-left: 8px;" ng-show="anySelected(alertSummary.alerts)">
|
||||
<div ng-if="!anySelectedAndTriaged(alertSummary.alerts)" class="btn-group" role="group" aria-label="alert-actions">
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="markAlertsInvalid(alertSummary)" title="Mark as invalid">
|
||||
<span class="fa fa-ban"></span>
|
||||
</button>
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="fileBug(alertSummary)" title="File bug for selected alerts">
|
||||
<span class="fa fa-bug"></span>
|
||||
</button>
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="addBugNumberToAlerts(alertSummary)" title="Link alerts to existing bug">
|
||||
<span class="fa fa-link"></span>
|
||||
</button>
|
||||
<button class="btn btn-default" role="button"
|
||||
ng-click="reassignAlerts(alertSummary)"
|
||||
title="Associate with another alert summary">
|
||||
<span class="fa fa-share"></span>
|
||||
</button>
|
||||
</div>
|
||||
<button ng-if="anySelectedAndTriaged(alertSummary.alerts)" class="btn btn-warning" role="button"
|
||||
ng-click="resetAlerts(alertSummary)" title="Reset selected alerts to untriaged">
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
<button ng-if="anySelectedAndTriaged(alertSummary.alerts)" class="btn btn-warning" role="button"
|
||||
ng-click="resetAlerts(alertSummary)" title="Reset selected alerts to untriaged">
|
||||
Reset
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted" ng-if="numFilteredAlertSummaries > 0">
|
||||
{{numFilteredAlertSummaries}} alerts not displayed because they had no changes matching filter criteria
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="well" ng-show="getMoreAlertSummariesHref">
|
||||
<div class="btn btn-default btn-sm"
|
||||
ng-click="getMoreAlertSummaries(count)">
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input id="filter" type="text" class="form-control" ng-model="filterOptions.filter" placeholder="e.g. linux tp5o" ng-change="updateFilters()"/>
|
||||
<input id="filter" type="text" class="form-control" ng-model="filterOptions.filter" placeholder="filter text e.g. linux tp5o" ng-change="updateFilters()"/>
|
||||
</div>
|
||||
<div class="checkbox" tooltip="Non-trivial changes (1.5%+)">
|
||||
<label>
|
||||
|
|
Загрузка…
Ссылка в новой задаче