Merge pull request #1119 from getredash/feature/params_ui

Feature: add UI to delete alerts
This commit is contained in:
Arik Fraimovich
2016-06-14 12:00:53 +03:00
committed by GitHub
5 changed files with 59 additions and 14 deletions

View File

@@ -67,10 +67,12 @@
if ($scope.alertId === "new") {
$scope.alert = new Alert({options: {}});
$scope.canEdit = true;
} else {
$scope.alert = Alert.get({id: $scope.alertId}, function(alert) {
$scope.onQuerySelected(new Query($scope.alert.query));
});
$scope.canEdit = currentUser.canEdit($scope.alert);
}
$scope.ops = ['greater than', 'less than', 'equals'];
@@ -110,6 +112,15 @@
});
};
$scope.delete = function() {
$scope.alert.$delete(function() {
$location.path('/alerts');
growl.addSuccessMessage("Alert deleted.");
}, function() {
growl.addErrorMessage("Failed deleting alert.");
});
}
};
angular.module('redash.directives').directive('alertSubscriptions', ['$q', '$sce', 'AlertSubscription', 'Destination', 'growl', function ($q, $sce, AlertSubscription, Destination, growl) {

View File

@@ -7,10 +7,10 @@
<div class="container">
<div class="row bg-white p-10">
<div class="col-md-8">
<form name="alertForm" ng-submit="saveChanges()" class="form">
<form name="alertForm" class="form">
<div class="form-group">
<label>Query</label>
<ui-select ng-model="alert.query" reset-search-input="false" on-select="onQuerySelected($item)">
<ui-select ng-model="alert.query" reset-search-input="false" on-select="onQuerySelected($item)" ng-disabled="!canEdit">
<ui-select-match placeholder="Search a query by name">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="q in queries"
refresh="searchQueries($select.search)"
@@ -22,7 +22,7 @@
<div class="form-group" ng-show="selectedQuery">
<label>Name</label>
<input type="string" placeholder="{{getDefaultName()}}" class="form-control" ng-model="alert.name">
<input type="string" placeholder="{{getDefaultName()}}" class="form-control" ng-model="alert.name" ng-disabled="!canEdit">
</div>
<div ng-show="queryResult" class="form-horizontal">
@@ -30,7 +30,7 @@
<label class="control-label col-md-2">Value column</label>
<div class="col-md-4">
<select ng-options="name for name in queryResult.getColumnNames()" ng-model="alert.options.column"
class="form-control"></select>
class="form-control" ng-disabled="!canEdit"></select>
</div>
<label class="control-label col-md-2">Value</label>
<div class="col-md-4">
@@ -40,24 +40,25 @@
<div class="form-group">
<label class="control-label col-md-2">Op</label>
<div class="col-md-4">
<select ng-options="name for name in ops" ng-model="alert.options.op" class="form-control"></select>
<select ng-options="name for name in ops" ng-model="alert.options.op" class="form-control" ng-disabled="!canEdit"></select>
</div>
<label class="control-label col-md-2">Reference</label>
<div class="col-md-4">
<input type="number" step="any" class="form-control" ng-model="alert.options.value" placeholder="reference value"
<input type="number" step="any" class="form-control" ng-model="alert.options.value" placeholder="reference value" ng-disabled="!canEdit"
required/>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Rearm seconds</label>
<div class="col-md-4">
<input type="number" class="form-control" ng-model="alert.rearm"/>
<input type="number" class="form-control" ng-model="alert.rearm" ng-disabled="!canEdit"/>
</div>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary" ng-disabled="!alertForm.$valid">Save</button>
<div class="form-group" ng-if="canEdit">
<button class="btn btn-primary" ng-disabled="!alertForm.$valid" ng-click="saveChanges()">Save</button>
<button class="btn btn-danger" ng-if="alert.id" ng-click="delete()">Delete</button>
</div>
</form>
</div>

View File

@@ -34,6 +34,11 @@ class AlertResource(BaseResource):
return alert.to_dict()
def delete(self, alert_id):
alert = get_object_or_404(models.Alert.get_by_id_and_org, alert_id, self.current_org)
require_admin_or_owner(alert.user.id)
alert.delete_instance(recursive=True)
class AlertListResource(BaseResource):
def post(self):

View File

@@ -187,7 +187,8 @@ class Factory(object):
def create_alert_subscription(self, **kwargs):
args = {
'user': self.user
'user': self.user,
'alert': self.create_alert()
}
args.update(**kwargs)

View File

@@ -1,8 +1,5 @@
from tests import BaseTestCase
from tests.factories import org_factory
from tests.handlers import authenticated_user, json_request
from redash.wsgi import app
from redash.models import AlertSubscription
from redash.models import AlertSubscription, Alert
class TestAlertResourceGet(BaseTestCase):
@@ -30,6 +27,36 @@ class TestAlertResourceGet(BaseTestCase):
self.assertEqual(rv.status_code, 404)
class TestAlertResourceDelete(BaseTestCase):
def test_removes_alert_and_subscriptions(self):
subscription = self.factory.create_alert_subscription()
alert = subscription.alert
rv = self.make_request('delete', "/api/alerts/{}".format(alert.id))
self.assertEqual(rv.status_code, 200)
self.assertRaises(Alert.DoesNotExist, Alert.get_by_id, subscription.alert.id)
self.assertRaises(AlertSubscription.DoesNotExist, AlertSubscription.get_by_id, subscription.id)
def test_returns_403_if_not_allowed(self):
alert = self.factory.create_alert()
user = self.factory.create_user()
rv = self.make_request('delete', "/api/alerts/{}".format(alert.id), user=user)
self.assertEqual(rv.status_code, 403)
rv = self.make_request('delete', "/api/alerts/{}".format(alert.id), user=self.factory.create_admin())
self.assertEqual(rv.status_code, 200)
def test_returns_404_for_unauthorized_users(self):
alert = self.factory.create_alert()
second_org = self.factory.create_org()
second_org_admin = self.factory.create_admin(org=second_org)
rv = self.make_request('delete', "/api/alerts/{}".format(alert.id), user=second_org_admin)
self.assertEqual(rv.status_code, 404)
class TestAlertListPost(BaseTestCase):
def test_returns_200_if_has_access_to_query(self):
query = self.factory.create_query()