/* ===================================================================== aether-medical / Ansicht: Bausteine Pflege der Textvorlagen für Behandlungs- und Berichtsbogen. Ein Baustein ist vorbereiteter Text — er wird nie von selbst eingesetzt und schreibt nichts in eine Dokumentation. ===================================================================== */ "use strict"; (() => { const { sicher, aufruf, meldung, fenster, bestaetigen } = App; const z = { bereich: "behandlung", // gewählter Bogen daten: null, }; /* ---- Gerüst ------------------------------------------------------------ */ function reiterleiste(d) { return `
${d.bereiche.map((b) => ` `).join("")}
`; } /* ---- Übersicht ---------------------------------------------------------- */ function uebersicht(behaelter) { const d = z.daten; behaelter.innerHTML = `

Bausteine

Vorformulierter Text für die Bögen. Ein Baustein füllt beim Einsetzen nur das Formular — gespeichert wird danach von Hand, und vorhandener Text bleibt stehen.

${reiterleiste(d)}
Bausteine für diesen Bogen Die Reihenfolge bestimmt nur die Anzeige
${d.liste.length ? d.liste.map(zeile).join("") : `
Für diesen Bogen ist noch nichts hinterlegt.
`}
Felder dieses Bogens
${d.felder.map((f) => `${sicher(f.name)}`).join("")}
Ein Baustein kann nur füllen, was es im Bogen auch gibt. Felder, für die jemandem das Recht fehlt, bleiben beim Einsetzen unberührt.
`; verdrahteUebersicht(behaelter); } function zeile(b) { return `
${sicher(b.kennung)}
${sicher(b.name)}
${b.felder.length ? sicher(b.felder.join(" · ")) : "füllt kein Feld"}
Reihenfolge ${b.sortierung} ${b.aktiv ? "einsetzbar" : "abgeschaltet"}
`; } function verdrahteUebersicht(behaelter) { behaelter.querySelectorAll("[data-reiter]").forEach((el) => { el.addEventListener("click", () => { z.bereich = el.dataset.reiter; rendern(behaelter); }); }); const neu = behaelter.querySelector("[data-neu]"); if (neu) neu.addEventListener("click", () => bearbeitenFenster(behaelter, null)); behaelter.querySelectorAll("[data-ansehen]").forEach((el) => { el.addEventListener("click", () => { const b = z.daten.liste.find((e) => e.id === +el.dataset.ansehen); if (b) ansehenFenster(b); }); }); behaelter.querySelectorAll("[data-bearbeiten]").forEach((el) => { el.addEventListener("click", () => { const b = z.daten.liste.find((e) => e.id === +el.dataset.bearbeiten); if (b) bearbeitenFenster(behaelter, b); }); }); behaelter.querySelectorAll("[data-aktiv]").forEach((el) => { el.addEventListener("click", async () => { try { await aufruf("vorlage", "aktiv", { id: +el.dataset.aktiv, aktiv: el.dataset.ziel === "1", }); meldung(el.dataset.ziel === "1" ? "Baustein einsetzbar." : "Baustein abgeschaltet.", "gut"); rendern(behaelter); } catch (f) { meldung(f.message, "fehler"); } }); }); behaelter.querySelectorAll("[data-entfernen]").forEach((el) => { el.addEventListener("click", () => { const b = z.daten.liste.find((e) => e.id === +el.dataset.entfernen); if (b) entfernenFenster(behaelter, b); }); }); } /* ---- Ansehen ------------------------------------------------------------- */ function ansehenFenster(b) { const d = z.daten; fenster({ titel: `${b.kennung} · ${b.name}`, inhalt: `

So sieht der Text aus, der beim Einsetzen in die Felder wandert. Vorhandener Text im Bogen bleibt erhalten.

${d.felder.filter((f) => b.inhalt[f.id]).map((f) => `
${sicher(b.inhalt[f.id]).replace(/\n/g, "
")}
`).join("") || `
Dieser Baustein ist leer.
`}`, }); } /* ---- Anlegen und bearbeiten ------------------------------------------------ */ function bearbeitenFenster(behaelter, b) { const d = z.daten; const neu = !b; bestaetigen({ titel: neu ? `Baustein für den ${d.bereiche.find((e) => e.id === z.bereich).name}` : `„${b.name}" bearbeiten`, inhalt: `
Leer gelassene Felder bleiben beim Einsetzen unberührt. Ein Baustein muss mindestens ein Feld füllen.
${d.felder.map((f) => `
`).join("")} ${neu ? "" : `
Der Bogen eines Bausteins lässt sich nicht wechseln — die Felder des einen passen nicht auf den anderen.
`}`, bestaetigenText: neu ? "Anlegen" : "Speichern", bestaetigt: async (el, zu) => { const name = el.querySelector("[name=name]").value.trim(); if (!name) return meldung("Bitte einen Namen angeben.", "fehler"); // Nur gefüllte Felder wandern in den Baustein const inhalt = {}; d.felder.forEach((f) => { const wert = el.querySelector(`[name=${f.id}]`).value.trim(); if (wert) inhalt[f.id] = wert; }); if (!Object.keys(inhalt).length) { return meldung("Bitte mindestens ein Feld ausfüllen.", "fehler"); } try { await aufruf("vorlage", "speichern", { id: neu ? null : b.id, bereich: z.bereich, name, sortierung: +el.querySelector("[name=sortierung]").value, inhalt, }); zu(); meldung(neu ? "Baustein angelegt." : "Baustein gespeichert.", "gut"); rendern(behaelter); } catch (f) { meldung(f.message, "fehler"); } }, }); } function entfernenFenster(behaelter, b) { bestaetigen({ titel: `„${b.name}" entfernen`, gefahr: true, inhalt: `

Der Baustein verschwindet aus der Auswahl.

ℹ
Was damit bereits geschrieben wurde, steht in den Bögen und bleibt unberührt. Soll der Baustein nur vorübergehend verschwinden, ist Abschalten der sanftere Weg.
`, bestaetigenText: "Entfernen", bestaetigt: async (el, zu) => { const grund = el.querySelector("[name=grund]").value.trim(); if (!grund) return meldung("Bitte einen Grund angeben.", "fehler"); try { await aufruf("vorlage", "entfernen", { id: b.id, grund }); zu(); meldung("Baustein entfernt.", "gut"); rendern(behaelter); } catch (f) { meldung(f.message, "fehler"); } }, }); } /* ---- Laden -------------------------------------------------------------------- */ async function rendern(behaelter) { try { z.daten = await aufruf("vorlage", "uebersicht", { bereich: z.bereich }); uebersicht(behaelter); } catch (f) { behaelter.innerHTML = `

Bausteine

Konnte nicht geladen werden: ${sicher(f.message)}

`; } } App.registriereAnsicht("vorlage", { rendern, aktualisieren() { if (App.zustand.aktivesModul === "vorlage" && !document.querySelector(".fenster-hg")) { rendern(App.$("inhalt")); } }, }); })();