Compare commits
2 Commits
d9ec2537e2
...
e314a6af98
| Author | SHA1 | Date | |
|---|---|---|---|
| e314a6af98 | |||
| 03ff3795b2 |
@ -37,7 +37,10 @@ const TOKEN_FN = {
|
|||||||
bcc: (m) => m.bcc,
|
bcc: (m) => m.bcc,
|
||||||
subject: (m) => m.subject,
|
subject: (m) => m.subject,
|
||||||
body: (m) => m.bodyText,
|
body: (m) => m.bodyText,
|
||||||
date: (m) => m.date,
|
// Nur der Kalendertag: auf lokale Mitternacht gesetzt, damit „Datum" auch in
|
||||||
|
// einem DateTime- oder Textfeld keine Uhrzeit trägt (gleiche Konvention wie
|
||||||
|
// archiveDate). Den echten Zeitpunkt liefert dateTime.
|
||||||
|
date: (m) => dayOnly(m.date),
|
||||||
direction: (m) => m.direction,
|
direction: (m) => m.direction,
|
||||||
size: (m) => m.sizeBytes,
|
size: (m) => m.sizeBytes,
|
||||||
account: (m) => m.account,
|
account: (m) => m.account,
|
||||||
@ -49,7 +52,7 @@ const TOKEN_FN = {
|
|||||||
time: (m) => fmtTime(m.date),
|
time: (m) => fmtTime(m.date),
|
||||||
// archiveDate ist bewusst auf Mitternacht gesetzt: so bleibt es „nur Datum",
|
// archiveDate ist bewusst auf Mitternacht gesetzt: so bleibt es „nur Datum",
|
||||||
// auch wenn es auf ein DateTime-Feld gemappt wird. archiveDateTime trägt die Uhrzeit.
|
// auch wenn es auf ein DateTime-Feld gemappt wird. archiveDateTime trägt die Uhrzeit.
|
||||||
archiveDate: () => { const n = new Date(); return new Date(n.getFullYear(), n.getMonth(), n.getDate()); },
|
archiveDate: () => dayOnly(new Date()),
|
||||||
archiveDateTime: () => new Date(),
|
archiveDateTime: () => new Date(),
|
||||||
|
|
||||||
// Dokumentbezogen
|
// Dokumentbezogen
|
||||||
@ -500,6 +503,8 @@ function buildInput(f) {
|
|||||||
// DateTime-Feld: Tag UND Uhrzeit erfassbar (vor dem reinen date-Zweig prüfen).
|
// DateTime-Feld: Tag UND Uhrzeit erfassbar (vor dem reinen date-Zweig prüfen).
|
||||||
el = document.createElement("input");
|
el = document.createElement("input");
|
||||||
el.type = "datetime-local";
|
el.type = "datetime-local";
|
||||||
|
// Ohne step="1" kennt das Control nur Minuten und schneidet die Sekunden ab.
|
||||||
|
el.step = "1";
|
||||||
} else if (t.includes("date")) {
|
} else if (t.includes("date")) {
|
||||||
el = document.createElement("input");
|
el = document.createElement("input");
|
||||||
el.type = "date";
|
el.type = "date";
|
||||||
@ -564,7 +569,10 @@ function setFieldValue(name, f, val) {
|
|||||||
}
|
}
|
||||||
el.value = String(val);
|
el.value = String(val);
|
||||||
} else {
|
} else {
|
||||||
el.value = val instanceof Date ? toDateInput(val) : String(val);
|
// Textfeld: Datum lesbar ausschreiben ("04.08.2026 16:28:51"). Früher lief
|
||||||
|
// hier toDateInput – das warf die Uhrzeit weg, obwohl ein Textfeld sie
|
||||||
|
// problemlos trägt (genau der Fall „Datum + Uhrzeit" ohne Uhrzeit).
|
||||||
|
el.value = val instanceof Date ? DocuWare.dateToText(val) : String(val);
|
||||||
}
|
}
|
||||||
wrap.classList.add("prefilled");
|
wrap.classList.add("prefilled");
|
||||||
}
|
}
|
||||||
@ -859,10 +867,21 @@ const toDateInput = (d) => {
|
|||||||
// Lokal als YYYY-MM-DDTHH:MM für <input type="datetime-local">.
|
// Lokal als YYYY-MM-DDTHH:MM für <input type="datetime-local">.
|
||||||
const toDateTimeInput = (d) => `${toDateInput(d)}T${fmtTime(d)}`;
|
const toDateTimeInput = (d) => `${toDateInput(d)}T${fmtTime(d)}`;
|
||||||
// Uhrzeit HH:MM lokal (auch als eigenständiger Text-Token nutzbar).
|
// Uhrzeit HH:MM lokal (auch als eigenständiger Text-Token nutzbar).
|
||||||
|
// Kalendertag ohne Uhrzeit (lokale Mitternacht). Funktionsdeklaration, damit
|
||||||
|
// TOKEN_FN sie oben im Modul schon verwenden kann.
|
||||||
|
function dayOnly(d) {
|
||||||
|
const dt = d instanceof Date ? d : new Date(d);
|
||||||
|
if (isNaN(dt)) return dt;
|
||||||
|
return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uhrzeit inkl. Sekunden ("16:28:51"). Die Sekunden braucht auch
|
||||||
|
// toDateTimeInput – ein datetime-local mit step="1" nimmt sie entgegen.
|
||||||
function fmtTime(d) {
|
function fmtTime(d) {
|
||||||
const dt = d instanceof Date ? d : new Date(d);
|
const dt = d instanceof Date ? d : new Date(d);
|
||||||
if (isNaN(dt)) return "";
|
if (isNaN(dt)) return "";
|
||||||
return `${String(dt.getHours()).padStart(2, "0")}:${String(dt.getMinutes()).padStart(2, "0")}`;
|
const p = (n) => String(n).padStart(2, "0");
|
||||||
|
return `${p(dt.getHours())}:${p(dt.getMinutes())}:${p(dt.getSeconds())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dateiname, den die E-Mail selbst beim Upload bekäme – für die Vorschau im
|
// Dateiname, den die E-Mail selbst beim Upload bekäme – für die Vorschau im
|
||||||
|
|||||||
@ -427,22 +427,47 @@ const DocuWare = {
|
|||||||
return out;
|
return out;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date-Objekt als deutscher Text: "04.08.2026 16:28:51". Ohne Uhrzeit (exakt
|
||||||
|
* Mitternacht) nur "04.08.2026" – so tragen reine Datums-Tokens kein
|
||||||
|
* künstliches " 00:00:00". Gebraucht, sobald ein Datum in einem TEXT-Feld
|
||||||
|
* landet: String(dateObjekt) lieferte sonst die JS-Standardausgabe
|
||||||
|
* ("Mon Aug 04 2026 16:28:51 GMT+0200 (Mitteleuropäische Sommerzeit)").
|
||||||
|
* Bewusst lokale Zeit ohne UTC-Umrechnung – der Text soll zeigen, was der
|
||||||
|
* Nutzer in Thunderbird sieht.
|
||||||
|
*/
|
||||||
|
dateToText(value) {
|
||||||
|
const d = value instanceof Date ? value : new Date(value);
|
||||||
|
if (isNaN(d)) return String(value);
|
||||||
|
const p = (n) => String(n).padStart(2, "0");
|
||||||
|
const day = `${p(d.getDate())}.${p(d.getMonth() + 1)}.${d.getFullYear()}`;
|
||||||
|
if (!d.getHours() && !d.getMinutes() && !d.getSeconds()) return day;
|
||||||
|
return `${day} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
||||||
|
},
|
||||||
|
|
||||||
_field(name, value, type) {
|
_field(name, value, type) {
|
||||||
const t = (type || "Text").toLowerCase();
|
const t = (type || "Text").toLowerCase();
|
||||||
|
// Datum in einem Text-/Memo-Feld lesbar machen (s. dateToText).
|
||||||
|
const asText = (v) => (v instanceof Date ? this.dateToText(v) : String(v));
|
||||||
// WICHTIG: "datetime" zuerst prüfen – "DateTime".includes("date") ist true und
|
// WICHTIG: "datetime" zuerst prüfen – "DateTime".includes("date") ist true und
|
||||||
// würde sonst die Uhrzeit auf Mitternacht normalisieren (Datenverlust).
|
// würde sonst die Uhrzeit auf Mitternacht normalisieren (Datenverlust).
|
||||||
if (t.includes("datetime")) {
|
if (t.includes("datetime")) {
|
||||||
const d = value instanceof Date ? value : new Date(value);
|
const d = value instanceof Date ? value : new Date(value);
|
||||||
if (isNaN(d)) return { FieldName: name, Item: String(value), ItemElementName: "DateTime" };
|
if (isNaN(d)) return { FieldName: name, Item: String(value), ItemElementName: "DateTime" };
|
||||||
// Mit Uhrzeit: echter Zeitpunkt, daher unverändert als ISO (UTC) senden.
|
// LOKALE Wanduhrzeit ohne Zeitzonen-Suffix ("2026-08-04T16:28:51").
|
||||||
//
|
//
|
||||||
// UNGEPRÜFT gegen den Server: ob DocuWare das "Z" auswertet (dann stimmt die
|
// Vorher ging hier d.toISOString() raus, also UTC mit "Z". Ob DocuWare das
|
||||||
// Uhrzeit) oder die ISO-Zeichenkette als lokale Wanduhrzeit übernimmt (dann
|
// "Z" in Serverzeit zurückrechnet, hängt vom Server ab (Cloud-Instanzen
|
||||||
// erscheint sie um den UTC-Versatz verschoben, in Wien -2 h). Reine Date-Felder
|
// laufen meist auf UTC) – die Uhrzeit erschien dann um den Versatz
|
||||||
// sind davon nicht betroffen, die werden auf UTC-Mitternacht normalisiert.
|
// verschoben, in Wien -2 h. Schlimmer beim Kalendertag: lokale Mitternacht
|
||||||
// Falls im Testarchiv verschoben: hier stattdessen die lokale Wanduhrzeit ohne
|
// wird als UTC zum VORTAG 22:00.
|
||||||
// Zeitzone senden, also `${toLocalIso(d)}` statt d.toISOString().
|
// Ohne Suffix ist der Wert eindeutig: der Server übernimmt ihn so, wie der
|
||||||
return { FieldName: name, Item: d.toISOString(), ItemElementName: "DateTime" };
|
// Nutzer die Zeit in Thunderbird sieht. Reine Date-Felder bleiben unberührt.
|
||||||
|
const p = (n) => String(n).padStart(2, "0");
|
||||||
|
const iso =
|
||||||
|
`${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}` +
|
||||||
|
`T${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
||||||
|
return { FieldName: name, Item: iso, ItemElementName: "DateTime" };
|
||||||
}
|
}
|
||||||
if (t.includes("date")) {
|
if (t.includes("date")) {
|
||||||
// DocuWare erwartet /Date(ms)/ oder ISO; ISO funktioniert bei Platform.
|
// DocuWare erwartet /Date(ms)/ oder ISO; ISO funktioniert bei Platform.
|
||||||
@ -461,13 +486,13 @@ const DocuWare = {
|
|||||||
return { FieldName: name, Item: Number(value), ItemElementName: "Int" };
|
return { FieldName: name, Item: Number(value), ItemElementName: "Int" };
|
||||||
}
|
}
|
||||||
if (t.includes("memo")) {
|
if (t.includes("memo")) {
|
||||||
return { FieldName: name, Item: String(value), ItemElementName: "Memo" };
|
return { FieldName: name, Item: asText(value), ItemElementName: "Memo" };
|
||||||
}
|
}
|
||||||
if (t.includes("keyword")) {
|
if (t.includes("keyword")) {
|
||||||
const arr = Array.isArray(value) ? value : [String(value)];
|
const arr = Array.isArray(value) ? value : [asText(value)];
|
||||||
return { FieldName: name, Item: arr, ItemElementName: "Keywords" };
|
return { FieldName: name, Item: arr, ItemElementName: "Keywords" };
|
||||||
}
|
}
|
||||||
return { FieldName: name, Item: String(value), ItemElementName: "String" };
|
return { FieldName: name, Item: asText(value), ItemElementName: "String" };
|
||||||
},
|
},
|
||||||
|
|
||||||
_isSystemField(dbName) {
|
_isSystemField(dbName) {
|
||||||
|
|||||||
@ -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.12.2",
|
"version": "0.12.3",
|
||||||
"author": "l.lingler",
|
"author": "l.lingler",
|
||||||
"applications": {
|
"applications": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
{
|
{
|
||||||
"version": "0.12.2",
|
"version": "0.12.2",
|
||||||
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.12.2/docuware-ablage-0.12.2.xpi"
|
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.12.2/docuware-ablage-0.12.2.xpi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.12.3",
|
||||||
|
"update_link": "https://sylyx.xyz/sylyx/thunderbird2docuware/releases/download/v0.12.3/docuware-ablage-0.12.3.xpi"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user