feat(Diary): implement quick create functionality for training days and enhance localization
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 44s
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 44s
- Added a new button for quick creation of training days in the DiaryView, improving user experience. - Implemented logic to find the next available training slot across groups and create a training day entry. - Enhanced localization by adding new keys for quick create messages in multiple languages, ensuring better accessibility for users. - Updated the DiaryManager to handle quick create operations and clear errors effectively.
This commit is contained in:
@@ -43,6 +43,11 @@ kotlin {
|
||||
iosMain.dependencies {
|
||||
implementation(libs.ktor.client.darwin)
|
||||
}
|
||||
androidUnitTest.dependencies {
|
||||
implementation(libs.junit)
|
||||
implementation(kotlin("test-junit"))
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package de.tsschulz.tt_tagebuch.shared.api.models
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Phase 14: Regression gegen API-Inkonsistenzen (Boolean als 0/1/String) – siehe [FlexibleNullableBooleanSerializer].
|
||||
*/
|
||||
class InternalTournamentSerializationTest {
|
||||
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
isLenient = true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun internalSummary_deserializesNumericBooleans() {
|
||||
val raw = """{"id":1,"name":"X","allowsExternal":1,"isDoublesTournament":0}"""
|
||||
val dto = json.decodeFromString(InternalTournamentSummaryDto.serializer(), raw)
|
||||
assertEquals(1, dto.id)
|
||||
assertEquals(true, dto.allowsExternal)
|
||||
assertEquals(false, dto.isDoublesTournament)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun internalSummary_deserializesStringBooleans() {
|
||||
val raw = """{"id":2,"allowsExternal":"true","isDoublesTournament":"no"}"""
|
||||
val dto = json.decodeFromString(InternalTournamentSummaryDto.serializer(), raw)
|
||||
assertTrue(dto.allowsExternal == true)
|
||||
assertTrue(dto.isDoublesTournament == false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun internalDetail_deserializesMixedBooleanForms() {
|
||||
val raw = """{"id":3,"allowsExternal":0,"isDoublesTournament":"1"}"""
|
||||
val dto = json.decodeFromString(InternalTournamentDetailDto.serializer(), raw)
|
||||
assertFalse(dto.allowsExternal == true)
|
||||
assertTrue(dto.isDoublesTournament == true)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -219,6 +219,10 @@ class DiaryManager(
|
||||
participantsApi.updateParticipantGroup(diaryDateId, memberId, groupId)
|
||||
}
|
||||
|
||||
fun clearError() {
|
||||
_state.value = _state.value.copy(error = null)
|
||||
}
|
||||
|
||||
suspend fun loadDates(clubId: Int) {
|
||||
_state.value = _state.value.copy(isLoading = true, error = null)
|
||||
try {
|
||||
@@ -229,13 +233,16 @@ class DiaryManager(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun createDate(clubId: Int, date: String, trainingStart: String?, trainingEnd: String?) {
|
||||
/** @return neue `diaryDateId` bei Erfolg, sonst `null` */
|
||||
suspend fun createDate(clubId: Int, date: String, trainingStart: String?, trainingEnd: String?): Int? {
|
||||
_state.value = _state.value.copy(isLoading = true, error = null)
|
||||
try {
|
||||
diaryApi.createDate(clubId, date, trainingStart, trainingEnd)
|
||||
return try {
|
||||
val created = diaryApi.createDate(clubId, date, trainingStart, trainingEnd)
|
||||
loadDates(clubId)
|
||||
created.id
|
||||
} catch (t: Throwable) {
|
||||
_state.value = _state.value.copy(isLoading = false, error = t.toUserMessage("Eintrag konnte nicht erstellt werden"))
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user