add date and turn entry into CRDT

This commit is contained in:
Julian 2025-07-11 23:01:13 +02:00
parent 1091fa9ddb
commit b856d31fcc
5 changed files with 47 additions and 33 deletions

View file

@ -30,13 +30,19 @@ object Main {
println("test")
val allEntriesVar = Var(Set.empty[Entry])
// update entries whenever db updates
entriesObservable.subscribe(entries =>
entries.onComplete {
case Failure(exception) => println("failed to get entries from db")
case Success(value) => allEntriesVar.set(value.toSet)
}
)
val allEntries: Signal[List[Entry]] = allEntriesVar.signal.map(_.toList)
// update db when edit events happen
entryEditBus.stream.addObserver(entryDbObserver)(using unsafeWindowOwner)
val allEntries: Signal[Set[Entry]] =
allEntriesVar.signal
}

View file

@ -5,7 +5,7 @@ import fahrtenbuch.model.Entry
import fahrtenbuch.Main.entryEditBus
import rdts.base.Uid
class AppComponent(allEntries: Signal[List[Entry]]):
class AppComponent(allEntries: Signal[Set[Entry]]):
// tracks whenever a user clicks on an edit button
val editClickBus = new EventBus[(Uid, Boolean)]
@ -21,7 +21,7 @@ class AppComponent(allEntries: Signal[List[Entry]]):
.combineWith(editStateSignal)
.map { case (entries, editState) =>
entries.toList
.sortBy(_.id)
.sortBy(_.date.payload.getTime())
.map(entry =>
EntryComponent(
entry,
@ -42,7 +42,7 @@ class AppComponent(allEntries: Signal[List[Entry]]):
cls := "table",
thead(
tr(
// th("Date"),
th("Datum"),
th("Fahrer*in"),
th("Start Km"),
th("Ende Km"),

View file

@ -14,18 +14,20 @@ class EntryComponent(
):
def render: ReactiveHtmlElement[HTMLTableRowElement] = {
if editMode then
val driverInput = input(cls := "input", value := entry.driver)
val driverInput = input(cls := "input", value := entry.driver.payload)
val startKmInput =
input(cls := "input", value := entry.startKm.toString())
val endKmInput = input(cls := "input", value := entry.endKm.toString())
val animalInput = input(cls := "input", value := entry.animal)
input(cls := "input", value := entry.startKm.payload.toString())
val endKmInput =
input(cls := "input", value := entry.endKm.payload.toString())
val animalInput = input(cls := "input", value := entry.animal.payload)
val costWearInput =
input(cls := "input", value := entry.costWear.toString())
val costTotalInput =
input(cls := "input", value := entry.costTotal.toString())
val paidCheckbox = input(`type` := "checkbox", checked := entry.paid)
val paidCheckbox =
input(`type` := "checkbox", checked := entry.paid.payload)
tr(
// td(input(cls := "input", value := entry.date.toDateString())),
td(),
td(driverInput),
td(startKmInput),
td(endKmInput),
@ -40,10 +42,11 @@ class EntryComponent(
editClickBus.emit(entry.id, false)
entryEditBus.emit(
entry.copy(
startKm = startKmInput.ref.value.toDouble,
endKm = endKmInput.ref.value.toDouble,
animal = animalInput.ref.value,
paid = paidCheckbox.ref.checked
startKm =
entry.startKm.write(startKmInput.ref.value.toDouble),
endKm = entry.endKm.write(endKmInput.ref.value.toDouble),
animal = entry.animal.write(animalInput.ref.value),
paid = entry.paid.write(paidCheckbox.ref.checked)
)
)
},
@ -56,14 +59,14 @@ class EntryComponent(
)
else
tr(
// td(entry.date.toDateString()),
td(entry.driver),
td(entry.startKm),
td(entry.endKm),
td(entry.animal),
td(entry.date.payload.toISOString()),
td(entry.driver.payload),
td(entry.startKm.payload),
td(entry.endKm.payload),
td(entry.animal.payload),
td(s"${entry.costWear}"),
td(s"${entry.costTotal}"),
td(if entry.paid then "Ja" else "Nein"),
td(if entry.paid.payload then "Ja" else "Nein"),
td(
button(
cls := "button is-link",

View file

@ -7,6 +7,8 @@ import com.raquo.laminar.api.features.unitArrows
import fahrtenbuch.Main.entryEditBus
import fahrtenbuch.model.Entry
import rdts.base.Uid
import rdts.datatypes.LastWriterWins
import scala.scalajs.js.Date
class NewEntryInput(showNewEntryField: Var[Boolean]):
val newEntryDriver = input(cls := "input")
@ -17,6 +19,7 @@ class NewEntryInput(showNewEntryField: Var[Boolean]):
def render =
tr(
td(),
td(newEntryDriver),
td(newEntryStartKm),
td(newEntryEndKm),
@ -29,13 +32,14 @@ class NewEntryInput(showNewEntryField: Var[Boolean]):
cls := "button is-success",
onClick --> {
val id = Uid.gen()
val driver = newEntryDriver.ref.value
val startKm = newEntryStartKm.ref.value.toDouble
val endKm = newEntryEndKm.ref.value.toDouble
val animal = newEntryAnimal.ref.value
val paid = newEntryPaid.ref.checked
val driver = LastWriterWins.now(newEntryDriver.ref.value)
val startKm = LastWriterWins.now(newEntryStartKm.ref.value.toDouble)
val endKm = LastWriterWins.now(newEntryEndKm.ref.value.toDouble)
val animal = LastWriterWins.now(newEntryAnimal.ref.value)
val paid = LastWriterWins.now(newEntryPaid.ref.checked)
val date = LastWriterWins.now(new Date(Date.now()))
entryEditBus.emit(
Entry(id, startKm, endKm, animal, paid, driver)
Entry(id, startKm, endKm, animal, paid, driver, date)
)
showNewEntryField.set(false)
newEntryDriver.ref.value = ""

View file

@ -5,17 +5,18 @@ import scala.scalajs.js.Date
import org.getshaka.nativeconverter.NativeConverter
import org.getshaka.nativeconverter.ParseState
import scala.scalajs.js
import rdts.datatypes.LastWriterWins
case class Entry(
id: Uid,
startKm: Double,
endKm: Double,
animal: String,
paid: Boolean,
driver: String,
date: Option[Date] = None
startKm: LastWriterWins[Double],
endKm: LastWriterWins[Double],
animal: LastWriterWins[String],
paid: LastWriterWins[Boolean],
driver: LastWriterWins[String],
date: LastWriterWins[Date]
) derives NativeConverter:
val distance = endKm - startKm
val distance = endKm.payload - startKm.payload
// 13 cent pro km, 5 cent Abnutzung
def costGas: Double = distance * 0.13