mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Get a working Sieve scripts manager
This commit is contained in:
parent
a31834458b
commit
e3125ebfff
24 changed files with 439 additions and 304 deletions
|
|
@ -379,6 +379,8 @@ export const Notification = {
|
||||||
|
|
||||||
CantSaveFilters: 351,
|
CantSaveFilters: 351,
|
||||||
CantGetFilters: 352,
|
CantGetFilters: 352,
|
||||||
|
CantActivateFiltersScript: 351, // TODO: 353
|
||||||
|
CantDeleteFiltersScript: 351, // TODO: 354
|
||||||
FiltersAreNotCorrect: 355,
|
FiltersAreNotCorrect: 355,
|
||||||
|
|
||||||
CantCreateFolder: 400,
|
CantCreateFolder: 400,
|
||||||
|
|
|
||||||
|
|
@ -10,21 +10,23 @@ class SieveScriptModel extends AbstractModel
|
||||||
|
|
||||||
this.addObservables({
|
this.addObservables({
|
||||||
name: '',
|
name: '',
|
||||||
nameError: false,
|
|
||||||
nameFocused: false,
|
|
||||||
|
|
||||||
active: false,
|
active: false,
|
||||||
|
|
||||||
body: '',
|
body: '',
|
||||||
|
|
||||||
|
nameError: false,
|
||||||
|
bodyError: false,
|
||||||
deleteAccess: false,
|
deleteAccess: false,
|
||||||
canBeDeleted: false
|
canBeDeleted: false,
|
||||||
|
hasChanges: false
|
||||||
});
|
});
|
||||||
|
|
||||||
this.filters = ko.observableArray([]);
|
this.filters = ko.observableArray([]);
|
||||||
|
// this.saving = ko.observable(false).extend({ throttle: 200 });
|
||||||
|
|
||||||
this.addSubscribables({
|
this.addSubscribables({
|
||||||
name: sValue => this.nameError(!sValue)
|
name: () => this.hasChanges(true),
|
||||||
|
filters: () => this.hasChanges(true),
|
||||||
|
body: () => this.hasChanges(true)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,20 +36,17 @@ class SieveScriptModel extends AbstractModel
|
||||||
}
|
}
|
||||||
|
|
||||||
verify() {
|
verify() {
|
||||||
if (!this.name()) {
|
this.nameError(!this.name().trim());
|
||||||
this.nameError(true);
|
this.bodyError(this.allowFilters() ? !this.filters().length : !this.body().trim());
|
||||||
return false;
|
return !this.nameError() && !this.bodyError();
|
||||||
}
|
|
||||||
this.nameError(false);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson() {
|
toJson() {
|
||||||
return {
|
return {
|
||||||
name: this.name(),
|
name: this.name(),
|
||||||
active: this.active ? '1' : '0',
|
active: this.active() ? '1' : '0',
|
||||||
body: this.body,
|
body: this.body(),
|
||||||
// filters: this.filters()
|
filters: this.filters().map(item => item.toJson())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,12 +65,14 @@ class SieveScriptModel extends AbstractModel
|
||||||
static reviveFromJson(json) {
|
static reviveFromJson(json) {
|
||||||
const script = super.reviveFromJson(json);
|
const script = super.reviveFromJson(json);
|
||||||
if (script) {
|
if (script) {
|
||||||
script.filters([]);
|
|
||||||
if (script.allowFilters() && Array.isNotEmpty(json.filters)) {
|
if (script.allowFilters() && Array.isNotEmpty(json.filters)) {
|
||||||
script.filters(
|
script.filters(
|
||||||
json.filters.map(aData => FilterModel.reviveFromJson(aData)).filter(v => v)
|
json.filters.map(aData => FilterModel.reviveFromJson(aData)).filter(v => v)
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
script.filters([]);
|
||||||
}
|
}
|
||||||
|
script.hasChanges(false);
|
||||||
}
|
}
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,30 @@ class RemoteUserFetch extends AbstractFetchRemote {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?Function} fCallback
|
||||||
|
* @param {SieveScriptModel} script
|
||||||
|
*/
|
||||||
|
filtersScriptSave(fCallback, script) {
|
||||||
|
this.defaultRequest(fCallback, 'FiltersScriptSave', script.toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?Function} fCallback
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
|
filtersScriptActivate(fCallback, name) {
|
||||||
|
this.defaultRequest(fCallback, 'FiltersScriptActivate', {name:name});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?Function} fCallback
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
|
filtersScriptDelete(fCallback, name) {
|
||||||
|
this.defaultRequest(fCallback, 'FiltersScriptDelete', {name:name});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {?Function} fCallback
|
* @param {?Function} fCallback
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
import ko from 'ko';
|
import ko from 'ko';
|
||||||
|
|
||||||
|
import { delegateRunOnDestroy } from 'Common/UtilsUser';
|
||||||
import { StorageResultType, Notification } from 'Common/Enums';
|
import { StorageResultType, Notification } from 'Common/Enums';
|
||||||
import { getNotification } from 'Common/Translator';
|
import { getNotification } from 'Common/Translator';
|
||||||
|
|
||||||
import FilterStore from 'Stores/User/Filter';
|
|
||||||
import SieveStore from 'Stores/User/Sieve';
|
import SieveStore from 'Stores/User/Sieve';
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
||||||
import { FilterModel } from 'Model/Filter';
|
|
||||||
import { SieveScriptModel } from 'Model/SieveScript';
|
import { SieveScriptModel } from 'Model/SieveScript';
|
||||||
|
|
||||||
import { showScreenPopup } from 'Knoin/Knoin';
|
import { showScreenPopup } from 'Knoin/Knoin';
|
||||||
|
|
||||||
class FiltersUserSettings {
|
class FiltersUserSettings {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.filters = FilterStore.filters;
|
|
||||||
this.sieve = SieveStore;
|
this.sieve = SieveStore;
|
||||||
|
|
||||||
this.scripts = SieveStore.scripts;
|
this.scripts = SieveStore.scripts;
|
||||||
|
this.loading = ko.observable(false).extend({ throttle: 200 });
|
||||||
|
|
||||||
ko.addObservablesTo(this, {
|
ko.addObservablesTo(this, {
|
||||||
serverError: false,
|
serverError: false,
|
||||||
|
|
@ -33,23 +33,17 @@ class FiltersUserSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateList() {
|
updateList() {
|
||||||
if (!this.filters.loading()) {
|
if (!this.loading()) {
|
||||||
this.filters.loading(true);
|
this.loading(true);
|
||||||
|
|
||||||
Remote.filtersGet((result, data) => {
|
Remote.filtersGet((result, data) => {
|
||||||
this.filters.loading(false);
|
this.loading(false);
|
||||||
this.serverError(false);
|
this.serverError(false);
|
||||||
this.scripts([]);
|
this.scripts([]);
|
||||||
|
|
||||||
if (StorageResultType.Success === result && data && data.Result && Array.isArray(data.Result.Filters)) {
|
if (StorageResultType.Success === result && data && data.Result) {
|
||||||
this.serverError(false);
|
this.serverError(false);
|
||||||
|
|
||||||
this.filters(
|
|
||||||
data.Result.Filters.map(aItem => FilterModel.reviveFromJson(aItem)).filter(v => v)
|
|
||||||
);
|
|
||||||
|
|
||||||
FilterStore.modules(data.Result.Capa);
|
|
||||||
|
|
||||||
SieveStore.capa(data.Result.Capa);
|
SieveStore.capa(data.Result.Capa);
|
||||||
/*
|
/*
|
||||||
this.scripts(
|
this.scripts(
|
||||||
|
|
@ -60,20 +54,9 @@ class FiltersUserSettings {
|
||||||
value = SieveScriptModel.reviveFromJson(value);
|
value = SieveScriptModel.reviveFromJson(value);
|
||||||
value && this.scripts.push(value)
|
value && this.scripts.push(value)
|
||||||
});
|
});
|
||||||
|
|
||||||
FilterStore.raw(data.Result.Scripts['rainloop.user.raw'].body);
|
|
||||||
FilterStore.capa(data.Result.Capa.join(' '));
|
|
||||||
// this.filterRaw.active(data.Result.Scripts['rainloop.user.raw'].active);
|
|
||||||
// this.filterRaw.allow(!!data.Result.RawIsAllow);
|
|
||||||
} else {
|
} else {
|
||||||
this.filters([]);
|
this.scripts([]);
|
||||||
FilterStore.modules({});
|
|
||||||
|
|
||||||
SieveStore.capa([]);
|
SieveStore.capa([]);
|
||||||
|
|
||||||
FilterStore.raw('');
|
|
||||||
FilterStore.capa({});
|
|
||||||
|
|
||||||
this.serverError(true);
|
this.serverError(true);
|
||||||
this.serverErrorDesc(
|
this.serverErrorDesc(
|
||||||
data && data.ErrorCode ? getNotification(data.ErrorCode) : getNotification(Notification.CantGetFilters)
|
data && data.ErrorCode ? getNotification(data.ErrorCode) : getNotification(Notification.CantGetFilters)
|
||||||
|
|
@ -106,13 +89,42 @@ class FiltersUserSettings {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteScript() {
|
deleteScript(script) {
|
||||||
// TODO
|
if (!script.active()) {
|
||||||
|
Remote.filtersScriptDelete(
|
||||||
|
(result, data) => {
|
||||||
|
if (StorageResultType.Success === result && data && data.Result) {
|
||||||
|
this.scripts.remove(script);
|
||||||
|
delegateRunOnDestroy(script);
|
||||||
|
} else {
|
||||||
|
this.saveError(true);
|
||||||
|
this.saveErrorText((data && data.ErrorCode)
|
||||||
|
? (data.ErrorMessageAdditional || getNotification(data.ErrorCode))
|
||||||
|
: getNotification(Notification.CantActivateFiltersScript)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
script.name()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleScript(script) {
|
toggleScript(script) {
|
||||||
// TODO: activate/deactivate script
|
let name = script.active() ? '' : script.name();
|
||||||
script.active(!script.active());
|
Remote.filtersScriptActivate(
|
||||||
|
(result, data) => {
|
||||||
|
if (StorageResultType.Success === result && data && data.Result) {
|
||||||
|
this.scripts().forEach(script => script.active(script.name() === name));
|
||||||
|
} else {
|
||||||
|
this.saveError(true);
|
||||||
|
this.saveErrorText((data && data.ErrorCode)
|
||||||
|
? (data.ErrorMessageAdditional || getNotification(data.ErrorCode))
|
||||||
|
: getNotification(Notification.CantActivateFiltersScript)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onBuild(oDom) {
|
onBuild(oDom) {
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import ko from 'ko';
|
|
||||||
|
|
||||||
class FilterUserStore {
|
|
||||||
constructor() {
|
|
||||||
ko.addObservablesTo(this, {
|
|
||||||
capa: '',
|
|
||||||
modules: [],
|
|
||||||
raw: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
this.filters = ko.observableArray([]);
|
|
||||||
|
|
||||||
this.filters.loading = ko.observable(false).extend({ throttle: 200 });
|
|
||||||
this.filters.saving = ko.observable(false).extend({ throttle: 200 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new FilterUserStore();
|
|
||||||
|
|
@ -50,3 +50,8 @@ html.rl-mobile .b-settings-filters {
|
||||||
.filter-item .filter-sub-name {
|
.filter-item .filter-sub-name {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.b-filter-script textarea {
|
||||||
|
height: 300px;
|
||||||
|
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { FiltersAction, FilterConditionField, FilterConditionType } from 'Common
|
||||||
import { defaultOptionsAfterRender } from 'Common/Utils';
|
import { defaultOptionsAfterRender } from 'Common/Utils';
|
||||||
import { i18n, initOnStartOrLangChange } from 'Common/Translator';
|
import { i18n, initOnStartOrLangChange } from 'Common/Translator';
|
||||||
|
|
||||||
import FilterStore from 'Stores/User/Filter';
|
|
||||||
import FolderStore from 'Stores/User/Folder';
|
import FolderStore from 'Stores/User/Folder';
|
||||||
|
import SieveStore from 'Stores/User/Sieve';
|
||||||
|
|
||||||
import { popup, command } from 'Knoin/Knoin';
|
import { popup, command } from 'Knoin/Knoin';
|
||||||
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
|
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
|
||||||
|
|
@ -25,7 +25,7 @@ class FilterPopupView extends AbstractViewNext {
|
||||||
selectedFolderValue: ''
|
selectedFolderValue: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
this.modules = FilterStore.modules;
|
this.modules = SieveStore.capa;
|
||||||
|
|
||||||
this.fTrueCallback = null;
|
this.fTrueCallback = null;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,13 @@ import ko from 'ko';
|
||||||
import { delegateRunOnDestroy } from 'Common/UtilsUser';
|
import { delegateRunOnDestroy } from 'Common/UtilsUser';
|
||||||
import { StorageResultType, Notification } from 'Common/Enums';
|
import { StorageResultType, Notification } from 'Common/Enums';
|
||||||
import { getNotification } from 'Common/Translator';
|
import { getNotification } from 'Common/Translator';
|
||||||
|
import { i18nToNodes } from 'Common/Translator';
|
||||||
|
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
import FilterStore from 'Stores/User/Filter';
|
|
||||||
import FilterModel from 'Model/Filter';
|
import FilterModel from 'Model/Filter';
|
||||||
|
import SieveStore from 'Stores/User/Sieve';
|
||||||
|
|
||||||
import { popup, showScreenPopup, command } from 'Knoin/Knoin';
|
import { popup, showScreenPopup/*, command*/ } from 'Knoin/Knoin';
|
||||||
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
|
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
|
||||||
|
|
||||||
@popup({
|
@popup({
|
||||||
|
|
@ -19,78 +20,46 @@ class SieveScriptPopupView extends AbstractViewNext {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// this.filters = FilterStore.filters;
|
|
||||||
this.filters = ko.observableArray([]);
|
|
||||||
this.filters.loading = ko.observable(false).extend({ throttle: 200 });
|
|
||||||
this.filters.saving = ko.observable(false).extend({ throttle: 200 });
|
|
||||||
|
|
||||||
this.modules = FilterStore.modules;
|
|
||||||
|
|
||||||
this.script = {
|
|
||||||
filters: FilterStore.filters,
|
|
||||||
saving: () => FilterStore.filters.saving()
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.addObservablesTo(this, {
|
ko.addObservablesTo(this, {
|
||||||
isNew: true,
|
isNew: true,
|
||||||
serverError: false,
|
saveError: false,
|
||||||
serverErrorDesc: '',
|
|
||||||
saveErrorText: '',
|
saveErrorText: '',
|
||||||
haveChanges: false,
|
rawActive: false,
|
||||||
filterRaw: ''
|
script: null
|
||||||
});
|
});
|
||||||
|
|
||||||
this.serverError.subscribe(value => value || this.serverErrorDesc(''), this);
|
this.sieveCapabilities = SieveStore.capa.join(' ');
|
||||||
|
this.saving = false;
|
||||||
// this.filterRaw = FilterStore.raw;
|
|
||||||
this.filterRaw.capa = FilterStore.capa;
|
|
||||||
this.filterRaw.active = ko.observable(false);
|
|
||||||
this.filterRaw.allow = ko.observable(false);
|
|
||||||
this.filterRaw.error = ko.observable(false);
|
|
||||||
|
|
||||||
this.filterForDeletion = ko.observable(null).deleteAccessHelper();
|
this.filterForDeletion = ko.observable(null).deleteAccessHelper();
|
||||||
|
|
||||||
this.filters.subscribe(() => this.haveChanges(true));
|
|
||||||
|
|
||||||
this.filterRaw.subscribe(() => {
|
|
||||||
this.haveChanges(true);
|
|
||||||
this.filterRaw.error(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.haveChanges.subscribe(() => this.saveErrorText(''));
|
|
||||||
|
|
||||||
this.filterRaw.active.subscribe(() => {
|
|
||||||
this.haveChanges(true);
|
|
||||||
this.filterRaw.error(false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@command((self) => self.haveChanges())
|
// @command()
|
||||||
saveScriptCommand() {
|
saveScriptCommand() {
|
||||||
if (!this.filters.saving()) {
|
let script = this.script();
|
||||||
if (this.filterRaw.active() && !this.filterRaw().trim()) {
|
if (!this.saving/* && script.hasChanges()*/) {
|
||||||
this.filterRaw.error(true);
|
if (!script.verify()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.filters.saving(true);
|
this.saving = true;
|
||||||
this.saveErrorText('');
|
this.saveError(false);
|
||||||
|
|
||||||
Remote.filtersSave(
|
Remote.filtersScriptSave(
|
||||||
(result, data) => {
|
(result, data) => {
|
||||||
this.filters.saving(false);
|
this.saving = false;
|
||||||
|
|
||||||
if (StorageResultType.Success === result && data && data.Result) {
|
if (StorageResultType.Success === result && data && data.Result) {
|
||||||
this.haveChanges(false);
|
script.hasChanges(false);
|
||||||
} else if (data && data.ErrorCode) {
|
|
||||||
this.saveErrorText(data.ErrorMessageAdditional || getNotification(data.ErrorCode));
|
|
||||||
} else {
|
} else {
|
||||||
this.saveErrorText(getNotification(Notification.CantSaveFilters));
|
this.saveError(true);
|
||||||
|
this.saveErrorText((data && data.ErrorCode)
|
||||||
|
? (data.ErrorMessageAdditional || getNotification(data.ErrorCode))
|
||||||
|
: getNotification(Notification.CantSaveFilters)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
this.filters(),
|
script
|
||||||
this.filterRaw(),
|
|
||||||
this.filterRaw.active()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,19 +67,18 @@ class SieveScriptPopupView extends AbstractViewNext {
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteFilter(filter) {
|
deleteFilter(filter) {
|
||||||
this.filters.remove(filter);
|
this.script().filters.remove(filter);
|
||||||
delegateRunOnDestroy(filter);
|
delegateRunOnDestroy(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
addFilter() {
|
addFilter() {
|
||||||
|
/* this = SieveScriptModel */
|
||||||
const filter = new FilterModel();
|
const filter = new FilterModel();
|
||||||
|
|
||||||
filter.generateID();
|
filter.generateID();
|
||||||
showScreenPopup(require('View/Popup/Filter'), [
|
showScreenPopup(require('View/Popup/Filter'), [
|
||||||
filter,
|
filter,
|
||||||
() => {
|
() => {
|
||||||
this.filters.push(filter);
|
this.filters.push(filter);
|
||||||
this.filterRaw.active(false);
|
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
]);
|
]);
|
||||||
|
|
@ -118,19 +86,16 @@ class SieveScriptPopupView extends AbstractViewNext {
|
||||||
|
|
||||||
editFilter(filter) {
|
editFilter(filter) {
|
||||||
const clonedFilter = filter.cloneSelf();
|
const clonedFilter = filter.cloneSelf();
|
||||||
|
|
||||||
showScreenPopup(require('View/Popup/Filter'), [
|
showScreenPopup(require('View/Popup/Filter'), [
|
||||||
clonedFilter,
|
clonedFilter,
|
||||||
() => {
|
() => {
|
||||||
const filters = this.filters(),
|
const script = this.script(),
|
||||||
|
filters = script.filters(),
|
||||||
index = filters.indexOf(filter);
|
index = filters.indexOf(filter);
|
||||||
|
if (-1 < index) {
|
||||||
if (-1 < index && filters[index]) {
|
|
||||||
delegateRunOnDestroy(filters[index]);
|
delegateRunOnDestroy(filters[index]);
|
||||||
filters[index] = clonedFilter;
|
filters[index] = clonedFilter;
|
||||||
|
script.filters(filters);
|
||||||
this.filters(filters);
|
|
||||||
this.haveChanges(true);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
|
|
@ -141,36 +106,22 @@ class SieveScriptPopupView extends AbstractViewNext {
|
||||||
oDom.addEventListener('click', event => {
|
oDom.addEventListener('click', event => {
|
||||||
const el = event.target.closestWithin('.filter-item .e-action', oDom),
|
const el = event.target.closestWithin('.filter-item .e-action', oDom),
|
||||||
filter = el && ko.dataFor(el);
|
filter = el && ko.dataFor(el);
|
||||||
filter && this.editFilter(ko.dataFor(el));
|
filter && this.editFilter(filter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onShow(oScript, fTrueCallback, bEdit) {
|
onShow(oScript, fTrueCallback, bEdit) {
|
||||||
this.clearPopup();
|
|
||||||
|
|
||||||
this.fTrueCallback = fTrueCallback;
|
this.fTrueCallback = fTrueCallback;
|
||||||
this.filters(oScript.filters());
|
this.script(oScript);
|
||||||
|
this.rawActive(!oScript.allowFilters());
|
||||||
this.filterRaw(oScript.body());
|
|
||||||
this.filterRaw.active(!oScript.allowFilters());
|
|
||||||
this.filterRaw.error(false);
|
|
||||||
|
|
||||||
this.isNew(!bEdit);
|
this.isNew(!bEdit);
|
||||||
|
this.saveError(false);
|
||||||
if (!bEdit && oScript) {
|
|
||||||
// oScript.nameFocused(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onShowWithDelay() {
|
onShowWithDelay() {
|
||||||
|
// Sometimes not everything is translated, try again
|
||||||
|
i18nToNodes(this.viewModelDom);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearPopup() {
|
|
||||||
this.isNew(true);
|
|
||||||
this.fTrueCallback = null;
|
|
||||||
this.filters([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { SieveScriptPopupView, SieveScriptPopupView as default };
|
export { SieveScriptPopupView, SieveScriptPopupView as default };
|
||||||
|
|
|
||||||
|
|
@ -326,6 +326,17 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \MailSo\Net\Exceptions\Exception
|
||||||
|
* @throws \MailSo\Sieve\Exceptions\NegativeResponseException
|
||||||
|
*/
|
||||||
|
public function RenameScript(string $sOldName, string $sNewName) : self
|
||||||
|
{
|
||||||
|
$this->sendRequestWithCheck('RENAMESCRIPT "'.$sOldName.'" "'.$sNewName.'"');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \MailSo\Net\Exceptions\Exception
|
* @throws \MailSo\Net\Exceptions\Exception
|
||||||
* @throws \MailSo\Sieve\Exceptions\NegativeResponseException
|
* @throws \MailSo\Sieve\Exceptions\NegativeResponseException
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,64 @@ trait Filters
|
||||||
$aFilters, $sRaw, $bRawIsActive));
|
$aFilters, $sRaw, $bRawIsActive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function DoFiltersScriptSave() : array
|
||||||
|
{
|
||||||
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
|
||||||
|
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||||
|
return $this->FalseResponse(__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sName = $this->GetActionParam('name', '');
|
||||||
|
|
||||||
|
$aFilters = array();
|
||||||
|
if (\RainLoop\Providers\Filters\SieveStorage::SIEVE_FILE_NAME === $sName) {
|
||||||
|
$aIncFilters = $this->GetActionParam('filters', array());
|
||||||
|
foreach ($aIncFilters as $aFilter) {
|
||||||
|
if (\is_array($aFilter)) {
|
||||||
|
$oFilter = new \RainLoop\Providers\Filters\Classes\Filter();
|
||||||
|
if ($oFilter->FromJSON($aFilter)) {
|
||||||
|
$aFilters[] = $oFilter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->GetActionParam('active', false)) {
|
||||||
|
// $this->FiltersProvider()->ActivateScript($oAccount, $sName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Save(
|
||||||
|
$oAccount, $sName, $aFilters, $this->GetActionParam('body', '')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DoFiltersScriptActivate() : array
|
||||||
|
{
|
||||||
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
|
||||||
|
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||||
|
return $this->FalseResponse(__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->ActivateScript(
|
||||||
|
$oAccount, $this->GetActionParam('name', '')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DoFiltersScriptDelete() : array
|
||||||
|
{
|
||||||
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
|
||||||
|
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||||
|
return $this->FalseResponse(__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->DeleteScript(
|
||||||
|
$oAccount, $this->GetActionParam('name', '')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
protected function FiltersProvider() : \RainLoop\Providers\Filters
|
protected function FiltersProvider() : \RainLoop\Providers\Filters
|
||||||
{
|
{
|
||||||
if (!$this->oFiltersProvider) {
|
if (!$this->oFiltersProvider) {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ class Notifications
|
||||||
|
|
||||||
const CantSaveFilters = 351;
|
const CantSaveFilters = 351;
|
||||||
const CantGetFilters = 352;
|
const CantGetFilters = 352;
|
||||||
|
const CantActivateFiltersScript = 351; // TODO: 353
|
||||||
|
const CantDeleteFiltersScript = 351; // TODO: 354
|
||||||
const FiltersAreNotCorrect = 355;
|
const FiltersAreNotCorrect = 355;
|
||||||
|
|
||||||
const CantCreateFolder = 400;
|
const CantCreateFolder = 400;
|
||||||
|
|
|
||||||
|
|
@ -14,47 +14,73 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
||||||
$this->oDriver = $oDriver;
|
$this->oDriver = $oDriver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function handleException(\Throwable $oException, int $defNotification) : void
|
||||||
|
{
|
||||||
|
if ($oException instanceof \MailSo\Net\Exceptions\SocketCanNotConnectToHostException) {
|
||||||
|
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oException instanceof \MailSo\Sieve\Exceptions\NegativeResponseException) {
|
||||||
|
throw new \RainLoop\Exceptions\ClientException(
|
||||||
|
\RainLoop\Notifications::ClientViewError, $oException, \implode("\r\n", $oException->GetResponses())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \RainLoop\Exceptions\ClientException($defNotification, $oException);
|
||||||
|
}
|
||||||
|
|
||||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array
|
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return $this->IsActive() ? $this->oDriver->Load($oAccount, $bAllowRaw) : array();
|
return $this->IsActive() ? $this->oDriver->Load($oAccount, $bAllowRaw) : array();
|
||||||
}
|
}
|
||||||
catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException)
|
|
||||||
{
|
|
||||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException);
|
|
||||||
}
|
|
||||||
catch (\Throwable $oException)
|
catch (\Throwable $oException)
|
||||||
{
|
{
|
||||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetFilters, $oException);
|
static::handleException($oException, \RainLoop\Notifications::CantGetFilters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
public function Save(\RainLoop\Model\Account $oAccount, string $sScriptName, array $aFilters, string $sRaw = '') : bool
|
||||||
}
|
|
||||||
|
|
||||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters, string $sRaw = '', bool $bRawIsActive = false) : bool
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return $this->IsActive() ? $this->oDriver->Save(
|
return $this->IsActive()
|
||||||
$oAccount, $aFilters, $sRaw, $bRawIsActive) : false;
|
? $this->oDriver->Save($oAccount, $sScriptName, $aFilters, $sRaw)
|
||||||
}
|
: false;
|
||||||
catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException)
|
|
||||||
{
|
|
||||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException);
|
|
||||||
}
|
|
||||||
catch (\MailSo\Sieve\Exceptions\NegativeResponseException $oException)
|
|
||||||
{
|
|
||||||
throw new \RainLoop\Exceptions\ClientException(
|
|
||||||
\RainLoop\Notifications::ClientViewError, $oException,
|
|
||||||
\implode("\r\n", $oException->GetResponses()));
|
|
||||||
}
|
}
|
||||||
catch (\Throwable $oException)
|
catch (\Throwable $oException)
|
||||||
{
|
{
|
||||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSaveFilters, $oException);
|
static::handleException($oException. \RainLoop\Notifications::CantSaveFilters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
public function ActivateScript(\RainLoop\Model\Account $oAccount, string $sScriptName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return $this->IsActive()
|
||||||
|
? $this->oDriver->Activate($oAccount, $sScriptName)
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
catch (\Throwable $oException)
|
||||||
|
{
|
||||||
|
static::handleException($oException. \RainLoop\Notifications::CantActivateFiltersScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DeleteScript(\RainLoop\Model\Account $oAccount, string $sScriptName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return $this->IsActive()
|
||||||
|
? $this->oDriver->Delete($oAccount, $sScriptName)
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
catch (\Throwable $oException)
|
||||||
|
{
|
||||||
|
static::handleException($oException. \RainLoop\Notifications::CantDeleteFiltersScript);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IsActive() : bool
|
public function IsActive() : bool
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,9 @@ interface FiltersInterface
|
||||||
{
|
{
|
||||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array;
|
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array;
|
||||||
|
|
||||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters) : bool;
|
public function Save(\RainLoop\Model\Account $oAccount, string $sScriptName, array $aFilters, string $sRaw = '') : bool;
|
||||||
|
|
||||||
|
public function Activate(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool;
|
||||||
|
|
||||||
|
public function Delete(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,37 +39,43 @@ class SieveStorage implements FiltersInterface
|
||||||
$this->bUtf8FolderName = !!$this->oConfig->Get('labs', 'sieve_utf8_folder_name', true);
|
$this->bUtf8FolderName = !!$this->oConfig->Get('labs', 'sieve_utf8_folder_name', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getConnection(\RainLoop\Model\Account $oAccount) : ?\MailSo\Sieve\ManageSieveClient
|
||||||
|
{
|
||||||
|
$oSieveClient = new \MailSo\Sieve\ManageSieveClient();
|
||||||
|
$oSieveClient->SetLogger($this->oLogger);
|
||||||
|
$oSieveClient->SetTimeOuts(10, (int) \RainLoop\Api::Config()->Get('labs', 'sieve_timeout', 10));
|
||||||
|
return $oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig)
|
||||||
|
? $oSieveClient
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array
|
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array
|
||||||
{
|
{
|
||||||
$aModules = array();
|
$aModules = array();
|
||||||
$aFilters = array();
|
|
||||||
$aScripts = array();
|
$aScripts = array();
|
||||||
|
|
||||||
$oSieveClient = new \MailSo\Sieve\ManageSieveClient();
|
$oSieveClient = $this->getConnection($oAccount);
|
||||||
$oSieveClient->SetLogger($this->oLogger);
|
if ($oSieveClient) {
|
||||||
$oSieveClient->SetTimeOuts(10, (int) $this->oConfig->Get('labs', 'sieve_timeout', 10));
|
|
||||||
|
|
||||||
if ($oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig)) {
|
|
||||||
$aModules = $oSieveClient->Modules();
|
$aModules = $oSieveClient->Modules();
|
||||||
|
\sort($aModules);
|
||||||
|
|
||||||
$aList = $oSieveClient->ListScripts();
|
$aList = $oSieveClient->ListScripts();
|
||||||
|
|
||||||
if (!empty($aList[self::SIEVE_FILE_NAME])) {
|
|
||||||
$sS = $oSieveClient->GetScript(self::SIEVE_FILE_NAME);
|
|
||||||
if ($sS) {
|
|
||||||
$aFilters = $this->fileStringToCollection($sS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bAllowRaw) {
|
|
||||||
foreach ($aList as $name => $active) {
|
foreach ($aList as $name => $active) {
|
||||||
if ($name != self::SIEVE_FILE_NAME) {
|
if ($name != self::SIEVE_FILE_NAME) {
|
||||||
|
if ($bAllowRaw) {
|
||||||
$aScripts[$name] = array(
|
$aScripts[$name] = array(
|
||||||
'@Object' => 'Object/SieveScript',
|
'@Object' => 'Object/SieveScript',
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'active' => $active,
|
'active' => $active,
|
||||||
'body' => $oSieveClient->GetScript($name) // \trim() ?
|
'body' => $oSieveClient->GetScript($name) // \trim() ?
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
$sS = $oSieveClient->GetScript(self::SIEVE_FILE_NAME);
|
||||||
|
if ($sS) {
|
||||||
|
$aFilters = $this->fileStringToCollection($sS);
|
||||||
|
}
|
||||||
$aScripts[$name] = array(
|
$aScripts[$name] = array(
|
||||||
'@Object' => 'Object/SieveScript',
|
'@Object' => 'Object/SieveScript',
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
|
|
@ -79,12 +85,21 @@ class SieveStorage implements FiltersInterface
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$oSieveClient->LogoutAndDisconnect();
|
$oSieveClient->LogoutAndDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($aList[self::SIEVE_FILE_NAME_RAW])) {
|
if (!isset($aList[self::SIEVE_FILE_NAME])) {
|
||||||
|
$aScripts[$name] = array(
|
||||||
|
'@Object' => 'Object/SieveScript',
|
||||||
|
'name' => self::SIEVE_FILE_NAME,
|
||||||
|
'active' => false,
|
||||||
|
'body' => '',
|
||||||
|
'filters' => []
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($bAllowRaw && !isset($aList[self::SIEVE_FILE_NAME_RAW])) {
|
||||||
$aScripts[$name] = array(
|
$aScripts[$name] = array(
|
||||||
'@Object' => 'Object/SieveScript',
|
'@Object' => 'Object/SieveScript',
|
||||||
'name' => self::SIEVE_FILE_NAME_RAW,
|
'name' => self::SIEVE_FILE_NAME_RAW,
|
||||||
|
|
@ -96,55 +111,52 @@ class SieveStorage implements FiltersInterface
|
||||||
\ksort($aScripts);
|
\ksort($aScripts);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'RawIsAllow' => $bAllowRaw,
|
|
||||||
'Filters' => $aFilters,
|
|
||||||
'Capa' => $aModules,
|
'Capa' => $aModules,
|
||||||
'Scripts' => $aScripts
|
'Scripts' => $aScripts
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters, string $sRaw = '', bool $bRawIsActive = false) : bool
|
public function Save(\RainLoop\Model\Account $oAccount, string $sScriptName, array $aFilters, string $sRaw = '') : bool
|
||||||
{
|
|
||||||
$oSieveClient = new \MailSo\Sieve\ManageSieveClient();
|
|
||||||
$oSieveClient->SetLogger($this->oLogger);
|
|
||||||
$oSieveClient->SetTimeOuts(10, (int) \RainLoop\Api::Config()->Get('labs', 'sieve_timeout', 10));
|
|
||||||
|
|
||||||
if ($oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig))
|
|
||||||
{
|
{
|
||||||
|
if (self::SIEVE_FILE_NAME === $sScriptName) {
|
||||||
|
$sRaw = $this->collectionToFileString($aFilters);
|
||||||
|
}
|
||||||
|
$oSieveClient = $this->getConnection($oAccount);
|
||||||
|
if ($oSieveClient) {
|
||||||
|
if (empty($sRaw)) {
|
||||||
$aList = $oSieveClient->ListScripts();
|
$aList = $oSieveClient->ListScripts();
|
||||||
|
if (isset($aList[$sScriptName])) {
|
||||||
if ($bRawIsActive)
|
$oSieveClient->DeleteScript($sScriptName);
|
||||||
{
|
|
||||||
if (!empty($sRaw))
|
|
||||||
{
|
|
||||||
$oSieveClient->PutScript(self::SIEVE_FILE_NAME_RAW, $sRaw);
|
|
||||||
$oSieveClient->SetActiveScript(self::SIEVE_FILE_NAME_RAW);
|
|
||||||
}
|
}
|
||||||
else if (isset($aList[self::SIEVE_FILE_NAME_RAW]))
|
} else {
|
||||||
{
|
$oSieveClient->PutScript($sScriptName, $sRaw);
|
||||||
$oSieveClient->DeleteScript(self::SIEVE_FILE_NAME_RAW);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sUserFilter = $this->collectionToFileString($aFilters);
|
|
||||||
|
|
||||||
if (!empty($sUserFilter))
|
|
||||||
{
|
|
||||||
$oSieveClient->PutScript(self::SIEVE_FILE_NAME, $sUserFilter);
|
|
||||||
$oSieveClient->SetActiveScript(self::SIEVE_FILE_NAME);
|
|
||||||
}
|
|
||||||
else if (isset($aList[self::SIEVE_FILE_NAME]))
|
|
||||||
{
|
|
||||||
$oSieveClient->DeleteScript(self::SIEVE_FILE_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$oSieveClient->LogoutAndDisconnect();
|
$oSieveClient->LogoutAndDisconnect();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If $sScriptName is the empty string (i.e., ""), then any active script is disabled.
|
||||||
|
*/
|
||||||
|
public function Activate(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool
|
||||||
|
{
|
||||||
|
$oSieveClient = $this->getConnection($oAccount);
|
||||||
|
if ($oSieveClient) {
|
||||||
|
$oSieveClient->SetActiveScript(\trim($sScriptName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Delete(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool
|
||||||
|
{
|
||||||
|
$oSieveClient = $this->getConnection($oAccount);
|
||||||
|
if ($oSieveClient) {
|
||||||
|
$oSieveClient->DeleteScript(\trim($sScriptName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,15 @@ en:
|
||||||
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
||||||
REJECT_MESSAGE_LABEL: "Reject message"
|
REJECT_MESSAGE_LABEL: "Reject message"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Create Script"
|
||||||
|
TITLE_EDIT: "Edit Script"
|
||||||
|
SCRIPT_NAME: "Name"
|
||||||
|
BUTTON_ADD_FILTER: "Add a Filter"
|
||||||
|
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||||
|
BUTTON_SAVE: "Save"
|
||||||
|
CAPABILITY_LABEL: "Capabilities"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
||||||
SELECT_CHOOSE_ONE: "Choose one"
|
SELECT_CHOOSE_ONE: "Choose one"
|
||||||
|
|
@ -431,21 +440,15 @@ en:
|
||||||
BUTTON_BACK: "Back"
|
BUTTON_BACK: "Back"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "Filters"
|
LEGEND_FILTERS: "Filters"
|
||||||
LEGEND_SIEVE_SCRIPT: "Sieve Script"
|
|
||||||
BUTTON_SAVE: "Save"
|
|
||||||
BUTTON_ADD_FILTER: "Add a Filter"
|
|
||||||
BUTTON_DELETE: "Delete"
|
BUTTON_DELETE: "Delete"
|
||||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
|
||||||
SUBNAME_NONE: "None"
|
SUBNAME_NONE: "None"
|
||||||
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "Reject"
|
SUBNAME_REJECT: "Reject"
|
||||||
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
||||||
SUBNAME_DISCARD: "Discard"
|
SUBNAME_DISCARD: "Discard"
|
||||||
CAPABILITY_LABEL: "Capability"
|
|
||||||
LOADING_PROCESS: "Updating filter list"
|
LOADING_PROCESS: "Updating filter list"
|
||||||
DELETING_ASK: "Are you sure?"
|
DELETING_ASK: "Are you sure?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "Identity"
|
LEGEND_IDENTITY: "Identity"
|
||||||
LABEL_DISPLAY_NAME: "Name"
|
LABEL_DISPLAY_NAME: "Name"
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,15 @@ de_DE:
|
||||||
VACATION_RECIPIENTS_LABEL: "Empfänger (durch Komma getrennt)"
|
VACATION_RECIPIENTS_LABEL: "Empfänger (durch Komma getrennt)"
|
||||||
REJECT_MESSAGE_LABEL: "Ablehnnachricht"
|
REJECT_MESSAGE_LABEL: "Ablehnnachricht"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "Alle eingehenden Nachrichten"
|
ALL_INCOMING_MESSAGES_DESC: "Alle eingehenden Nachrichten"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Skript erstellen"
|
||||||
|
TITLE_EDIT: "Skript bearbeiten"
|
||||||
|
SCRIPT_NAME: "Name"
|
||||||
|
BUTTON_ADD_FILTER: "Filter hinzufügen"
|
||||||
|
BUTTON_RAW_SCRIPT: "Benutzerdefiniertes Skript verwenden"
|
||||||
|
BUTTON_SAVE: "Speichern"
|
||||||
|
CAPABILITY_LABEL: "Unterstützte Module"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "Die Änderungen müssen auf dem Server gespeichert werden."
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "Wählen Sie die Systemordner aus"
|
TITLE_SYSTEM_FOLDERS: "Wählen Sie die Systemordner aus"
|
||||||
SELECT_CHOOSE_ONE: "Wählen Sie einen aus"
|
SELECT_CHOOSE_ONE: "Wählen Sie einen aus"
|
||||||
|
|
@ -431,20 +440,15 @@ de_DE:
|
||||||
BUTTON_BACK: "Zurück"
|
BUTTON_BACK: "Zurück"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "Filter"
|
LEGEND_FILTERS: "Filter"
|
||||||
BUTTON_SAVE: "Speichern"
|
|
||||||
BUTTON_ADD_FILTER: "Filter hinzufügen"
|
|
||||||
BUTTON_DELETE: "Löschen"
|
BUTTON_DELETE: "Löschen"
|
||||||
BUTTON_RAW_SCRIPT: "Benutzerdefiniertes Skript verwenden"
|
|
||||||
SUBNAME_NONE: "Keine"
|
SUBNAME_NONE: "Keine"
|
||||||
SUBNAME_MOVE_TO: "Verschieben nach \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "Verschieben nach \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "Weiterleiten nach \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "Weiterleiten nach \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "Ablehnen"
|
SUBNAME_REJECT: "Ablehnen"
|
||||||
SUBNAME_VACATION_MESSAGE: "Urlaubsbenachrichtigung"
|
SUBNAME_VACATION_MESSAGE: "Urlaubsbenachrichtigung"
|
||||||
SUBNAME_DISCARD: "Verwerfen"
|
SUBNAME_DISCARD: "Verwerfen"
|
||||||
CAPABILITY_LABEL: "Unterstützte Module"
|
|
||||||
LOADING_PROCESS: "Aktualisiere Filterliste"
|
LOADING_PROCESS: "Aktualisiere Filterliste"
|
||||||
DELETING_ASK: "Sind Sie sicher?"
|
DELETING_ASK: "Sind Sie sicher?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Die Änderungen müssen auf dem Server gespeichert werden."
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "Identität"
|
LEGEND_IDENTITY: "Identität"
|
||||||
LABEL_DISPLAY_NAME: "Name"
|
LABEL_DISPLAY_NAME: "Name"
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,15 @@ en_GB:
|
||||||
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
||||||
REJECT_MESSAGE_LABEL: "Reject message"
|
REJECT_MESSAGE_LABEL: "Reject message"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Create Script"
|
||||||
|
TITLE_EDIT: "Edit Script"
|
||||||
|
SCRIPT_NAME: "Name"
|
||||||
|
BUTTON_ADD_FILTER: "Add a Filter"
|
||||||
|
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||||
|
BUTTON_SAVE: "Save"
|
||||||
|
CAPABILITY_LABEL: "Capabilities"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
||||||
SELECT_CHOOSE_ONE: "Choose one"
|
SELECT_CHOOSE_ONE: "Choose one"
|
||||||
|
|
@ -431,20 +440,15 @@ en_GB:
|
||||||
BUTTON_BACK: "Back"
|
BUTTON_BACK: "Back"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "Filters"
|
LEGEND_FILTERS: "Filters"
|
||||||
BUTTON_SAVE: "Save"
|
|
||||||
BUTTON_ADD_FILTER: "Add a Filter"
|
|
||||||
BUTTON_DELETE: "Delete"
|
BUTTON_DELETE: "Delete"
|
||||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
|
||||||
SUBNAME_NONE: "None"
|
SUBNAME_NONE: "None"
|
||||||
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "Reject"
|
SUBNAME_REJECT: "Reject"
|
||||||
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
||||||
SUBNAME_DISCARD: "Discard"
|
SUBNAME_DISCARD: "Discard"
|
||||||
CAPABILITY_LABEL: "Capability"
|
|
||||||
LOADING_PROCESS: "Updating filter list"
|
LOADING_PROCESS: "Updating filter list"
|
||||||
DELETING_ASK: "Are you sure?"
|
DELETING_ASK: "Are you sure?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "Identity"
|
LEGEND_IDENTITY: "Identity"
|
||||||
LABEL_DISPLAY_NAME: "Name"
|
LABEL_DISPLAY_NAME: "Name"
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,15 @@ en_US:
|
||||||
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
||||||
REJECT_MESSAGE_LABEL: "Reject message"
|
REJECT_MESSAGE_LABEL: "Reject message"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Create Script"
|
||||||
|
TITLE_EDIT: "Edit Script"
|
||||||
|
SCRIPT_NAME: "Name"
|
||||||
|
BUTTON_ADD_FILTER: "Add a Filter"
|
||||||
|
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||||
|
BUTTON_SAVE: "Save"
|
||||||
|
CAPABILITY_LABEL: "Capabilities"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
||||||
SELECT_CHOOSE_ONE: "Choose one"
|
SELECT_CHOOSE_ONE: "Choose one"
|
||||||
|
|
@ -431,20 +440,15 @@ en_US:
|
||||||
BUTTON_BACK: "Back"
|
BUTTON_BACK: "Back"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "Filters"
|
LEGEND_FILTERS: "Filters"
|
||||||
BUTTON_SAVE: "Save"
|
|
||||||
BUTTON_ADD_FILTER: "Add a Filter"
|
|
||||||
BUTTON_DELETE: "Delete"
|
BUTTON_DELETE: "Delete"
|
||||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
|
||||||
SUBNAME_NONE: "None"
|
SUBNAME_NONE: "None"
|
||||||
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "Reject"
|
SUBNAME_REJECT: "Reject"
|
||||||
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
||||||
SUBNAME_DISCARD: "Discard"
|
SUBNAME_DISCARD: "Discard"
|
||||||
CAPABILITY_LABEL: "Capability"
|
|
||||||
LOADING_PROCESS: "Updating filter list"
|
LOADING_PROCESS: "Updating filter list"
|
||||||
DELETING_ASK: "Are you sure?"
|
DELETING_ASK: "Are you sure?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "Identity"
|
LEGEND_IDENTITY: "Identity"
|
||||||
LABEL_DISPLAY_NAME: "Name"
|
LABEL_DISPLAY_NAME: "Name"
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,15 @@ es_ES:
|
||||||
VACATION_RECIPIENTS_LABEL: "Destinatarios (separados por coma)"
|
VACATION_RECIPIENTS_LABEL: "Destinatarios (separados por coma)"
|
||||||
REJECT_MESSAGE_LABEL: "Rechazar mensaje"
|
REJECT_MESSAGE_LABEL: "Rechazar mensaje"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "Todos los mensajes entrantes"
|
ALL_INCOMING_MESSAGES_DESC: "Todos los mensajes entrantes"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Create Script"
|
||||||
|
TITLE_EDIT: "Edit Script"
|
||||||
|
SCRIPT_NAME: "Nombre"
|
||||||
|
BUTTON_ADD_FILTER: "Añadir un Filtro"
|
||||||
|
BUTTON_RAW_SCRIPT: "Usar Script Personalizado"
|
||||||
|
BUTTON_SAVE: "Guardar"
|
||||||
|
CAPABILITY_LABEL: "Capability"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "Estos cambios deben ser cambiados en el servidor."
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "Seleccione las carpetas del sistema"
|
TITLE_SYSTEM_FOLDERS: "Seleccione las carpetas del sistema"
|
||||||
SELECT_CHOOSE_ONE: "Elija una"
|
SELECT_CHOOSE_ONE: "Elija una"
|
||||||
|
|
@ -432,20 +441,15 @@ es_ES:
|
||||||
BUTTON_BACK: "Atrás"
|
BUTTON_BACK: "Atrás"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "Filtros"
|
LEGEND_FILTERS: "Filtros"
|
||||||
BUTTON_SAVE: "Guardar"
|
|
||||||
BUTTON_ADD_FILTER: "Añadir un Filtro"
|
|
||||||
BUTTON_DELETE: "Borrar"
|
BUTTON_DELETE: "Borrar"
|
||||||
BUTTON_RAW_SCRIPT: "Usar Script Personalizado"
|
|
||||||
SUBNAME_NONE: "Ninguno"
|
SUBNAME_NONE: "Ninguno"
|
||||||
SUBNAME_MOVE_TO: "Mover a \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "Mover a \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "Reenviar a \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "Reenviar a \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "Rechazar"
|
SUBNAME_REJECT: "Rechazar"
|
||||||
SUBNAME_VACATION_MESSAGE: "Mensaje de vacaciones"
|
SUBNAME_VACATION_MESSAGE: "Mensaje de vacaciones"
|
||||||
SUBNAME_DISCARD: "Descartar"
|
SUBNAME_DISCARD: "Descartar"
|
||||||
CAPABILITY_LABEL: "Capability"
|
|
||||||
LOADING_PROCESS: "Actualizando lista de filtros"
|
LOADING_PROCESS: "Actualizando lista de filtros"
|
||||||
DELETING_ASK: "¿Está seguro?"
|
DELETING_ASK: "¿Está seguro?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Estos cambios deben ser cambiados en el servidor."
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "Identidad"
|
LEGEND_IDENTITY: "Identidad"
|
||||||
LABEL_DISPLAY_NAME: "Nombre"
|
LABEL_DISPLAY_NAME: "Nombre"
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,15 @@ fr_FR:
|
||||||
VACATION_RECIPIENTS_LABEL: "Destinataires (séparés par des virgules)"
|
VACATION_RECIPIENTS_LABEL: "Destinataires (séparés par des virgules)"
|
||||||
REJECT_MESSAGE_LABEL: "Message rejeté"
|
REJECT_MESSAGE_LABEL: "Message rejeté"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "Tous les messages entrants"
|
ALL_INCOMING_MESSAGES_DESC: "Tous les messages entrants"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Create Script"
|
||||||
|
TITLE_EDIT: "Edit Script"
|
||||||
|
SCRIPT_NAME: "Nom"
|
||||||
|
BUTTON_ADD_FILTER: "Ajouter un filtre"
|
||||||
|
BUTTON_RAW_SCRIPT: "Utiliser le script d'un utilisateur"
|
||||||
|
BUTTON_SAVE: "Enregistrer"
|
||||||
|
CAPABILITY_LABEL: "Capacité"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "Ces changements doivent être enregistrés sur le serveur."
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "Sélectionner les dossiers systèmes"
|
TITLE_SYSTEM_FOLDERS: "Sélectionner les dossiers systèmes"
|
||||||
SELECT_CHOOSE_ONE: "Faites un choix"
|
SELECT_CHOOSE_ONE: "Faites un choix"
|
||||||
|
|
@ -432,20 +441,15 @@ fr_FR:
|
||||||
BUTTON_BACK: "Retour"
|
BUTTON_BACK: "Retour"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "Filtres"
|
LEGEND_FILTERS: "Filtres"
|
||||||
BUTTON_SAVE: "Enregistrer"
|
|
||||||
BUTTON_ADD_FILTER: "Ajouter un filtre"
|
|
||||||
BUTTON_DELETE: "Effacer"
|
BUTTON_DELETE: "Effacer"
|
||||||
BUTTON_RAW_SCRIPT: "Utiliser le script d'un utilisateur"
|
|
||||||
SUBNAME_NONE: "Aucun"
|
SUBNAME_NONE: "Aucun"
|
||||||
SUBNAME_MOVE_TO: "Déplacer vers \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "Déplacer vers \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "Faire suivre à \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "Faire suivre à \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "Rejeter"
|
SUBNAME_REJECT: "Rejeter"
|
||||||
SUBNAME_VACATION_MESSAGE: "Message d'absence"
|
SUBNAME_VACATION_MESSAGE: "Message d'absence"
|
||||||
SUBNAME_DISCARD: "Exclure"
|
SUBNAME_DISCARD: "Exclure"
|
||||||
CAPABILITY_LABEL: "Capacité"
|
|
||||||
LOADING_PROCESS: "Mise à jour de la liste de filtres"
|
LOADING_PROCESS: "Mise à jour de la liste de filtres"
|
||||||
DELETING_ASK: "Êtes-vous sûr ?"
|
DELETING_ASK: "Êtes-vous sûr ?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Ces changements doivent être enregistrés sur le serveur."
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "Identité"
|
LEGEND_IDENTITY: "Identité"
|
||||||
LABEL_DISPLAY_NAME: "Nom"
|
LABEL_DISPLAY_NAME: "Nom"
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,15 @@ nl_NL:
|
||||||
VACATION_RECIPIENTS_LABEL: "Ontvangers (comma gescheiden)"
|
VACATION_RECIPIENTS_LABEL: "Ontvangers (comma gescheiden)"
|
||||||
REJECT_MESSAGE_LABEL: "Afwijsbericht"
|
REJECT_MESSAGE_LABEL: "Afwijsbericht"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "Alle inkomende berichten"
|
ALL_INCOMING_MESSAGES_DESC: "Alle inkomende berichten"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Script toevoegen"
|
||||||
|
TITLE_EDIT: "Script aanpassen"
|
||||||
|
SCRIPT_NAME: "Naam"
|
||||||
|
BUTTON_ADD_FILTER: "Filter toevoegen"
|
||||||
|
BUTTON_RAW_SCRIPT: "Maak een custom script"
|
||||||
|
BUTTON_SAVE: "Opslaan"
|
||||||
|
CAPABILITY_LABEL: "Mogelijkheden"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "Wijzigingen moeten nog opgeslagen worden op de server."
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "Selecteer systeem mappen"
|
TITLE_SYSTEM_FOLDERS: "Selecteer systeem mappen"
|
||||||
SELECT_CHOOSE_ONE: "Kies één"
|
SELECT_CHOOSE_ONE: "Kies één"
|
||||||
|
|
@ -430,20 +439,15 @@ nl_NL:
|
||||||
BUTTON_BACK: "Terug"
|
BUTTON_BACK: "Terug"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "Filters"
|
LEGEND_FILTERS: "Filters"
|
||||||
BUTTON_SAVE: "Opslaan"
|
|
||||||
BUTTON_ADD_FILTER: "Filter toevoegen"
|
|
||||||
BUTTON_DELETE: "Verwijder"
|
BUTTON_DELETE: "Verwijder"
|
||||||
BUTTON_RAW_SCRIPT: "Maak een custom script"
|
|
||||||
SUBNAME_NONE: "Geen"
|
SUBNAME_NONE: "Geen"
|
||||||
SUBNAME_MOVE_TO: "Verplaats naar map \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "Verplaats naar map \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "Doorsturen naar \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "Doorsturen naar \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "Afwijzen"
|
SUBNAME_REJECT: "Afwijzen"
|
||||||
SUBNAME_VACATION_MESSAGE: "Afwezigheidsbericht"
|
SUBNAME_VACATION_MESSAGE: "Afwezigheidsbericht"
|
||||||
SUBNAME_DISCARD: "Gooi weg"
|
SUBNAME_DISCARD: "Gooi weg"
|
||||||
CAPABILITY_LABEL: "Mogelijkheden"
|
|
||||||
LOADING_PROCESS: "Bezig met updaten van de filter lijst"
|
LOADING_PROCESS: "Bezig met updaten van de filter lijst"
|
||||||
DELETING_ASK: "Weet u het zeker?"
|
DELETING_ASK: "Weet u het zeker?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Wijzigingen moeten nog opgeslagen worden op de server."
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "Identiteit"
|
LEGEND_IDENTITY: "Identiteit"
|
||||||
LABEL_DISPLAY_NAME: "Naam"
|
LABEL_DISPLAY_NAME: "Naam"
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,15 @@ zh_CN:
|
||||||
VACATION_RECIPIENTS_LABEL: "收件人 (半角逗号“,”分隔)"
|
VACATION_RECIPIENTS_LABEL: "收件人 (半角逗号“,”分隔)"
|
||||||
REJECT_MESSAGE_LABEL: "拒收邮件"
|
REJECT_MESSAGE_LABEL: "拒收邮件"
|
||||||
ALL_INCOMING_MESSAGES_DESC: "所有来信"
|
ALL_INCOMING_MESSAGES_DESC: "所有来信"
|
||||||
|
POPUPS_SIEVE_SCRIPT:
|
||||||
|
TITLE_CREATE: "Create Script"
|
||||||
|
TITLE_EDIT: "Edit Script"
|
||||||
|
SCRIPT_NAME: "名称"
|
||||||
|
BUTTON_ADD_FILTER: "添加筛选条件"
|
||||||
|
BUTTON_RAW_SCRIPT: "使用自定义脚本"
|
||||||
|
BUTTON_SAVE: "保存"
|
||||||
|
CAPABILITY_LABEL: "Capability"
|
||||||
|
CHANGES_NEED_TO_BE_SAVED_DESC: "这些更改需要保存。"
|
||||||
POPUPS_SYSTEM_FOLDERS:
|
POPUPS_SYSTEM_FOLDERS:
|
||||||
TITLE_SYSTEM_FOLDERS: "选择系统文件夹"
|
TITLE_SYSTEM_FOLDERS: "选择系统文件夹"
|
||||||
SELECT_CHOOSE_ONE: "选择一个"
|
SELECT_CHOOSE_ONE: "选择一个"
|
||||||
|
|
@ -429,20 +438,15 @@ zh_CN:
|
||||||
BUTTON_BACK: "返回"
|
BUTTON_BACK: "返回"
|
||||||
SETTINGS_FILTERS:
|
SETTINGS_FILTERS:
|
||||||
LEGEND_FILTERS: "筛选器"
|
LEGEND_FILTERS: "筛选器"
|
||||||
BUTTON_SAVE: "保存"
|
|
||||||
BUTTON_ADD_FILTER: "添加筛选条件"
|
|
||||||
BUTTON_DELETE: "删除"
|
BUTTON_DELETE: "删除"
|
||||||
BUTTON_RAW_SCRIPT: "使用自定义脚本"
|
|
||||||
SUBNAME_NONE: "无"
|
SUBNAME_NONE: "无"
|
||||||
SUBNAME_MOVE_TO: "移动到 \"%FOLDER%\""
|
SUBNAME_MOVE_TO: "移动到 \"%FOLDER%\""
|
||||||
SUBNAME_FORWARD_TO: "转发到 \"%EMAIL%\""
|
SUBNAME_FORWARD_TO: "转发到 \"%EMAIL%\""
|
||||||
SUBNAME_REJECT: "拒绝"
|
SUBNAME_REJECT: "拒绝"
|
||||||
SUBNAME_VACATION_MESSAGE: "假期自动回复"
|
SUBNAME_VACATION_MESSAGE: "假期自动回复"
|
||||||
SUBNAME_DISCARD: "取消"
|
SUBNAME_DISCARD: "取消"
|
||||||
CAPABILITY_LABEL: "Capability"
|
|
||||||
LOADING_PROCESS: "正在更新筛选规则列表"
|
LOADING_PROCESS: "正在更新筛选规则列表"
|
||||||
DELETING_ASK: "确定删除?"
|
DELETING_ASK: "确定删除?"
|
||||||
CHANGES_NEED_TO_BE_SAVED_DESC: "这些更改需要保存。"
|
|
||||||
SETTINGS_IDENTITY:
|
SETTINGS_IDENTITY:
|
||||||
LEGEND_IDENTITY: "身份"
|
LEGEND_IDENTITY: "身份"
|
||||||
LABEL_DISPLAY_NAME: "名称"
|
LABEL_DISPLAY_NAME: "名称"
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,65 @@
|
||||||
<div class="modal fade b-filter-script g-ui-user-select-none" data-bind="modal: modalVisibility">
|
<div class="modal fade b-filter-script g-ui-user-select-none" data-bind="modal: modalVisibility">
|
||||||
<div>
|
<div data-bind="with: script">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-bind="command: cancelCommand">×</button>
|
<button type="button" class="close" data-bind="command: $root.cancelCommand">×</button>
|
||||||
<h3 class="i18n" data-i18n="POPUPS_FILTER/LEGEND_SIEVE_SCRIPT"></h3>
|
<h3>
|
||||||
|
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/TITLE_CREATE" data-bind="visible: $root.isNew"></span>
|
||||||
|
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/TITLE_EDIT" data-bind="visible: !$root.isNew()"></span>
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" data-bind="visible: haveChanges">
|
|
||||||
|
<div class="control-group" data-bind="css: {'error': nameError}">
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" class="i18n span5"
|
||||||
|
data-bind="value: name, hasFocus: $root.isNew, visible: $root.isNew"
|
||||||
|
autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||||
|
data-i18n="[placeholder]POPUPS_SIEVE_SCRIPT/SCRIPT_NAME"
|
||||||
|
/>
|
||||||
|
<span data-bind="text: name, visible: !$root.isNew()"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" data-bind="visible: hasChanges">
|
||||||
<div class="span8 width100-on-mobile">
|
<div class="span8 width100-on-mobile">
|
||||||
<br />
|
<div class="alert g-ui-user-select-none">
|
||||||
<div class="alert g-ui-user-select-none" style="margin-bottom: 0">
|
|
||||||
<i class="icon-warning"></i>
|
<i class="icon-warning"></i>
|
||||||
|
|
||||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/CHANGES_NEED_TO_BE_SAVED_DESC"></span>
|
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/CHANGES_NEED_TO_BE_SAVED_DESC"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" data-bind="visible: serverError">
|
<div class="row" data-bind="visible: $root.saveError">
|
||||||
<div class="span8 width100-on-mobile">
|
<div class="span8 width100-on-mobile">
|
||||||
<div class="alert alert-error g-ui-user-select-none" style="margin-bottom: 0">
|
<div class="alert alert-error g-ui-user-select-none">
|
||||||
<i class="icon-warning"></i>
|
<i class="icon-warning"></i>
|
||||||
|
|
||||||
<span data-bind="text: serverErrorDesc"></span>
|
<span data-bind="text: $root.saveErrorText"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<!--
|
||||||
<div class="row">
|
<div class="row" data-bind="visible: allowFilters">
|
||||||
<div class="span5 width100-on-mobile">
|
<div class="span5 width100-on-mobile">
|
||||||
<a class="btn" data-bind="click: function () { filterRaw.active(!filterRaw.active()) },
|
<a class="btn" data-bind="click: function () { $root.rawActive(!$root.rawActive()) },
|
||||||
css: {'active': filterRaw.active }, tooltip: 'SETTINGS_FILTERS/BUTTON_RAW_SCRIPT'">
|
css: {'active': $root.rawActive }, tooltip: 'POPUPS_SIEVE_SCRIPT/BUTTON_RAW_SCRIPT'">
|
||||||
<i class="icon-file-code"></i>
|
<i class="icon-file-code"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span8 width100-on-mobile">
|
<div class="span8 width100-on-mobile">
|
||||||
<div class="control-group" data-bind="css: {'error': filterRaw.error}, visible: filterRaw.active()">
|
<div class="control-group" data-bind="visible: $root.rawActive">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<pre style="word-break: break-word;" data-bind="visible: '' !== filterRaw.capa()">
|
<pre>
|
||||||
<b class="i18n" data-i18n="SETTINGS_FILTERS/CAPABILITY_LABEL"></b>:
|
<b class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/CAPABILITY_LABEL"></b>:
|
||||||
<span data-bind="text: filterRaw.capa"></span>
|
<span data-bind="text: $root.sieveCapabilities"></span>
|
||||||
</pre>
|
</pre>
|
||||||
<textarea class="span8" style="height: 300px; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;"
|
<textarea class="span8" data-bind="value: body, valueUpdate: 'afterkeydown'"></textarea>
|
||||||
data-bind="value: filterRaw, valueUpdate: 'afterkeydown'"></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div data-bind="visible: !filterRaw.active()">
|
<div data-bind="visible: !$root.rawActive()">
|
||||||
<table class="table table-hover list-table filters-list g-ui-user-select-none"
|
<table class="table table-hover list-table filters-list g-ui-user-select-none"
|
||||||
data-bind="i18nUpdate: filters">
|
data-bind="i18nUpdate: filters">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
|
|
@ -55,10 +69,10 @@
|
||||||
<col style="width: 140px" />
|
<col style="width: 140px" />
|
||||||
<col style="width: 1%" />
|
<col style="width: 1%" />
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<tbody data-bind="foreach: filters" style="width: 600px">
|
<tbody data-bind="foreach: filters">
|
||||||
<tr class="filter-item" draggable="true" data-bind="sortableItem: { list: $root.filters }">
|
<tr class="filter-item" draggable="true" data-bind="sortableItem: { list: $root.filters }">
|
||||||
<td>
|
<td>
|
||||||
<span class="disabled-filter" data-bind="click: function () { $root.haveChanges(true); enabled(!enabled()); }">
|
<span class="disabled-filter" data-bind="click: function () { $parent.hasChanges(true); enabled(!enabled()); }">
|
||||||
<i data-bind="css: {'icon-checkbox-checked': enabled, 'icon-checkbox-unchecked': !enabled()}"></i>
|
<i data-bind="css: {'icon-checkbox-checked': enabled, 'icon-checkbox-unchecked': !enabled()}"></i>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -83,20 +97,20 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<a class="btn" data-bind="click: addFilter">
|
<a class="btn" data-bind="click: $root.addFilter">
|
||||||
<i class="icon-plus"></i>
|
<i class="icon-plus"></i>
|
||||||
|
|
||||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/BUTTON_ADD_FILTER"></span>
|
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/BUTTON_ADD_FILTER"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a class="btn buttonSave" data-bind="command: saveScriptCommand, tooltipErrorTip: saveErrorText, css: {'btn-danger': '' !== saveErrorText()}">
|
<a class="btn buttonSave" data-bind="visible: hasChanges, click: function() { $root.saveScriptCommand(); }, css: {'btn-danger': $root.saveError}">
|
||||||
<i data-bind="css: {'icon-floppy': !script.saving(), 'icon-spinner animated': script.saving()}"></i>
|
<i data-bind="css: {'icon-floppy': !$root.saving, 'icon-spinner animated': $root.saving}"></i>
|
||||||
|
|
||||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/BUTTON_SAVE"></span>
|
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/BUTTON_SAVE"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/LEGEND_FILTERS"></span>
|
<span class="i18n" data-i18n="SETTINGS_FILTERS/LEGEND_FILTERS"></span>
|
||||||
|
|
||||||
<i class="icon-spinner animated" style="margin-top: 5px" data-bind="visible: filters.loading"></i>
|
<i class="icon-spinner animated" style="margin-top: 5px" data-bind="visible: loading"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" data-bind="visible: serverError">
|
<div class="row" data-bind="visible: serverError">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue