Adding backend code for sources models
This commit is contained in:
@ -0,0 +1,38 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">
|
||||
<h3 class="modal-header">Edit <span class="text-muted"><small>{{ certificate.name }}</small></span></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form name="editForm" class="form-horizontal" role="form" novalidate>
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': editForm.owner.$invalid, 'has-success': !editForm.owner.$invalid&&editForm.owner.$dirty}">
|
||||
<label class="control-label col-sm-2">
|
||||
Owner
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" name="owner" ng-model="certificate.owner" placeholder="owner@netflix.com"
|
||||
class="form-control" required/>
|
||||
|
||||
<p ng-show="editForm.owner.$invalid && !editForm.owner.$pristine" class="help-block">Enter a valid
|
||||
email.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': editForm.description.$invalid, 'has-success': !editForm.$invalid&&editForm.description.$dirty}">
|
||||
<label class="control-label col-sm-2">
|
||||
Description
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea name="description" ng-model="certificate.description" placeholder="Something elegant" class="form-control" ng-pattern="/^[\w\-\s]+$/" required></textarea>
|
||||
<p ng-show="editForm.description.$invalid && !editForm.description.$pristine" class="help-block">You must give a short description about this authority will be used for, this description should only include alphanumeric characters</p>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-include="'angular/certificates/certificate/notifications.tpl.html'"></div>
|
||||
<div ng-include="'angular/certificates/certificate/destinations.tpl.html'"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" ng-click="save(certificate)" ng-disabled="editForm.$invalid" class="btn btn-success">Save</button>
|
||||
<button ng-click="cancel()" class="btn btn-danger">Cancel</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,28 @@
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
Notifications
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group">
|
||||
<input type="text" ng-model="certificate.selectedNotification" placeholder="Email"
|
||||
typeahead="notification.label for notification in notificationService.findNotificationsByName($viewValue)" typeahead-loading="loadingDestinations"
|
||||
class="form-control input-md" typeahead-on-select="certificate.attachNotification($item)" typeahead-min-wait="50"
|
||||
tooltip="By default Lemur will always notify you about this certificate through Email notifications."
|
||||
tooltip-trigger="focus" tooltip-placement="top">
|
||||
<span class="input-group-btn">
|
||||
<button ng-model="notifications.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||
<span class="badge">{{ certificate.notifications.length || 0 }}</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<table class="table">
|
||||
<tr ng-repeat="notification in certificate.notifications track by $index">
|
||||
<td><a class="btn btn-sm btn-info" href="#/notifications/{{ notification.id }}/certificates">{{ notification.label }}</a></td>
|
||||
<td><span class="text-muted">{{ notification.description }}</span></td>
|
||||
<td>
|
||||
<button type="button" ng-click="certificate.removeNotification($index)" class="btn btn-danger btn-sm pull-right">Remove</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
56
lemur/static/app/angular/notifications/notification/notification.js
vendored
Normal file
56
lemur/static/app/angular/notifications/notification/notification.js
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('lemur')
|
||||
|
||||
.controller('NotificationsCreateController', function ($scope, $modalInstance, PluginService, NotificationService, CertificateService, LemurRestangular){
|
||||
$scope.notification = LemurRestangular.restangularizeElement(null, {}, 'notifications');
|
||||
|
||||
PluginService.getByType('notification').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
});
|
||||
$scope.save = function (notification) {
|
||||
NotificationService.create(notification).then(
|
||||
function () {
|
||||
$modalInstance.close();
|
||||
},
|
||||
function () {
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
$scope.certificateService = CertificateService;
|
||||
})
|
||||
|
||||
.controller('NotificationsEditController', function ($scope, $modalInstance, NotificationService, NotificationApi, PluginService, CertificateService, editId) {
|
||||
NotificationApi.get(editId).then(function (notification) {
|
||||
$scope.notification = notification;
|
||||
NotificationService.getCertificates(notification);
|
||||
});
|
||||
|
||||
PluginService.getByType('notification').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
_.each($scope.plugins, function (plugin) {
|
||||
if (plugin.slug == $scope.notification.pluginName) {
|
||||
plugin.pluginOptions = $scope.notification.notificationOptions;
|
||||
$scope.notification.plugin = plugin;
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
$scope.save = function (notification) {
|
||||
NotificationService.update(notification).then(function () {
|
||||
$modalInstance.close();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
$scope.certificateService = CertificateService;
|
||||
});
|
@ -0,0 +1,87 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">
|
||||
<h3 class="modal-header"><span ng-show="!notification.fromServer">Create</span><span ng-show="notification.fromServer">Edit</span> Notification <span class="text-muted"><small>you gotta speak louder son!</small></span></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form name="createForm" class="form-horizontal" role="form" novalidate>
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': createForm.label.$invalid, 'has-success': !createForm.label.$invalid&&createForm.label.$dirty}">
|
||||
<label class="control-label col-sm-2">
|
||||
Label
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<input name="label" ng-model="notification.label" placeholder="Label" class="form-control" required/>
|
||||
<p ng-show="createForm.label.$invalid && !createForm.label.$pristine" class="help-block">You must enter an notification label</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
Description
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea name="comments" ng-model="notification.description" placeholder="Something elegant" class="form-control" ></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
Plugin
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control" ng-model="notification.plugin" ng-options="plugin.title for plugin in plugins" required></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-repeat="item in notification.plugin.pluginOptions">
|
||||
<ng-form name="subForm" class="form-horizontal" role="form" novalidate>
|
||||
<div ng-class="{'has-error': subForm.sub.$invalid, 'has-success': !subForm.sub.$invalid&&subForm.sub.$dirty}">
|
||||
<label class="control-label col-sm-2">
|
||||
{{ item.name | titleCase }}
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<input name="sub" ng-if="item.type == 'int'" type="number" ng-pattern="item.validation" class="form-control" ng-model="item.value"/>
|
||||
<select name="sub" ng-if="item.type == 'select'" class="form-control" ng-options="i as (i | titleCase) for i in item.available" ng-model="item.value"></select>
|
||||
<input name="sub" ng-if="item.type == 'bool'" class="form-control" type="checkbox" ng-model="item.value">
|
||||
<input name="sub" ng-if="item.type == 'str'" ng-pattern="item.validation" type="text" class="form-control" ng-model="item.value"/>
|
||||
<p ng-show="subForm.sub.$invalid && !subForm.sub.$pristine" class="help-block">{{ item.helpMessage }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</ng-form>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
Certificates
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group">
|
||||
<input type="text" ng-model="notification.selectedCertificate" placeholder="Certificate Name"
|
||||
typeahead="certificate.name for certificate in certificateService.findCertificatesByName($viewValue)" typeahead-loading="loadingCertificates"
|
||||
class="form-control input-md" typeahead-on-select="notification.attachCertificate($item)" typeahead-min-wait="50">
|
||||
<span class="input-group-btn">
|
||||
<button ng-model="certificates.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||
<span class="badge">{{ notification.certificates.total || 0 }}</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<table ng-show="notification.certificates" class="table">
|
||||
<tr ng-repeat="certificate in notification.certificates track by $index">
|
||||
<td><a class="btn btn-sm btn-info" href="#">{{ certificate.name }}</a></td>
|
||||
<td><span class="text-muted">{{ certificate.description }}</span></td>
|
||||
<td>
|
||||
<button type="button" ng-click="notification.removeCertificate($index)" class="btn btn-danger btn-sm pull-right">Remove</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><a class="pull-right" ng-click="loadMoreCertificates()"><strong>More</strong></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button ng-click="save(notification)" type="submit" ng-disabled="createForm.$invalid" class="btn btn-primary">Save</button>
|
||||
<button ng-click="cancel()" class="btn btn-danger">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
106
lemur/static/app/angular/notifications/services.js
vendored
Normal file
106
lemur/static/app/angular/notifications/services.js
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
'use strict';
|
||||
angular.module('lemur')
|
||||
.service('NotificationApi', function (LemurRestangular) {
|
||||
LemurRestangular.extendModel('notifications', function (obj) {
|
||||
return angular.extend(obj, {
|
||||
attachCertificate: function (certificate) {
|
||||
this.selectedCertificate = null;
|
||||
if (this.certificates === undefined) {
|
||||
this.certificates = [];
|
||||
}
|
||||
this.certificates.push(certificate);
|
||||
},
|
||||
removeCertificate: function (index) {
|
||||
this.certificate.splice(index, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
return LemurRestangular.all('notifications');
|
||||
})
|
||||
.service('NotificationService', function ($location, NotificationApi, PluginService, toaster) {
|
||||
var NotificationService = this;
|
||||
NotificationService.findNotificationsByName = function (filterValue) {
|
||||
return NotificationApi.getList({'filter[label]': filterValue})
|
||||
.then(function (notifications) {
|
||||
return notifications;
|
||||
});
|
||||
};
|
||||
|
||||
NotificationService.getCertificates = function (notification) {
|
||||
notification.getList('certificates').then(function (certificates) {
|
||||
notification.certificates = certificates;
|
||||
});
|
||||
};
|
||||
|
||||
NotificationService.getPlugin = function (notification) {
|
||||
return PluginService.getByName(notification.pluginName).then(function (plugin) {
|
||||
notification.plugin = plugin;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
NotificationService.loadMoreCertificates = function (notification, page) {
|
||||
notification.getList('certificates', {page: page}).then(function (certificates) {
|
||||
_.each(certificates, function (certificate) {
|
||||
notification.roles.push(certificate);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
NotificationService.create = function (notification) {
|
||||
return NotificationApi.post(notification).then(
|
||||
function () {
|
||||
toaster.pop({
|
||||
type: 'success',
|
||||
title: notification.label,
|
||||
body: 'Successfully created!'
|
||||
});
|
||||
$location.path('notifications');
|
||||
},
|
||||
function (response) {
|
||||
toaster.pop({
|
||||
type: 'error',
|
||||
title: notification.label,
|
||||
body: 'Was not created! ' + response.data.message
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
NotificationService.update = function (notification) {
|
||||
return notification.put().then(
|
||||
function () {
|
||||
toaster.pop({
|
||||
type: 'success',
|
||||
title: notification.label,
|
||||
body: 'Successfully updated!'
|
||||
});
|
||||
$location.path('notifications');
|
||||
},
|
||||
function (response) {
|
||||
toaster.pop({
|
||||
type: 'error',
|
||||
title: notification.label,
|
||||
body: 'Was not updated! ' + response.data.message
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
NotificationService.updateActive = function (notification) {
|
||||
notification.put().then(
|
||||
function () {
|
||||
toaster.pop({
|
||||
type: 'success',
|
||||
title: notification.name,
|
||||
body: 'Successfully updated!'
|
||||
});
|
||||
},
|
||||
function (response) {
|
||||
toaster.pop({
|
||||
type: 'error',
|
||||
title: notification.name,
|
||||
body: 'Was not updated! ' + response.data.message
|
||||
});
|
||||
});
|
||||
};
|
||||
return NotificationService;
|
||||
});
|
96
lemur/static/app/angular/notifications/view/view.js
vendored
Normal file
96
lemur/static/app/angular/notifications/view/view.js
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('lemur')
|
||||
|
||||
.config(function config($routeProvider) {
|
||||
$routeProvider.when('/notifications', {
|
||||
templateUrl: '/angular/notifications/view/view.tpl.html',
|
||||
controller: 'NotificationsViewController'
|
||||
});
|
||||
})
|
||||
|
||||
.controller('NotificationsViewController', function ($q, $scope, $modal, NotificationApi, NotificationService, ngTableParams, toaster) {
|
||||
$scope.filter = {};
|
||||
$scope.notificationsTable = new ngTableParams({
|
||||
page: 1, // show first page
|
||||
count: 10, // count per page
|
||||
sorting: {
|
||||
id: 'desc' // initial sorting
|
||||
},
|
||||
filter: $scope.filter
|
||||
}, {
|
||||
total: 0, // length of data
|
||||
getData: function ($defer, params) {
|
||||
NotificationApi.getList(params.url()).then(
|
||||
function (data) {
|
||||
_.each(data, function (notification) {
|
||||
NotificationService.getPlugin(notification);
|
||||
});
|
||||
params.total(data.total);
|
||||
$defer.resolve(data);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.getNotificationStatus = function () {
|
||||
var def = $q.defer();
|
||||
def.resolve([{'title': 'Active', 'id': true}, {'title': 'Inactive', 'id': false}]);
|
||||
return def;
|
||||
};
|
||||
|
||||
$scope.remove = function (notification) {
|
||||
notification.remove().then(
|
||||
function () {
|
||||
$scope.notificationsTable.reload();
|
||||
},
|
||||
function (response) {
|
||||
toaster.pop({
|
||||
type: 'error',
|
||||
title: 'Opps',
|
||||
body: 'I see what you did there' + response.data.message
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.edit = function (notificationId) {
|
||||
var modalInstance = $modal.open({
|
||||
animation: true,
|
||||
templateUrl: '/angular/notifications/notification/notification.tpl.html',
|
||||
controller: 'NotificationsEditController',
|
||||
size: 'lg',
|
||||
resolve: {
|
||||
editId: function () {
|
||||
return notificationId;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modalInstance.result.then(function () {
|
||||
$scope.notificationsTable.reload();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.create = function () {
|
||||
var modalInstance = $modal.open({
|
||||
animation: true,
|
||||
controller: 'NotificationsCreateController',
|
||||
templateUrl: '/angular/notifications/notification/notification.tpl.html',
|
||||
size: 'lg'
|
||||
});
|
||||
|
||||
modalInstance.result.then(function () {
|
||||
$scope.notificationsTable.reload();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.toggleFilter = function (params) {
|
||||
params.settings().$scope.show_filter = !params.settings().$scope.show_filter;
|
||||
};
|
||||
|
||||
$scope.notificationService = NotificationService;
|
||||
|
||||
});
|
52
lemur/static/app/angular/notifications/view/view.tpl.html
Normal file
52
lemur/static/app/angular/notifications/view/view.tpl.html
Normal file
@ -0,0 +1,52 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2 class="featurette-heading">Notifications
|
||||
<span class="text-muted"><small>you have to speak up son!</small></span></h2>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<button ng-click="create()" class="btn btn-primary">Create</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button ng-click="toggleFilter(notificationsTable)" class="btn btn-default">Filter</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table ng-table="notificationsTable" class="table table-striped" show-filter="false" template-pagination="angular/pager.html" >
|
||||
<tbody>
|
||||
<tr ng-repeat="notification in $data track by $index">
|
||||
<td data-title="'Label'" sortable="'label'" filter="{ 'label': 'text' }">
|
||||
<ul class="list-unstyled">
|
||||
<li>{{ notification.label }}</li>
|
||||
<li><span class="text-muted">{{ notification.description }}</span></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td data-title="'Plugin'">
|
||||
<ul class="list-unstyled">
|
||||
<li>{{ notification.plugin.title }}</li>
|
||||
<li><span class="text-muted">{{ notification.plugin.description }}</span></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td data-title="'Active'" filter="{ 'active': 'select' }" filter-data="getNotificationStatus()">
|
||||
<form>
|
||||
<switch ng-change="notificationService.updateActive(notification)" id="status" name="status" ng-model="notification.active" class="green small"></switch>
|
||||
</form>
|
||||
</td>
|
||||
<td data-title="''">
|
||||
<div class="btn-group-vertical pull-right">
|
||||
<button tooltip="Edit Notification" ng-click="edit(notification.id)" class="btn btn-sm btn-info">
|
||||
Edit
|
||||
</button>
|
||||
<button tooltip="Delete Notification" ng-click="remove(notification)" type="button" class="btn btn-sm btn-danger pull-left">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Reference in New Issue
Block a user