Added Sieve settings concept.

It fails due to i18n conflicts
This commit is contained in:
the-djmaze 2022-03-10 10:27:04 +01:00
parent cd734c7d5d
commit a096f963ef
4 changed files with 283 additions and 1 deletions

View file

@ -21,6 +21,8 @@ import { SystemDropDownUserView } from 'View/User/SystemDropDown';
import { SettingsMenuUserView } from 'View/User/Settings/Menu';
import { SettingsPaneUserView } from 'View/User/Settings/Pane';
//import { staticLink } from 'Common/Links';
export class SettingsUserScreen extends AbstractSettingsScreen {
constructor() {
super([SystemDropDownUserView, SettingsMenuUserView, SettingsPaneUserView]);
@ -39,6 +41,7 @@ export class SettingsUserScreen extends AbstractSettingsScreen {
if (SettingsCapa('Sieve')) {
views.push(UserSettingsFilters);
// rl.loadScript(staticLink('js/sieve.js')).then(() => 0).catch(e => console.error(e));
}
if (SettingsCapa('AutoLogout') || SettingsCapa('OpenPGP') || SettingsCapa('GnuPG')) {

View file

@ -0,0 +1,73 @@
import { getNotification } from 'Common/Translator';
import Remote from 'Remote/User/Fetch';
//export class UserSettingsFilters /*extends AbstractViewSettings*/ {
export class UserSettingsSieve /*extends AbstractViewSettings*/ {
constructor() {
const Sieve = window.Sieve;
this.scripts = Sieve.scripts;
this.loading = Sieve.loading;
this.serverError = Sieve.serverError;
this.serverErrorDesc = Sieve.serverErrorDesc;
this.scriptForDeletion = ko.observable(null).askDeleteHelper();
}
setError(text) {
this.serverError(true);
this.serverErrorDesc(text);
}
updateList() {
window.Sieve.updateList();
}
addScript() {
window.Sieve.ScriptView.showModal();
}
editScript(script) {
window.Sieve.ScriptView.showModal([script]);
}
deleteScript(script) {
this.serverError(false);
Remote.request('FiltersScriptDelete',
(iError, data) => {
if (iError) {
this.setError((data && data.ErrorMessageAdditional) || getNotification(iError));
} else {
this.scripts.remove(script);
}
},
{name:script.name()}
);
}
toggleScript(script) {
let name = script.active() ? '' : script.name();
this.serverError(false);
Remote.request('FiltersScriptActivate',
(iError, data) => {
if (iError) {
this.setError((data && data.ErrorMessageAdditional) || iError)
} else {
this.scripts.forEach(script => script.active(script.name() === name));
}
},
{name:name}
);
}
onBuild(oDom) {
oDom.addEventListener('click', event => {
const el = event.target.closestWithin('.script-item .e-action', oDom),
script = el && ko.dataFor(el);
script && this.editScript(script);
});
}
onShow() {
this.updateList();
}
}

206
dev/sieve.js Normal file
View file

@ -0,0 +1,206 @@
import { parseScript } from 'Sieve/Parser';
import { FilterModel } from 'Model/Filter';
import { SieveScriptModel } from 'Model/SieveScript';
import { FilterPopupView } from 'View/Popup/Filter';
//import { getNotification, i18nToNodes } from 'Common/Translator';
import { forEachObjectValue } from 'Common/Utils';
import { koArrayWithDestroy } from 'External/ko';
// SieveUserStore
const
/*
getNotificationMessage = code => {
let key = getKeyByValue(Notification, code);
return key ? I18N_DATA.NOTIFICATIONS[i18nKey(key).replace('_NOTIFICATION', '_ERROR')] : '';
rl.i18n('NOTIFICATIONS/')
},
getNotification = (code, message = '', defCode = 0) => {
code = parseInt(code, 10) || 0;
if (Notification.ClientViewError === code && message) {
return message;
}
return getNotificationMessage(code)
|| getNotificationMessage(parseInt(defCode, 10))
|| '';
},
*/
getNotification = code => 'ERROR ' + code,
Remote = rl.app.Remote,
Sieve = {
// capabilities
capa: ko.observableArray(),
// Sieve scripts SieveScriptModel
scripts: koArrayWithDestroy(),
parseScript: parseScript,
setError: text => {
Sieve.serverError(true);
Sieve.serverErrorDesc(text);
},
updateList: () => {
if (!Sieve.loading()) {
Sieve.loading(true);
Sieve.serverError(false);
Remote.request('Filters', (iError, data) => {
Sieve.loading(false);
Sieve.scripts([]);
if (iError) {
Sieve.capa([]);
Sieve.setError(getNotification(iError));
} else {
Sieve.capa(data.Result.Capa);
/*
Sieve.scripts(
data.Result.Scripts.map(aItem => SieveScriptModel.reviveFromJson(aItem)).filter(v => v)
);
*/
forEachObjectValue(data.Result.Scripts, value => {
value = SieveScriptModel.reviveFromJson(value);
value && Sieve.scripts.push(value)
});
}
});
}
},
loading: ko.observable(false).extend({ debounce: 200 }),
serverError: ko.observable(false),
serverErrorDesc: ko.observable('')
};
Sieve.ScriptView = class SieveScriptPopupView extends rl.pluginPopupView {
constructor() {
super('SieveScript');
this.addObservables({
saveError: false,
saveErrorText: '',
rawActive: false,
allowToggle: false,
script: null
});
this.sieveCapabilities = Sieve.capa.join(' ');
this.saving = false;
this.filterForDeletion = ko.observable(null).askDeleteHelper();
}
saveScript() {
let self = this,
script = self.script();
if (!self.saving/* && script.hasChanges()*/) {
if (!script.verify()) {
return;
}
if (!script.exists() && Sieve.scripts.find(item => item.name() === script.name())) {
script.nameError(true);
return;
}
self.saving = true;
self.saveError(false);
if (self.allowToggle()) {
script.body(script.filtersToRaw());
}
Remote.request('FiltersScriptSave',
(iError, data) => {
self.saving = false;
if (iError) {
self.saveError(true);
self.saveErrorText((data && data.ErrorMessageAdditional) || getNotification(iError));
} else {
script.exists() || Sieve.scripts.push(script);
script.exists(true);
script.hasChanges(false);
}
},
script.toJson()
);
}
}
deleteFilter(filter) {
this.script().filters.remove(filter);
}
addFilter() {
/* this = SieveScriptModel */
const filter = new FilterModel();
filter.generateID();
FilterPopupView.showModal([
filter,
() => this.filters.push(filter)
]);
}
editFilter(filter) {
const clonedFilter = filter.cloneSelf();
FilterPopupView.showModal([
clonedFilter,
() => {
const script = this.script(),
filters = script.filters(),
index = filters.indexOf(filter);
if (-1 < index) {
filters[index] = clonedFilter;
script.filters(filters);
}
},
true
]);
}
toggleFiltersRaw() {
let script = this.script(), notRaw = !this.rawActive();
if (notRaw) {
script.body(script.filtersToRaw());
script.hasChanges(script.hasChanges());
}
this.rawActive(notRaw);
}
onBuild(oDom) {
oDom.addEventListener('click', event => {
const el = event.target.closestWithin('td.e-action', oDom),
filter = el && ko.dataFor(el);
filter && this.editFilter(filter);
});
}
onShow(oScript) {
oScript = oScript || new SieveScriptModel();
let raw = !oScript.allowFilters();
this.script(oScript);
this.rawActive(raw);
this.allowToggle(!raw);
this.saveError(false);
/*
// TODO: Sieve GUI
let tree = parseScript(oScript.body(), oScript.name());
console.dir(tree);
console.log(tree.join('\r\n'));
*/
}
afterShow() {
// Sometimes not everything is translated, try again
// i18nToNodes(this.viewModelDom);
}
}
window.Sieve = Sieve;

View file

@ -133,6 +133,6 @@ exports.jsLint = jsLint;
exports.js = gulp.series(
jsClean,
jsLint,
gulp.parallel(jsBoot, jsServiceWorker, jsOpenPGP, jsLibs, jsSieve, jsApp, jsAdmin),
gulp.parallel(jsBoot, jsServiceWorker, jsOpenPGP, jsLibs/*, jsSieve*/, jsApp, jsAdmin),
jsMin
);