diff --git a/dashboard/src/js/client.js b/dashboard/src/js/client.js
index 613c0bfd8..ac9f12afb 100644
--- a/dashboard/src/js/client.js
+++ b/dashboard/src/js/client.js
@@ -1306,6 +1306,13 @@ angular.module('Application').service('Client', ['$http', '$interval', 'md5', 'N
}).error(defaultErrorHandler(callback));
};
+ Client.prototype.listMailingLists = function (domain, callback) {
+ get('/api/v1/mail/' + domain + '/lists').success(function(data, status) {
+ if (status !== 200) return callback(new ClientError(status, data));
+ callback(null, data.lists);
+ }).error(defaultErrorHandler(callback));
+ };
+
Client.prototype.getMailingList = function (domain, groupId, callback) {
get('/api/v1/mail/' + domain + '/lists/' + groupId).success(function(data, status) {
if (status !== 200) return callback(new ClientError(status, data));
diff --git a/dashboard/src/views/email.html b/dashboard/src/views/email.html
index c0904de8c..0a4d50432 100644
--- a/dashboard/src/views/email.html
+++ b/dashboard/src/views/email.html
@@ -149,6 +149,25 @@
+
+
Mailinglists
+
+
+
+
+
+ Mailinglists or forwarders are bound to user groups. Each user in a group will receive the mails sent to this group's email address.
+
+
+
+
+
+
Catch-all
diff --git a/dashboard/src/views/email.js b/dashboard/src/views/email.js
index 76d38b73b..c0db86dce 100644
--- a/dashboard/src/views/email.js
+++ b/dashboard/src/views/email.js
@@ -42,6 +42,23 @@ angular.module('Application').controller('EmailController', ['$scope', '$locatio
return $scope.mailRelay.relay.provider === provider;
};
+ // poor man's async
+ function asyncForEach(items, handler, callback) {
+ var cur = 0;
+
+ if (items.length === 0) return callback();
+
+ (function iterator() {
+ handler(items[cur], function (error) {
+ if (error) return callback(error);
+ if (cur >= items.length-1) return callback();
+ ++cur;
+
+ iterator();
+ });
+ })();
+ }
+
$scope.catchall = {
addresses: [],
availableAddresses: [],
@@ -58,6 +75,47 @@ angular.module('Application').controller('EmailController', ['$scope', '$locatio
}
};
+ $scope.mailinglists = {
+ busy: false,
+ groups: [], // current model in the ui by name
+ availableGroups: [], // all available groups by name
+ availableGroupsFull: [], // all available groups full objects
+ currentGroups: [], // currently set groups in the backend for new/removed detection
+
+ submit: function () {
+ $scope.mailinglists.busy = true;
+
+ var removedGroups = $scope.mailinglists.currentGroups.filter(function (g) { return $scope.mailinglists.groups.indexOf(g) === -1; })
+ .map(function (groupName) {
+ return $scope.mailinglists.availableGroupsFull.find(function (g) { return g.name === groupName; });
+ });
+ var newGroups = $scope.mailinglists.groups.filter(function (g) { return $scope.mailinglists.currentGroups.indexOf(g) === -1; })
+ .map(function (groupName) {
+ return $scope.mailinglists.availableGroupsFull.find(function (g) { return g.name === groupName; });
+ });
+
+ asyncForEach(removedGroups, function (group, callback) {
+ if (!group) return callback();
+
+ Client.removeMailingList($scope.selectedDomain.domain, group.id, callback);
+ }, function (error) {
+ if (error) console.error('Unable to remove mailinglists.', error);
+
+ asyncForEach(newGroups, function (group, callback) {
+ if (!group) return callback();
+
+ Client.addMailingList($scope.selectedDomain.domain, group.id, callback);
+ }, function (error) {
+ if (error) console.error('Unable to remove mailinglists.', error);
+
+ // reset the state
+ $scope.mailinglists.currentGroups = $scope.mailinglists.groups.slice();
+ $scope.mailinglists.busy = false;
+ });
+ });
+ }
+ };
+
$scope.toggleEmailEnabled = function () {
if ($scope.selectedDomain.mailConfig.enabled) {
$scope.disableEmail();
@@ -339,6 +397,21 @@ angular.module('Application').controller('EmailController', ['$scope', '$locatio
});
});
+ // mailinglists/groups
+ Client.getGroups(function (error, groups) {
+ if (error) return console.error(error);
+
+ $scope.mailinglists.availableGroupsFull = groups.slice();
+ $scope.mailinglists.availableGroups = groups.map(function (u) { return u.name; });
+
+ Client.listMailingLists($scope.selectedDomain.domain, function (error, lists) {
+ if (error) return console.error(error);
+
+ $scope.mailinglists.groups = lists.map(function (u) { return u.name; });
+ $scope.mailinglists.currentGroups = lists.map(function (u) { return u.name; });
+ });
+ });
+
// we will fetch the status without blocking the ui
Client.getMailStatusForDomain($scope.selectedDomain.domain, function (error, mailStatus) {
$scope.refreshBusy = false;