mirror of
https://github.com/getredash/redash.git
synced 2025-12-19 17:37:19 -05:00
This is basic implementation for alerts feature, where you can define a simple rule on the last query result to send an alert. As part of the implementation added Flask-Mail to the project, to send emails. Should be useful to make re:dash more "self aware" (notify users about potential issues, when queries done executing and more).
171 lines
5.1 KiB
JavaScript
171 lines
5.1 KiB
JavaScript
(function() {
|
|
|
|
var AlertsCtrl = function($scope, Events, Alert) {
|
|
Events.record(currentUser, "view", "page", "alerts");
|
|
$scope.$parent.pageTitle = "Alerts";
|
|
|
|
$scope.alerts = []
|
|
Alert.query(function(alerts) {
|
|
var stateClass = {
|
|
'ok': 'label label-success',
|
|
'triggered': 'label label-danger',
|
|
'unknown': 'label label-warning'
|
|
};
|
|
_.each(alerts, function(alert) {
|
|
alert.class = stateClass[alert.state];
|
|
})
|
|
$scope.alerts = alerts;
|
|
|
|
});
|
|
|
|
$scope.gridConfig = {
|
|
isPaginationEnabled: true,
|
|
itemsByPage: 50,
|
|
maxSize: 8,
|
|
};
|
|
|
|
|
|
$scope.gridColumns = [
|
|
{
|
|
"label": "Name",
|
|
"map": "name",
|
|
"cellTemplate": '<a href="/alerts/{{dataRow.id}}">{{dataRow.name}}</a> (<a href="/queries/{{dataRow.query.id}}">query</a>)'
|
|
},
|
|
{
|
|
'label': 'Created By',
|
|
'map': 'user.name'
|
|
},
|
|
{
|
|
'label': 'State',
|
|
'cellTemplate': '<span ng-class="dataRow.class">{{dataRow.state | uppercase}}</span> since <span am-time-ago="dataRow.updated_at"></span>'
|
|
},
|
|
{
|
|
'label': 'Created At',
|
|
'cellTemplate': '<span am-time-ago="dataRow.created_at"></span>'
|
|
}
|
|
];
|
|
};
|
|
|
|
var AlertCtrl = function($scope, $routeParams, growl, Query, Events, Alert) {
|
|
$scope.$parent.pageTitle = "Alerts";
|
|
|
|
$scope.alertId = $routeParams.alertId;
|
|
if ($scope.alertId === "new") {
|
|
Events.record(currentUser, 'view', 'page', 'alerts/new');
|
|
} else {
|
|
Events.record(currentUser, 'view', 'alert', $scope.alertId);
|
|
}
|
|
|
|
$scope.onQuerySelected = function(item) {
|
|
$scope.selectedQuery = item;
|
|
item.getQueryResultPromise().then(function(result) {
|
|
$scope.queryResult = result;
|
|
$scope.alert.options.column = result.getColumnNames()[0];
|
|
});
|
|
};
|
|
|
|
if ($scope.alertId === "new") {
|
|
$scope.alert = new Alert({options: {}});
|
|
} else {
|
|
$scope.alert = Alert.get({id: $scope.alertId}, function(alert) {
|
|
$scope.onQuerySelected(new Query($scope.alert.query));
|
|
});
|
|
}
|
|
|
|
$scope.ops = ['greater than', 'less than', 'equals'];
|
|
$scope.selectedQuery = null;
|
|
|
|
$scope.getDefaultName = function() {
|
|
if (!$scope.alert.query) {
|
|
return undefined;
|
|
}
|
|
return _.template("<%= query.name %>: <%= options.column %> <%= options.op %> <%= options.value %>", $scope.alert);
|
|
};
|
|
|
|
$scope.searchQueries = function (term) {
|
|
if (!term || term.length < 3) {
|
|
return;
|
|
}
|
|
|
|
Query.search({q: term}, function(results) {
|
|
$scope.queries = results;
|
|
});
|
|
};
|
|
|
|
$scope.saveChanges = function() {
|
|
if ($scope.alert.name === undefined || $scope.alert.name === '') {
|
|
$scope.alert.name = $scope.getDefaultName();
|
|
}
|
|
|
|
$scope.alert.$save(function() {
|
|
growl.addSuccessMessage("Saved.");
|
|
}, function() {
|
|
growl.addErrorMessage("Failed saving alert.");
|
|
});
|
|
};
|
|
};
|
|
|
|
angular.module('redash.directives').directive('alertSubscribers', ['AlertSubscription', function (AlertSubscription) {
|
|
return {
|
|
restrict: 'E',
|
|
replace: true,
|
|
templateUrl: '/views/alerts/subscribers.html',
|
|
scope: {
|
|
'alertId': '='
|
|
},
|
|
controller: function ($scope) {
|
|
$scope.subscribers = AlertSubscription.query({alertId: $scope.alertId});
|
|
}
|
|
}
|
|
}]);
|
|
|
|
angular.module('redash.directives').directive('subscribeButton', ['AlertSubscription', 'growl', function (AlertSubscription, growl) {
|
|
return {
|
|
restrict: 'E',
|
|
replace: true,
|
|
template: '<button class="btn btn-default btn-xs" ng-click="toggleSubscription()"><i ng-class="class"></i></button>',
|
|
controller: function ($scope) {
|
|
var updateClass = function() {
|
|
if ($scope.subscription) {
|
|
$scope.class = "fa fa-eye-slash";
|
|
} else {
|
|
$scope.class = "fa fa-eye";
|
|
}
|
|
}
|
|
|
|
$scope.subscribers.$promise.then(function() {
|
|
$scope.subscription = _.find($scope.subscribers, function(subscription) {
|
|
return (subscription.user.email == currentUser.email);
|
|
});
|
|
|
|
updateClass();
|
|
});
|
|
|
|
$scope.toggleSubscription = function() {
|
|
if ($scope.subscription) {
|
|
$scope.subscription.$delete(function() {
|
|
$scope.subscribers = _.without($scope.subscribers, $scope.subscription);
|
|
$scope.subscription = undefined;
|
|
updateClass();
|
|
}, function() {
|
|
growl.addErrorMessage("Failed saving subscription.");
|
|
});
|
|
} else {
|
|
$scope.subscription = new AlertSubscription({alert_id: $scope.alertId});
|
|
$scope.subscription.$save(function() {
|
|
$scope.subscribers.push($scope.subscription);
|
|
updateClass();
|
|
}, function() {
|
|
growl.addErrorMessage("Unsubscription failed.");
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}]);
|
|
|
|
angular.module('redash.controllers')
|
|
.controller('AlertsCtrl', ['$scope', 'Events', 'Alert', AlertsCtrl])
|
|
.controller('AlertCtrl', ['$scope', '$routeParams', 'growl', 'Query', 'Events', 'Alert', AlertCtrl])
|
|
|
|
})(); |