Improve mail (Sieve) filter editor

- Used 'controller as' syntax;
- Don't create new filter if user cancels the edition;
- Set default values for new filter.
This commit is contained in:
Francis Lachapelle
2015-10-05 10:45:30 -04:00
parent a393128d7a
commit 9fa9b7acab
5 changed files with 75 additions and 62 deletions

View File

@@ -318,6 +318,9 @@
"matches regex" = "matches regex"; "matches regex" = "matches regex";
"does not match regex" = "does not match regex"; "does not match regex" = "does not match regex";
/* Placeholder for the value field of a condition */
"Value" = "Value";
"Seen" = "Seen"; "Seen" = "Seen";
"Deleted" = "Deleted"; "Deleted" = "Deleted";
"Answered" = "Answered"; "Answered" = "Answered";

View File

@@ -8,15 +8,15 @@
xmlns:rsrc="OGo:url" xmlns:rsrc="OGo:url"
xmlns:uix="OGo:uix"><var:string var:value="doctype" const:escapeHTML="NO" /> xmlns:uix="OGo:uix"><var:string var:value="doctype" const:escapeHTML="NO" />
<md-dialog flex="50" flex-sm="100"> <md-dialog flex="50" flex-sm="100">
<form id="mainForm" var:href="ownPath"> <form name="mainForm" ng-submit="filterEditor.save(mainForm)">
<md-toolbar> <md-toolbar>
<div class="md-toolbar-tools"> <div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">filter_list</md-icon> <md-icon class="material-icons sg-icon-toolbar-bg">filter_list</md-icon>
<md-input-container> <md-input-container>
<label><var:string label:value="Filter name:"/></label> <label><var:string label:value="Filter name:"/></label>
<input class="md-title" type="text" ng-model="filter.name" required="required"/> <input class="md-title" type="text" ng-model="filterEditor.filter.name" required="required"/>
</md-input-container> </md-input-container>
<md-button type="button" class="sg-icon-button " ng-click="cancel()"> <md-button type="button" class="sg-icon-button " ng-click="filterEditor.cancel()">
<md-icon>close</md-icon> <md-icon>close</md-icon>
</md-button> </md-button>
</div> </div>
@@ -29,9 +29,9 @@
</script> </script>
<div layout="row" layout-align="start center"> <div layout="row" layout-align="start center">
<div><var:string label:value="For incoming messages that"/></div> <var:string label:value="For incoming messages that"/>
<md-input-container class="md-flex"> <md-input-container class="md-flex">
<md-select ng-model="filter.match" required="required"> <md-select ng-model="filterEditor.filter.match" required="required">
<md-option const:value="all"> <md-option const:value="all">
<var:string label:value="match all of the following rules:"/> <var:string label:value="match all of the following rules:"/>
</md-option> </md-option>
@@ -49,10 +49,10 @@
<div layout="column"> <div layout="column">
<div id="filterRules"><!-- empty --> <div id="filterRules"><!-- empty -->
<md-list> <md-list>
<md-list-item ng-repeat="rule in filter.rules"> <md-list-item ng-repeat="rule in filterEditor.filter.rules">
<md-input-container flex="25"> <md-input-container flex="25">
<md-select ng-model="rule.field"> <md-select ng-model="rule.field">
<md-option ng-value="key" ng-repeat="(key, value) in fieldLabels">{{ value }}</md-option> <md-option ng-value="key" ng-repeat="(key, value) in filterEditor.fieldLabels">{{ value }}</md-option>
</md-select> </md-select>
</md-input-container> </md-input-container>
@@ -62,7 +62,7 @@
<md-input-container flex="25" ng-show="rule.field == 'size'"> <md-input-container flex="25" ng-show="rule.field == 'size'">
<md-select ng-model="rule.operator"> <md-select ng-model="rule.operator">
<md-option ng-value="key" ng-repeat="(key, value) in numberOperatorLabels"> <md-option ng-value="key" ng-repeat="(key, value) in filterEditor.numberOperatorLabels">
{{ value }} {{ value }}
</md-option> </md-option>
</md-select> </md-select>
@@ -70,18 +70,18 @@
<md-input-container flex="25" ng-show="rule.field != 'size'"> <md-input-container flex="25" ng-show="rule.field != 'size'">
<md-select ng-model="rule.operator"> <md-select ng-model="rule.operator">
<md-option ng-value="key" ng-repeat="(key, value) in textOperatorLabels"> <md-option ng-value="key" ng-repeat="(key, value) in filterEditor.textOperatorLabels">
{{ value }} {{ value }}
</md-option> </md-option>
</md-select> </md-select>
</md-input-container> </md-input-container>
<md-input-container class="md-flex"> <md-input-container class="md-flex" md-no-float="md-no-float">
<input type="text" ng-model="rule.value"/> <input type="text" label:placeholder="Value" ng-model="rule.value"/>
</md-input-container> </md-input-container>
<md-button class="sg-icon-button" type="button" <md-button class="sg-icon-button" type="button"
ng-click="removeMailFilterRule($index)"> ng-click="filterEditor.removeMailFilterRule($index)">
<md-icon>remove_circle</md-icon> <md-icon>remove_circle</md-icon>
</md-button> </md-button>
@@ -91,7 +91,7 @@
<div layout="row" layout-align="end center"> <div layout="row" layout-align="end center">
<md-button class="sg-icon-button" type="button" <md-button class="sg-icon-button" type="button"
ng-click="addMailFilterRule($event)"> ng-click="filterEditor.addMailFilterRule($event)">
<md-icon>add_circle</md-icon> <md-icon>add_circle</md-icon>
</md-button> </md-button>
</div> </div>
@@ -104,10 +104,10 @@
<md-list> <md-list>
<md-list-item layout="row" layout-align="space-between center" <md-list-item layout="row" layout-align="space-between center"
ng-repeat="action in filter.actions"> ng-repeat="action in filterEditor.filter.actions">
<md-input-container> <md-input-container>
<md-select ng-model="action.method"> <md-select ng-model="action.method">
<md-option ng-value="key" ng-repeat="(key, value) in methodLabels">{{ value }}</md-option> <md-option ng-value="key" ng-repeat="(key, value) in filterEditor.methodLabels">{{ value }}</md-option>
</md-select> </md-select>
</md-input-container> </md-input-container>
@@ -130,7 +130,7 @@
<!-- FILE INTO --> <!-- FILE INTO -->
<md-input-container ng-show="action.method == 'fileinto'" > <md-input-container ng-show="action.method == 'fileinto'" >
<md-select ng-model="action.argument"> <md-select ng-model="action.argument">
<md-option ng-value="item.path" ng-repeat="item in mailboxes"> <md-option ng-value="item.path" ng-repeat="item in filterEditor.mailboxes">
{{ item.name }} {{ item.name }}
</md-option> </md-option>
</md-select> </md-select>
@@ -153,7 +153,7 @@
<!-- nada --> <!-- nada -->
<md-button class="sg-icon-button" type="button" <md-button class="sg-icon-button" type="button"
ng-click="removeMailFilterAction($index)"> ng-click="filterEditor.removeMailFilterAction($index)">
<md-icon>remove_circle</md-icon> <md-icon>remove_circle</md-icon>
</md-button> </md-button>
@@ -162,14 +162,14 @@
<div layout="row" layout-align="end center"> <div layout="row" layout-align="end center">
<md-button class="sg-icon-button" type="button" <md-button class="sg-icon-button" type="button"
ng-click="addMailFilterAction($event)"> ng-click="filterEditor.addMailFilterAction($event)">
<md-icon>add_circle</md-icon> <md-icon>add_circle</md-icon>
</md-button> </md-button>
</div> </div>
</div> </div>
</md-dialog-content> </md-dialog-content>
<div class="md-actions"> <div class="md-actions">
<md-button type="button" ng-click="save()"><var:string label:value="Save"/></md-button> <md-button type="submit"><var:string label:value="Save"/></md-button>
</div> </div>
</form> </form>
</md-dialog> </md-dialog>

