Compare commits
No commits in common. "c7f205d9bce90ec3c4a5ba0032f15ec634ae99d1" and "f1c6d43613deed66fea7c8a5205898c012128b5c" have entirely different histories.
c7f205d9bc
...
f1c6d43613
@ -51,9 +51,6 @@ textarea { resize: vertical; min-height: 56px; }
|
|||||||
.field.prefilled input, .field.prefilled textarea { background: #f3f4f6; color: #4b5563; }
|
.field.prefilled input, .field.prefilled textarea { background: #f3f4f6; color: #4b5563; }
|
||||||
|
|
||||||
.options { margin: 0; }
|
.options { margin: 0; }
|
||||||
.format { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 5px 0; }
|
|
||||||
.format-label { font-weight: 500; }
|
|
||||||
.format .radio { margin: 0; }
|
|
||||||
.radio, .check { display: flex; align-items: center; gap: 8px; margin: 5px 0; font-weight: 400; }
|
.radio, .check { display: flex; align-items: center; gap: 8px; margin: 5px 0; font-weight: 400; }
|
||||||
.radio input, .check input { accent-color: #2563eb; }
|
.radio input, .check input { accent-color: #2563eb; }
|
||||||
|
|
||||||
|
|||||||
@ -68,12 +68,10 @@
|
|||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<section class="options">
|
<section class="options">
|
||||||
<div class="format">
|
<label class="radio"><input type="radio" name="scope" value="both" checked /> E-Mail und Anhänge</label>
|
||||||
<span class="format-label">E-Mail ablegen als:</span>
|
<label class="radio"><input type="radio" name="scope" value="att" /> Nur Anhänge</label>
|
||||||
<label class="radio"><input type="radio" name="mailFormat" value="eml" checked /> Original (.eml)</label>
|
<label class="radio"><input type="radio" name="scope" value="eml" /> Nur E-Mail</label>
|
||||||
<label class="radio"><input type="radio" name="mailFormat" value="pdf" /> PDF</label>
|
<label class="check"><input type="checkbox" id="optPdf" /> Zusätzlich als PDF ablegen</label>
|
||||||
</div>
|
|
||||||
<label class="check"><input type="checkbox" id="optAtt" checked /> Anhänge mit ablegen</label>
|
|
||||||
<ul id="attList" class="att-list"></ul>
|
<ul id="attList" class="att-list"></ul>
|
||||||
</section>
|
</section>
|
||||||
<div id="status" class="muted"></div>
|
<div id="status" class="muted"></div>
|
||||||
|
|||||||
124
dialog/dialog.js
124
dialog/dialog.js
@ -17,35 +17,33 @@ let STATE = {
|
|||||||
cabinetFieldsByCab: {}, // Cache: cabinetId -> [Feldnamen] (für EML_ID-Erkennung)
|
cabinetFieldsByCab: {}, // Cache: cabinetId -> [Feldnamen] (für EML_ID-Erkennung)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mail-Token -> Funktion, die den Wert aus den Mail-Metadaten liefert.
|
// Mapping DocuWare-Feldname -> Funktion, die einen Vorbefüllwert aus meta liefert.
|
||||||
// Welches DocuWare-Feld welchen Token bekommt, steht im Mapping (s. effectiveFieldMap).
|
const PREFILL = {
|
||||||
const TOKEN_FN = {
|
EML_SENDER: (m) => m.senderEmail,
|
||||||
senderEmail: (m) => m.senderEmail,
|
EML_SENDER_DISPLAYNAME: (m) => m.senderName,
|
||||||
senderName: (m) => m.senderName,
|
EML_SENDER_NAME: (m) => m.senderName,
|
||||||
to: (m) => m.to,
|
EML_RECEIVER: (m) => m.to,
|
||||||
cc: (m) => m.cc,
|
EML_CC: (m) => m.cc,
|
||||||
bcc: (m) => m.bcc,
|
EML_BCC: (m) => m.bcc,
|
||||||
subject: (m) => m.subject,
|
EML_SUBJECT: (m) => m.subject,
|
||||||
body: (m) => m.bodyText,
|
DOC_SUBJECT: (m) => m.subject,
|
||||||
date: (m) => m.date,
|
EML_BODY: (m) => m.bodyText,
|
||||||
direction: (m) => m.direction,
|
EML_SENDINGDATE: (m) => m.date,
|
||||||
size: (m) => m.sizeBytes,
|
EML_DISPLAYDATE: (m) => m.date,
|
||||||
account: (m) => m.account,
|
EML_RECEIVINGDATE: (m) => m.date,
|
||||||
|
EML_DIRECTION: (m) => m.direction,
|
||||||
|
EML_SIZE: (m) => m.sizeBytes,
|
||||||
|
EML_ACCOUNT: (m) => m.account,
|
||||||
|
DOC_DATE: (m) => m.date,
|
||||||
|
// Naheliegende generische Feldnamen (Schränke ohne EML_*-Schema)
|
||||||
|
SUBJECT: (m) => m.subject,
|
||||||
|
BETREFF: (m) => m.subject,
|
||||||
|
EMAIL: (m) => m.senderEmail,
|
||||||
|
E_MAIL: (m) => m.senderEmail,
|
||||||
|
DATE: (m) => m.date,
|
||||||
|
DATUM: (m) => m.date,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Aktives Feld-Mapping: eigenes (aus den Einstellungen) wenn gesetzt, sonst Default.
|
|
||||||
function effectiveFieldMap() {
|
|
||||||
const m = STATE.settings && STATE.settings.fieldMapping;
|
|
||||||
return m && Object.keys(m).length ? m : DEFAULT_FIELD_MAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vorbefüllwert für ein DocuWare-Feld aus den Mail-Metadaten (oder undefined).
|
|
||||||
function prefillFor(fieldName, meta) {
|
|
||||||
const token = effectiveFieldMap()[fieldName];
|
|
||||||
const fn = token && TOKEN_FN[token];
|
|
||||||
return fn ? fn(meta) : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function status(msg, kind) {
|
function status(msg, kind) {
|
||||||
const el = $("status");
|
const el = $("status");
|
||||||
el.textContent = msg || "";
|
el.textContent = msg || "";
|
||||||
@ -155,24 +153,28 @@ function askPassword(errMsg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applyDefaults() {
|
function applyDefaults() {
|
||||||
// Mail-Format (.eml ODER PDF) aus den Einstellungen.
|
$("optPdf").checked = STATE.settings.storePdf;
|
||||||
setMailFormat(STATE.settings.mailFormat === "pdf" ? "pdf" : "eml");
|
|
||||||
// Anhänge-Haken nur sinnvoll, wenn die Mail überhaupt Anhänge hat.
|
|
||||||
const hasAtt = STATE.attachments.length > 0;
|
const hasAtt = STATE.attachments.length > 0;
|
||||||
const att = $("optAtt");
|
// Standard-Umfang aus den Einstellungen ableiten.
|
||||||
att.checked = hasAtt && STATE.settings.storeAttachments !== false;
|
let scope = "both";
|
||||||
att.disabled = !hasAtt;
|
if (STATE.settings.storeEml && !STATE.settings.storeAttachments) scope = "eml";
|
||||||
$("attList").style.display = hasAtt && att.checked ? "" : "none";
|
else if (!STATE.settings.storeEml && STATE.settings.storeAttachments) scope = "att";
|
||||||
|
if (!hasAtt) scope = "eml"; // ohne Anhänge nur E-Mail sinnvoll
|
||||||
|
setScope(scope);
|
||||||
|
// Optionen, die Anhänge erfordern, deaktivieren wenn keine vorhanden.
|
||||||
|
document.querySelectorAll('input[name="scope"]').forEach((r) => {
|
||||||
|
if ((r.value === "att" || r.value === "both") && !hasAtt) r.disabled = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMailFormat(value) {
|
function setScope(value) {
|
||||||
const el = document.querySelector(`input[name="mailFormat"][value="${value}"]`);
|
const el = document.querySelector(`input[name="scope"][value="${value}"]`);
|
||||||
if (el) el.checked = true;
|
if (el) el.checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMailFormat() {
|
function getScope() {
|
||||||
const el = document.querySelector('input[name="mailFormat"]:checked');
|
const el = document.querySelector('input[name="scope"]:checked');
|
||||||
return el ? el.value : "eml";
|
return el ? el.value : "both";
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderAttachments() {
|
function renderAttachments() {
|
||||||
@ -442,7 +444,9 @@ function applyFieldDefaults() {
|
|||||||
|
|
||||||
function prefillFields() {
|
function prefillFields() {
|
||||||
STATE.fields.forEach((f) => {
|
STATE.fields.forEach((f) => {
|
||||||
const val = prefillFor(f.name, STATE.meta);
|
const fn = PREFILL[f.name];
|
||||||
|
if (!fn) return;
|
||||||
|
const val = fn(STATE.meta);
|
||||||
if (val === undefined || val === null || val === "") return;
|
if (val === undefined || val === null || val === "") return;
|
||||||
setFieldValue(f.name, f, val);
|
setFieldValue(f.name, f, val);
|
||||||
});
|
});
|
||||||
@ -541,11 +545,15 @@ async function submit() {
|
|||||||
result = collected.result;
|
result = collected.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fmt = getMailFormat(); // "eml" ODER "pdf" – nie beides
|
const scope = getScope();
|
||||||
const wantEml = fmt === "eml";
|
const wantEml = scope !== "att";
|
||||||
const wantPdf = fmt === "pdf";
|
const wantPdf = $("optPdf").checked;
|
||||||
const att = $("optAtt");
|
const wantAttScope = scope !== "eml";
|
||||||
const wantAttScope = att.checked && !att.disabled;
|
|
||||||
|
if (!wantEml && !wantAttScope) {
|
||||||
|
status("Nichts ausgewählt zum Ablegen.", "err");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Dubletten-Warnung (nur Einzelmail): liegt die Mail im Ziel schon, warnen –
|
// Dubletten-Warnung (nur Einzelmail): liegt die Mail im Ziel schon, warnen –
|
||||||
// „Trotzdem ablegen" bleibt aber möglich.
|
// „Trotzdem ablegen" bleibt aber möglich.
|
||||||
@ -567,7 +575,7 @@ async function submit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await saveOptionPrefs(fmt, wantAttScope); // Sticky: Format + Anhänge-Wahl merken
|
await saveOptionPrefs(scope, wantPdf); // Sticky: Umfang merken
|
||||||
|
|
||||||
$("submit").disabled = true;
|
$("submit").disabled = true;
|
||||||
const multi = STATE.messageIds.length > 1;
|
const multi = STATE.messageIds.length > 1;
|
||||||
@ -642,17 +650,21 @@ function fieldsForMessage(baseResult, meta, multi) {
|
|||||||
if (!multi) return baseResult; // Einzelmail: manuelle Edits respektieren
|
if (!multi) return baseResult; // Einzelmail: manuelle Edits respektieren
|
||||||
const result = { ...baseResult };
|
const result = { ...baseResult };
|
||||||
STATE.fields.forEach((f) => {
|
STATE.fields.forEach((f) => {
|
||||||
const val = prefillFor(f.name, meta);
|
const fn = PREFILL[f.name];
|
||||||
|
if (!fn) return;
|
||||||
|
const val = fn(meta);
|
||||||
if (val === undefined || val === null || val === "") return;
|
if (val === undefined || val === null || val === "") return;
|
||||||
result[f.name] = { value: val, type: f.type };
|
result[f.name] = { value: val, type: f.type };
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sticky: zuletzt genutztes Format + Anhänge-Wahl in den Einstellungen merken.
|
// Sticky: zuletzt genutzten Ablage-Umfang in den Einstellungen merken.
|
||||||
async function saveOptionPrefs(mailFormat, storeAttachments) {
|
async function saveOptionPrefs(scope, wantPdf) {
|
||||||
|
const storeEml = scope !== "att";
|
||||||
|
const storeAttachments = scope !== "eml";
|
||||||
try {
|
try {
|
||||||
STATE.settings = await Settings.set({ mailFormat, storeAttachments });
|
STATE.settings = await Settings.set({ storeEml, storeAttachments, storePdf: wantPdf });
|
||||||
} catch (_) { /* nicht kritisch */ }
|
} catch (_) { /* nicht kritisch */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,13 +728,11 @@ $("reset").addEventListener("click", resetForm);
|
|||||||
$("cancel").addEventListener("click", () => window.close());
|
$("cancel").addEventListener("click", () => window.close());
|
||||||
|
|
||||||
// Sticky: Optionen sofort bei Änderung merken (nicht erst beim Ablegen).
|
// Sticky: Optionen sofort bei Änderung merken (nicht erst beim Ablegen).
|
||||||
document.querySelectorAll('input[name="mailFormat"]').forEach((r) =>
|
document.querySelectorAll('input[name="scope"]').forEach((r) =>
|
||||||
r.addEventListener("change", () => saveOptionPrefs(getMailFormat(), $("optAtt").checked))
|
r.addEventListener("change", () => saveOptionPrefs(getScope(), $("optPdf").checked))
|
||||||
|
);
|
||||||
|
$("optPdf").addEventListener("change", () =>
|
||||||
|
saveOptionPrefs(getScope(), $("optPdf").checked)
|
||||||
);
|
);
|
||||||
$("optAtt").addEventListener("change", () => {
|
|
||||||
const show = $("optAtt").checked && STATE.attachments.length > 0;
|
|
||||||
$("attList").style.display = show ? "" : "none";
|
|
||||||
saveOptionPrefs(getMailFormat(), $("optAtt").checked);
|
|
||||||
});
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|||||||
58
lib/store.js
58
lib/store.js
@ -9,65 +9,16 @@ const DEFAULTS = {
|
|||||||
username: "",
|
username: "",
|
||||||
defaultCabinetId: "",
|
defaultCabinetId: "",
|
||||||
dialogByCabinet: {}, // gemerkter Ablagedialog je Schrank: { [cabinetId]: dialogId }
|
dialogByCabinet: {}, // gemerkter Ablagedialog je Schrank: { [cabinetId]: dialogId }
|
||||||
mailFormat: "eml", // E-Mail wird als "eml" ODER "pdf" abgelegt (nie beides)
|
storeEml: true,
|
||||||
|
storePdf: true,
|
||||||
storeAttachments: true,
|
storeAttachments: true,
|
||||||
tagOnSuccess: true,
|
tagOnSuccess: true,
|
||||||
fieldMapping: {}, // DocuWare-Feldname -> Mail-Attribut (Token). Leer = DEFAULT_FIELD_MAP.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mögliche Mail-Attribute für die Vorbefüllung (Token + Anzeigename).
|
|
||||||
// Wird von dialog.js (Werte aus meta) und options.js (Mapping-Editor) genutzt.
|
|
||||||
const MAIL_TOKENS = [
|
|
||||||
{ key: "senderEmail", label: "Absender – E-Mail" },
|
|
||||||
{ key: "senderName", label: "Absender – Name" },
|
|
||||||
{ key: "to", label: "Empfänger (An)" },
|
|
||||||
{ key: "cc", label: "CC" },
|
|
||||||
{ key: "bcc", label: "BCC" },
|
|
||||||
{ key: "subject", label: "Betreff" },
|
|
||||||
{ key: "body", label: "Text (Body)" },
|
|
||||||
{ key: "date", label: "Datum" },
|
|
||||||
{ key: "direction", label: "Richtung (Ein-/Ausgang)" },
|
|
||||||
{ key: "size", label: "Größe (Bytes)" },
|
|
||||||
{ key: "account", label: "Konto" },
|
|
||||||
];
|
|
||||||
|
|
||||||
// Standard-Zuordnung DocuWare-Feldname -> Mail-Token. Greift, solange der Nutzer
|
|
||||||
// in den Einstellungen kein eigenes fieldMapping gespeichert hat.
|
|
||||||
const DEFAULT_FIELD_MAP = {
|
|
||||||
EML_SENDER: "senderEmail",
|
|
||||||
EML_SENDER_DISPLAYNAME: "senderName",
|
|
||||||
EML_SENDER_NAME: "senderName",
|
|
||||||
EML_RECEIVER: "to",
|
|
||||||
EML_CC: "cc",
|
|
||||||
EML_BCC: "bcc",
|
|
||||||
EML_SUBJECT: "subject",
|
|
||||||
DOC_SUBJECT: "subject",
|
|
||||||
EML_BODY: "body",
|
|
||||||
EML_SENDINGDATE: "date",
|
|
||||||
EML_DISPLAYDATE: "date",
|
|
||||||
EML_RECEIVINGDATE: "date",
|
|
||||||
EML_DIRECTION: "direction",
|
|
||||||
EML_SIZE: "size",
|
|
||||||
EML_ACCOUNT: "account",
|
|
||||||
DOC_DATE: "date",
|
|
||||||
SUBJECT: "subject",
|
|
||||||
BETREFF: "subject",
|
|
||||||
EMAIL: "senderEmail",
|
|
||||||
E_MAIL: "senderEmail",
|
|
||||||
DATE: "date",
|
|
||||||
DATUM: "date",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Settings = {
|
const Settings = {
|
||||||
async get() {
|
async get() {
|
||||||
const stored = await browser.storage.local.get("settings");
|
const stored = await browser.storage.local.get("settings");
|
||||||
const raw = stored.settings || {};
|
return { ...DEFAULTS, ...(stored.settings || {}) };
|
||||||
const s = { ...DEFAULTS, ...raw };
|
|
||||||
// Migration: altes storeEml/storePdf -> mailFormat (einmalig, nicht persistiert).
|
|
||||||
if (raw.mailFormat === undefined && raw.storePdf && !raw.storeEml) {
|
|
||||||
s.mailFormat = "pdf";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async set(partial) {
|
async set(partial) {
|
||||||
@ -87,5 +38,4 @@ const Settings = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof module !== "undefined")
|
if (typeof module !== "undefined") module.exports = { Settings, DEFAULTS };
|
||||||
module.exports = { Settings, DEFAULTS, MAIL_TOKENS, DEFAULT_FIELD_MAP };
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "DocuWare Ablage",
|
"name": "DocuWare Ablage",
|
||||||
"description": "Legt markierte E-Mails (als .eml, PDF und mit Anhängen) in DocuWare ab.",
|
"description": "Legt markierte E-Mails (als .eml, PDF und mit Anhängen) in DocuWare ab.",
|
||||||
"version": "0.10.3",
|
"version": "0.10.2",
|
||||||
"author": "l.lingler",
|
"author": "l.lingler",
|
||||||
"applications": {
|
"applications": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
|
|||||||
@ -17,13 +17,6 @@
|
|||||||
#status { font-size: 13px; min-height: 18px; }
|
#status { font-size: 13px; min-height: 18px; }
|
||||||
.ok { color: #15803d; } .err { color: #b91c1c; }
|
.ok { color: #15803d; } .err { color: #b91c1c; }
|
||||||
.hint { font-size: 12px; color: #666; margin-top: 2px; }
|
.hint { font-size: 12px; color: #666; margin-top: 2px; }
|
||||||
table.map { width: 100%; border-collapse: collapse; margin-top: 8px; }
|
|
||||||
table.map th { text-align: left; font-size: 12px; color: #666; font-weight: 600; padding: 2px 4px; }
|
|
||||||
table.map td { padding: 3px 4px; vertical-align: middle; }
|
|
||||||
table.map input, table.map select { width: 100%; padding: 5px 7px; border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box; }
|
|
||||||
table.map td.del { width: 36px; }
|
|
||||||
table.map button { padding: 5px 9px; }
|
|
||||||
button.secondary { background: #e5e7eb; color: #111; }
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -55,12 +48,9 @@
|
|||||||
</select>
|
</select>
|
||||||
<div class="hint">Liste wird nach erfolgreichem Verbindungstest gefüllt.</div>
|
<div class="hint">Liste wird nach erfolgreichem Verbindungstest gefüllt.</div>
|
||||||
|
|
||||||
<label>Standard-Format der E-Mail</label>
|
<div class="check"><input type="checkbox" id="storeEml" /> <label for="storeEml" style="margin:0">E-Mail als .eml ablegen</label></div>
|
||||||
<div class="check"><input type="radio" name="mailFormat" id="fmtEml" value="eml" /> <label for="fmtEml" style="margin:0">Original (.eml)</label></div>
|
<div class="check"><input type="checkbox" id="storePdf" /> <label for="storePdf" style="margin:0">E-Mail als PDF ablegen</label></div>
|
||||||
<div class="check"><input type="radio" name="mailFormat" id="fmtPdf" value="pdf" /> <label for="fmtPdf" style="margin:0">PDF</label></div>
|
<div class="check"><input type="checkbox" id="storeAttachments" /> <label for="storeAttachments" style="margin:0">Anhänge separat ablegen</label></div>
|
||||||
<div class="hint">Die E-Mail wird immer in genau einem Format abgelegt (nicht beides). Im Ablage-Fenster umstellbar.</div>
|
|
||||||
|
|
||||||
<div class="check" style="margin-top:10px"><input type="checkbox" id="storeAttachments" /> <label for="storeAttachments" style="margin:0">Anhänge mit ablegen</label></div>
|
|
||||||
<div class="check"><input type="checkbox" id="tagOnSuccess" /> <label for="tagOnSuccess" style="margin:0">Mail nach Ablage als „DocuWare" markieren</label></div>
|
<div class="check"><input type="checkbox" id="tagOnSuccess" /> <label for="tagOnSuccess" style="margin:0">Mail nach Ablage als „DocuWare" markieren</label></div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
@ -70,21 +60,6 @@
|
|||||||
<span id="status"></span>
|
<span id="status"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend>Feld-Zuordnung (Vorbefüllung)</legend>
|
|
||||||
<div class="hint">Legt fest, welches DocuWare-Indexfeld aus welchem Mail-Attribut vorbefüllt
|
|
||||||
wird. <strong>Feldname</strong> = DocuWare-Datenbankname (z. B. <code>EML_SUBJECT</code>).
|
|
||||||
Gilt für alle Aktenschränke. Leere/entfernte Zeilen befüllen nichts vor.</div>
|
|
||||||
<table class="map">
|
|
||||||
<thead><tr><th>DocuWare-Feldname</th><th>Mail-Attribut</th><th></th></tr></thead>
|
|
||||||
<tbody id="mapBody"></tbody>
|
|
||||||
</table>
|
|
||||||
<div class="row">
|
|
||||||
<button id="mapAdd" class="secondary" type="button">+ Zeile</button>
|
|
||||||
<button id="mapReset" class="secondary" type="button">Auf Standard zurücksetzen</button>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Einstellungen sichern</legend>
|
<legend>Einstellungen sichern</legend>
|
||||||
<div class="hint">Exportiert/importiert die Einstellungen (Server, Organisation,
|
<div class="hint">Exportiert/importiert die Einstellungen (Server, Organisation,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ const $ = (id) => document.getElementById(id);
|
|||||||
// Passwort ist bewusst NICHT dabei – es wird nie gespeichert, nur zum Testen/Login
|
// Passwort ist bewusst NICHT dabei – es wird nie gespeichert, nur zum Testen/Login
|
||||||
// transient verwendet (siehe "Verbindung testen").
|
// transient verwendet (siehe "Verbindung testen").
|
||||||
const FIELDS = ["serverUrl", "organization", "username"];
|
const FIELDS = ["serverUrl", "organization", "username"];
|
||||||
const CHECKS = ["storeAttachments", "tagOnSuccess"];
|
const CHECKS = ["storeEml", "storePdf", "storeAttachments", "tagOnSuccess"];
|
||||||
|
|
||||||
function setStatus(msg, kind) {
|
function setStatus(msg, kind) {
|
||||||
const el = $("status");
|
const el = $("status");
|
||||||
@ -16,67 +16,11 @@ async function load() {
|
|||||||
const s = await Settings.get();
|
const s = await Settings.get();
|
||||||
FIELDS.forEach((f) => ($(f).value = s[f] || ""));
|
FIELDS.forEach((f) => ($(f).value = s[f] || ""));
|
||||||
CHECKS.forEach((c) => ($(c).checked = !!s[c]));
|
CHECKS.forEach((c) => ($(c).checked = !!s[c]));
|
||||||
setMailFormat(s.mailFormat === "pdf" ? "pdf" : "eml");
|
|
||||||
loadMapping(s.fieldMapping && Object.keys(s.fieldMapping).length ? s.fieldMapping : DEFAULT_FIELD_MAP);
|
|
||||||
// Schrankliste, falls vorher schon getestet (im Storage gecached)
|
// Schrankliste, falls vorher schon getestet (im Storage gecached)
|
||||||
const cached = (await browser.storage.local.get("cabinets")).cabinets || [];
|
const cached = (await browser.storage.local.get("cabinets")).cabinets || [];
|
||||||
fillCabinets(cached, s.defaultCabinetId);
|
fillCabinets(cached, s.defaultCabinetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fillCabinets(cabinets, selectedId) {
|
function fillCabinets(cabinets, selectedId) {
|
||||||
const sel = $("defaultCabinet");
|
const sel = $("defaultCabinet");
|
||||||
sel.innerHTML = '<option value="">— keiner —</option>';
|
sel.innerHTML = '<option value="">— keiner —</option>';
|
||||||
@ -102,14 +46,9 @@ function collect() {
|
|||||||
FIELDS.forEach((f) => (partial[f] = $(f).value.trim()));
|
FIELDS.forEach((f) => (partial[f] = $(f).value.trim()));
|
||||||
CHECKS.forEach((c) => (partial[c] = $(c).checked));
|
CHECKS.forEach((c) => (partial[c] = $(c).checked));
|
||||||
partial.defaultCabinetId = $("defaultCabinet").value;
|
partial.defaultCabinetId = $("defaultCabinet").value;
|
||||||
partial.mailFormat = getMailFormat();
|
|
||||||
partial.fieldMapping = collectMapping();
|
|
||||||
return partial;
|
return partial;
|
||||||
}
|
}
|
||||||
|
|
||||||
$("mapAdd").addEventListener("click", () => addMapRow());
|
|
||||||
$("mapReset").addEventListener("click", () => loadMapping(DEFAULT_FIELD_MAP));
|
|
||||||
|
|
||||||
$("save").addEventListener("click", async () => {
|
$("save").addEventListener("click", async () => {
|
||||||
await Settings.set(collect());
|
await Settings.set(collect());
|
||||||
setStatus("Gespeichert.", "ok");
|
setStatus("Gespeichert.", "ok");
|
||||||
|
|||||||
@ -13,10 +13,6 @@
|
|||||||
{
|
{
|
||||||
"version": "0.10.2",
|
"version": "0.10.2",
|
||||||
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.10.2/docuware-ablage-0.10.2.xpi"
|
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.10.2/docuware-ablage-0.10.2.xpi"
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "0.10.3",
|
|
||||||
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.10.3/docuware-ablage-0.10.3.xpi"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user