feat: free-text timestamps instead of datetime pickers

Users wanted to type things like "unbekannt" or comments for the date
fields. Start/End are now plain text inputs (max 120 chars) and are
stored/displayed verbatim - no Date parsing, no formatting. Existing
records that contain ISO strings keep working: they render exactly as
stored and refill the edit form unchanged. Also removes a duplicated
block in setup() that had slipped in earlier (double reload/flash).

Verified: node --check, no datetime-local/Date-parsing remnants,
crypto roundtrip with free-text and legacy ISO timestamps, pytest 3/3.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
2026-10-11 00:58:19 +02:00
parent 8d488f44ff
commit c82de902a8
2 changed files with 17 additions and 19 deletions
+11 -15
View File
@@ -91,10 +91,10 @@ async function api(path, opts = {}) {
// ---------- rendering ----------
function iso(ts) {
if (ts === null || ts === "") return "–";
const d = new Date(ts);
return isNaN(d) ? String(ts) : d.toLocaleString();
// Timestamps are free text now ("unknown", "Sommer 2025", …). Display
// them verbatim; nothing to parse or format.
function showTs(value) {
return (value === null || value === undefined || value === "") ? "–" : String(value);
}
function renderRow(record, payload) {
@@ -102,8 +102,8 @@ function renderRow(record, payload) {
const cells = [
payload.personA,
payload.personB,
iso(payload.tsStart),
iso(payload.tsEnd),
showTs(payload.tsStart),
showTs(payload.tsEnd),
payload.action,
];
for (const text of cells) {
@@ -162,8 +162,8 @@ function openEditor(record, payload) {
$("#editor-title").textContent = "Datensatz bearbeiten";
$("#f-persona").value = payload.personA ?? "";
$("#f-personb").value = payload.personB ?? "";
$("#f-tsstart").value = payload.tsStart ? new Date(payload.tsStart).toISOString().slice(0, 16) : "";
$("#f-tsend").value = payload.tsEnd ? new Date(payload.tsEnd).toISOString().slice(0, 16) : "";
$("#f-tsstart").value = payload.tsStart ?? "";
$("#f-tsend").value = payload.tsEnd ?? "";
$("#f-action").value = payload.action ?? "";
$("#editor-backdrop").hidden = false;
}
@@ -184,9 +184,9 @@ function closeEditor() {
}
function tsOrNull(inputValue) {
if (!inputValue) return null;
const d = new Date(inputValue);
return isNaN(d) ? null : d.toISOString();
// Free-text field: trim to null or the plain string.
const v = inputValue.trim();
return v === "" ? null : v;
}
// ---------- record operations ----------
@@ -275,10 +275,6 @@ async function setup(ev) {
resetSession();
return;
}
$("#passphrase").value = "";
$("#setup").hidden = true;
$("#app").hidden = false;
await reload();
$("#setup-pass1").value = "";
$("#setup-pass2").value = "";
$("#setup").hidden = true;