Add UI for managing repo notifications
This commit is contained in:
parent
a84fe0681a
commit
de8e898ad0
11 changed files with 450 additions and 81 deletions
|
@ -1537,7 +1537,7 @@ def create_repo_notification(repo, event_name, method_name, config):
|
|||
method = ExternalNotificationMethod.get(ExternalNotificationMethod.name == method_name)
|
||||
|
||||
return RepositoryNotification.create(repository=repo, event=event, method=method,
|
||||
confing_json=json.dumps(config))
|
||||
config_json=json.dumps(config))
|
||||
|
||||
|
||||
def get_repo_notification(namespace_name, repository_name, uuid):
|
||||
|
|
|
@ -16,8 +16,8 @@ def notification_view(notification):
|
|||
|
||||
return {
|
||||
'uuid': notification.uuid,
|
||||
'kind': notification.kind,
|
||||
'method': notification.method,
|
||||
'event': notification.event.name,
|
||||
'method': notification.method.name,
|
||||
'config': config
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ EXTERNAL_JS = [
|
|||
]
|
||||
|
||||
EXTERNAL_CSS = [
|
||||
'netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css',
|
||||
'netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.css',
|
||||
'netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css',
|
||||
'fonts.googleapis.com/css?family=Droid+Sans:400,700',
|
||||
]
|
||||
|
|
|
@ -3889,6 +3889,11 @@ pre.command:before {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.dropdown-select input.form-control[readonly] {
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.dropdown-select .lookahead-input {
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
@ -4429,3 +4434,42 @@ have a fixed width and height (but it's not required).
|
|||
float: right;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
i.quay-icon {
|
||||
background-image: url(/static/img/favicon.ico);
|
||||
background-size: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.external-notification-view-element {
|
||||
margin: 10px;
|
||||
padding: 6px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.external-notification-view-element .view-row {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.external-notification-view-element .view-row:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.external-notification-view-element .flow-text {
|
||||
display: inline-block;
|
||||
color: #aaa;
|
||||
text-transform: lowercase;
|
||||
font-variant: small-caps;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.external-notification-view-element .side-controls {
|
||||
opacity: 0;
|
||||
transition: opacity 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.external-notification-view-element:hover .side-controls {
|
||||
opacity: 1;
|
||||
}
|
91
static/directives/create-external-notification-dialog.html
Normal file
91
static/directives/create-external-notification-dialog.html
Normal file
|
@ -0,0 +1,91 @@
|
|||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="createNotificationModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form id="createForm" name="createForm" ng-submit="createNotification()">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-disabled="creating">×</button>
|
||||
<h4 class="modal-title">
|
||||
Create Repository Notification
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="quay-spinner" ng-show="creating"></div>
|
||||
|
||||
<table style="width: 100%" ng-show="!creating">
|
||||
<tr>
|
||||
<td style="width: 120px">When this occurs:</td>
|
||||
<td>
|
||||
<div class="dropdown-select" placeholder="'(Notification Event)'" selected-item="currentEvent.title"
|
||||
handle-item-selected="handleEventSelected(datum)">
|
||||
<!-- Icons -->
|
||||
<i class="dropdown-select-icon fa fa-lg" ng-class="currentEvent.icon"></i>
|
||||
|
||||
<!-- Dropdown menu -->
|
||||
<ul class="dropdown-select-menu pull-right" role="menu">
|
||||
<li ng-repeat="event in events">
|
||||
<a href="javascript:void(0)" ng-click="setEvent(event)">
|
||||
<i class="fa fa-lg" ng-class="event.icon"></i> {{ event.title }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Then issue a:</td>
|
||||
<td>
|
||||
<div class="dropdown-select" placeholder="'(Notification Action)'" selected-item="currentMethod.title"
|
||||
handle-item-selected="handleMethodSelected(datum)">
|
||||
<!-- Icons -->
|
||||
<i class="dropdown-select-icon fa fa-lg" ng-class="currentMethod.icon"></i>
|
||||
|
||||
<!-- Dropdown menu -->
|
||||
<ul class="dropdown-select-menu pull-right" role="menu">
|
||||
<li ng-repeat="method in methods">
|
||||
<a href="javascript:void(0)" ng-click="setMethod(method)">
|
||||
<i class="fa fa-lg" ng-class="method.icon"></i> {{ method.title }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-if="currentMethod.fields.length"><td colspan="2"><hr></td></tr>
|
||||
|
||||
<tr ng-repeat="field in currentMethod.fields">
|
||||
<td>{{ field.title }}:</td>
|
||||
<td>
|
||||
<div ng-switch on="field.type">
|
||||
<input type="email" class="form-control" ng-model="currentConfig[field.name]" ng-switch-when="email" required>
|
||||
<input type="url" class="form-control" ng-model="currentConfig[field.name]" ng-switch-when="url" required>
|
||||
<input type="text" class="form-control" ng-model="currentConfig[field.name]" ng-switch-when="string" required>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-if="currentMethod.id == 'webhook'">
|
||||
<td colspan="2">
|
||||
<div class="alert alert-info" style="margin-top: 20px; margin-bottom: 0px">
|
||||
JSON metadata representing the event will be <b>POST</b>ed to the URL.
|
||||
<br><br>
|
||||
The contents for each event can be found in the user guide:
|
||||
<a href="http://docs.quay.io/guides/notifications.html" target="_blank">http://docs.quay.io/guides/notifications.html</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
ng-disabled="createForm.$invalid || !currentMethod || !currentEvent || creating">
|
||||
Create Notification
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" ng-disabled="creating">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
|
@ -1,7 +1,8 @@
|
|||
<div class="dropdown-select-element" ng-class="selectedItem ? 'has-item' : ''">
|
||||
<div class="current-item">
|
||||
<div class="dropdown-select-icon-transclude"></div>
|
||||
<input type="text" class="lookahead-input form-control" placeholder="{{ placeholder }}"></input>
|
||||
<input type="text" class="lookahead-input form-control" placeholder="{{ placeholder }}"
|
||||
ng-readonly="!lookaheadItems || !lookaheadItems.length"></input>
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
|
|
50
static/directives/external-notification-view.html
Normal file
50
static/directives/external-notification-view.html
Normal file
|
@ -0,0 +1,50 @@
|
|||
<div class="external-notification-view-element">
|
||||
<div class="side-controls">
|
||||
<div class="dropdown" style="display: inline-block">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-cog"></i>
|
||||
<b class="caret"></b>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right pull-right">
|
||||
<li><a href="javascript:void(0)" ng-click="testNotification()">
|
||||
<i class="fa fa-send"></i>
|
||||
Issue Test Notification</a>
|
||||
</li>
|
||||
<li><a href="javascript:void(0)" ng-click="deleteNotification()">
|
||||
<i class="fa fa-times"></i>
|
||||
Delete</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="view-row">
|
||||
<span class="flow-text">On A</span>
|
||||
<span class="notification-event">
|
||||
<i class="fa fa-lg" ng-class="eventInfo.icon"></i>
|
||||
{{ eventInfo.title }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="view-row">
|
||||
<span class="flow-text">Issue A</span>
|
||||
<span class="notification-method">
|
||||
<i class="fa fa-lg" ng-class="methodInfo.icon"></i>
|
||||
{{ methodInfo.title }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="view-row" ng-if="methodInfo.id == 'email' || methodInfo.id == 'webhook'">
|
||||
<span ng-switch on="methodInfo.id">
|
||||
<span ng-switch-when="email">
|
||||
<span class="flow-text">To</span>
|
||||
<code>{{ config.email }}</code>
|
||||
</span>
|
||||
|
||||
<span ng-switch-when="webhook">
|
||||
<span class="flow-text">To</span>
|
||||
<code>{{ config.url }}</code>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
208
static/js/app.js
208
static/js/app.js
|
@ -969,6 +969,94 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
return userService;
|
||||
}]);
|
||||
|
||||
$provide.factory('ExternalNotificationData', [function() {
|
||||
var externalNotificationData = {};
|
||||
|
||||
var events = [
|
||||
{
|
||||
'id': 'repo_push',
|
||||
'title': 'Push to Repository',
|
||||
'icon': 'fa-upload'
|
||||
},
|
||||
{
|
||||
'id': 'build_start',
|
||||
'title': 'Dockerfile Build Started',
|
||||
'icon': 'fa-tasks'
|
||||
},
|
||||
{
|
||||
'id': 'build_success',
|
||||
'title': 'Dockerfile Build Successfully Completed',
|
||||
'icon': 'fa-check-circle-o'
|
||||
},
|
||||
{
|
||||
'id': 'build_failure',
|
||||
'title': 'Dockerfile Build Failed',
|
||||
'icon': 'fa-times-circle-o'
|
||||
}
|
||||
];
|
||||
|
||||
var methods = [
|
||||
{
|
||||
'id': 'quay_notification',
|
||||
'title': 'Quay.io notification',
|
||||
'icon': 'quay-icon'
|
||||
},
|
||||
{
|
||||
'id': 'email',
|
||||
'title': 'E-mail notification',
|
||||
'icon': 'fa-envelope',
|
||||
'fields': [
|
||||
{
|
||||
'name': 'email',
|
||||
'type': 'email',
|
||||
'title': 'E-mail address'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id': 'webhook',
|
||||
'title': 'Webhook invoke',
|
||||
'icon': 'fa-link',
|
||||
'fields': [
|
||||
{
|
||||
'name': 'url',
|
||||
'type': 'url',
|
||||
'title': 'Webhook URL'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
var methodMap = {};
|
||||
var eventMap = {};
|
||||
|
||||
for (var i = 0; i < methods.length; ++i) {
|
||||
methodMap[methods[i].id] = methods[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < events.length; ++i) {
|
||||
eventMap[events[i].id] = events[i];
|
||||
}
|
||||
|
||||
externalNotificationData.getSupportedEvents = function() {
|
||||
return events;
|
||||
};
|
||||
|
||||
externalNotificationData.getSupportedMethods = function() {
|
||||
return methods;
|
||||
};
|
||||
|
||||
externalNotificationData.getEventInfo = function(event) {
|
||||
return eventMap[event];
|
||||
};
|
||||
|
||||
externalNotificationData.getMethodInfo = function(method) {
|
||||
return methodMap[method];
|
||||
};
|
||||
|
||||
return externalNotificationData;
|
||||
}]);
|
||||
|
||||
$provide.factory('NotificationService', ['$rootScope', '$interval', 'UserService', 'ApiService', 'StringBuilderService', 'PlanService', 'UserService', 'Config',
|
||||
function($rootScope, $interval, UserService, ApiService, StringBuilderService, PlanService, UserService, Config) {
|
||||
var notificationService = {
|
||||
|
@ -4462,6 +4550,126 @@ quayApp.directive('buildProgress', function () {
|
|||
});
|
||||
|
||||
|
||||
quayApp.directive('externalNotificationView', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/external-notification-view.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'repository': '=repository',
|
||||
'notification': '=notification',
|
||||
'notificationDeleted': '¬ificationDeleted'
|
||||
},
|
||||
controller: function($scope, $element, ExternalNotificationData, ApiService) {
|
||||
$scope.deleteNotification = function() {
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'uuid': $scope.notification.uuid
|
||||
};
|
||||
|
||||
ApiService.deleteRepoNotification(null, params).then(function() {
|
||||
$scope.notificationDeleted({'notification': $scope.notification});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.testNotification = function() {
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'uuid': $scope.notification.uuid
|
||||
};
|
||||
|
||||
ApiService.testRepoNotification(null, params).then(function() {
|
||||
bootbox.dialog({
|
||||
"message": "Test Notification Sent",
|
||||
"buttons": {
|
||||
"close": {
|
||||
"label": "Close",
|
||||
"className": "btn-primary"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$watch('notification', function(notification) {
|
||||
if (notification) {
|
||||
$scope.eventInfo = ExternalNotificationData.getEventInfo(notification.event);
|
||||
$scope.methodInfo = ExternalNotificationData.getMethodInfo(notification.method);
|
||||
$scope.config = notification.config;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('createExternalNotificationDialog', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/create-external-notification-dialog.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'repository': '=repository',
|
||||
'counter': '=counter',
|
||||
'notificationCreated': '¬ificationCreated'
|
||||
},
|
||||
controller: function($scope, $element, ExternalNotificationData, ApiService) {
|
||||
$scope.currentEvent = null;
|
||||
$scope.currentMethod = null;
|
||||
$scope.creating = false;
|
||||
$scope.currentConfig = {};
|
||||
|
||||
$scope.events = ExternalNotificationData.getSupportedEvents();
|
||||
$scope.methods = ExternalNotificationData.getSupportedMethods();
|
||||
|
||||
$scope.setEvent = function(event) {
|
||||
$scope.currentEvent = event;
|
||||
};
|
||||
|
||||
$scope.setMethod = function(method) {
|
||||
$scope.currentConfig = {};
|
||||
$scope.currentMethod = method;
|
||||
};
|
||||
|
||||
$scope.createNotification = function() {
|
||||
$scope.creating = true;
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name
|
||||
};
|
||||
|
||||
var data = {
|
||||
'event': $scope.currentEvent.id,
|
||||
'method': $scope.currentMethod.id,
|
||||
'config': $scope.currentConfig
|
||||
};
|
||||
|
||||
ApiService.createRepoNotification(data, params).then(function(resp) {
|
||||
$scope.creating = false;
|
||||
$scope.notificationCreated({'notification': resp});
|
||||
$('#createNotificationModal').modal('hide');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$watch('counter', function(counter) {
|
||||
if (counter) {
|
||||
$scope.creating = false;
|
||||
$scope.currentEvent = null;
|
||||
$scope.currentMethod = null;
|
||||
$('#createNotificationModal').modal({});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
|
||||
quayApp.directive('twitterView', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
|
|
|
@ -181,7 +181,7 @@ function TutorialCtrl($scope, AngularTour, AngularTourSignals, UserService, Conf
|
|||
},
|
||||
{
|
||||
'title': 'Repository Admin',
|
||||
'content': "The repository admin panel allows for modification of a repository's permissions, webhooks, visibility and other settings",
|
||||
'content': "The repository admin panel allows for modification of a repository's permissions, notifications, visibility and other settings",
|
||||
'overlayable': true,
|
||||
'mixpanelEvent': 'tutorial_view_admin'
|
||||
},
|
||||
|
@ -1246,7 +1246,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
|||
fetchRepository();
|
||||
}
|
||||
|
||||
function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, $routeParams, $rootScope, $location, UserService, Config, Features) {
|
||||
function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, $routeParams, $rootScope, $location, UserService, Config, Features, ExternalNotificationData) {
|
||||
var namespace = $routeParams.namespace;
|
||||
var name = $routeParams.name;
|
||||
|
||||
|
@ -1467,43 +1467,32 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, $routeParams
|
|||
});
|
||||
};
|
||||
|
||||
$scope.loadWebhooks = function() {
|
||||
$scope.showNewNotificationCounter = 0;
|
||||
|
||||
$scope.showNewNotificationDialog = function() {
|
||||
$scope.showNewNotificationCounter++;
|
||||
};
|
||||
|
||||
$scope.handleNotificationCreated = function(notification) {
|
||||
$scope.notifications.push(notification);
|
||||
};
|
||||
|
||||
$scope.handleNotificationDeleted = function(notification) {
|
||||
var index = $.inArray(notification, $scope.notifications);
|
||||
if (index < 0) { return; }
|
||||
$scope.notifications.splice(index, 1);
|
||||
};
|
||||
|
||||
$scope.loadNotifications = function() {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
$scope.newWebhook = {};
|
||||
$scope.webhooksResource = ApiService.listWebhooksAsResource(params).get(function(resp) {
|
||||
$scope.webhooks = resp.webhooks;
|
||||
return $scope.webhooks;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.createWebhook = function() {
|
||||
if (!$scope.newWebhook.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
var params = {
|
||||
'repository': namespace + '/' + name
|
||||
};
|
||||
|
||||
ApiService.createWebhook($scope.newWebhook, params).then(function(resp) {
|
||||
$scope.webhooks.push(resp);
|
||||
$scope.newWebhook.url = '';
|
||||
$scope.createWebhookForm.$setPristine();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteWebhook = function(webhook) {
|
||||
var params = {
|
||||
'repository': namespace + '/' + name,
|
||||
'public_id': webhook.public_id
|
||||
};
|
||||
|
||||
ApiService.deleteWebhook(null, params).then(function(resp) {
|
||||
$scope.webhooks.splice($scope.webhooks.indexOf(webhook), 1);
|
||||
});
|
||||
$scope.notificationsResource = ApiService.listRepoNotificationsAsResource(params).get(
|
||||
function(resp) {
|
||||
$scope.notifications = resp.notifications;
|
||||
return $scope.notifications;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showBuild = function(buildInfo) {
|
||||
|
@ -1635,7 +1624,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, $routeParams
|
|||
$scope.repo = repo;
|
||||
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
||||
$rootScope.description = 'Administrator settings for ' + namespace + '/' + name +
|
||||
': Permissions, webhooks and other settings';
|
||||
': Permissions, notifications and other settings';
|
||||
|
||||
// Fetch all the permissions and token info for the repository.
|
||||
fetchPermissions('user');
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<li class="active"><a href="javascript:void(0)" data-toggle="tab" data-target="#permissions">Permissions</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#trigger" ng-click="loadTriggers()">Build Triggers</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#badge">Status Badge</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#webhook" ng-click="loadWebhooks()">Webhooks</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#notification" ng-click="loadNotifications()">Notifications</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#publicprivate">Public/Private</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#delete">Delete</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">Usage Logs</a></li>
|
||||
|
@ -192,51 +192,32 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Webhook tab -->
|
||||
<div id="webhook" class="tab-pane">
|
||||
<!-- Notification tab -->
|
||||
<div id="notification" class="tab-pane">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Push Webhooks
|
||||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="URLs which will be invoked with an HTTP POST and JSON payload when a successful push to the repository occurs."></i>
|
||||
<div class="panel-heading">Repository Notifications
|
||||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="Notifications to call to external services (web, email, etc) on repository events"></i>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="resource-view" resource="webhooksResource" error-message="'Could not load webhooks'">
|
||||
<table class="permissions">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 500px;">Webhook URL</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr ng-repeat="webhook in webhooks">
|
||||
<td>{{ webhook.parameters.url }}</td>
|
||||
<td>
|
||||
<span class="delete-ui" delete-title="'Delete Webhook'" perform-delete="deleteWebhook(webhook)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- Notifications list -->
|
||||
<div class="resource-view" resource="notificationsResource" error-message="'Could not load notifications'">
|
||||
<div class="empty" ng-if="!notifications.length">
|
||||
There are no notifications defined for this repository
|
||||
</div>
|
||||
<div class="nonempty" ng-show="notifications.length">
|
||||
<div class="external-notification-view" notification="notification" repository="repo"
|
||||
notification-deleted="handleNotificationDeleted(notification)"
|
||||
ng-repeat="notification in notifications"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form name="createWebhookForm" ng-submit="createWebhook()">
|
||||
<table class="permissions">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 500px;">
|
||||
<input type="url" class="form-control" placeholder="New webhook url..." ng-model="newWebhook.url" required>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-primary" type="submit" ng-disabled="createWebhookForm.$invalid">Create</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<div class="right-info">
|
||||
Quay will <b>POST</b> to these webhooks whenever a push occurs. See the <a href="/guide">User Guide</a> for more information.
|
||||
<!-- Right controls -->
|
||||
<div class="right-controls">
|
||||
<button class="btn btn-success" ng-click="showNewNotificationDialog()">
|
||||
<i class="fa fa-paper-plane"></i>
|
||||
New Notification
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -390,6 +371,11 @@
|
|||
canceled="cancelSetupTrigger(trigger)"
|
||||
counter="showTriggerSetupCounter"></div>
|
||||
|
||||
<!-- New notification dialog-->
|
||||
<div class="create-external-notification-dialog" repository="repo"
|
||||
counter="showNewNotificationCounter"
|
||||
notification-created="handleNotificationCreated(notification)"></div>
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="cannotchangeModal">
|
||||
<div class="modal-dialog">
|
||||
|
|
Binary file not shown.
Reference in a new issue