@@ -2473,7 +2473,38 @@ function vReifen() {
Felder decken genau das ab , was die Einzelfahrt - Seite anzeigt ; Verbrauch ,
Status und km - Quelle bleiben außen vor , die meldet das Fahrzeug bzw . leitet
das Backend ab . * /
/ * G e s p e i c h e r t b l e i b t d e r k l e i n g e s c h r i e b e n e S c h l ü s s e l - e r w i r d a n m e h r e r e n
Stellen verglichen ( Pille auf der Einzelfahrt , Statistik "Arbeitsweg" , CSV )
und steht so auch in allen bereits erfassten Fahrten . Angezeigt wird er
groß , deshalb artText ( ) statt eines geänderten Werts . * /
const FAHRT _ARTEN = [ "privat" , "arbeitsweg" ] ;
const artText = ( a ) => ( a ? a . charAt ( 0 ) . toUpperCase ( ) + a . slice ( 1 ) : "" ) ;
/ * " 1 S t d . 1 5 M i n . " s t a t t " 7 5 m i n " - b e i m e h r s t ü n d i g e n F a h r t e n l i e s t s i c h d i e
reine Minutenzahl schlecht . * /
function dauerText ( sekunden ) {
if ( sekunden == null || ! isFinite ( sekunden ) ) return "– " ;
const min = Math . max ( 0 , Math . round ( sekunden / 60 ) ) ;
const std = Math . floor ( min / 60 ) ;
return std ? ` ${ std } Std. ${ min % 60 } Min. ` : ` ${ min } Min. ` ;
}
/ * S t a r t u n d A n k u n f t e i n e s F o r m u l a r s a l s e c h t e Z e i t p u n k t e . L i e g t d i e A n k u n f t
vor der Abfahrt , wurde über Mitternacht gefahren - dann zählt der Folgetag .
null , solange Datum oder eine der beiden Uhrzeiten fehlt . * /
function fahrtZeitraum ( praefix ) {
const datum = $ ( ` # ${ praefix } Datum ` ) . value , ab = $ ( ` # ${ praefix } Start ` ) . value , an = $ ( ` # ${ praefix } Ende ` ) . value ;
if ( ! datum || ! ab || ! an ) return null ;
const start = new Date ( ` ${ datum } T ${ ab } :00 ` ) ;
let ende = new Date ( ` ${ datum } T ${ an } :00 ` ) ;
if ( isNaN ( start ) || isNaN ( ende ) ) return null ;
if ( ende <= start ) ende = new Date ( ende . getTime ( ) + dTag ) ;
return { start , ende } ;
}
function fahrtDauerText ( praefix ) {
const z = fahrtZeitraum ( praefix ) ;
return z ? dauerText ( ( z . ende - z . start ) / 1000 ) : "– " ;
}
/ * D a t u m f ü r e i n < i n p u t t y p e = " d a t e " > i n O r t s z e i t . B e w u s s t n i c h t ü b e r
toISOString ( ) , das rechnet nach UTC um und liefert kurz nach Mitternacht
@@ -2489,16 +2520,30 @@ function zeitfeld(d) {
function fahrtFelder ( praefix , t ) {
const start = t && t . ts _start ? new Date ( t . ts _start ) : new Date ( ) ;
const dauer = t && t . duration _s != null ? Math . round ( t . duration _s / 60 ) : "" ;
const ende = t && t . ts _end ? new Date ( t . ts _end ) : null ;
const art = t && t . art ? t . art : FAHRT _ARTEN [ 0 ] ;
const wert = ( v ) => ( v == null ? "" : v ) ;
const startzeit = t ? zeitfeld ( start ) : "08:00" , ankunftzeit = ende ? zeitfeld ( ende ) : "08:30" ;
// Die Dauer ist bewusst kein Eingabefeld: sie ergibt sich aus Start und
// Ankunft und würde sich sonst mit ihnen widersprechen können. Aus
// t.duration_s statt neu berechnet, damit eine über Mitternacht laufende
// bestehende Fahrt (Ankunft "kleiner" als Start) korrekt bleibt; bei einer
// neuen Fahrt (t === null) ergibt sich der Startwert aus denselben
// Vorgabezeiten wie die Felder selbst. Der data-fahrtzeitfeld-Handler
// rechnet bei jeder Änderung neu.
let dauerSekunden = t && t . duration _s != null ? t . duration _s : null ;
if ( dauerSekunden == null ) {
const [ sh , sm ] = startzeit . split ( ":" ) . map ( Number ) , [ eh , em ] = ankunftzeit . split ( ":" ) . map ( Number ) ;
dauerSekunden = ( ( eh * 60 + em ) - ( sh * 60 + sm ) + ( eh * 60 + em <= sh * 60 + sm ? 1440 : 0 ) ) * 60 ;
}
const dauer = dauerText ( dauerSekunden ) ;
return `
< div class = "feld" > < label for = "${praefix}Datum" > Datum < / l a b e l > < i n p u t t y p e = " d a t e " i d = " $ { p r a e f i x } D a t u m " v a l u e = " $ { d a t u m s f e l d ( s t a r t ) } " > < / d i v >
< div class = "feld" > < label for = "${praefix}Start" > Startzeit < / l a b e l > < i n p u t t y p e = " t i m e " i d = " $ { p r a e f i x } S t a r t " v a l u e = " $ { t ? z e i t f e l d ( s t a r t ) : " 0 8 : 0 0 " } " > < / d i v >
< div class = "feld" > < label for = "${praefix}Dauer " > Dauer < / l a b e l >
< span class = "mitEinheit" > < input type = "number" min = "0" id = "${praefix}Dauer" value = "${dauer}" placeholder = "0" > < span > min < / s p a n > < / s p a n > < / d i v >
< div class = "feld" > < label for = "${praefix}Datum" > Datum < / l a b e l > < i n p u t t y p e = " d a t e " i d = " $ { p r a e f i x } D a t u m " v a l u e = " $ { d a t u m s f e l d ( s t a r t ) } " d a t a - f a h r t z e i t f e l d = " $ { p r a e f i x } " > < / d i v >
< div class = "feld" > < label for = "${praefix}Start" > Startzeit < / l a b e l > < i n p u t t y p e = " t i m e " i d = " $ { p r a e f i x } S t a r t " v a l u e = " $ { s t a r t z e i t } " d a t a - f a h r t z e i t f e l d = " $ { p r a e f i x } " > < / d i v >
< div class = "feld" > < label for = "${praefix}Ende " > Ankunftszeit < / l a b e l > < i n p u t t y p e = " t i m e " i d = " $ { p r a e f i x } E n d e " v a l u e = " $ { a n k u n f t z e i t } " d a t a - f a h r t z e i t f e l d = " $ { p r a e f i x } " > < / d i v >
< div class = "feld" > < label > Dauer < / l a b e l > < s p a n i d = " $ { p r a e f i x } D a u e r A n z e i g e " s t y l e = " c o l o r : v a r ( - - f g 2 ) " > $ { d a u e r } < / s p a n > < / d i v >
< div class = "feld" > < label for = "${praefix}Art" > Art < / l a b e l >
< select id = "${praefix}Art" > $ { FAHRT _ARTEN . map ( ( a ) => ` <option ${ a === art ? "selected" : "" } > ${ a } </option> ` ) . join ( "" ) } < / s e l e c t > < / d i v >
< select id = "${praefix}Art" > $ { FAHRT _ARTEN . map ( ( a ) => ` <option value=" ${ a } " ${ a === art ? "selected" : "" } > ${ artText ( a ) } </option> ` ) . join ( "" ) } < / s e l e c t > < / d i v >
< div class = "feld" > < label for = "${praefix}Startort" > Startort < / l a b e l > < i n p u t i d = " $ { p r a e f i x } S t a r t o r t " v a l u e = " $ { e s c ( w e r t ( t & & t . s t a r t _ a d d r e s s ) ) } " p l a c e h o l d e r = " u n b e k a n n t " > < / d i v >
< div class = "feld" > < label for = "${praefix}Zielort" > Zielort < / l a b e l > < i n p u t i d = " $ { p r a e f i x } Z i e l o r t " v a l u e = " $ { e s c ( w e r t ( t & & t . e n d _ a d d r e s s ) ) } " p l a c e h o l d e r = " u n b e k a n n t " > < / d i v >
< div class = "feld" > < label for = "${praefix}OdoStart" > Startkilometer < / l a b e l > < i n p u t t y p e = " n u m b e r " i d = " $ { p r a e f i x } O d o S t a r t " v a l u e = " $ { w e r t ( t & & t . o d o _ s t a r t ) } " p l a c e h o l d e r = " w i r d e r g ä n z t " > < / d i v >
@@ -2510,11 +2555,10 @@ function fahrtFelder(praefix, t) {
function fahrtFormularWerte ( praefix ) {
const zahl = ( id ) => { const v = $ ( ` # ${ praefix } ${ id } ` ) . value ; return v === "" ? null : parseFloat ( v . replace ( "," , "." ) ) ; } ;
const text = ( id ) => $ ( ` # ${ praefix } ${ id } ` ) . value . trim ( ) || null ;
const dauer = parseInt ( $ ( ` # ${ praefix } Dauer ` ) . value , 10 ) || 0 ;
const tsStart = new Date ( ` ${ $ ( ` # ${ praefix } Datum ` ) . value } T ${ $ ( ` # ${ praefix } Start ` ) . value } :00 ` ) ;
const z = fahrtZeitraum ( praefix ) ;
return {
ts _start : tsStart . toISOString ( ) ,
ts _end : new Date ( tsStart . getTime ( ) + dauer * 60000 ) . toISOString ( ) ,
ts _start : z ? z . start . toISOString ( ) : null ,
ts _end : z ? z . ende . toISOString ( ) : null ,
art : $ ( ` # ${ praefix } Art ` ) . value ,
start _ort : text ( "Startort" ) , ziel _ort : text ( "Zielort" ) ,
odo _start : zahl ( "OdoStart" ) , odo _end : zahl ( "OdoEnde" ) , distanz : zahl ( "Distanz" ) ,
@@ -2556,7 +2600,7 @@ function vTrips() {
< div class = "acc-b ${mi === 0 ? " on " : " "}" id = "m${j}${m}" > ` ;
tm . forEach ( ( t ) => { h += swipeZeile ( ` trip: ${ t . trip _id } ` , ` <button class="leaf" data-go="trip: ${ t . trip _id } ">
< span class = "k" > $ { strecke ( t ) }
< small > $ { dedat ( new Date ( t . ts _start ) ) } · $ { esc ( t . art ) } < / s m a l l > < / s p a n >
< small > $ { dedat ( new Date ( t . ts _start ) ) } · $ { artText ( t . art ) } < / s m a l l > < / s p a n >
< span class = "v" > $ { t . distance _km != null ? de ( t . distance _km ) + " km" : "offen" } < small > $ { fahrtVerbrauch ( t ) != null ? de ( fahrtVerbrauch ( t ) , 1 ) + " l/100 km" : t . status } < / s m a l l > < / s p a n >
< svg class = "chev" viewBox = "0 0 6 10" > < polyline points = "1,1 5,5 1,9" / > < / s v g > < / b u t t o n > ` ) ; } ) ;
h += ` </div></div> ` ;
@@ -2586,9 +2630,8 @@ function vTrip(id) {
< span class = "label" > Distanz < / s p a n >
< div class = "fig" style = "font-size:52px;margin-top:10px" > $ { t . distance _km != null ? de ( t . distance _km ) : "– " } < span class = "unit" > km < / s p a n > < / d i v >
< div style = "margin-top:15px" >
< button class = "pill ${t.art === " arbeitsweg " ? " work " : " "} " data - art = "${t.trip_id}"
style = "cursor:pointer;font-family:inherit" > $ { esc ( t . art ) } < / b u t t o n > < / d i v >
< span class = "label" style = "margin-top:12px" > tippen zum Umschalten < / s p a n >
< button class = "pill" data - art = "${t.trip_id}"
style = "cursor:pointer;font-family:inherit" > $ { artText ( t . art ) } < / b u t t o n > < / d i v >
< / d i v >
< div class = "tile" > < dl class = "rows" >
< div class = "row" > < dt > Startort < / d t > < d d > $ { e s c ( t . s t a r t _ a d d r e s s | | " u n b e k a n n t " ) } < s m a l l > $ { d e d a t ( n e w D a t e ( t . t s _ s t a r t ) ) } < / s m a l l > < / d d > < / d i v >
@@ -4128,6 +4171,15 @@ function ereignisseVerdrahten() {
if ( liste ) liste . innerHTML = entitaetZeilenMarkup ( sucheFeld , key , setupSuchtext , wert ) ;
return ;
}
// Gleicher Grund wie beim tankpreisfeld-Handler darunter: nur die
// Anzeige patchen, kein render() - das würde das gerade bearbeitete Feld
// neu erzeugen und den Fokus verlieren.
const zeitfeldPraefix = e . target . dataset . fahrtzeitfeld ;
if ( zeitfeldPraefix ) {
const anzeige = ROOT . getElementById ( ` ${ zeitfeldPraefix } DauerAnzeige ` ) ;
if ( anzeige ) anzeige . textContent = fahrtDauerText ( zeitfeldPraefix ) ;
return ;
}
const praefix = e . target . dataset . tankpreisfeld ;
if ( ! praefix ) return ;
const liter = parseFloat ( ( ROOT . getElementById ( ` ${ praefix } Liter ` ) . value || "0" ) . replace ( "," , "." ) ) ;