Einstellungen -> Grundriss: Etagen, Raeume und Kacheln am Plan pflegen

Neuer Reiter mit Plan-Editor: Etagen anlegen, umbenennen, sortieren,
loeschen und als Standard markieren; Grundrissbild hochladen; Raeume mit
Name, Kuerzel und Thermostat-Zweig anlegen und bearbeiten; Kacheln im Plan
ziehen oder einen Raum ohne Kachel mit "Platzieren" und einem Klick setzen.
Loest tools/kachelpositionen.php ab - Raster, Geisterkachel und die
Umrechnung Mitte -> linke obere Ecke sind von dort uebernommen.

- restricted/grundriss.php: alle Pruefungen und Schreibzugriffe. Eine
  Etage mit Raeumen oder Automatiken laesst sich nicht loeschen, die
  Ablehnung nennt die Namen. Raeume loeschen laesst ihre Geraete ohne Raum.
- Grundrissbilder nach tiles/grundriss/ (beschreibbar, nicht im Git),
  nur PNG/JPEG/WebP, am Inhalt geprueft; SVG bewusst nicht. Prüfsumme im
  Dateinamen, alte hochgeladene Bilder werden weggeraeumt.
- ajax/settings.php: ?action=grundriss und sieben POST-Aktionen, jede
  antwortet mit dem ganzen neuen Stand.
- "Werte" springt in den Reiter Home-Kacheln und oeffnet die Kachel;
  Home-Kacheln und Geraete laden nach einer Grundriss-Aenderung nach.
- Startseite ohne Etage mit platziertem Raum: Hinweis auf die
  Einstellungen statt einer leeren Zeichenflaeche.
- README: Grundriss als Inhalt statt Code, neue Dateien und Endpunkte,
  Reihenfolge der Schema-Dateien fuer ein neues Haus.

Backend mit einer Probe-Etage durchgespielt (auch Fehlerfaelle, Upload,
Aufraeumen); Oberflaeche auf einer Probeseite mit echten Daten und
Zeiger-Ereignissen geprueft: Ziehen, Antippen, Platzieren, neuer Raum.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 11:11:10 +02:00
co-authored by Claude Opus 5
parent 62a8af3fc6
commit 8d626abc6d
12 changed files with 1365 additions and 255 deletions
+44
View File
@@ -812,11 +812,55 @@ function kachelnBinden() {
if (neuLaden) neuLaden.addEventListener("click", kachelnHolen);
}
/**
* Eine Kachel von aussen aufschlagen - der Knopf "Werte" im Reiter Grundriss.
*
* Wechselt in diesen Reiter, laedt nach, falls sich der Grundriss seit dem
* letzten Laden geaendert hat (eine eben gesetzte Kachel stuende sonst nicht
* in der Liste), und oeffnet die Zeile.
*/
async function kachelOeffnen(floor, room) {
const knopf = document.getElementById("einstellung-kacheln-tab");
if (knopf && typeof bootstrap !== "undefined") new bootstrap.Tab(knopf).show();
if (window.grundrissGeaendert || !kachelModell) {
window.grundrissGeaendert = false;
await kachelnHolen();
}
const k = kachelModell && kachelSuchen(floor, room);
if (!k) return;
kachelModell.kacheln.forEach(a => { a._offen = false; });
k._offen = true;
if (!k._entwurf) k._entwurf = JSON.parse(JSON.stringify(k.werte));
zeichneKacheln();
const zeile = document.querySelector('.kachel-zeile[data-floor="' + k.floor + '"][data-room="' + k.room + '"]');
if (zeile) zeile.scrollIntoView({ behavior: "smooth", block: "center" });
}
document.addEventListener("DOMContentLoaded", function () {
// Das Merken des offenen Reiters macht reiterMerken() in common.js - fuer
// jede Leiste der Seite, nicht nur fuer diese.
kachelnBinden();
kachelnHolen();
// Nach einer Aenderung im Reiter Grundriss wissen Kacheln und Geraete nicht
// mehr, was gilt: neue Raeume fehlen, umbenannte heissen noch wie vorher.
// Nachgeladen wird beim naechsten Oeffnen - nicht sofort, sonst liefe bei
// jedem gezogenen Kachelchen eine Anfrage fuer zwei Reiter mit.
const kachelReiter = document.getElementById("einstellung-kacheln-tab");
if (kachelReiter) kachelReiter.addEventListener("shown.bs.tab", function () {
if (window.grundrissGeaendert) {
window.grundrissGeaendert = false;
window.geraeteVeraltet = true;
kachelnHolen();
}
});
const geraeteReiter = document.getElementById("einstellung-geraete-tab");
if (geraeteReiter) geraeteReiter.addEventListener("shown.bs.tab", function () {
if (window.grundrissGeaendert || window.geraeteVeraltet) {
window.geraeteVeraltet = false;
if (typeof geraeteHolen === "function") geraeteHolen();
}
});
});