2026-06-03 11:15:59 +00:00
|
|
|
|
// Logik der Einstellungsseite.
|
|
|
|
|
|
|
|
|
|
|
|
const $ = (id) => document.getElementById(id);
|
2026-06-03 13:14:05 +00:00
|
|
|
|
// Passwort ist bewusst NICHT dabei – es wird nie gespeichert, nur zum Testen/Login
|
|
|
|
|
|
// transient verwendet (siehe "Verbindung testen").
|
|
|
|
|
|
const FIELDS = ["serverUrl", "organization", "username"];
|
2026-06-16 11:23:39 +00:00
|
|
|
|
const CHECKS = ["storeAttachments", "tagOnSuccess"];
|
2026-06-03 11:15:59 +00:00
|
|
|
|
|
|
|
|
|
|
function setStatus(msg, kind) {
|
|
|
|
|
|
const el = $("status");
|
|
|
|
|
|
el.textContent = msg;
|
|
|
|
|
|
el.className = kind || "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function load() {
|
|
|
|
|
|
const s = await Settings.get();
|
|
|
|
|
|
FIELDS.forEach((f) => ($(f).value = s[f] || ""));
|
|
|
|
|
|
CHECKS.forEach((c) => ($(c).checked = !!s[c]));
|
2026-06-16 11:23:39 +00:00
|
|
|
|
setMailFormat(s.mailFormat === "pdf" ? "pdf" : "eml");
|
|
|
|
|
|
loadMapping(s.fieldMapping && Object.keys(s.fieldMapping).length ? s.fieldMapping : DEFAULT_FIELD_MAP);
|
2026-06-03 11:15:59 +00:00
|
|
|
|
// Schrankliste, falls vorher schon getestet (im Storage gecached)
|
|
|
|
|
|
const cached = (await browser.storage.local.get("cabinets")).cabinets || [];
|
|
|
|
|
|
fillCabinets(cached, s.defaultCabinetId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-16 11:23:39 +00:00
|
|
|
|
function setMailFormat(v) {
|
|
|
|
|
|
const el = document.querySelector(`input[name="mailFormat"][value="${v}"]`);
|
|
|
|
|
|
if (el) el.checked = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
function getMailFormat() {
|
|
|
|
|
|
const el = document.querySelector('input[name="mailFormat"]:checked');
|
|
|
|
|
|
return el ? el.value : "eml";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- Feld-Mapping-Editor ---------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
function addMapRow(field = "", token = "") {
|
|
|
|
|
|
const tr = document.createElement("tr");
|
|
|
|
|
|
|
|
|
|
|
|
const inp = document.createElement("input");
|
|
|
|
|
|
inp.type = "text"; inp.className = "map-field"; inp.value = field;
|
|
|
|
|
|
inp.placeholder = "EML_SUBJECT";
|
|
|
|
|
|
const tdF = document.createElement("td"); tdF.appendChild(inp);
|
|
|
|
|
|
|
|
|
|
|
|
const sel = document.createElement("select"); sel.className = "map-token";
|
|
|
|
|
|
const none = document.createElement("option"); none.value = ""; none.textContent = "— nichts —";
|
|
|
|
|
|
sel.appendChild(none);
|
|
|
|
|
|
MAIL_TOKENS.forEach((t) => {
|
|
|
|
|
|
const o = document.createElement("option");
|
|
|
|
|
|
o.value = t.key; o.textContent = t.label;
|
|
|
|
|
|
if (t.key === token) o.selected = true;
|
|
|
|
|
|
sel.appendChild(o);
|
|
|
|
|
|
});
|
|
|
|
|
|
const tdT = document.createElement("td"); tdT.appendChild(sel);
|
|
|
|
|
|
|
|
|
|
|
|
const del = document.createElement("button");
|
|
|
|
|
|
del.type = "button"; del.className = "secondary"; del.textContent = "✕";
|
|
|
|
|
|
del.addEventListener("click", () => tr.remove());
|
|
|
|
|
|
const tdX = document.createElement("td"); tdX.className = "del"; tdX.appendChild(del);
|
|
|
|
|
|
|
|
|
|
|
|
tr.append(tdF, tdT, tdX);
|
|
|
|
|
|
$("mapBody").appendChild(tr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function loadMapping(map) {
|
|
|
|
|
|
$("mapBody").innerHTML = "";
|
|
|
|
|
|
Object.entries(map || {}).forEach(([f, t]) => addMapRow(f, t));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function collectMapping() {
|
|
|
|
|
|
const map = {};
|
|
|
|
|
|
document.querySelectorAll("#mapBody tr").forEach((tr) => {
|
|
|
|
|
|
const f = tr.querySelector(".map-field").value.trim();
|
|
|
|
|
|
const t = tr.querySelector(".map-token").value;
|
|
|
|
|
|
if (f && t) map[f] = t; // leere Feldnamen/Token ignorieren
|
|
|
|
|
|
});
|
|
|
|
|
|
return map;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-03 11:15:59 +00:00
|
|
|
|
function fillCabinets(cabinets, selectedId) {
|
|
|
|
|
|
const sel = $("defaultCabinet");
|
|
|
|
|
|
sel.innerHTML = '<option value="">— keiner —</option>';
|
|
|
|
|
|
const addGroup = (label, list) => {
|
|
|
|
|
|
if (!list.length) return;
|
|
|
|
|
|
const g = document.createElement("optgroup");
|
|
|
|
|
|
g.label = label;
|
|
|
|
|
|
list.forEach((c) => {
|
|
|
|
|
|
const o = document.createElement("option");
|
|
|
|
|
|
o.value = c.id;
|
|
|
|
|
|
o.textContent = c.name;
|
|
|
|
|
|
if (String(c.id) === String(selectedId)) o.selected = true;
|
|
|
|
|
|
g.appendChild(o);
|
|
|
|
|
|
});
|
|
|
|
|
|
sel.appendChild(g);
|
|
|
|
|
|
};
|
|
|
|
|
|
addGroup("Archive", cabinets.filter((c) => !c.isBasket));
|
|
|
|
|
|
addGroup("Briefkörbe", cabinets.filter((c) => c.isBasket));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function collect() {
|
|
|
|
|
|
const partial = {};
|
|
|
|
|
|
FIELDS.forEach((f) => (partial[f] = $(f).value.trim()));
|
|
|
|
|
|
CHECKS.forEach((c) => (partial[c] = $(c).checked));
|
|
|
|
|
|
partial.defaultCabinetId = $("defaultCabinet").value;
|
2026-06-16 11:23:39 +00:00
|
|
|
|
partial.mailFormat = getMailFormat();
|
|
|
|
|
|
partial.fieldMapping = collectMapping();
|
2026-06-03 11:15:59 +00:00
|
|
|
|
return partial;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-16 11:23:39 +00:00
|
|
|
|
$("mapAdd").addEventListener("click", () => addMapRow());
|
|
|
|
|
|
$("mapReset").addEventListener("click", () => loadMapping(DEFAULT_FIELD_MAP));
|
|
|
|
|
|
|
2026-06-03 11:15:59 +00:00
|
|
|
|
$("save").addEventListener("click", async () => {
|
|
|
|
|
|
await Settings.set(collect());
|
|
|
|
|
|
setStatus("Gespeichert.", "ok");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$("test").addEventListener("click", async () => {
|
2026-06-03 13:14:05 +00:00
|
|
|
|
const pw = $("password").value;
|
|
|
|
|
|
if (!pw) { setStatus("Bitte Passwort eingeben.", "err"); return; }
|
2026-06-03 11:15:59 +00:00
|
|
|
|
setStatus("Verbinde …");
|
|
|
|
|
|
try {
|
2026-06-03 13:14:05 +00:00
|
|
|
|
const s = await Settings.set(collect()); // erst speichern (ohne Passwort), dann testen
|
|
|
|
|
|
// Anmeldung über den Hintergrund-Broker: primt zugleich die Sitzung, sodass
|
|
|
|
|
|
// das Ablege-Fenster danach nicht erneut nach dem Passwort fragt.
|
|
|
|
|
|
const res = await browser.runtime.sendMessage({ type: "auth:logon", password: pw });
|
|
|
|
|
|
if (!res || !res.ok) throw new Error(res && res.error ? res.error : "Anmeldung fehlgeschlagen.");
|
|
|
|
|
|
Auth.setToken(res.token);
|
|
|
|
|
|
$("password").value = ""; // Passwort nicht behalten
|
2026-06-03 11:15:59 +00:00
|
|
|
|
const cabinets = await DocuWare.listCabinets(s);
|
|
|
|
|
|
await browser.storage.local.set({ cabinets });
|
|
|
|
|
|
fillCabinets(cabinets, s.defaultCabinetId);
|
|
|
|
|
|
const arch = cabinets.filter((c) => !c.isBasket).length;
|
|
|
|
|
|
const bk = cabinets.filter((c) => c.isBasket).length;
|
|
|
|
|
|
setStatus(`Verbindung ok – ${arch} Archive, ${bk} Briefkörbe gefunden.`, "ok");
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
setStatus(`Fehler: ${e.message}`, "err");
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$("exportBtn").addEventListener("click", async () => {
|
|
|
|
|
|
const s = await Settings.get();
|
|
|
|
|
|
const blob = new Blob([JSON.stringify(s, null, 2)], { type: "application/json" });
|
|
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
|
|
const a = document.createElement("a");
|
|
|
|
|
|
a.href = url;
|
|
|
|
|
|
a.download = "docuware-ablage-einstellungen.json";
|
|
|
|
|
|
document.body.appendChild(a);
|
|
|
|
|
|
a.click();
|
|
|
|
|
|
a.remove();
|
|
|
|
|
|
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
|
|
|
|
setStatus("Einstellungen exportiert.", "ok");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$("importBtn").addEventListener("click", () => $("importFile").click());
|
|
|
|
|
|
|
|
|
|
|
|
$("importFile").addEventListener("change", async (e) => {
|
|
|
|
|
|
const file = e.target.files && e.target.files[0];
|
|
|
|
|
|
if (!file) return;
|
|
|
|
|
|
try {
|
|
|
|
|
|
const text = await file.text();
|
|
|
|
|
|
const data = JSON.parse(text);
|
|
|
|
|
|
await Settings.set(data);
|
|
|
|
|
|
await load();
|
|
|
|
|
|
setStatus("Einstellungen importiert.", "ok");
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
setStatus(`Import fehlgeschlagen: ${err.message}`, "err");
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
e.target.value = "";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$("diagBtn").addEventListener("click", async () => {
|
|
|
|
|
|
const cabinetId = $("defaultCabinet").value;
|
|
|
|
|
|
const out = $("diag");
|
|
|
|
|
|
out.style.display = "block";
|
|
|
|
|
|
if (!cabinetId) {
|
|
|
|
|
|
out.value = "Bitte oben zuerst ein Standard-Ziel (Archiv) wählen.";
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
out.value = "Analysiere …";
|
|
|
|
|
|
try {
|
|
|
|
|
|
const s = await Settings.set(collect());
|
2026-06-03 13:14:05 +00:00
|
|
|
|
// Sitzungs-Token nutzen; falls noch keiner da ist, Passwortfeld verwenden.
|
|
|
|
|
|
const st = await browser.runtime.sendMessage({ type: "auth:status" });
|
|
|
|
|
|
if (st && st.hasToken && st.token) {
|
|
|
|
|
|
Auth.setToken(st.token);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
const pw = $("password").value;
|
|
|
|
|
|
if (!pw) { out.value = "Bitte Passwort eingeben (oder zuerst „Verbindung testen“)."; return; }
|
|
|
|
|
|
const res = await browser.runtime.sendMessage({ type: "auth:logon", password: pw });
|
|
|
|
|
|
if (!res || !res.ok) throw new Error(res && res.error ? res.error : "Anmeldung fehlgeschlagen.");
|
|
|
|
|
|
Auth.setToken(res.token);
|
|
|
|
|
|
$("password").value = "";
|
|
|
|
|
|
}
|
2026-06-03 11:15:59 +00:00
|
|
|
|
const dump = await DocuWare.diagnoseStoreDialog(s, cabinetId);
|
|
|
|
|
|
out.value = JSON.stringify(dump, null, 2);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
out.value = `Fehler: ${e.message}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
load();
|