### feat: implementiere SQLite-Integration und Repository-Refactoring
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 58s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m0s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 6m10s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Failing after 2m0s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m55s
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 58s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m0s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 6m10s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Failing after 2m0s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m55s
- Erstelle Persistenz-Layer mit SQLite-Tabellen für `Verein` und `Reiter` inkl. Queries. - Entferne Mock-Daten in `ReiterViewModel` und nutze Repository-Injektion. - Integriere neue Tabellen und Queries im `DesktopMasterdataRepository`. - Erweitere `VeranstalterWizardViewModel` um lokale Suche mit SQLite-Queries. - Harmonisiere Feldnamen (`remoteReiterResults`) über alle Module hinweg. - Aktualisiere DI-Module (`VeranstalterModule`, `ReiterModule`, `DesktopModule`) mit SQLite-Injektionen. - Refaktor UI-Komponenten und Screens (`ReiterScreen`, `StammdatenImportScreen`) mit neuer Logik.
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
package at.mocode.frontend.features.reiter.data
|
||||
|
||||
import at.mocode.frontend.features.reiter.domain.Reiter
|
||||
import at.mocode.frontend.features.reiter.domain.ReiterRepository
|
||||
|
||||
class FakeReiterRepository : ReiterRepository {
|
||||
private val mockData = mutableListOf(
|
||||
Reiter("1", "Stefan", "Möbius", "123456"),
|
||||
Reiter("2", "Julia", "Reiterin", "654321"),
|
||||
Reiter("3", "Max", "Mustermann", "112233")
|
||||
)
|
||||
|
||||
override suspend fun getReiter(): Result<List<Reiter>> = Result.success(mockData)
|
||||
|
||||
override suspend fun searchReiter(query: String): Result<List<Reiter>> = Result.success(
|
||||
mockData.filter { it.vorname.contains(query, true) || it.nachname.contains(query, true) }
|
||||
)
|
||||
|
||||
override suspend fun findByZnsNr(znsNr: String): Reiter? = mockData.find { it.satznummer == znsNr }
|
||||
|
||||
override suspend fun saveReiter(reiter: Reiter): Result<Reiter> = Result.success(reiter)
|
||||
}
|
||||
+4
-1
@@ -1,8 +1,11 @@
|
||||
package at.mocode.frontend.features.reiter.di
|
||||
|
||||
import at.mocode.frontend.features.reiter.data.FakeReiterRepository
|
||||
import at.mocode.frontend.features.reiter.domain.ReiterRepository
|
||||
import at.mocode.frontend.features.reiter.presentation.ReiterViewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val reiterModule = module {
|
||||
factory { ReiterViewModel() }
|
||||
single<ReiterRepository> { FakeReiterRepository() }
|
||||
factory { ReiterViewModel(get<ReiterRepository>()) }
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package at.mocode.frontend.features.reiter.domain
|
||||
|
||||
interface ReiterRepository {
|
||||
suspend fun getReiter(): Result<List<Reiter>>
|
||||
suspend fun searchReiter(query: String): Result<List<Reiter>>
|
||||
suspend fun findByZnsNr(znsNr: String): Reiter?
|
||||
suspend fun saveReiter(reiter: Reiter): Result<Reiter>
|
||||
}
|
||||
+3
-2
@@ -14,6 +14,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.frontend.core.designsystem.components.*
|
||||
import at.mocode.frontend.core.designsystem.models.PlaceholderContent
|
||||
import at.mocode.frontend.features.reiter.data.FakeReiterRepository
|
||||
import at.mocode.frontend.features.reiter.domain.LizenzKlasse
|
||||
import at.mocode.frontend.features.reiter.domain.Reiter
|
||||
import at.mocode.frontend.features.reiter.domain.Sparte
|
||||
@@ -58,7 +59,7 @@ fun ReiterScreen(
|
||||
Spacer(Modifier.height(16.dp))
|
||||
ReiterCard(
|
||||
reiter = uiState.selectedReiter,
|
||||
onEdit = { viewModel.selectReiter(uiState.selectedReiter) }
|
||||
onEdit = { viewModel.selectReiter(uiState.selectedReiter!!) }
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@@ -392,7 +393,7 @@ private fun ReiterEditorContent(
|
||||
|
||||
@Composable
|
||||
fun ReiterScreenPreviewContent() {
|
||||
val viewModel = ReiterViewModel().apply {
|
||||
val viewModel = ReiterViewModel(FakeReiterRepository()).apply {
|
||||
// Optional: Hier könnten Mock-Daten direkt gesetzt werden,
|
||||
// falls das ViewModel dies unterstützt.
|
||||
}
|
||||
|
||||
+24
-15
@@ -4,10 +4,9 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import at.mocode.frontend.features.reiter.domain.LizenzKlasse
|
||||
import at.mocode.frontend.features.reiter.domain.Reiter
|
||||
import at.mocode.frontend.features.reiter.domain.ReiterStatus
|
||||
import at.mocode.frontend.features.reiter.domain.Sparte
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import at.mocode.frontend.features.reiter.domain.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* UI-State für die Reiter-Verwaltung.
|
||||
@@ -36,32 +35,42 @@ data class ReiterUiState(
|
||||
|
||||
/**
|
||||
* ViewModel für die Reiter-Verwaltung.
|
||||
* In einem echten Szenario würden wir hier ein Repository injizieren.
|
||||
*/
|
||||
open class ReiterViewModel(initialLoad: Boolean = true) : ViewModel() {
|
||||
open class ReiterViewModel(
|
||||
private val repository: ReiterRepository,
|
||||
initialLoad: Boolean = true
|
||||
) : ViewModel() {
|
||||
var uiState by mutableStateOf(ReiterUiState())
|
||||
protected set
|
||||
|
||||
init {
|
||||
if (initialLoad) {
|
||||
// Initialer Load (Mock-Daten)
|
||||
loadReiter()
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadReiter() {
|
||||
val mockData = listOf(
|
||||
Reiter("1", "Stefan", "Möbius", "123456", LizenzKlasse.R2D2, Sparte.DRESSUR, ReiterStatus.AKTIV),
|
||||
Reiter("2", "Julia", "Reiterin", "654321", LizenzKlasse.R1, Sparte.SPRINGEN, ReiterStatus.AKTIV),
|
||||
Reiter("3", "Max", "Mustermann", "112233", LizenzKlasse.KEINE, Sparte.KEINE, ReiterStatus.GESPERRT),
|
||||
Reiter("4", "Lisa", "Springen", "445566", LizenzKlasse.R3, Sparte.SPRINGEN, ReiterStatus.AKTIV)
|
||||
)
|
||||
uiState = uiState.copy(searchResults = mockData)
|
||||
uiState = uiState.copy(isLoading = true)
|
||||
viewModelScope.launch {
|
||||
repository.getReiter().onSuccess { data ->
|
||||
uiState = uiState.copy(searchResults = data, isLoading = false)
|
||||
}.onFailure {
|
||||
uiState = uiState.copy(isLoading = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onSearchQueryChange(query: String) {
|
||||
uiState = uiState.copy(searchQuery = query)
|
||||
// Hier würde die Filter-Logik greifen
|
||||
if (query.length >= 3) {
|
||||
viewModelScope.launch {
|
||||
repository.searchReiter(query).onSuccess { data ->
|
||||
uiState = uiState.copy(searchResults = data)
|
||||
}
|
||||
}
|
||||
} else if (query.isEmpty()) {
|
||||
loadReiter()
|
||||
}
|
||||
}
|
||||
|
||||
fun selectReiter(reiter: Reiter) {
|
||||
|
||||
+3
-2
@@ -3,6 +3,7 @@ package at.mocode.frontend.features.reiter.presentation
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import at.mocode.frontend.core.designsystem.preview.ComponentPreview
|
||||
import at.mocode.frontend.features.reiter.data.FakeReiterRepository
|
||||
import at.mocode.frontend.features.reiter.domain.LizenzKlasse
|
||||
import at.mocode.frontend.features.reiter.domain.Reiter
|
||||
import at.mocode.frontend.features.reiter.domain.ReiterStatus
|
||||
@@ -11,7 +12,7 @@ import at.mocode.frontend.features.reiter.domain.Sparte
|
||||
/**
|
||||
* Hilf's-ViewModel für die Vorschau, um den Status direkt setzen zu können.
|
||||
*/
|
||||
private class PreviewReiterViewModel(initialState: ReiterUiState) : ReiterViewModel(initialLoad = false) {
|
||||
private class PreviewReiterViewModel(initialState: ReiterUiState) : ReiterViewModel(FakeReiterRepository(), initialLoad = false) {
|
||||
init {
|
||||
uiState = initialState
|
||||
}
|
||||
@@ -20,7 +21,7 @@ private class PreviewReiterViewModel(initialState: ReiterUiState) : ReiterViewMo
|
||||
@ComponentPreview
|
||||
@Composable
|
||||
fun PreviewReiterScreen_List() {
|
||||
val viewModel = ReiterViewModel() // Nutzt die Mock-Daten aus dem init-Block
|
||||
val viewModel = ReiterViewModel(FakeReiterRepository()) // Nutzt die Mock-Daten aus dem init-Block
|
||||
MaterialTheme {
|
||||
ReiterScreen(viewModel = viewModel)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user