Öffnungszeiten: Speichern zeichnet nur neu, was sich geändert hat

Ungespeicherte Eingaben in anderen Formularen bleiben stehen: nach dem Speichern
wird nur die Plankarte, die Planliste (mit den Eingaben der übrigen Karten),
Feiertage oder Ausnahmen neu gezeichnet, „Nein, danke“ entfernt nur die Frage.
Während des Speicherns sind auch die Eingabefelder gesperrt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-05 06:18:21 +00:00
1 parent 04a3525f79
commit f01ed15247
6 files changed
+409 -58

No files matched your search

+26 -9
View File
@@ -1,7 +1,9 @@
/* Oeffnungszeiten live im Kundenbereich: Editor, Bereiche 2 „Feiertage“ und 3 „Ausnahmen“ (Spec 3.4). Jeder Bereich ist eine Funktion
(t) => Element; t = { ctx, sp, zeichne, wurzel } kommt aus zeiten-editor.js (sp = Speicher des Editors, zeichne() zeichnet alle Abschnitte
neu). Jede Aenderung speichert die ganzen Daten (zeiten-speichern.js). Abgeschaltete Funktion (ctx.nurLesen): dieselben Felder gesperrt,
(t) => Element; t = { ctx, sp, zeichne, wurzel } kommt aus zeiten-editor.js (sp = Speicher des Editors, zeichne([…]) zeichnet einzelne
Abschnitte neu). Jede Aenderung speichert die ganzen Daten (zeiten-speichern.js). Abgeschaltete Funktion (ctx.nurLesen): dieselben Felder gesperrt,
ohne Knoepfe zum Aendern. Stil: termine-team-ausnahmen.js (Abwesenheiten, Feiertage, Sonderoeffnungen).
Nach einem Speichern wird nur neu gezeichnet, was sich geaendert hat (nachSpeichern mit neuZeichnen): ungespeicherte Eingaben in den anderen Abschnitten
und Formularen bleiben stehen.
Feiertage: Bundesland (ein eigenes Speichern; die Liste kommt vom Server und gilt danach fuer das neue Land) und die Feiertage der naechsten
12 Monate (ctx.stand.feiertage). Gespeichert werden nur Abweichungen von der Vorgabe (daten.feiertage): ein gesetzlicher Feiertag ist
„geschlossen“, ein „bitte prüfen“-Tag (Heiligabend, Silvester, nur ortsuebliche Feiertage) folgt dem Wochenplan.
@@ -22,6 +24,17 @@ const zeitraum = (a) => (a.von === a.bis ? datumKurz(a.von) : `${datumKurz(a.von
const FEIERTAG_WAHL = Object.freeze([['', 'geschlossen (Vorgabe)'], ...MODUS_WAHL.filter(([wert]) => wert !== 'zu')])
const PRUEFEN_WAHL = Object.freeze([['', 'wie im Wochenplan (Vorgabe)'], ...MODUS_WAHL])
// Pro Abschnitt „Feiertage“ die Tageseingaben je Datum: nach einem Wechsel des Bundeslands bekommen Tage, die es auch im neuen Land gibt, ihre Eingaben zurueck
const ZEILEN = new WeakMap()
/** Wird nach dem Neuzeichnen des Abschnitts (Bundesland gewechselt) mit dem alten und dem neuen Abschnitt gerufen: ungespeicherte Eingaben wandern mit. */
export function feiertageUebernehmen(alt, neu) {
const frueher = ZEILEN.get(alt)
const jetzt = ZEILEN.get(neu)
if (!frueher || !jetzt) return
for (const [tag, eingabe] of jetzt) if (frueher.has(tag)) eingabe.stelleWieder(frueher.get(tag).merke())
}
export function feiertage(t) {
const { ctx, sp } = t
const daten = ctx.stand.daten
@@ -39,7 +52,8 @@ export function feiertage(t) {
const ok = await sp.speichere((entwurf) => { entwurf.land = land.value }, { container: landForm })
if (!ok || !sp.nochHier()) return
const name = BUNDESLAENDER.find(([key]) => key === land.value)?.[1] ?? land.value
nachSpeichern(t, `Bundesland gespeichert: ${name}. Die Feiertage unten gelten jetzt dafür.`, 'form[aria-label="Bundesland"] button[type="submit"]')
// die Liste darunter gilt jetzt fuer das neue Land: nur dieser Abschnitt wird neu gezeichnet
nachSpeichern(t, `Bundesland gespeichert: ${name}. Die Feiertage unten gelten jetzt dafür.`, 'form[aria-label="Bundesland"] button[type="submit"]', () => t.zeichne(['feiertage']))
})
const zeilen = ctx.stand.feiertage.map((f) => {
@@ -92,14 +106,17 @@ export function feiertage(t) {
return true
}, { container: form })
if (!ok || !sp.nochHier()) return
nachSpeichern(t, 'Feiertage gespeichert.', 'form[aria-label="Feiertage"] button[type="submit"]')
// die Liste zeigt schon, was gespeichert ist; nichts neu zeichnen (das Bundesland darueber koennte noch ungespeichert gewaehlt sein)
nachSpeichern(t, 'Feiertage gespeichert.', 'form[aria-label="Feiertage"] button[type="submit"]', () => {})
})
return abschnitt('Feiertage',
const el = abschnitt('Feiertage',
'An gesetzlichen Feiertagen ist deine Website als „geschlossen“ eingetragen. Willst du an einem Feiertag öffnen, wähle eigene Zeiten. „Bitte prüfen“ sind Tage, die nicht überall oder nicht für jeden frei sind (zum Beispiel Heiligabend, Silvester oder Fronleichnam): Hier gilt als Vorgabe dein Wochenplan.',
landForm,
h('p', { class: 'tm-hinweis' }, 'Gemeinde-Feiertage sind nicht enthalten. Trage sie bei Bedarf unten als Sondertag ein.'),
form)
ZEILEN.set(el, new Map(zeilen.map(({ f, tag }) => [f.tag, tag])))
return el
}
/* -------------------------------------------------------------- Ausnahmen --- */
@@ -169,7 +186,7 @@ function hinweisFrage(t) {
h('button', { type: 'submit', class: 'kb-btn-primary', 'data-aktion': 'hinweis-ja' }, 'Ja, anlegen'),
h('button', { type: 'button', class: 'kb-btn-outline', 'data-aktion': 'hinweis-nein', onclick: () => {
ctx.hinweisFrage = null
t.zeichne()
form.remove() // nur die Frage verschwindet, alles andere in der Seite bleibt
t.wurzel.querySelector('[data-werkzeug="urlaub-neu"]')?.focus()
} }, 'Nein, danke')))
form.dataset.frage = 'hinweis'
@@ -179,7 +196,7 @@ function hinweisFrage(t) {
}, { container: form })
if (!ok || !sp.nochHier()) return
ctx.hinweisFrage = null
nachSpeichern(t, `Die Hinweis-Leiste „${v.text}“ ist angelegt.`, '[data-werkzeug="urlaub-neu"]')
nachSpeichern(t, `Die Hinweis-Leiste „${v.text}“ ist angelegt.`, '[data-werkzeug="urlaub-neu"]', () => t.zeichne(['ausnahmen']))
})
return form
}
@@ -212,7 +229,7 @@ function formular(t, { a, art, schliessen }) {
titel: `${wort} entfernen?`,
text: urlaub ? 'In dieser Zeit gilt danach wieder der Wochenplan.' : 'An diesem Tag gilt danach wieder der Wochenplan (und der Feiertag, falls einer ist).',
aendere: (entwurf) => { entwurf.ausnahmen = (entwurf.ausnahmen || []).filter((x) => x?.id !== alt.id) },
nachher: () => nachSpeichern(t, `${wort} entfernt.`, '[data-werkzeug="urlaub-neu"]'),
nachher: () => nachSpeichern(t, `${wort} entfernt.`, '[data-werkzeug="urlaub-neu"]', () => t.zeichne(['ausnahmen'])),
})
const speichern = h('button', { type: 'submit', class: 'kb-btn-primary', 'data-aktion': 'speichern' }, neu ? `${wort} eintragen` : 'Speichern')
const form = h('form', { class: 'kb-panel tm-formular', novalidate: true, 'aria-label': neu ? `${wort} eintragen` : `${wort} bearbeiten` },
@@ -274,7 +291,7 @@ function formular(t, { a, art, schliessen }) {
const geaendert = neu || alt.von !== eintrag.von || alt.bis !== eintrag.bis
ctx.hinweisFrage = vorschlag && geaendert && !gibtHinweis(ctx.stand.daten.hinweise, vorschlag) ? { vorschlag } : null
}
nachSpeichern(t, neu ? `${wort} eingetragen.` : `${wort} gespeichert.`, `li[data-id="${CSS.escape(alt.id)}"] [data-aktion="bearbeiten"]`)
nachSpeichern(t, neu ? `${wort} eingetragen.` : `${wort} gespeichert.`, `li[data-id="${CSS.escape(alt.id)}"] [data-aktion="bearbeiten"]`, () => t.zeichne(['ausnahmen']))
})
return h('div', { class: 'tm-editor' }, form, entfernen?.box)
}