Strecken gestaffelt anzeigen (2026.9.1.18)
Die gewonnene Genauigkeit kam nicht an: de() formatiert ohne Nachkommastelle,
aus 6,896 km wurde in beiden Oberflaechen "7 km". Den ganzen Tag auf zehn Meter
genau gemessen und im letzten Schritt weggerundet.
Staffelung, vom Eigentuemer festgelegt: unter 1 km Meter ("400 m"), bis
99,9 km eine Nachkommastelle ("6,9 km"), ab 100 km ganze Kilometer ("104 km").
streckeTeile()/streckeText() in beiden Codebasen, wortgleich.
Gestaffelt wird nach dem GERUNDETEN Wert: 0,9996 km sind gerundet 1000 m und
gehoeren in die km-Stufe, sonst stuende dort "1.000 m". streckeTeile() gibt
Wert und Einheit getrennt zurueck, weil die Detailansicht beide in getrennten
Elementen setzt - ohne das stuende unter "400" weiterhin "km".
Im Panel heisst die Funktion streckeText, nicht strecke: den Namen gibt es dort
schon fuer die Ortsangaben einer Fahrt. node --check hat die Kollision gefunden.
Angewandt auf Einzelfahrt und Jahres-/Monatssummen. Nicht auf Kilometerstaende,
Serviceintervalle oder Reichweite - das sind Zaehlerstaende und Prognosen.
VERIFIZIERT: 12 Faelle gegen die Staffelung samt beider Grenzen, 165/165 Tests
gruen, Panel als Modul, tsc --noEmit und vite build sauber, im Browser
nachgesehen: die Fahrt vom 01.09. steht jetzt mit 6,9 km statt "7 km".
Die angepasste Testerwartung ist selbst ein Beleg: sie verlangte "43 km" fuer
eine Summe von 42,5 km - die alte Anzeige rundete schon dort, wo es etwas zu
zeigen gab.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,36 @@ export function eur(wert: number | null | undefined): string {
|
||||
liegen. */
|
||||
|
||||
/** Wie de(), aber „–" statt „0" wenn nichts bekannt ist. */
|
||||
/** Eine gefahrene Strecke in der Staffelung, die der Eigentümer am 01.09.2026
|
||||
* festgelegt hat:
|
||||
*
|
||||
* unter 1 km -> Meter, ganzzahlig ("400 m", "999 m")
|
||||
* bis 99,9 km -> eine Nachkommastelle ("1,0 km", "6,9 km")
|
||||
* ab 100 km -> ganze Kilometer ("104 km")
|
||||
*
|
||||
* Seit der GNSS-Verfeinerung messen wir auf etwa zehn Meter genau; ohne
|
||||
* Nachkommastelle wurde davon nichts sichtbar (aus 6,896 km wurde "7 km").
|
||||
* Umgekehrt wäre eine Nachkommastelle bei dreistelligen Summen nur Unruhe.
|
||||
*
|
||||
* Gestaffelt wird nach dem GERUNDETEN Wert: 0,9996 km sind gerundet 1000 m
|
||||
* und gehören damit schon in die km-Stufe, sonst stünde dort "1.000 m".
|
||||
*
|
||||
* Wortgleich mit streckeTeile()/streckeText() im Panel. */
|
||||
export function streckeTeile(km: number | null | undefined): { wert: string; einheit: string } | null {
|
||||
const n = Number(km)
|
||||
if (km === null || km === undefined || !Number.isFinite(n)) return null
|
||||
const meter = Math.round(n * 1000)
|
||||
if (Math.abs(meter) < 1000) return { wert: de(meter), einheit: "m" }
|
||||
const fein = Math.round(n * 10) / 10
|
||||
if (Math.abs(fein) < 100) return { wert: de(fein, 1), einheit: "km" }
|
||||
return { wert: de(Math.round(n)), einheit: "km" }
|
||||
}
|
||||
|
||||
export function streckeText(km: number | null | undefined, ersatz = "–"): string {
|
||||
const t = streckeTeile(km)
|
||||
return t ? `${t.wert} ${t.einheit}` : ersatz
|
||||
}
|
||||
|
||||
export function deOderStrich(wert: number | null | undefined, nachkomma = 0): string {
|
||||
return wert === null || wert === undefined ? "–" : de(wert, nachkomma)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { ActionButton, Feld, Fig, Pill, Tile } from "@audi-dash/ui"
|
||||
|
||||
import type { Fahrt } from "../api"
|
||||
import { useDaten } from "../daten/DatenKontext"
|
||||
import { datum, dauer, de, deOderStrich, uhrzeit } from "../format"
|
||||
import { datum, dauer, de, streckeTeile, uhrzeit } from "../format"
|
||||
import type { SeitenName } from "../navigation"
|
||||
import { Leerzustand, Wertzeile, Werteliste, bestaetigen } from "./bausteine"
|
||||
import { FahrtFelderFormular, fahrtFelderAusFahrt, fahrtFelderAuswerten } from "./FahrtFelder"
|
||||
@@ -109,7 +109,11 @@ export function FahrtDetail({ id, geheZu }: { id: string | undefined; geheZu: (n
|
||||
<Tile variant="flat" className="dm-distanzkachel">
|
||||
<span className="ads-eyebrow">Distanz</span>
|
||||
<div style={{ marginTop: "10px" }}>
|
||||
<Fig value={deOderStrich(fahrt.distance_km)} unit="km" size={52} />
|
||||
<Fig
|
||||
value={(streckeTeile(fahrt.distance_km) ?? { wert: "–" }).wert}
|
||||
unit={(streckeTeile(fahrt.distance_km) ?? { einheit: "km" }).einheit}
|
||||
size={52}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ marginTop: "15px" }}>
|
||||
{/* Knopf, nicht Anzeige: im Panel schaltet dieselbe Pille seit jeher
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Accordion, ActionButton, Feld, Tile } from "@audi-dash/ui"
|
||||
|
||||
import { useDaten } from "../daten/DatenKontext"
|
||||
import { nachJahrUndMonat } from "../daten/statistik"
|
||||
import { datum, de, summe } from "../format"
|
||||
import { datum, de, streckeText, summe } from "../format"
|
||||
import type { SeitenName } from "../navigation"
|
||||
import { Blattzeile, Leerzustand } from "./bausteine"
|
||||
import { FahrtFelderFormular, LEERE_FAHRT_FELDER, fahrtFelderAuswerten } from "./FahrtFelder"
|
||||
@@ -64,7 +64,7 @@ export function Fahrten({ geheZu }: { geheZu: (name: SeitenName, id?: string) =>
|
||||
title={String(jahr.jahr)}
|
||||
summary={
|
||||
<>
|
||||
{de(summe(jahr.eintraege, (f) => f.distance_km ?? 0))} km
|
||||
{streckeText(summe(jahr.eintraege, (f) => f.distance_km ?? 0))}
|
||||
<br />
|
||||
{jahr.eintraege.length} Fahrt{jahr.eintraege.length === 1 ? "" : "en"}
|
||||
</>
|
||||
@@ -76,7 +76,7 @@ export function Fahrten({ geheZu }: { geheZu: (name: SeitenName, id?: string) =>
|
||||
key={monat.schluessel}
|
||||
level={2}
|
||||
title={monatName(monat.jahr, monat.monat)}
|
||||
summary={`${de(summe(monat.eintraege, (f) => f.distance_km ?? 0))} km`}
|
||||
summary={streckeText(summe(monat.eintraege, (f) => f.distance_km ?? 0))}
|
||||
defaultOpen={monat === jahr.monate[0]}
|
||||
>
|
||||
{monat.eintraege.map((fahrt, i) => (
|
||||
@@ -89,7 +89,7 @@ export function Fahrten({ geheZu }: { geheZu: (name: SeitenName, id?: string) =>
|
||||
label={strecke(fahrt)}
|
||||
labelZusatz={`${datum(fahrt.ts_start)} · ${artText(fahrt.art)}`}
|
||||
wert={
|
||||
fahrt.distance_km != null ? `${de(fahrt.distance_km)} km` : "offen"
|
||||
streckeText(fahrt.distance_km, "offen")
|
||||
}
|
||||
wertZusatz={
|
||||
fahrt.verbrauch_l_100km != null
|
||||
|
||||
@@ -126,9 +126,10 @@ describe("Inhalte kommen wirklich aus den Daten", () => {
|
||||
it("gruppiert Fahrten nach Jahr", async () => {
|
||||
zeige("trips")
|
||||
await waitFor(() => expect(screen.getByText("2026")).toBeTruthy())
|
||||
// Ganze Kilometer in der Liste, wie vTrips() im Panel (`de(t.distance_km)`
|
||||
// ohne Nachkommastelle) - die Nachkommastelle steht auf der Einzelfahrt.
|
||||
expect(screen.getByText("43 km")).toBeTruthy()
|
||||
// Gestaffelt nach streckeText(): unter 100 km mit einer Nachkommastelle.
|
||||
// Die Regel gilt seit dem 01.09.2026 fuer Einzelfahrten UND Summen, damit
|
||||
// die auf zehn Meter genaue GNSS-Messung ueberhaupt sichtbar wird.
|
||||
expect(screen.getByText("42,5 km")).toBeTruthy()
|
||||
})
|
||||
|
||||
it("zeigt bei einer Fahrt ohne Position keine erfundene Route", async () => {
|
||||
|
||||
Reference in New Issue
Block a user