View File

@@ -604,7 +604,7 @@
<input type="text" ng-model="app.preferences.defaults.SOGoSieveFilters[$index].name"/> <input type="text" ng-model="app.preferences.defaults.SOGoSieveFilters[$index].name"/>
</md-input-container> </md-input-container>
<md-button class="sg-icon-button" type="button" <md-button class="sg-icon-button" type="button"
ng-click="app.editMailFilter($index)" ng-click="app.editMailFilter($event, $index)"
layout="row" layout-align="end center" layout="row" layout-align="end center"
label:aria-label="Edit Filter"> label:aria-label="Edit Filter">
<md-icon>edit</md-icon> <md-icon>edit</md-icon>

View File

@@ -9,11 +9,19 @@
*/ */
FiltersDialogController.$inject = ['$scope', '$mdDialog', 'filter', 'mailboxes', 'labels', 'sieveCapabilities']; FiltersDialogController.$inject = ['$scope', '$mdDialog', 'filter', 'mailboxes', 'labels', 'sieveCapabilities'];
function FiltersDialogController($scope, $mdDialog, filter, mailboxes, labels, sieveCapabilities) { function FiltersDialogController($scope, $mdDialog, filter, mailboxes, labels, sieveCapabilities) {
$scope.filter = filter; var vm = this;
$scope.mailboxes = mailboxes;
$scope.labels = labels;
$scope.fieldLabels = { vm.filter = filter;
vm.mailboxes = mailboxes;
vm.labels = labels;
vm.cancel = cancel;
vm.save = save;
vm.addMailFilterRule = addMailFilterRule;
vm.removeMailFilterRule = removeMailFilterRule;
vm.addMailFilterAction = addMailFilterAction;
vm.removeMailFilterAction = removeMailFilterAction;
vm.fieldLabels = {
"subject": l("Subject"), "subject": l("Subject"),
"from": l("From"), "from": l("From"),
"to": l("To"), "to": l("To"),
@@ -24,9 +32,9 @@
}; };
if (sieveCapabilities.indexOf("body") > -1) if (sieveCapabilities.indexOf("body") > -1)
$scope.fieldLabels.body = l("Body"); vm.fieldLabels.body = l("Body");
$scope.methodLabels = { vm.methodLabels = {
"discard": l("Discard the message"), "discard": l("Discard the message"),
"keep": l("Keep the message"), "keep": l("Keep the message"),
"redirect": l("Forward the message to:"), "redirect": l("Forward the message to:"),
@@ -35,20 +43,20 @@
}; };
if (sieveCapabilities.indexOf("reject") > -1) if (sieveCapabilities.indexOf("reject") > -1)
$scope.methodLabels.reject = l("Send a reject message:"); vm.methodLabels.reject = l("Send a reject message:");
if (sieveCapabilities.indexOf("fileinto") > -1) if (sieveCapabilities.indexOf("fileinto") > -1)
$scope.methodLabels.fileinto = l("File the message in:"); vm.methodLabels.fileinto = l("File the message in:");
if (sieveCapabilities.indexOf("imapflags") > -1 || sieveCapabilities.indexOf("imap4flags") > -1) if (sieveCapabilities.indexOf("imapflags") > -1 || sieveCapabilities.indexOf("imap4flags") > -1)
$scope.methodLabels.addflag = l("Flag the message with:"); vm.methodLabels.addflag = l("Flag the message with:");
$scope.numberOperatorLabels = { vm.numberOperatorLabels = {
"under": l("is under"), "under": l("is under"),
"over": l("is over") "over": l("is over")
}; };
$scope.textOperatorLabels = { vm.textOperatorLabels = {
"is": l("is"), "is": l("is"),
"is_not": l("is not"), "is_not": l("is not"),
"contains": l("contains"), "contains": l("contains"),
@@ -58,11 +66,11 @@
}; };
if (sieveCapabilities.indexOf("regex") > -1) { if (sieveCapabilities.indexOf("regex") > -1) {
$scope.textOperatorLabels.regex = l("matches regex"); vm.textOperatorLabels.regex = l("matches regex");
$scope.textOperatorLabels.regex_not = l("does not match regex"); vm.textOperatorLabels.regex_not = l("does not match regex");
} }
$scope.flagLabels = { vm.flagLabels = {
"seen": l("Seen"), "seen": l("Seen"),
"deleted": l("Deleted"), "deleted": l("Deleted"),
"answered": l("Answered"), "answered": l("Answered"),
@@ -71,35 +79,35 @@
"not_junk": l("Not Junk") "not_junk": l("Not Junk")
}; };
$scope.cancel = function() { function cancel() {
$mdDialog.cancel(); $mdDialog.cancel();
}; }
$scope.save = function() { function save(form) {
$mdDialog.hide(); $mdDialog.hide();
}; }
$scope.addMailFilterRule = function(event) { function addMailFilterRule(event) {
if (!$scope.filter.rules) if (!vm.filter.rules)
$scope.filter.rules = []; vm.filter.rules = [];
$scope.filter.rules.push({}); vm.filter.rules.push({ field: 'subject', operator: 'contains' });
}; }
$scope.removeMailFilterRule = function(index) { function removeMailFilterRule(index) {
$scope.filter.rules.splice(index, 1); vm.filter.rules.splice(index, 1);
}; }
$scope.addMailFilterAction = function(event) { function addMailFilterAction(event) {
if (!$scope.filter.actions) if (!vm.filter.actions)
$scope.filter.actions = []; vm.filter.actions = [];
$scope.filter.actions.push({}); vm.filter.actions.push({ method: 'discard' });
}; }
$scope.removeMailFilterAction = function(index) { function removeMailFilterAction(index) {
$scope.filter.actions.splice(index, 1); vm.filter.actions.splice(index, 1);
}; }
} }
angular angular

