feat(desktop, masterdata): ZNS-Sync-Status in Footer hinzugefügt & Consul-Healthcheck stabilisiert

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-04-17 09:54:12 +02:00
parent 4b6a242372
commit 0128f98164
4 changed files with 115 additions and 6 deletions
@@ -20,6 +20,7 @@ import at.mocode.desktop.screens.onboarding.OnboardingSettings
import at.mocode.desktop.screens.onboarding.SettingsManager
import at.mocode.frontend.core.designsystem.theme.AppColors
import at.mocode.frontend.core.designsystem.theme.Dimens
import at.mocode.frontend.core.domain.zns.ZnsImportProvider
import at.mocode.frontend.core.navigation.AppScreen
import at.mocode.frontend.core.network.ConnectivityTracker
import at.mocode.frontend.core.network.discovery.NetworkDiscoveryService
@@ -857,8 +858,10 @@ private fun DesktopContentArea(
private fun DesktopFooterBar(settings: OnboardingSettings) {
val connectivityTracker = koinInject<ConnectivityTracker>()
val discoveryService = koinInject<NetworkDiscoveryService>()
val znsImporter = koinInject<ZnsImportProvider>()
val online by connectivityTracker.isOnline.collectAsState()
val znsState = znsImporter.state
val discoveredServices = remember { mutableStateOf(discoveryService.getDiscoveredServices()) }
val deviceName = settings.geraetName.ifBlank { "Unbekannt" }
@@ -901,6 +904,17 @@ private fun DesktopFooterBar(settings: OnboardingSettings) {
label = if (deviceCount > 0) "Verbunden: $deviceName ($deviceCount im Netz)" else "Lokal: $deviceName",
color = if (deviceCount > 0) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline
)
Spacer(Modifier.width(Dimens.SpacingM))
// Status: ZNS Stammdaten
val lastSync = znsState.lastSyncVersion
val znsLabel = if (lastSync != null) "ZNS: $lastSync" else "ZNS: Kein Sync"
StatusIndicator(
icon = Icons.Default.Dataset,
label = znsLabel,
color = if (lastSync != null) MaterialTheme.colorScheme.secondary else MaterialTheme.colorScheme.error
)
}
Row(verticalAlignment = Alignment.CenterVertically) {
@@ -277,8 +277,14 @@ fun VeranstalterAnlegenWizard(
OutlinedTextField(
value = oeps,
onValueChange = { oeps = it },
label = { Text("OEPS-Nummer") },
modifier = Modifier.weight(1f)
label = { Text("OEPS-Nummer (z.B. 4-001)") },
modifier = Modifier.weight(1f),
isError = oeps.isNotEmpty() && !oeps.matches(Regex("^[1-9]-[0-9]{3}$")),
supportingText = {
if (oeps.isNotEmpty() && !oeps.matches(Regex("^[1-9]-[0-9]{3}$"))) {
Text("Format: B-NNN (z.B. 4-001)")
}
}
)
}
@@ -614,6 +620,13 @@ fun VeranstaltungKonfigV2(
}
val today = LocalDate.now()
val isStartInPast = dateVon != null && dateVon.isBefore(today)
val daysBetween = if (dateVon != null && dateBis != null) {
java.time.temporal.ChronoUnit.DAYS.between(dateVon, dateBis) + 1
} else null
val isOetoConform = daysBetween == null || daysBetween <= 2
val isDateRangeInvalid =
(dateVon != null && dateBis != null && dateBis.isBefore(dateVon)) || isStartInPast
@@ -663,8 +676,27 @@ fun VeranstaltungKonfigV2(
}
},
supportingText = {
if (isDateRangeInvalid) {
Text("Enddatum darf nicht vor dem Startdatum liegen.")
Column {
if (isDateRangeInvalid) {
Text("Enddatum darf nicht vor dem Startdatum liegen.")
}
if (isOetoConform.not()) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
Icon(
Icons.Default.Info,
contentDescription = null,
modifier = Modifier.size(14.dp),
tint = MaterialTheme.colorScheme.primary
)
Text(
"Hinweis: Gemäß ÖTO sind C-Turniere auf 2 Tage begrenzt.",
color = MaterialTheme.colorScheme.primary
)
}
}
}
}
)