Ergänzung Datenschutzerklärung und Impressum, Fristenformular in Einstellungen
This commit is contained in:
@@ -296,57 +296,66 @@ export async function adminView(root, { back }) {
|
||||
// Automatik
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function automationCard() {
|
||||
const deactivate = el("input.months", {
|
||||
type: "number", min: "0", max: "600",
|
||||
value: String(config.auto_deactivate_months),
|
||||
});
|
||||
const remove = el("input.months", {
|
||||
type: "number", min: "0", max: "600",
|
||||
value: String(config.auto_delete_months),
|
||||
});
|
||||
const archive = el("input.months", {
|
||||
type: "number", min: "0", max: "600",
|
||||
value: String(config.auto_archive_months),
|
||||
});
|
||||
const archiveDelete = el("input.months", {
|
||||
type: "number", min: "0", max: "600",
|
||||
value: String(config.archive_delete_months),
|
||||
});
|
||||
/** Fristen aus dem Server: Beschriftung, Einheit und Grenzen kommen
|
||||
* von dort, damit nicht das eine steht und das andere gilt. */
|
||||
function durationsCard() {
|
||||
const fields = new Map();
|
||||
|
||||
const group = (title, keys, lead) => {
|
||||
const rows = config.durations.filter((d) => keys.includes(d.key));
|
||||
if (!rows.length) return null;
|
||||
|
||||
return el("div.duration-group", {},
|
||||
el("h3.device-heading", {}, title),
|
||||
lead ? el("p.sub", {}, lead) : null,
|
||||
rows.map((entry) => {
|
||||
const input = el("input.months", {
|
||||
type: "number",
|
||||
min: String(entry.minimum),
|
||||
max: String(entry.maximum),
|
||||
value: String(entry.value),
|
||||
title: `${entry.minimum} bis ${entry.maximum} ${entry.unit}`,
|
||||
});
|
||||
fields.set(entry.key, input);
|
||||
|
||||
return el("div.duration-row", {},
|
||||
el("div.duration-text", {},
|
||||
el("span.duration-label", {}, `${entry.label} … ${entry.unit}`),
|
||||
el("span.duration-note", {},
|
||||
entry.note,
|
||||
entry.zero_means ? ` · 0 = ${entry.zero_means}` : "",
|
||||
entry.value !== entry.default
|
||||
? ` · Vorgabe ${entry.default}` : "")),
|
||||
input);
|
||||
}));
|
||||
};
|
||||
|
||||
return el("section.card", {},
|
||||
el("h2", {}, "Automatische Bereinigung"),
|
||||
el("h2", {}, "Fristen"),
|
||||
el("p.lead", {},
|
||||
"Läuft einmal täglich. ",
|
||||
el("strong", {}, "0 bedeutet abgeschaltet"),
|
||||
", nicht „sofort“. Administratorkonten sind ausgenommen."),
|
||||
"Diese Werte gelten zur Laufzeit und werden auch für die " +
|
||||
"Datenschutzerklärung gebraucht. Der Aufräumlauf setzt sie " +
|
||||
"einmal täglich um."),
|
||||
|
||||
el("label", {}, "Deaktivieren nach … Monaten ohne Anmeldung"),
|
||||
deactivate,
|
||||
el("label", {}, "Löschen nach … Monaten Deaktivierung"),
|
||||
remove,
|
||||
|
||||
el("h3.device-heading", {}, "Listen"),
|
||||
el("label", {}, "Archivieren nach … Monaten ohne Öffnen"),
|
||||
archive,
|
||||
el("p.sub", {},
|
||||
"Gilt je Person: Die Liste verschwindet nur aus der Übersicht " +
|
||||
"derjenigen, die sie nicht geöffnet hat."),
|
||||
el("label", {}, "Löschen nach … Monaten im Archiv"),
|
||||
archiveDelete,
|
||||
el("p.sub", {},
|
||||
"Maßgeblich ist allein das Archivdatum des Eigentümers. Er wird " +
|
||||
"7 Tage und 1 Tag vorher per E-Mail gewarnt."),
|
||||
group("Konten",
|
||||
["auto_deactivate_months", "auto_delete_months"]),
|
||||
group("Listen",
|
||||
["auto_archive_months", "archive_delete_months"]),
|
||||
group("Aufbewahrung",
|
||||
["cleanup_deleted_days", "cleanup_ops_days", "product_cache_days"]),
|
||||
group("Sitzungen und Links",
|
||||
["session_days", "invite_days", "welcome_days", "verify_hours",
|
||||
"reset_hours", "email_change_hours"]),
|
||||
|
||||
el("button.primary", {
|
||||
type: "button",
|
||||
onclick: () => guarded(async () => {
|
||||
await put("/api/admin/settings", {
|
||||
auto_deactivate_months: Number(deactivate.value) || 0,
|
||||
auto_delete_months: Number(remove.value) || 0,
|
||||
auto_archive_months: Number(archive.value) || 0,
|
||||
archive_delete_months: Number(archiveDelete.value) || 0,
|
||||
});
|
||||
say("Einstellungen gespeichert.");
|
||||
const durations = {};
|
||||
for (const [key, input] of fields) {
|
||||
durations[key] = Number(input.value) || 0;
|
||||
}
|
||||
await put("/api/admin/settings", { durations });
|
||||
say("Fristen gespeichert.");
|
||||
}),
|
||||
}, "Speichern"),
|
||||
|
||||
@@ -354,7 +363,19 @@ export async function adminView(root, { back }) {
|
||||
el("button", {
|
||||
type: "button",
|
||||
onclick: () => guarded(() => post("/api/admin/cleanup")),
|
||||
}, "Jetzt aufräumen"))
|
||||
}, "Jetzt aufräumen")),
|
||||
|
||||
// Was hier nicht einstellbar ist, soll trotzdem sichtbar sein -
|
||||
// sonst wirkt die Übersicht vollständig, ohne es zu sein.
|
||||
Object.keys(config.fixed || {}).length
|
||||
? el("div", {},
|
||||
el("h3.device-heading", {}, "Fest eingestellt"),
|
||||
el("ul.fixed-list", {},
|
||||
Object.entries(config.fixed).map(([label, value]) =>
|
||||
el("li", {},
|
||||
el("span.name", {}, label),
|
||||
el("span.sub", {}, value)))))
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
||||
@@ -375,7 +396,7 @@ export async function adminView(root, { back }) {
|
||||
registrationToggle(),
|
||||
el("ul.admin-users", {}, users.map(userRow))),
|
||||
createCard(),
|
||||
automationCard()
|
||||
durationsCard()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user