From cd398bc80025bf01f63cdd01400545dd5070beef Mon Sep 17 00:00:00 2001 From: "m0@nas" Date: Tue, 8 Sep 2026 23:24:14 +0200 Subject: [PATCH] Kachelsymbole: jedes Bootstrap-Icon statt einer Handvoll Fuer die Symbole vor den Zahlen standen drei Codepunkte von Hand in rooms.php, und die Maske bot genau diese drei an. Jedes weitere Symbol waere eine Codeaenderung gewesen. Die Codepunkte stehen aber schon im Haus: css/bootstrap-icons.min.css fuehrt sie unter .bi-::before - dieselbe Quelle, aus der auch der Browser liest. bootstrapIcons() liest sie von dort (2078 Stueck, einmal je Anfrage), kachelIcon() schlaegt darin nach. Damit ist jedes Symbol moeglich, und ein Versionswechsel der Icons zieht von selbst mit. In der Maske steht deshalb kein Auswahlfeld mehr, sondern der Name mit einer Vorschau davor - "moisture" sagt nichts, das Symbol daneben schon. Die Vorschlagsliste beginnt mit gut dreissig ueblichen Symbolen unter deutscher Beschriftung (Temperatur, Feuchte, Leistung, Wallbox, Regen ...), danach folgt der ganze Rest alphabetisch. Ein Name, den es nicht gibt, zeigt sofort ein rotes Fragezeichen und wird beim Speichern mit Begruendung abgelehnt. In der eingeklappten Kurzfassung einer Kachel steht das Symbol jetzt mit - es ist das schnellste Erkennungszeichen dafuer, welcher der drei Werte gemeint ist. Co-Authored-By: Claude Opus 5 --- ajax/settings.php | 3 +- css/solar.css | 21 +++++++- js/solar/settings.js | 85 +++++++++++++++++++++++++++++---- restricted/kacheln.php | 106 +++++++++++++++++++++++++++++++++++++---- restricted/rooms.php | 50 +++++++++++++++---- 5 files changed, 234 insertions(+), 31 deletions(-) diff --git a/ajax/settings.php b/ajax/settings.php index 8282b9f..d6eb583 100644 --- a/ajax/settings.php +++ b/ajax/settings.php @@ -100,7 +100,8 @@ if ($action === "kacheln") { try { jsonAntwort([ "kacheln" => kachelListe(), - "symbole" => kachelSymbole(), + // Alle Symbolnamen - die üblichen zuerst und mit Beschriftung. + "symbole" => kachelIconNamen(), // Auswahlliste je Geraet - dieselbe Quelle wie im Automatik-Editor. "katalog" => kachelKatalog(), // Fuer die Eingabe von Hand, wenn etwas nicht im Katalog steht. diff --git a/css/solar.css b/css/solar.css index cd4bcfa..a49168d 100644 --- a/css/solar.css +++ b/css/solar.css @@ -1927,6 +1927,7 @@ input[type='range']::-webkit-slider-runnable-track { white-space: nowrap; } .kachel-chip.leer { font-style: italic; } +.kachel-chip .bi { margin-right: .3rem; opacity: .8; } .kachel-editor { padding: .25rem .75rem .75rem; @@ -1937,13 +1938,31 @@ input[type='range']::-webkit-slider-runnable-track { untereinander - die Felder sind zu kurz, um sie zu quetschen. */ .kachel-wert { display: grid; - grid-template-columns: 7.5rem minmax(10rem, 1fr) 7rem 5.5rem 4rem auto; + grid-template-columns: 7.5rem minmax(10rem, 1fr) 7rem 5.5rem 9.5rem auto; gap: .4rem; align-items: center; padding: .5rem 0; border-bottom: 1px dashed var(--ton-linie, rgba(138, 148, 158, .2)); } .kachel-wert:last-of-type { border-bottom: 0; } +/* Symbolname mit Vorschau davor: die Vorschau sagt, was der Name bedeutet - + "moisture" allein sagt es nicht. */ +.kachel-wert .kw-symbol { + display: flex; + align-items: center; + gap: .35rem; +} +.kachel-wert .kw-symbol-schau { + flex: none; + width: 1.5rem; + text-align: center; + font-size: 1.05rem; + line-height: 1; + color: var(--ton-schrift-2, #9aa6ad); +} +.kachel-wert .kw-symbol-schau .unbekannt { color: var(--ton-schlecht, #e06060); } +.kachel-wert .kw-symbol input { min-width: 0; } + .kachel-wert .kw-schalter { display: flex; align-items: center; diff --git a/js/solar/settings.js b/js/solar/settings.js index c150bd4..ff3efc4 100644 --- a/js/solar/settings.js +++ b/js/solar/settings.js @@ -376,9 +376,14 @@ function zeichneKacheln() { /** Eine Raumzeile: Name, Kurzfassung der Werte, darunter der Editor. */ function kachelZeile(k) { const werte = k._entwurf || k.werte; + // Das Symbol steht auch in der Kurzfassung: es ist das, was auf der Kachel + // vor der Zahl steht, und damit der schnellste Weg zu erkennen, welcher der + // drei Werte gemeint ist. const kurz = werte.length - ? werte.map(w => '' + textSchuetzen(kachelWertKurz(w, k)) - + "").join("") + ? werte.map(w => '' + + (w.icon && kachelSymbolBekannt(w.icon) + ? '' : "") + + textSchuetzen(kachelWertKurz(w, k)) + "").join("") : 'ohne Messwert'; let html = '
"; } +/* --- Symbole ------------------------------------------------------------- */ + +/** + * Das Feld für das Symbol: eine Vorschau und ein Name. + * + * Statt einer Auswahlliste mit einer Handvoll Symbole steht hier der Name des + * Bootstrap-Icons - damit sind alle gut zweitausend möglich, ohne dass für + * jedes neue eines im Code nachgetragen werden müsste. Die üblichen stehen in + * der Vorschlagsliste obenan, mit deutscher Beschriftung; wer ein anderes + * will, tippt und bekommt den Rest angeboten (icons.getbootstrap.com). + * + * Die Vorschau ist die eigentliche Hilfe: ein Name wie "moisture" sagt nichts, + * das Symbol daneben schon. + */ +function kachelSymbolFeld(icon) { + return '' + kachelSymbolVorschau(icon) + "" + + ''; +} + +/** Der Inhalt der Vorschau: das Symbol, ein Strich, oder ein Fragezeichen. */ +function kachelSymbolVorschau(icon) { + if (!icon) return ''; + if (!kachelSymbolBekannt(icon)) { + return ''; + } + return ''; +} + +function kachelSymbolBekannt(icon) { + if (!kachelSymbolBekannt._satz) { + kachelSymbolBekannt._satz = new Set((kachelModell.symbole || []).map(s => s.name)); + } + return kachelSymbolBekannt._satz.has(icon); +} + +/** + * Die Vorschlagsliste steht einmal im Dokument, nicht in jeder Zeile. + * + * Zweitausend Einträge sind rund siebzig Kilobyte Markup; bei jedem + * Neuzeichnen einer Kachel neu zu bauen waere Verschwendung. Sie haengt + * deshalb am Ende des Dokuments und ueberlebt das Neuzeichnen der Liste. + */ +function kachelIconListeSicherstellen() { + if (document.getElementById("kachelIcons")) return; + const liste = document.createElement("datalist"); + liste.id = "kachelIcons"; + liste.innerHTML = (kachelModell.symbole || []).map(s => '"; - }).join(""); // Eingabeart. "Messwert" steht nur zur Wahl, wenn es einen Katalog gibt - // ohne Mesh-Datenbank waere es eine leere Liste. @@ -516,8 +569,7 @@ function kachelWertZeile(wert, i, kachel) { + (wert.format === "leistung" ? " disabled" : "") + ' value="' + (wert.stellen === undefined ? "" : wert.stellen) + '">
' - + '
" + + '
' + kachelSymbolFeld(wert.icon || "") + "
" + '
' + '