Batteriespannungs-Messwertliste, Wisch-Löschen, Reifensatz-Archiv, CI-Icons
Fünf vom Nutzer angeforderte Erweiterungen in einer Runde:
- Batteriespannungs-Kachel bekommt eine Messwertliste (Datum, Uhrzeit,
Spannung, optional Außentemperatur über den neuen AUSSENTEMP_SENSOR),
erreichbar über ein neues list-s-Symbol in der Diagramm-Kachel. Werte
über AGM_RUHE_MAX_V (12,8 V) sind keine Ruhespannung, sondern
Lichtmaschinenspannung - die Zeile markiert das jetzt mit
"Generatorspannung" statt es unkommentiert als Messwert auszugeben.
- Jede Zeile der neuen Liste wischbar zum Löschen (neuer Dienst
batterieverlauf_loeschen), über dieselbe Wisch-Mechanik wie Fahrten/
Tankvorgänge in beiden Oberflächen.
- Batteriespannungs-Diagramm im Panel war auf großen Bildschirmen (≥860px,
Spaltenlayout) stark in die Breite gezogen (preserveAspectRatio="none"
bei fester Höhe) - gedeckelt wie die dort bereits vorhandenen Popups.
- Statistik-Tab-Symbol in beiden Oberflächen durch das Audi-CI-Symbol
polls-s ersetzt.
- Neue Möglichkeit, einen Reifensatz zu archivieren ("Neue Räder
anlegen"): der aktuelle Stand (km, Marke, Modell, DOT, Maße, Solldruck,
Kommentar) wandert in ein Archiv, der laufende Satz beginnt bei 0 km neu.
Archiv als aufklappbare Übersicht mit voller Bearbeitungsmöglichkeit,
über drei neue, bewusst nicht über profilSchreiben laufende Dienste
(reifen_archivieren/-aktualisieren/-loeschen) - aus demselben Grund wie
reifen_wechseln: kein im Browser gehaltener Stand darf einen
zwischenzeitlich fortgeschriebenen km-Wert überschreiben.
Live im Testcontainer geprüft (erstmals über :18123 statt :8123 erreichbar)
und dabei zwei echte Layout-Fehler gefunden, die kein Compile-/Testlauf
sehen konnte: die Archiv-Eingabefelder waren durch ein fälschlich
verwendetes .mitEinheit (feste 96px-Breite, eigentlich für Zahl+Einheit
gedacht) abgeschnitten ("Continenta" statt "Continental"), und die
Kilometerzahl in der eingeklappten Archiv-Zeile war klein an das Datum
gequetscht statt wie der Satzname lesbar. Beides behoben, live erneut
bestätigt.
Backend: py_compile clean, services.yaml ergänzt. Panel: node --check
clean. companion-app: tsc/Testsuite (146/146)/Build/OTA-Bündel alle grün.
Manifest 2026.8.25.2 → .8, jeder Neustart im Testcontainer sauber.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
{"version":"2026.8.24.11","sha256":"c1a85f9a15b434121f4cd19e2729cfbe60ca89757163954f07152483b8b209af","bytes":233245,"gebaut":"2026-08-24T14:58:21Z"}
|
||||
{"version":"2026.8.25.8","sha256":"464c294c6c07dcb636a8ea3bd93c7e525b21722defb41f573e2b31fefade49ea","bytes":235525,"gebaut":"2026-08-27T09:40:45Z"}
|
||||
Binary file not shown.
@@ -176,6 +176,12 @@ function profilZuCar(p, status) {
|
||||
wechsel: p.reifen.wechsel,
|
||||
sommer: reifenSatz("sommer"),
|
||||
winter: reifenSatz("winter"),
|
||||
// Neueste zuerst, schon so im Profil (reifen.py archivieren()). Nur
|
||||
// gelesen - bearbeitet/gelöscht wird über eigene Dienste
|
||||
// (reifen_archiv_aktualisieren/-loeschen), nicht über profilSpeichern,
|
||||
// aus demselben Grund wie km oben: kein Stand im Browser darf einen
|
||||
// zwischenzeitlichen Servereintrag überschreiben.
|
||||
archiv: p.reifen.archiv || [],
|
||||
},
|
||||
service: p.service,
|
||||
technik: p.technik,
|
||||
@@ -1044,6 +1050,16 @@ const CI = {
|
||||
verbatim uebernommen) - l im 48er-, s im 24er-Grid wie poi-l/poi-s. */
|
||||
battery12vL: '<path fill="currentColor" d="M11 11h7v4h13v-4h7v4h6v23H5V15h6zm1 4h5v-3h-5zm-6 1v21h37V16zm31-1v-3h-5v3zm-3 11v4.5h-1V26h-4.5v-1H33v-4.5h1V25h4.5v1zm-15.5 0h-8v-1h8z"/>',
|
||||
battery12vS: '<path fill="currentColor" d="M5 5h4v2h6V5h4v2h3v12H2V7h3zm1 2h2V6H6zM3 8v10h18V8zm15-1V6h-2v1zm-1 6v2h-1v-2h-2v-1h2v-2h1v2h2v1zm-8 0H5v-1h4z"/>',
|
||||
/* list-l/-s, polls-l/-s, package-l/-s aus dem Audi-CI-Icon-Satz (vom Nutzer
|
||||
als SVG geliefert, verbatim uebernommen) - l im 48er-, s im 24er-Grid wie
|
||||
poi-l/poi-s. list: Sprung vom Diagramm zur Werteliste (Batteriespannung).
|
||||
polls: Statistik-Tab in der Tableiste. package: "Neue Räder anlegen". */
|
||||
listL: '<path fill="currentColor" d="M14 19h-2v-1h2zm2-1h18v1H16zm-4 6h2v1h-2zm4 0h12v1H16zm-4 6h2v1h-2zm4 0h5v1h-5z"/>',
|
||||
listS: '<path fill="currentColor" d="M5 8H3V7h2zm2-1h14v1H7zm-4 4h2v1H3zm4 0h9v1H7zm-4 4h2v1H3zm4 0h5v1H7z"/>',
|
||||
pollsL: '<path fill="currentColor" d="M19 3h10v37H19zm1 1v35h8V4zm13 8h10v28H33zm1 1v26h8V13zM5 19h10v21H5zm1 1v19h8V20zM5 44h38v1H5z"/>',
|
||||
pollsS: '<path fill="currentColor" d="M9 0h6v21H9zm1 1v19h4V1zm7 4h6v16h-6zm1 1v14h4V6zM1 9h6v12H1zm1 1v10h4V10zM1 23h22v1H1z"/>',
|
||||
packageL: '<path fill="currentColor" d="m24 2.97 20.99 9v24.07l-20.99 9-20.99-9V11.96l20.99-9ZM16.11 7.4l19.18 8.29 7.97-3.41L24 4.03l-7.89 3.38Zm27.9 5.62L24.5 21.39v22.37L44 35.39V13.03Zm-20.5 30.73V21.39L4 13.03v22.36l19.52 8.37ZM4.74 12.29 24 20.54l10.06-4.31-19.19-8.29L4.74 12.3Z"/>',
|
||||
packageS: '<path fill="currentColor" d="m12 .96 11 4.71v12.66l-11 4.71-11-4.71V5.67zM2 6.76v10.91l9.5 4.07V10.83zm10.5 4.07v10.91l9.5-4.07V6.76zM21.23 6 12 2.04 8.41 3.58l9.2 3.97zM7.15 4.12 2.77 6 12 9.96l4.34-1.86-9.2-3.98Z"/>',
|
||||
/* edit-l/-s aus dem Audi-CI-Icon-Satz (vom Nutzer als SVG geliefert,
|
||||
verbatim uebernommen) - l im 48er-, s im 24er-Grid wie poi-l/poi-s. */
|
||||
editL: '<path fill="currentColor" d="M28.99 3.6c.34-.1.73-.11 1.1.04h.02l3.61 1.81c.35.18.58.5.68.84s.11.73-.04 1.1v.01l-2.01 4.06 4.02 2.02-6.72 13.44-.9-.44 6.28-12.56-3.13-1.56-13.6 27.47-6.3 4.66v-7.8L28.15 4.27c.18-.35.5-.58.84-.68Zm2.46 7.42 2-4.02a.65.65 0 0 0 0-.41c-.05-.14-.12-.22-.17-.24l-3.58-1.8a.65.65 0 0 0-.41 0c-.14.05-.22.12-.24.17L27.02 8.8zm-4.88-1.33-13.4 26.89 4.5 2.25L31.01 11.9l-4.44-2.2ZM13 37.61v4.9l3.95-2.93z"/>',
|
||||
@@ -1782,7 +1798,10 @@ function vBatterieverlauf() {
|
||||
|
||||
return `
|
||||
<div class="tile">
|
||||
<span class="label">Verlauf</span>
|
||||
<div style="display:flex;justify-content:space-between;align-items:center">
|
||||
<span class="label">Verlauf</span>
|
||||
<button class="iconbtn" aria-label="Messwertliste" data-go="battliste:x">${ciSVG(CI.listS, 18)}</button>
|
||||
</div>
|
||||
${genug ? `
|
||||
<div id="bvChart" style="margin-top:14px;touch-action:none;position:relative">
|
||||
<svg id="bvSvg" viewBox="0 0 ${BV_W} ${BV_H}" preserveAspectRatio="none" style="width:100%;height:170px;display:block"></svg>
|
||||
@@ -1825,6 +1844,31 @@ function vBatterieverlauf() {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/* Messwertliste zur Batteriespannungs-Kachel: ein Eintrag pro Tag (dieselben
|
||||
Daten wie das Diagramm), aber als Liste mit Datum, Uhrzeit, Spannung und
|
||||
Außentemperatur. Jede Zeile wischbar zum Löschen wie Fahrten/Tankvorgänge
|
||||
(art "batt" in eintragLoeschen()/LOESCH_TEXT/LOESCH_HINWEIS) - kein
|
||||
data-go/Chevron, es gibt keine Detailseite für einen einzelnen Messwert.
|
||||
Liegt der Tagesminimalwert über AGM_RUHE_MAX_V, wurde er nie in Ruhe
|
||||
gemessen (an dem Tag stand das Fahrzeug nie lange genug still) - die Zeile
|
||||
markiert das mit "Generatorspannung" statt so zu tun, als sei es ein
|
||||
Ruhewert (dieselbe Schwelle wie im Diagramm selbst, siehe bvPunkte oben). */
|
||||
function vBatterieliste() {
|
||||
const messwerte = BATTERIEVERLAUF.filter((e) => e.min != null).slice().reverse();
|
||||
if (messwerte.length === 0) {
|
||||
return `<div class="tile"><span class="label" style="color:var(--fg3)">Keine Messwerte</span></div>`;
|
||||
}
|
||||
return `<div class="tile">${messwerte.map((e) => {
|
||||
const zeit = e.min_ts ? new Date(e.min_ts) : null;
|
||||
const wann = zeit ? `${dedat(zeit)} · ${zeit.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" })} Uhr` : dedat(new Date(e.datum));
|
||||
return swipeZeile(`batt:${e.datum}`, `
|
||||
<div class="leaf">
|
||||
<span class="k">${de(e.min, 2)} V<small>${e.min_temp_c != null ? de(e.min_temp_c, 1) + " °C" : "—"}</small></span>
|
||||
<span class="v">${wann}${e.min > AGM_RUHE_MAX_V ? `<span class="pill" style="margin-top:4px;padding:3px 9px;font-size:11px">Generatorspannung</span>` : ""}</span>
|
||||
</div>`);
|
||||
}).join("")}</div>`;
|
||||
}
|
||||
|
||||
function bvSkalaX(t) { return BV_ML + ((t - bvDomain[0]) / (bvDomain[1] - bvDomain[0])) * (BV_W - BV_ML - BV_MR); }
|
||||
function bvSkalaY(v, yMin, yMax) { return BV_H - BV_MB - ((v - yMin) / (yMax - yMin)) * (BV_H - BV_MT - BV_MB); }
|
||||
function bvDomainKlemmen(domain) {
|
||||
@@ -2843,7 +2887,10 @@ function vReifen() {
|
||||
<button type="button" class="loeschen" data-bildloeschen="${radDatei}">Löschen</button>
|
||||
</div>` : ""}
|
||||
<button data-satz="${k === "sommer" ? "Sommer" : "Winter"}" class="montiert ${aktiv ? "on" : ""}">Montiert</button>
|
||||
<div style="margin-top:22px">
|
||||
<div style="display:flex;justify-content:flex-end;margin-top:10px">
|
||||
<button class="iconbtn" data-reifenarchivieren="${k}" aria-label="Neue Räder anlegen">${ciSVG(CI.packageS, 18)}</button>
|
||||
</div>
|
||||
<div style="margin-top:12px">
|
||||
${feld(k, "marke", "Hersteller")}
|
||||
${feld(k, "modell", "Modell")}
|
||||
${feld(k, "mass", "Größe")}
|
||||
@@ -2856,7 +2903,8 @@ function vReifen() {
|
||||
<span>bar</span>
|
||||
</span>
|
||||
</div>
|
||||
${feld(k, "kommentar", "Kommentar")}
|
||||
<div class="feld feld--breit"><label>Kommentar</label>
|
||||
<input value="${esc(t.kommentar ?? "")}" data-rf="${k}|kommentar" placeholder="noch offen"></div>
|
||||
</div>
|
||||
</div>`;
|
||||
};
|
||||
@@ -2883,7 +2931,55 @@ function vReifen() {
|
||||
<button class="aktion" data-ics="reifen">In den Kalender übernehmen</button>
|
||||
</div>
|
||||
${satz("sommer")}
|
||||
${satz("winter")}`;
|
||||
${satz("winter")}
|
||||
${vReifenArchiv()}`;
|
||||
}
|
||||
|
||||
/* Übersicht der per "Neue Räder anlegen" archivierten Sätze - jede Zeile
|
||||
aufklappbar (dasselbe acc-h/acc-b-Muster wie die Tankvorgänge-Liste), mit
|
||||
inline editierbaren Feldern wie bei den laufenden Sätzen oben, nur über
|
||||
eigene Dienste statt profilSpeichern (siehe profilZuCar()). */
|
||||
function vReifenArchiv() {
|
||||
const archiv = CAR.reifen.archiv || [];
|
||||
if (archiv.length === 0) return "";
|
||||
// Kein .mitEinheit hier (das erzwingt eine feste 96px-Eingabebreite fürs
|
||||
// Zahl+Einheit-Muster, z. B. km/Nm - für freien Text wie Hersteller/Modell/
|
||||
// Kommentar riss das den Wert ab, siehe live beobachtet: "Continenta",
|
||||
// "SportConta"). Genau wie feld() in satz() oben: einfaches <input>, das
|
||||
// sich über den .feld-Flex den ganzen Rest der Zeile nimmt.
|
||||
const feld = (a, schluessel, bez) => `<div class="feld"><label>${bez}</label>
|
||||
<input value="${esc(a[schluessel] ?? "")}" data-rfa="${a.id}|${schluessel}" placeholder="–"></div>`;
|
||||
return `<div class="tile"><span class="label">Archiv</span>
|
||||
${archiv.map((a, i) => {
|
||||
const satzLabel = a.satz === "winter" ? "Winterräder" : "Sommerräder";
|
||||
return `<button class="acc-h" aria-expanded="false" data-acc="rfarch${i}"><span class="mark"></span>
|
||||
<span class="k">${satzLabel}</span>
|
||||
<span class="v" style="display:flex;flex-direction:column;align-items:flex-end;gap:3px">
|
||||
<span style="color:var(--fg);font-size:15px">${a.km != null ? de(a.km) + " km" : "–"}</span>
|
||||
<small>Ersetzt am ${dedat(new Date(a.ersetzt_am))}</small>
|
||||
</span></button>
|
||||
<div class="acc-b" id="rfarch${i}">
|
||||
<div class="feld"><label>Ersetzt am</label><input type="date" value="${esc(a.ersetzt_am ?? "")}" data-rfa="${a.id}|ersetzt_am"></div>
|
||||
<div class="feld"><label>Gefahrene Strecke</label>
|
||||
<span class="mitEinheit"><input type="number" step="0.1" min="0" value="${a.km ?? ""}" data-rfa="${a.id}|km"><span>km</span></span></div>
|
||||
${feld(a, "marke", "Hersteller")}
|
||||
${feld(a, "modell", "Modell")}
|
||||
${feld(a, "mass", "Größe")}
|
||||
${feld(a, "dot", "DOT")}
|
||||
<div class="feld"><label>Solldruck vorn / hinten</label>
|
||||
<span class="mitEinheit">
|
||||
<input class="druckfeld" value="${esc(a.druck_vorne ?? "")}" data-rfa="${a.id}|druck_vorne" placeholder="–">
|
||||
<span>/</span>
|
||||
<input class="druckfeld" value="${esc(a.druck_hinten ?? "")}" data-rfa="${a.id}|druck_hinten" placeholder="–">
|
||||
<span>bar</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="feld feld--breit"><label>Kommentar</label>
|
||||
<input value="${esc(a.kommentar ?? "")}" data-rfa="${a.id}|kommentar" placeholder="–"></div>
|
||||
<button class="aktion loeschen" style="margin-top:10px" data-reifenarchivloeschen="${a.id}">Löschen</button>
|
||||
</div>`;
|
||||
}).join("")}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/* Gemeinsames Formular für "Neue Fahrt" und das Bearbeiten einer bestehenden
|
||||
@@ -3250,12 +3346,14 @@ const LOESCH_TEXT = {
|
||||
fill: "Tankvorgang löschen?",
|
||||
sbuch: "Servicebuch-Eintrag löschen?",
|
||||
bild: "Foto löschen?",
|
||||
batt: "Messwert löschen?",
|
||||
};
|
||||
const LOESCH_HINWEIS = {
|
||||
trip: "Die Fahrt wird aus dem Fahrtenbuch entfernt. Das lässt sich nicht widerrufen.",
|
||||
fill: "Der Tankvorgang und der zugehörige Beleg werden entfernt. Das lässt sich nicht widerrufen.",
|
||||
sbuch: "Der Eintrag wird aus dem Servicebuch entfernt. Das lässt sich nicht widerrufen.",
|
||||
bild: "Das Foto wird vom Server gelöscht. Der Platz bleibt bestehen und kann neu belegt werden.",
|
||||
batt: "Der Tageseintrag wird aus der Messwertliste entfernt. Das lässt sich nicht widerrufen.",
|
||||
};
|
||||
function eintragLoeschen(art, id) {
|
||||
if (art === "trip") {
|
||||
@@ -3267,6 +3365,9 @@ function eintragLoeschen(art, id) {
|
||||
} else if (art === "sbuch") {
|
||||
CAR.service.buch.splice(parseInt(id, 10), 1);
|
||||
profilSpeichern();
|
||||
} else if (art === "batt") {
|
||||
serviceRufen("batterieverlauf_loeschen", { datum: id });
|
||||
BATTERIEVERLAUF = BATTERIEVERLAUF.filter((e) => e.datum !== id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3511,7 +3612,9 @@ const ICONS = {
|
||||
assets/icons/car.svg). Flaeche statt Kontur, deshalb die Klasse "voll". */
|
||||
audi: '<path d="M5.46 4.05a80 80 0 0 1 13.08 0l.24.02.14.2A55 55 0 0 1 21.9 9.2l2.1 2.1v8.2c0 .83-.67 1.5-1.5 1.5h-2a1.5 1.5 0 0 1-1.5-1.5V19l-14-.04v.54c0 .83-.67 1.5-1.5 1.5h-2A1.5 1.5 0 0 1 0 19.5v-8.2l2.1-2.1a55 55 0 0 1 2.98-4.93l.14-.2zM2.7 10 1 11.7v.3h4v1H1v6.5c0 .28.22.5.5.5h2a.5.5 0 0 0 .5-.5v-1.55L20 18v1.5c0 .28.22.5.5.5h2a.5.5 0 0 0 .5-.5V13h-4v-1h4v-.3L21.3 10zm17.94-1a45 45 0 0 0-2.43-3.98 78 78 0 0 0-12.44 0L4.51 7c-.3.5-.7 1.16-1.16 2.01h17.3ZM7.3 12h9.42l1.36 1.36-.1.3c-.31 1-.6 1.78-.88 2.31-.13.27-.27.5-.41.67-.13.15-.36.36-.68.36H8a.9.9 0 0 1-.68-.36c-.14-.17-.28-.4-.41-.67a17 17 0 0 1-.89-2.32l-.09-.29zm.42 1-.64.64c.28.84.52 1.47.73 1.89a2.4 2.4 0 0 0 .3.47h7.8l.02-.01c.07-.08.16-.23.28-.46.21-.42.45-1.05.73-1.9L16.3 13H7.71Z"/>',
|
||||
trips: '<circle cx="6" cy="6" r="2.2"/><circle cx="18" cy="18" r="2.2"/><path d="M8 7.5c4 1.5 4.5 3 3 5s-1 3.5 4.5 5"/>',
|
||||
stat: '<path d="M4 20V9.5M10 20V4.5M16 20v-8M22 20H2"/>',
|
||||
/* CI-Symbol polls-s statt der vorherigen handgezeichneten Balken - dieselbe
|
||||
Fuellflaeche-statt-Kontur-Behandlung wie "audi" (siehe ICONS_VOLL). */
|
||||
stat: CI.pollsS,
|
||||
fuel: '<path d="M4.5 20V6.2c0-.9.8-1.7 1.7-1.7h5.6c1 0 1.7.8 1.7 1.7V20"/><path d="M3 20h12.5"/><path d="M4.5 11h10.5"/><path d="M17 20v-8.5a2 2 0 0 0-2-2"/><path d="M17 11.5V7.8l-2-2.3"/>',
|
||||
};
|
||||
const TABS = [
|
||||
@@ -3522,7 +3625,7 @@ const TABS = [
|
||||
{ id: "fuel", label: "Tanken", eyebrow: "", title: "Tanken" },
|
||||
];
|
||||
/* Symbole, die als Flaeche gezeichnet sind statt als Kontur */
|
||||
const ICONS_VOLL = new Set(["audi"]);
|
||||
const ICONS_VOLL = new Set(["audi", "stat"]);
|
||||
let route = { name: "home" };
|
||||
const ZURUECK = {
|
||||
trip: "trips", fill: "fuel", service: "audi", reifen: "audi", ident: "audi",
|
||||
@@ -3530,6 +3633,7 @@ const ZURUECK = {
|
||||
vertrag: "vers",
|
||||
steuer: "vers", notruf: "vers", werkstatt: "service", sbuch: "service", einst: "home",
|
||||
battverlauf: "audi",
|
||||
battliste: "battverlauf",
|
||||
/* Fehlte: die Sicherheitsansicht war eine Sackgasse ohne sichtbaren
|
||||
Zurück-Pfeil. */
|
||||
sicherheit: "home",
|
||||
@@ -3889,6 +3993,7 @@ function render() {
|
||||
else if (route.name === "schutz") { head = ["Im Ernstfall", "Schutzbrief"]; v.innerHTML = vSchutz(); }
|
||||
else if (route.name === "werkstatt") { head = ["Service", "Autohaus"]; v.innerHTML = vWerkstatt(); }
|
||||
else if (route.name === "battverlauf") { head = ["Fahrzeug", "Batteriespannung"]; v.innerHTML = vBatterieverlauf(); bvZeichnen(); }
|
||||
else if (route.name === "battliste") { head = ["Batteriespannung", "Messwerte"]; v.innerHTML = vBatterieliste(); }
|
||||
else if (route.name === "sbuch") { head = ["Servicebuch", "Eintrag"]; v.innerHTML = vSbuch(); }
|
||||
else if (route.name === "standort") { head = ["Fahrzeug", "Standort"]; v.innerHTML = vStandort(); }
|
||||
else { const t = TABS.find((x) => x.id === route.name); head = [t.eyebrow, t.id === "audi" ? "Mein Audi" : t.title];
|
||||
@@ -4724,6 +4829,25 @@ function ereignisseVerdrahten() {
|
||||
}
|
||||
const satz = e.target.closest("[data-satz]");
|
||||
if (satz) { serviceRufen("reifen_wechseln", { satz: satz.dataset.satz.toLowerCase() }); CAR.reifen.aktiv = satz.dataset.satz; render(); return; }
|
||||
const rfArch = e.target.closest("[data-reifenarchivieren]");
|
||||
if (rfArch) {
|
||||
const k = rfArch.dataset.reifenarchivieren;
|
||||
bestaetigen("Neue Räder anlegen?",
|
||||
"Der aktuelle Stand wird ins Archiv gelegt, der laufende Satz beginnt neu bei 0 km.",
|
||||
"Anlegen", () => { serviceRufen("reifen_archivieren", { satz: k }); }, false);
|
||||
return;
|
||||
}
|
||||
const rfArchDel = e.target.closest("[data-reifenarchivloeschen]");
|
||||
if (rfArchDel) {
|
||||
const id = rfArchDel.dataset.reifenarchivloeschen;
|
||||
bestaetigen("Archivierten Reifensatz löschen?",
|
||||
"Das lässt sich nicht widerrufen.", "Löschen", () => {
|
||||
serviceRufen("reifen_archiv_loeschen", { id });
|
||||
CAR.reifen.archiv = CAR.reifen.archiv.filter((a) => a.id !== id);
|
||||
render();
|
||||
}, true);
|
||||
return;
|
||||
}
|
||||
const k = e.target.closest("[data-ics]");
|
||||
if (k) {
|
||||
if (k.dataset.ics === "service") {
|
||||
@@ -4912,6 +5036,18 @@ function ereignisseVerdrahten() {
|
||||
CAR.reifen[k][schluessel] = wert;
|
||||
profilSpeichern(); render(); return;
|
||||
}
|
||||
const rfa = e.target.dataset.rfa;
|
||||
if (rfa) {
|
||||
const [id, schluessel] = rfa.split("|");
|
||||
const wert = schluessel === "km" ? parseFloat(e.target.value) || 0 : e.target.value;
|
||||
const eintrag = CAR.reifen.archiv.find((a) => a.id === id);
|
||||
if (eintrag) eintrag[schluessel] = wert;
|
||||
// Eigener Dienst statt profilSpeichern (siehe profilZuCar()) - ändert
|
||||
// nur diesen einen archivierten Satz, statt das ganze Profil (samt
|
||||
// eines womöglich seither fortgeschriebenen km-Stands) zu überschreiben.
|
||||
serviceRufen("reifen_archiv_aktualisieren", { id, [schluessel]: wert });
|
||||
return;
|
||||
}
|
||||
if (e.target.dataset.schrift !== undefined) {
|
||||
beschriftung = e.target.checked;
|
||||
try { localStorage.setItem(SCHRIFT_KEY, beschriftung ? "an" : "aus"); } catch (err) { /* Privatmodus */ }
|
||||
|
||||
@@ -334,6 +334,14 @@ main#view{--seitenrand:16px;padding:0 var(--seitenrand) 30px;scroll-behavior:smo
|
||||
Einblend-Animation dieser Elemente zu beruehren. */
|
||||
.setup-popup,.sdpopup,.sheet,.beleg-popup{max-width:560px;margin-left:auto;margin-right:auto}
|
||||
.standortmenu{max-width:640px;margin-left:auto;margin-right:auto}
|
||||
|
||||
/* Batteriespannungs-Diagramm ist auf BV_W=320 SVG-Einheiten gezeichnet
|
||||
(audi-dashboard-app.js) und haelt seine Hoehe fest bei 170px - bei voller
|
||||
Spaltenbreite (772px Inhaltsbreite: 860 - 2*44px Seitenrand) zog
|
||||
preserveAspectRatio="none" das Diagramm zu einem extrem breiten, flachen
|
||||
Band auseinander. Gedeckelt wie die Popups oben, statt die feste Hoehe
|
||||
oder die BV_*-Zeichen-Logik anzufassen. */
|
||||
#bvChart{max-width:400px;margin-left:auto;margin-right:auto}
|
||||
}
|
||||
|
||||
/* Fahrzeugbild randlos wie in einer Fahrzeug-App: der Platzhalter bleibt
|
||||
|
||||
@@ -171,6 +171,17 @@
|
||||
.themebtn:hover { background: var(--tile-2); color: var(--fg); }
|
||||
.themebtn:active { background: var(--tile-2); color: var(--fg); transform: scale(.92); }
|
||||
.themebtn svg { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
|
||||
/* Wie .themebtn (44px Trefferflaeche), aber ohne die Kontur-Stroke-Regel -
|
||||
fuer CI-Symbole (ciSVG()), deren Pfade ihr eigenes fill="currentColor"
|
||||
mitbringen (z. B. list-s im Kopf der Batteriespannungs-Kachel). */
|
||||
.iconbtn {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 44px; height: 44px; border-radius: 50%;
|
||||
border: none; background: none; color: var(--fg3);
|
||||
cursor: pointer; padding: 0; flex: 0 0 auto;
|
||||
}
|
||||
.iconbtn:hover { background: var(--tile-2); color: var(--fg); }
|
||||
.iconbtn:active { background: var(--tile-2); color: var(--fg); transform: scale(.92); }
|
||||
/* D4 war urspruenglich: die Ringe sind Marke, kein Knopf. Seit die
|
||||
iOS-Auflage in Telefonbreite das Zahnrad ausblendet, sind sie dort aber der
|
||||
einzige Zugang zu den Einstellungen - und als reines div mit
|
||||
@@ -665,6 +676,15 @@ button.sicherheitszeile:active { background: var(--tile-2); }
|
||||
appearance: none;
|
||||
}
|
||||
.feld input:focus, .feld select:focus, .notiz:focus { outline: none; border-color: var(--red); }
|
||||
/* Label und Eingabe untereinander statt nebeneinander, die Eingabe über die
|
||||
volle Zeilenbreite - für Felder, deren Wert typischerweise länger ist als
|
||||
ein Kurztext (Kommentar bei Sommer-/Winterrädern, live wie archiviert).
|
||||
Sonst gilt .feld input oben: die Eingabe wächst nie über ihre intrinsische
|
||||
Breite, nur das Label tut das (flex:1 1 auto) - für einen Reifenkommentar
|
||||
("Profiltiefe 5,1 mm bei der letzten Montage") reichte das nicht. */
|
||||
.feld--breit { display: block; }
|
||||
.feld--breit label { display: block; margin-bottom: 8px; }
|
||||
.feld--breit input { width: 100%; text-align: left; }
|
||||
/* Das AUFGEKLAPPTE <select>-Popup ist Browser-/OS-Chrome, kein Teil des
|
||||
Seiten-DOMs - color-scheme (siehe :host weiter oben) beeinflusst es nur
|
||||
teilweise, der Rest bleibt hell. Einzige zuverlaessige Stellschraube:
|
||||
|
||||
Reference in New Issue
Block a user