Compare commits
2 Commits
c7f205d9bc
...
2194cc2d56
| Author | SHA1 | Date | |
|---|---|---|---|
| 2194cc2d56 | |||
| 52e8942e6d |
@ -2,7 +2,7 @@
|
||||
"manifest_version": 2,
|
||||
"name": "DocuWare Ablage",
|
||||
"description": "Legt markierte E-Mails (als .eml, PDF und mit Anhängen) in DocuWare ab.",
|
||||
"version": "0.10.3",
|
||||
"version": "0.10.4",
|
||||
"author": "l.lingler",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
|
||||
@ -4,33 +4,154 @@
|
||||
<meta charset="utf-8" />
|
||||
<title>DocuWare Ablage – Einstellungen</title>
|
||||
<style>
|
||||
body { font: 14px/1.5 system-ui, sans-serif; max-width: 560px; margin: 24px auto; padding: 0 16px; color: #1a1a1a; }
|
||||
h1 { font-size: 20px; }
|
||||
fieldset { border: 1px solid #ddd; border-radius: 8px; margin: 16px 0; padding: 12px 16px; }
|
||||
legend { font-weight: 600; padding: 0 6px; }
|
||||
label { display: block; margin: 10px 0 4px; font-weight: 500; }
|
||||
input[type="text"], input[type="password"], input[type="url"] { width: 100%; padding: 7px 9px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; }
|
||||
.check { display: flex; align-items: center; gap: 8px; font-weight: 400; margin: 8px 0; }
|
||||
.row { display: flex; gap: 12px; align-items: center; margin-top: 16px; }
|
||||
button { padding: 8px 16px; border: 0; border-radius: 6px; background: #2563eb; color: #fff; font-weight: 600; cursor: pointer; }
|
||||
button.secondary { background: #e5e7eb; color: #111; }
|
||||
/* DocuWare-naher Dark-Style: tiefes Slate, DocuWare-Blau als Akzent. */
|
||||
:root {
|
||||
--bg: #11151b;
|
||||
--bg-grad: radial-gradient(1200px 500px at 80% -10%, #18324a 0%, rgba(17,21,27,0) 60%);
|
||||
--surface: #1a1f27;
|
||||
--surface-2: #222a34;
|
||||
--border: #2b3340;
|
||||
--border-strong: #38424f;
|
||||
--text: #e8edf2;
|
||||
--muted: #8c97a4;
|
||||
--accent: #2aa4df; /* DocuWare-Blau */
|
||||
--accent-hover: #3cb6f0;
|
||||
--accent-weak: rgba(42,164,223,.14);
|
||||
--ok: #46c98a;
|
||||
--err: #ec6b75;
|
||||
--radius: 10px;
|
||||
--shadow: 0 1px 0 rgba(255,255,255,.02) inset, 0 8px 24px rgba(0,0,0,.28);
|
||||
font-synthesis: none;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html, body { background: var(--bg); }
|
||||
body {
|
||||
font: 14px/1.55 "Segoe UI", "Helvetica Neue", system-ui, sans-serif;
|
||||
color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0 16px 120px;
|
||||
background-image: var(--bg-grad);
|
||||
background-repeat: no-repeat;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
.wrap { max-width: 620px; margin: 0 auto; }
|
||||
|
||||
/* Kopfzeile */
|
||||
header.app {
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
padding: 26px 2px 18px;
|
||||
}
|
||||
.logo {
|
||||
width: 34px; height: 34px; border-radius: 8px; flex: none;
|
||||
background: linear-gradient(135deg, var(--accent), #1c6fae);
|
||||
display: grid; place-items: center;
|
||||
box-shadow: 0 4px 14px rgba(42,164,223,.35);
|
||||
}
|
||||
.logo svg { width: 20px; height: 20px; }
|
||||
header.app h1 { font-size: 18px; font-weight: 650; margin: 0; letter-spacing: .2px; }
|
||||
header.app .sub { font-size: 12px; color: var(--muted); margin-top: 1px; }
|
||||
|
||||
/* Karten / Abschnitte */
|
||||
section.card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
padding: 18px 20px 20px;
|
||||
margin: 14px 0;
|
||||
}
|
||||
.card-head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 6px; }
|
||||
.card-head h2 {
|
||||
font-size: 13px; font-weight: 650; text-transform: uppercase;
|
||||
letter-spacing: .8px; color: var(--accent); margin: 0;
|
||||
}
|
||||
.card-head .num {
|
||||
font-size: 11px; color: var(--muted); border: 1px solid var(--border-strong);
|
||||
border-radius: 999px; padding: 1px 8px; line-height: 1.5;
|
||||
}
|
||||
|
||||
label { display: block; margin: 14px 0 5px; font-weight: 550; font-size: 13px; }
|
||||
input[type="text"], input[type="password"], input[type="url"], select {
|
||||
width: 100%; padding: 9px 11px; color: var(--text);
|
||||
background: var(--surface-2); border: 1px solid var(--border-strong);
|
||||
border-radius: 8px; font: inherit; outline: none;
|
||||
transition: border-color .15s, box-shadow .15s, background .15s;
|
||||
}
|
||||
select { appearance: none;
|
||||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2 4l4 4 4-4' fill='none' stroke='%238c97a4' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
|
||||
background-repeat: no-repeat; background-position: right 11px center; padding-right: 30px;
|
||||
}
|
||||
input:focus, select:focus {
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 0 0 3px var(--accent-weak);
|
||||
}
|
||||
input::placeholder { color: #5f6b78; }
|
||||
code { background: var(--surface-2); border: 1px solid var(--border); border-radius: 4px;
|
||||
padding: 1px 5px; font-size: 12px; color: #b7c2cd; }
|
||||
.hint { font-size: 12px; color: var(--muted); margin-top: 5px; }
|
||||
|
||||
.check { display: flex; align-items: center; gap: 9px; margin: 9px 0; font-weight: 450; }
|
||||
.check label { margin: 0; font-weight: 450; font-size: 13px; }
|
||||
input[type="checkbox"], input[type="radio"] { width: 16px; height: 16px; accent-color: var(--accent); flex: none; }
|
||||
|
||||
/* Mapping-Tabelle */
|
||||
.map-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 12px; }
|
||||
.map-toolbar .grow { flex: 1; min-width: 180px; }
|
||||
table.map { width: 100%; border-collapse: separate; border-spacing: 0 6px; }
|
||||
table.map th { text-align: left; font-size: 11px; letter-spacing: .4px; text-transform: uppercase;
|
||||
color: var(--muted); font-weight: 600; padding: 0 6px 2px; }
|
||||
table.map td { padding: 0 6px; vertical-align: middle; }
|
||||
table.map input, table.map select { padding: 7px 9px; }
|
||||
table.map td.del { width: 40px; }
|
||||
.icon-btn {
|
||||
width: 30px; height: 30px; padding: 0; border-radius: 7px; cursor: pointer;
|
||||
background: var(--surface-2); border: 1px solid var(--border-strong); color: var(--muted);
|
||||
font-size: 14px; line-height: 1; transition: .15s;
|
||||
}
|
||||
.icon-btn:hover { color: var(--err); border-color: var(--err); }
|
||||
|
||||
/* Buttons */
|
||||
button { font: inherit; cursor: pointer; border-radius: 8px; }
|
||||
button.primary {
|
||||
padding: 9px 18px; border: 0; font-weight: 650; color: #04222f;
|
||||
background: linear-gradient(180deg, var(--accent-hover), var(--accent));
|
||||
box-shadow: 0 4px 14px rgba(42,164,223,.3);
|
||||
}
|
||||
button.primary:hover { filter: brightness(1.06); }
|
||||
button.ghost {
|
||||
padding: 8px 15px; font-weight: 550; color: var(--text);
|
||||
background: var(--surface-2); border: 1px solid var(--border-strong);
|
||||
}
|
||||
button.ghost:hover { border-color: var(--accent); color: var(--accent); }
|
||||
button:disabled { opacity: .5; cursor: default; }
|
||||
|
||||
/* Sticky Aktionsleiste */
|
||||
.actionbar {
|
||||
position: fixed; left: 0; right: 0; bottom: 0; z-index: 5;
|
||||
background: rgba(17,21,27,.82); backdrop-filter: blur(8px);
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
.actionbar .inner { max-width: 620px; margin: 0 auto; padding: 12px 16px;
|
||||
display: flex; align-items: center; gap: 12px; }
|
||||
#status { font-size: 13px; min-height: 18px; }
|
||||
.ok { color: #15803d; } .err { color: #b91c1c; }
|
||||
.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; }
|
||||
.ok { color: var(--ok); } .err { color: var(--err); }
|
||||
.spacer { flex: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>DocuWare Ablage – Einstellungen</h1>
|
||||
<div class="wrap">
|
||||
<header class="app">
|
||||
<span class="logo" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" fill="none"><path d="M4 5.5A1.5 1.5 0 0 1 5.5 4H13l3 3h2.5A1.5 1.5 0 0 1 20 8.5v10A1.5 1.5 0 0 1 18.5 20h-13A1.5 1.5 0 0 1 4 18.5v-13Z" fill="#fff" opacity=".95"/><path d="M9 13.5h6M12 11v5" stroke="#1c6fae" stroke-width="1.6" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<div>
|
||||
<h1>DocuWare Ablage</h1>
|
||||
<div class="sub">Einstellungen</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<legend>Verbindung</legend>
|
||||
<section class="card">
|
||||
<div class="card-head"><span class="num">1</span><h2>Verbindung</h2></div>
|
||||
<label for="serverUrl">Server-URL</label>
|
||||
<input type="url" id="serverUrl" placeholder="https://docuware.example.com" />
|
||||
<div class="hint">Basis-URL ohne <code>/DocuWare/Platform</code>.</div>
|
||||
@ -45,68 +166,57 @@
|
||||
<input type="password" id="password" autocomplete="off" />
|
||||
<div class="hint">Wird <strong>nicht gespeichert</strong> – nur zum Anmelden/Testen für
|
||||
diese Sitzung. Im Ablage-Fenster wird es 1× pro Sitzung abgefragt.</div>
|
||||
</fieldset>
|
||||
</section>
|
||||
|
||||
<fieldset>
|
||||
<legend>Standardwerte</legend>
|
||||
<section class="card">
|
||||
<div class="card-head"><span class="num">2</span><h2>Standardwerte</h2></div>
|
||||
<label for="defaultCabinet">Standard-Ziel (Archiv oder Briefkorb)</label>
|
||||
<select id="defaultCabinet" style="width:100%;padding:7px;border:1px solid #ccc;border-radius:6px;">
|
||||
<option value="">— keiner —</option>
|
||||
</select>
|
||||
<select id="defaultCabinet"><option value="">— keiner —</option></select>
|
||||
<div class="hint">Liste wird nach erfolgreichem Verbindungstest gefüllt.</div>
|
||||
|
||||
<label>Standard-Format der E-Mail</label>
|
||||
<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="radio" name="mailFormat" id="fmtPdf" value="pdf" /> <label for="fmtPdf" style="margin:0">PDF</label></div>
|
||||
<div class="check"><input type="radio" name="mailFormat" id="fmtEml" value="eml" /> <label for="fmtEml">Original (.eml)</label></div>
|
||||
<div class="check"><input type="radio" name="mailFormat" id="fmtPdf" value="pdf" /> <label for="fmtPdf">PDF</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>
|
||||
</fieldset>
|
||||
<div class="check" style="margin-top:12px"><input type="checkbox" id="storeAttachments" /> <label for="storeAttachments">Anhänge mit ablegen</label></div>
|
||||
<div class="check"><input type="checkbox" id="tagOnSuccess" /> <label for="tagOnSuccess">Mail nach Ablage als „DocuWare" markieren</label></div>
|
||||
</section>
|
||||
|
||||
<div class="row">
|
||||
<button id="save">Speichern</button>
|
||||
<button id="test" class="secondary">Verbindung testen</button>
|
||||
<span id="status"></span>
|
||||
<section class="card">
|
||||
<div class="card-head"><span class="num">3</span><h2>Feld-Zuordnung</h2></div>
|
||||
<div class="hint" style="margin-bottom:10px">Welches DocuWare-Indexfeld wird aus welchem
|
||||
Mail-Attribut vorbefüllt? Gilt für alle Aktenschränke. Leere/entfernte Zeilen befüllen
|
||||
nichts vor.</div>
|
||||
|
||||
<div class="map-toolbar">
|
||||
<div class="grow">
|
||||
<select id="mapCabinet"><option value="">Feldnamen aus Archiv vorschlagen …</option></select>
|
||||
</div>
|
||||
<span id="mapFieldStatus" class="hint" style="margin:0"></span>
|
||||
</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>
|
||||
<datalist id="fieldNames"></datalist>
|
||||
|
||||
<fieldset>
|
||||
<legend>Einstellungen sichern</legend>
|
||||
<div class="hint">Exportiert/importiert die Einstellungen (Server, Organisation,
|
||||
Benutzer, Standardwerte) als Datei. <strong>Das Passwort ist nicht enthalten</strong>
|
||||
und muss nach einer Neuinstallation einmal neu eingegeben werden.</div>
|
||||
<div class="row">
|
||||
<button id="exportBtn" class="secondary">Exportieren</button>
|
||||
<button id="importBtn" class="secondary">Importieren</button>
|
||||
<input type="file" id="importFile" accept="application/json,.json" style="display:none" />
|
||||
<div class="map-toolbar" style="margin-top:10px">
|
||||
<button id="mapAdd" class="ghost" type="button">+ Zeile</button>
|
||||
<button id="mapReset" class="ghost" type="button">Auf Standard zurücksetzen</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Diagnose (für Entwicklung)</legend>
|
||||
<div class="hint">Analysiert den Store-Dialog des oben gewählten Standard-Ziels und
|
||||
zeigt die Rohstruktur (Felder, Auswahllisten, Defaults). Inhalt bitte kopieren und
|
||||
an den Entwickler geben.</div>
|
||||
<div class="row">
|
||||
<button id="diagBtn" class="secondary">Store-Dialog analysieren</button>
|
||||
<div class="actionbar">
|
||||
<div class="inner">
|
||||
<button id="save" class="primary">Speichern</button>
|
||||
<button id="test" class="ghost">Verbindung testen</button>
|
||||
<span class="spacer"></span>
|
||||
<span id="status"></span>
|
||||
</div>
|
||||
</div>
|
||||
<textarea id="diag" readonly style="width:100%;height:240px;margin-top:10px;font:12px/1.4 monospace;border:1px solid #ccc;border-radius:6px;padding:8px;display:none;"></textarea>
|
||||
</fieldset>
|
||||
|
||||
<script src="../lib/store.js"></script>
|
||||
<script src="../lib/auth.js"></script>
|
||||
|
||||
@ -32,6 +32,53 @@ function getMailFormat() {
|
||||
return el ? el.value : "eml";
|
||||
}
|
||||
|
||||
function fillCabinets(cabinets, selectedId) {
|
||||
// Standard-Ziel (Archive + Briefkörbe)
|
||||
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));
|
||||
|
||||
// Mapping-Helfer: nur Archive (Briefkörbe haben keine Indexfelder).
|
||||
const mc = $("mapCabinet");
|
||||
const keep = mc.value;
|
||||
mc.innerHTML = '<option value="">Feldnamen aus Archiv vorschlagen …</option>';
|
||||
cabinets.filter((c) => !c.isBasket).forEach((c) => {
|
||||
const o = document.createElement("option");
|
||||
o.value = c.id;
|
||||
o.textContent = c.name;
|
||||
mc.appendChild(o);
|
||||
});
|
||||
if (keep) mc.value = keep;
|
||||
}
|
||||
|
||||
// Besorgt einen Sitzungs-Token: vorhandenen vom Broker nutzen, sonst mit dem
|
||||
// (transienten) Passwortfeld anmelden. Liefert false, wenn kein Passwort da ist.
|
||||
async function ensureToken() {
|
||||
const st = await browser.runtime.sendMessage({ type: "auth:status" });
|
||||
if (st && st.hasToken && st.token) { Auth.setToken(st.token); return true; }
|
||||
const pw = $("password").value;
|
||||
if (!pw) return false;
|
||||
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
|
||||
return true;
|
||||
}
|
||||
|
||||
// --- Feld-Mapping-Editor ---------------------------------------------------
|
||||
|
||||
function addMapRow(field = "", token = "") {
|
||||
@ -40,6 +87,7 @@ function addMapRow(field = "", token = "") {
|
||||
const inp = document.createElement("input");
|
||||
inp.type = "text"; inp.className = "map-field"; inp.value = field;
|
||||
inp.placeholder = "EML_SUBJECT";
|
||||
inp.setAttribute("list", "fieldNames"); // Vorschläge aus gewähltem Archiv
|
||||
const tdF = document.createElement("td"); tdF.appendChild(inp);
|
||||
|
||||
const sel = document.createElement("select"); sel.className = "map-token";
|
||||
@ -54,7 +102,7 @@ function addMapRow(field = "", token = "") {
|
||||
const tdT = document.createElement("td"); tdT.appendChild(sel);
|
||||
|
||||
const del = document.createElement("button");
|
||||
del.type = "button"; del.className = "secondary"; del.textContent = "✕";
|
||||
del.type = "button"; del.className = "icon-btn"; del.textContent = "✕"; del.title = "Zeile entfernen";
|
||||
del.addEventListener("click", () => tr.remove());
|
||||
const tdX = document.createElement("td"); tdX.className = "del"; tdX.appendChild(del);
|
||||
|
||||
@ -77,26 +125,6 @@ function collectMapping() {
|
||||
return map;
|
||||
}
|
||||
|
||||
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()));
|
||||
@ -107,8 +135,7 @@ function collect() {
|
||||
return partial;
|
||||
}
|
||||
|
||||
$("mapAdd").addEventListener("click", () => addMapRow());
|
||||
$("mapReset").addEventListener("click", () => loadMapping(DEFAULT_FIELD_MAP));
|
||||
// --- Events ----------------------------------------------------------------
|
||||
|
||||
$("save").addEventListener("click", async () => {
|
||||
await Settings.set(collect());
|
||||
@ -116,17 +143,11 @@ $("save").addEventListener("click", async () => {
|
||||
});
|
||||
|
||||
$("test").addEventListener("click", async () => {
|
||||
const pw = $("password").value;
|
||||
if (!pw) { setStatus("Bitte Passwort eingeben.", "err"); return; }
|
||||
setStatus("Verbinde …");
|
||||
try {
|
||||
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
|
||||
const ok = await ensureToken();
|
||||
if (!ok) { setStatus("Bitte Passwort eingeben.", "err"); return; }
|
||||
const cabinets = await DocuWare.listCabinets(s);
|
||||
await browser.storage.local.set({ cabinets });
|
||||
fillCabinets(cabinets, s.defaultCabinetId);
|
||||
@ -138,65 +159,31 @@ $("test").addEventListener("click", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
$("exportBtn").addEventListener("click", async () => {
|
||||
$("mapAdd").addEventListener("click", () => addMapRow());
|
||||
$("mapReset").addEventListener("click", () => loadMapping(DEFAULT_FIELD_MAP));
|
||||
|
||||
// Archiv wählen -> dessen Indexfelder als Vorschläge (datalist) für alle Feldnamen.
|
||||
$("mapCabinet").addEventListener("change", async () => {
|
||||
const id = $("mapCabinet").value;
|
||||
const dl = $("fieldNames");
|
||||
const st = $("mapFieldStatus");
|
||||
if (!id) { dl.innerHTML = ""; st.textContent = ""; return; }
|
||||
st.textContent = "Lade Felder …";
|
||||
try {
|
||||
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());
|
||||
// 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 = "";
|
||||
}
|
||||
const dump = await DocuWare.diagnoseStoreDialog(s, cabinetId);
|
||||
out.value = JSON.stringify(dump, null, 2);
|
||||
const ok = await ensureToken();
|
||||
if (!ok) { st.textContent = "Erst „Verbindung testen“ (Passwort nötig)."; return; }
|
||||
const names = (await DocuWare.cabinetFieldNames(s, id))
|
||||
.filter((n) => n && !/^DW[A-Z]/.test(n)); // DW*-Systemfelder ausblenden
|
||||
dl.innerHTML = "";
|
||||
names.sort().forEach((n) => {
|
||||
const o = document.createElement("option");
|
||||
o.value = n;
|
||||
dl.appendChild(o);
|
||||
});
|
||||
st.textContent = `${names.length} Felder als Vorschlag geladen.`;
|
||||
} catch (e) {
|
||||
out.value = `Fehler: ${e.message}`;
|
||||
st.textContent = `Fehler: ${e.message}`;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -17,6 +17,10 @@
|
||||
{
|
||||
"version": "0.10.3",
|
||||
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.10.3/docuware-ablage-0.10.3.xpi"
|
||||
},
|
||||
{
|
||||
"version": "0.10.4",
|
||||
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.10.4/docuware-ablage-0.10.4.xpi"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user