View File

@@ -125,14 +125,11 @@
} }
function addMailFilter(ev) { function addMailFilter(ev) {
if (!vm.preferences.defaults.SOGoSieveFilters) var filter = { match: 'all' };
vm.preferences.defaults.SOGoSieveFilters = [];
vm.preferences.defaults.SOGoSieveFilters.push({});
var filter = _.last(vm.preferences.defaults.SOGoSieveFilters);
$mdDialog.show({ $mdDialog.show({
controller: 'FiltersDialogController',
templateUrl: 'editFilter?filter=new', templateUrl: 'editFilter?filter=new',
controller: 'FiltersDialogController',
controllerAs: 'filterEditor',
targetEvent: ev, targetEvent: ev,
locals: { locals: {
filter: filter, filter: filter,
@@ -140,15 +137,20 @@
labels: vm.preferences.defaults.SOGoMailLabelsColors, labels: vm.preferences.defaults.SOGoMailLabelsColors,
sieveCapabilities: window.sieveCapabilities sieveCapabilities: window.sieveCapabilities
} }
}).then(function() {
if (!vm.preferences.defaults.SOGoSieveFilters)
vm.preferences.defaults.SOGoSieveFilters = [];
vm.preferences.defaults.SOGoSieveFilters.push(filter);
}); });
} }
function editMailFilter(index) { function editMailFilter(ev, index) {
var filter = angular.copy(vm.preferences.defaults.SOGoSieveFilters[index]); var filter = angular.copy(vm.preferences.defaults.SOGoSieveFilters[index]);
$mdDialog.show({ $mdDialog.show({
controller: 'FiltersDialogController',
templateUrl: 'editFilter?filter=' + index, templateUrl: 'editFilter?filter=' + index,
controller: 'FiltersDialogController',
controllerAs: 'filterEditor',
targetEvent: null, targetEvent: null,
locals: { locals: {
filter: filter, filter: filter,