- aether-medical: Stationen/Belegung, Intensivstation, Blutbank, Fuhrpark, Nachrichten/Aushänge, Berichte und Textbausteine (server + NUI) - aether-admin: vollständiges Server-Admin-Panel als echtes FiveM-Resource, an aether-core gekoppelt (Rechte über aether_users.admin_group), mit WebRTC-Live-Kameras (Bildschirmfreigabe) und separatem Media-Server (SFU) - Prototypen admin/ vervollständigt - SQL-Schema aether_admin.sql - Docker-Compose mit MariaDB und idempotenter Auto-Migration (schema_migrations) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
484 lines
20 KiB
JavaScript
484 lines
20 KiB
JavaScript
/* =====================================================================
|
||
aether-police / Ansicht: Einsätze & Dispatch
|
||
|
||
Zwei Spalten: links das Einsatzaufkommen, rechts die verfügbaren
|
||
Einheiten. Zugewiesen wird nur auf ausdrückliche Anweisung der
|
||
Leitstelle — und auch dann entscheidet die Einheit selbst, ob sie
|
||
beitritt.
|
||
===================================================================== */
|
||
"use strict";
|
||
|
||
(() => {
|
||
const { sicher, zeit, aufruf, meldung, fenster, bestaetigen, $, anClient } = App;
|
||
|
||
const z = {
|
||
daten: null,
|
||
offenerEinsatz: null,
|
||
nurOffene: true,
|
||
};
|
||
|
||
/* ---- Bausteine --------------------------------------------------- */
|
||
|
||
const statusText = {
|
||
offen: "Offen", zugewiesen: "Zugewiesen",
|
||
vorort: "Vor Ort", abgeschlossen: "Abgeschlossen",
|
||
};
|
||
const statusArt = {
|
||
offen: "kritisch", zugewiesen: "warn", vorort: "info", abgeschlossen: "neutral",
|
||
};
|
||
const quelleText = {
|
||
manuell: "manuell erfasst", notruf: "Notruf", panik: "Panikknopf", extern: "extern",
|
||
};
|
||
|
||
/** Farbe einer Kategorie aus der Serverkonfiguration */
|
||
function kategorieFarbe(id) {
|
||
const treffer = (z.daten.kategorien || []).find((k) => k.id === id);
|
||
return treffer ? treffer.farbe : "#8a93a5";
|
||
}
|
||
function kategorieName(id) {
|
||
const treffer = (z.daten.kategorien || []).find((k) => k.id === id);
|
||
return treffer ? treffer.name : id;
|
||
}
|
||
|
||
function einsatzKarte(e) {
|
||
return `
|
||
<div class="einsatz-karte ${e.status === "offen" ? "offen" : ""}" data-einsatz="${e.id}">
|
||
<span class="prio p${Math.min(4, e.prioritaet || 3)}"></span>
|
||
<div class="ek-haupt">
|
||
<div class="ek-titel">
|
||
${sicher(e.titel)}
|
||
${e.ichDabei > 0 ? '<span class="marker gut">Du bist dabei</span>' : ""}
|
||
</div>
|
||
<div class="ek-unter">
|
||
<span class="ek-kategorie" style="--kf:${kategorieFarbe(e.kategorie)}">
|
||
${sicher(kategorieName(e.kategorie))}
|
||
</span>
|
||
${sicher(e.nummer)} · ${sicher(e.ort || "Ort unbekannt")} · ${zeit(e.erstellt_am)}
|
||
${e.quelle !== "manuell" ? " · " + sicher(quelleText[e.quelle] || e.quelle) : ""}
|
||
</div>
|
||
</div>
|
||
<div class="ek-rechts">
|
||
<span class="marker ${statusArt[e.status]}">${sicher(statusText[e.status] || e.status)}</span>
|
||
<span class="ek-einheiten">${e.einheiten || 0} 🚓</span>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
function einheitenListe(beamte) {
|
||
if (!beamte.length) return `<div class="liste-leer">Niemand im Dienst.</div>`;
|
||
|
||
const farbe = { verfuegbar: "gut", einsatz: "warn", pause: "neutral", nicht: "kritisch" };
|
||
const text = { verfuegbar: "Verfügbar", einsatz: "Im Einsatz", pause: "Pause", nicht: "Nicht verfügbar" };
|
||
|
||
return `<div class="liste">${beamte.map((b) =>
|
||
`<div class="liste-zeile">
|
||
<span class="marker ${farbe[b.status] || "neutral"}">${sicher(b.dienstnummer)}</span>
|
||
<div class="lz-haupt">
|
||
<div class="lz-titel">${sicher(b.name)}
|
||
${b.leitstelle ? '<span class="marker info">Leitstelle</span>' : ""}</div>
|
||
<div class="lz-unter">${sicher(text[b.status] || b.status)} · ${sicher(b.abteilung)}</div>
|
||
</div>
|
||
</div>`).join("")}</div>`;
|
||
}
|
||
|
||
/* ---- Übersicht --------------------------------------------------- */
|
||
|
||
function uebersicht(behaelter) {
|
||
const d = z.daten;
|
||
const offene = d.einsaetze.filter((e) => e.status === "offen");
|
||
const laufende = d.einsaetze.filter((e) => e.status !== "offen" && e.status !== "abgeschlossen");
|
||
const erledigt = d.einsaetze.filter((e) => e.status === "abgeschlossen");
|
||
|
||
behaelter.innerHTML = `
|
||
<div class="seiten-kopf">
|
||
<div>
|
||
<h2>Einsätze & Dispatch</h2>
|
||
<p>${d.istLeitstelle
|
||
? "Du führst die Leitstelle — du entscheidest über die Zuweisung."
|
||
: "Einsätze werden nicht automatisch verteilt. Tritt bei, wenn du übernimmst."}</p>
|
||
</div>
|
||
<div style="display:flex;gap:8px">
|
||
<button class="knopf leise klein" id="e-filter">
|
||
${z.nurOffene ? "Auch abgeschlossene" : "Nur laufende"}
|
||
</button>
|
||
<button class="knopf klein" id="e-neu">+ Einsatz anlegen</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dispatch">
|
||
<div class="dispatch-spalte">
|
||
<div class="karte">
|
||
<div class="karte-kopf">
|
||
<span class="karte-titel">Offen — keine Einheit zugeordnet</span>
|
||
<span class="marker ${offene.length ? "kritisch" : "neutral"}">${offene.length}</span>
|
||
</div>
|
||
${offene.length ? offene.map(einsatzKarte).join("")
|
||
: `<div class="liste-leer">Keine offenen Einsätze.</div>`}
|
||
</div>
|
||
|
||
<div class="karte" style="margin-top:14px">
|
||
<div class="karte-kopf">
|
||
<span class="karte-titel">In Bearbeitung</span>
|
||
<span class="marker neutral">${laufende.length}</span>
|
||
</div>
|
||
${laufende.length ? laufende.map(einsatzKarte).join("")
|
||
: `<div class="liste-leer">Keine laufenden Einsätze.</div>`}
|
||
</div>
|
||
|
||
${!z.nurOffene ? `
|
||
<div class="karte" style="margin-top:14px">
|
||
<div class="karte-kopf">
|
||
<span class="karte-titel">Abgeschlossen</span>
|
||
<span class="marker neutral">${erledigt.length}</span>
|
||
</div>
|
||
${erledigt.length ? erledigt.map(einsatzKarte).join("")
|
||
: `<div class="liste-leer">Nichts abgeschlossen.</div>`}
|
||
</div>` : ""}
|
||
</div>
|
||
|
||
<div class="dispatch-spalte schmal">
|
||
<div class="karte">
|
||
<div class="karte-kopf">
|
||
<span class="karte-titel">Einheiten im Dienst</span>
|
||
<span class="marker neutral">${d.beamteImDienst.length}</span>
|
||
</div>
|
||
${einheitenListe(d.beamteImDienst)}
|
||
<div class="grundsatz">
|
||
<span>ℹ</span>
|
||
<div>Eine Zuweisung ist eine <b>Aufforderung</b>, kein Befehl an das System.
|
||
Die Einheit entscheidet selbst, ob sie den Einsatz übernimmt.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`;
|
||
|
||
$("e-neu").addEventListener("click", () => einsatzAnlegen(behaelter));
|
||
$("e-filter").addEventListener("click", () => {
|
||
z.nurOffene = !z.nurOffene;
|
||
rendern(behaelter);
|
||
});
|
||
|
||
behaelter.querySelectorAll("[data-einsatz]").forEach((el) =>
|
||
el.addEventListener("click", () => oeffneEinsatz(behaelter, +el.dataset.einsatz)));
|
||
}
|
||
|
||
/* ---- Einzelansicht ------------------------------------------------ */
|
||
|
||
function einsatzAnsicht(behaelter, d) {
|
||
const e = d.einsatz;
|
||
const aktiv = e.status !== "abgeschlossen";
|
||
const beteiligt = (e.beamte || []).filter((b) => !b.verlassen);
|
||
|
||
behaelter.innerHTML = `
|
||
<div class="seiten-kopf">
|
||
<div>
|
||
<h2>${sicher(e.titel)}</h2>
|
||
<p>${sicher(e.nummer)} · ${sicher(kategorieName(e.kategorie))} ·
|
||
${sicher(quelleText[e.quelle] || e.quelle)} · ${zeit(e.erstellt_am)}</p>
|
||
</div>
|
||
<button class="knopf leise klein" id="e-zurueck">‹ Zurück</button>
|
||
</div>
|
||
|
||
<div class="dispatch">
|
||
<div class="dispatch-spalte">
|
||
<div class="karte">
|
||
<div class="karte-kopf">
|
||
<span class="karte-titel">Lage</span>
|
||
<span class="marker ${statusArt[e.status]}">${sicher(statusText[e.status] || e.status)}</span>
|
||
</div>
|
||
<div class="akte-zeilen" style="grid-template-columns:auto 1fr">
|
||
<span>Priorität</span><b>${sicher(e.prioritaet)} ${e.prioritaet === 1 ? "(höchste)" : ""}</b>
|
||
<span>Ort</span><b>${sicher(e.ort || "unbekannt")}</b>
|
||
<span>Gemeldet von</span><b>${e.erstellt_von
|
||
? sicher((e.ersteller_vorname || "") + " " + (e.ersteller_nachname || ""))
|
||
: sicher(quelleText[e.quelle] || "extern")}</b>
|
||
</div>
|
||
${e.beschreibung ? `<div class="akte-inhalt" style="margin-top:12px">${sicher(e.beschreibung).replace(/\n/g, "<br>")}</div>` : ""}
|
||
|
||
<div style="display:flex;gap:8px;flex-wrap:wrap;margin-top:14px">
|
||
${e.pos_x ? `<button class="knopf leise klein" id="e-route">📍 Route setzen</button>` : ""}
|
||
${aktiv && !e.ichDabei ? `<button class="knopf klein" id="e-beitreten">Einsatz übernehmen</button>` : ""}
|
||
${aktiv && e.ichDabei ? `<button class="knopf leise klein" id="e-verlassen">Einsatz verlassen</button>` : ""}
|
||
${aktiv && e.ichDabei ? `<button class="knopf leise klein" id="e-vorort">Status: Vor Ort</button>` : ""}
|
||
${aktiv && d.rechte.schliessen ? `<button class="knopf leise klein" id="e-schliessen">Abschließen</button>` : ""}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="karte" style="margin-top:14px">
|
||
<div class="karte-kopf">
|
||
<span class="karte-titel">Einsatzverlauf</span>
|
||
${aktiv ? `<button class="knopf leise klein" id="e-notiz">+ Notiz</button>` : ""}
|
||
</div>
|
||
${(e.notizen || []).length ? `<div class="liste">${e.notizen.map((n) =>
|
||
`<div class="liste-zeile">
|
||
<span class="marker neutral">${zeit(n.am).slice(-5)}</span>
|
||
<div class="lz-haupt">
|
||
<div class="lz-titel" style="font-weight:600">${sicher(n.text)}</div>
|
||
<div class="lz-unter">${sicher(n.dienstnummer || "")}
|
||
${sicher((n.firstname || "") + " " + (n.lastname || ""))}</div>
|
||
</div>
|
||
</div>`).join("")}</div>`
|
||
: `<div class="liste-leer">Noch keine Einträge.</div>`}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dispatch-spalte schmal">
|
||
<div class="karte">
|
||
<div class="karte-kopf">
|
||
<span class="karte-titel">Beteiligte Einheiten</span>
|
||
<span class="marker neutral">${beteiligt.length}</span>
|
||
</div>
|
||
${beteiligt.length ? `<div class="liste">${beteiligt.map((b) =>
|
||
`<div class="liste-zeile">
|
||
<span class="marker info">${sicher(b.dienstnummer || "—")}</span>
|
||
<div class="lz-haupt">
|
||
<div class="lz-titel">${sicher((b.firstname || "") + " " + (b.lastname || ""))}</div>
|
||
<div class="lz-unter">seit ${zeit(b.beigetreten)}</div>
|
||
</div>
|
||
</div>`).join("")}</div>`
|
||
: `<div class="liste-leer">Keine Einheit vor Ort.</div>`}
|
||
</div>
|
||
|
||
${aktiv && d.rechte.zuweisen ? `
|
||
<div class="karte" style="margin-top:14px">
|
||
<div class="karte-kopf"><span class="karte-titel">Einheit anfordern</span></div>
|
||
<div class="liste">${d.beamteImDienst.map((b) =>
|
||
`<div class="liste-zeile">
|
||
<span class="marker neutral">${sicher(b.dienstnummer)}</span>
|
||
<div class="lz-haupt">
|
||
<div class="lz-titel">${sicher(b.name)}</div>
|
||
<div class="lz-unter">${sicher(b.status)}</div>
|
||
</div>
|
||
<button class="knopf leise klein" data-zuweisen="${b.quelle}">Anfordern</button>
|
||
</div>`).join("")}</div>
|
||
<div class="grundsatz">
|
||
<span>ℹ</span>
|
||
<div>Die Einheit erhält eine <b>Anfrage</b> mit Wegpunkt. Ob sie übernimmt,
|
||
entscheidet sie selbst.</div>
|
||
</div>
|
||
</div>` : ""}
|
||
</div>
|
||
</div>`;
|
||
|
||
/* ---- Aktionen ---- */
|
||
$("e-zurueck").addEventListener("click", () => { z.offenerEinsatz = null; rendern(behaelter); });
|
||
|
||
const route = $("e-route");
|
||
if (route) route.addEventListener("click", () =>
|
||
anClient("wegpunkt", { x: e.pos_x, y: e.pos_y }));
|
||
|
||
const beitreten = $("e-beitreten");
|
||
if (beitreten) beitreten.addEventListener("click", async () => {
|
||
try {
|
||
await aufruf("einsatz", "beitreten", { id: e.id });
|
||
meldung("Du hast den Einsatz übernommen.", "gut");
|
||
oeffneEinsatz(behaelter, e.id);
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
});
|
||
|
||
const verlassen = $("e-verlassen");
|
||
if (verlassen) verlassen.addEventListener("click", async () => {
|
||
try {
|
||
await aufruf("einsatz", "verlassen", { id: e.id });
|
||
meldung("Du hast den Einsatz verlassen.");
|
||
oeffneEinsatz(behaelter, e.id);
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
});
|
||
|
||
const vorort = $("e-vorort");
|
||
if (vorort) vorort.addEventListener("click", async () => {
|
||
try {
|
||
await aufruf("einsatz", "status", { id: e.id, status: "vorort" });
|
||
oeffneEinsatz(behaelter, e.id);
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
});
|
||
|
||
const notiz = $("e-notiz");
|
||
if (notiz) notiz.addEventListener("click", () => {
|
||
fenster({
|
||
titel: "Notiz zum Einsatz",
|
||
inhalt: `<div class="feld"><label>Eintrag</label>
|
||
<textarea id="en-text" placeholder="Was ist geschehen?"></textarea>
|
||
<div class="feld-hinweis">Der Verlauf hilft später beim Bericht.</div></div>`,
|
||
knoepfe: [
|
||
{ text: "Abbrechen", klick: (_, zu) => zu() },
|
||
{ text: "Eintragen", klick: async (el, zu) => {
|
||
const text = el.querySelector("#en-text").value.trim();
|
||
if (text.length < 2) { meldung("Bitte einen Text eingeben.", "fehler"); return; }
|
||
try {
|
||
await aufruf("einsatz", "notiz", { id: e.id, text });
|
||
zu(); oeffneEinsatz(behaelter, e.id);
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
}},
|
||
],
|
||
});
|
||
});
|
||
|
||
behaelter.querySelectorAll("[data-zuweisen]").forEach((b) =>
|
||
b.addEventListener("click", async () => {
|
||
try {
|
||
await aufruf("einsatz", "zuweisen", { id: e.id, quelle: +b.dataset.zuweisen });
|
||
meldung("Anfrage an die Einheit gesendet.", "gut");
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
}));
|
||
|
||
const schliessen = $("e-schliessen");
|
||
if (schliessen) schliessen.addEventListener("click", () => {
|
||
bestaetigen({
|
||
titel: "Einsatz abschließen",
|
||
inhalt: `
|
||
<p style="margin:0 0 12px;font-size:13px;line-height:1.6">
|
||
<b>${sicher(e.nummer)} — ${sicher(e.titel)}</b><br>
|
||
Alle Beteiligungen werden beendet. Es wird festgehalten, dass du den Einsatz
|
||
abgeschlossen hast.
|
||
</p>
|
||
<div class="feld"><label>Abschlussvermerk</label>
|
||
<input id="es-grund" placeholder="Ergebnis in einem Satz"></div>
|
||
${d.rechte.bericht ? `
|
||
<label style="display:flex;gap:9px;align-items:flex-start;font-size:12.5px;cursor:pointer">
|
||
<input type="checkbox" id="es-bericht" checked style="margin-top:2px">
|
||
<span>Berichtsentwurf vorbereiten — Titel, Beteiligte und der Einsatzverlauf
|
||
werden übernommen. Der Bericht bleibt ein <b>Entwurf</b>, bis du ihn ausarbeitest.</span>
|
||
</label>` : ""}`,
|
||
bestaetigenText: "Einsatz abschließen",
|
||
bestaetigt: async (el, zu) => {
|
||
const kasten = el.querySelector("#es-bericht");
|
||
try {
|
||
const ergebnis = await aufruf("einsatz", "abschliessen", {
|
||
id: e.id,
|
||
grund: el.querySelector("#es-grund").value.trim(),
|
||
berichtAnlegen: kasten ? kasten.checked : false,
|
||
});
|
||
zu();
|
||
meldung(ergebnis.berichtNummer
|
||
? "Einsatz abgeschlossen · Entwurf " + ergebnis.berichtNummer + " angelegt."
|
||
: "Einsatz abgeschlossen.", "gut");
|
||
z.offenerEinsatz = null;
|
||
rendern(behaelter);
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
},
|
||
});
|
||
});
|
||
}
|
||
|
||
async function oeffneEinsatz(behaelter, einsatzId) {
|
||
try {
|
||
const d = await aufruf("einsatz", "oeffnen", { id: einsatzId });
|
||
z.offenerEinsatz = einsatzId;
|
||
// Kategorien für die Anzeige mitführen
|
||
if (!z.daten) z.daten = { kategorien: [] };
|
||
d.kategorien = z.daten.kategorien;
|
||
einsatzAnsicht(behaelter, d);
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
}
|
||
|
||
/* ---- Anlegen ------------------------------------------------------ */
|
||
|
||
function einsatzAnlegen(behaelter) {
|
||
const kategorien = (z.daten && z.daten.kategorien) || [];
|
||
|
||
fenster({
|
||
titel: "Einsatz anlegen",
|
||
inhalt: `
|
||
<div class="feld"><label>Titel</label>
|
||
<input id="ne-titel" placeholder="Kurz und eindeutig"></div>
|
||
<div class="feld"><label>Kategorie</label>
|
||
<select id="ne-kategorie">
|
||
${kategorien.map((k) => `<option value="${sicher(k.id)}">${sicher(k.name)}</option>`).join("")}
|
||
</select></div>
|
||
<div class="feld"><label>Priorität</label>
|
||
<select id="ne-prio">
|
||
<option value="1">1 — höchste (sofort)</option>
|
||
<option value="2">2 — hoch</option>
|
||
<option value="3" selected>3 — normal</option>
|
||
<option value="4">4 — niedrig</option>
|
||
</select></div>
|
||
<div class="feld"><label>Ort</label>
|
||
<input id="ne-ort" placeholder="Straße, Bezirk oder Objekt"></div>
|
||
<div class="feld"><label>Beschreibung</label>
|
||
<textarea id="ne-text" placeholder="Was ist bekannt?"></textarea></div>
|
||
<label style="display:flex;gap:9px;align-items:center;font-size:12.5px;cursor:pointer">
|
||
<input type="checkbox" id="ne-hier" checked>
|
||
<span>Meine aktuelle Position als Einsatzort übernehmen</span>
|
||
</label>`,
|
||
knoepfe: [
|
||
{ text: "Abbrechen", klick: (_, zu) => zu() },
|
||
{ text: "Einsatz anlegen", klick: async (el, zu) => {
|
||
try {
|
||
const ergebnis = await aufruf("einsatz", "erstellen", {
|
||
titel: el.querySelector("#ne-titel").value.trim(),
|
||
kategorie: el.querySelector("#ne-kategorie").value,
|
||
prioritaet: +el.querySelector("#ne-prio").value,
|
||
ort: el.querySelector("#ne-ort").value.trim(),
|
||
beschreibung: el.querySelector("#ne-text").value,
|
||
eigenePosition: el.querySelector("#ne-hier").checked,
|
||
});
|
||
zu();
|
||
meldung("Einsatz " + ergebnis.nummer + " angelegt.", "gut");
|
||
oeffneEinsatz(behaelter, ergebnis.id);
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
}},
|
||
],
|
||
});
|
||
}
|
||
|
||
/* ---- Laden -------------------------------------------------------- */
|
||
|
||
async function rendern(behaelter) {
|
||
try {
|
||
z.daten = await aufruf("einsatz", "liste", { nurOffene: z.nurOffene });
|
||
|
||
// Markierungen im Spiel setzen
|
||
anClient("einsatzBlips", { einsaetze: z.daten.einsaetze });
|
||
|
||
if (z.offenerEinsatz) await oeffneEinsatz(behaelter, z.offenerEinsatz);
|
||
else uebersicht(behaelter);
|
||
} catch (f) {
|
||
behaelter.innerHTML =
|
||
`<div class="seiten-kopf"><div><h2>Einsätze</h2>
|
||
<p>Konnte nicht geladen werden: ${sicher(f.message)}</p></div></div>`;
|
||
}
|
||
}
|
||
|
||
/* ---- Nachrichten vom Client -------------------------------------- */
|
||
|
||
window.addEventListener("message", (ereignis) => {
|
||
const n = ereignis.data || {};
|
||
|
||
// Eine Einheit wurde angefordert — der Beamte entscheidet selbst
|
||
if (n.aktion === "einsatzZuweisung") {
|
||
const d = n.daten || {};
|
||
bestaetigen({
|
||
titel: "Einsatz übernehmen?",
|
||
inhalt: `<p style="margin:0;font-size:13px;line-height:1.6">
|
||
<b>${sicher(d.von)}</b> bittet dich um Übernahme:<br><br>
|
||
<b>${sicher(d.nummer)} — ${sicher(d.titel)}</b><br>
|
||
${d.ort ? "Ort: " + sicher(d.ort) : "Ort unbekannt"}<br><br>
|
||
Ein Wegpunkt wurde bereits gesetzt.</p>`,
|
||
bestaetigenText: "Übernehmen",
|
||
bestaetigt: async (_, zu) => {
|
||
try {
|
||
await aufruf("einsatz", "beitreten", { id: d.id });
|
||
zu(); meldung("Einsatz übernommen.", "gut");
|
||
if (App.zustand.aktivesModul === "einsatz") rendern($("inhalt"));
|
||
} catch (f) { meldung(f.message, "fehler"); }
|
||
},
|
||
});
|
||
}
|
||
|
||
// Im Hintergrund hat sich etwas geändert
|
||
if (n.aktion === "einsatzAenderung" && App.zustand.aktivesModul === "einsatz") {
|
||
rendern($("inhalt"));
|
||
}
|
||
});
|
||
|
||
/* ---- Registrierung ------------------------------------------------ */
|
||
|
||
App.registriereAnsicht("einsatz", {
|
||
rendern,
|
||
aktualisieren: () => {
|
||
if (App.zustand.aktivesModul === "einsatz") rendern($("inhalt"));
|
||
},
|
||
});
|
||
})();
|