chore: enhance Stammdaten-Verwaltung and refine desktop UX across multiple features, fix typo in settings.json, enable WASM builds, and add Master-Detail layout for Funktionäre
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Has been cancelled

This commit is contained in:
2026-04-20 02:49:30 +02:00
parent d4aeba4666
commit 345c329350
14 changed files with 748 additions and 123 deletions
@@ -1,12 +1,12 @@
package at.mocode.frontend.core.designsystem.components
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
enum class ButtonVariant {
@@ -24,6 +24,7 @@ fun MsButton(
modifier: Modifier = Modifier,
variant: ButtonVariant = ButtonVariant.PRIMARY,
size: ButtonSize = ButtonSize.MEDIUM,
icon: ImageVector? = null,
enabled: Boolean = true,
isLoading: Boolean = false,
fullWidth: Boolean = false,
@@ -44,34 +45,38 @@ fun MsButton(
onClick = onClick,
modifier = buttonModifier,
enabled = enabled && !isLoading,
contentPadding = if (icon != null) ButtonDefaults.ButtonWithIconContentPadding else ButtonDefaults.ContentPadding,
colors = if (containerColor != null) ButtonDefaults.buttonColors(containerColor = containerColor) else ButtonDefaults.buttonColors()
) {
ButtonContent(text = text, isLoading = isLoading)
ButtonContent(text = text, isLoading = isLoading, icon = icon)
}
ButtonVariant.SECONDARY -> FilledTonalButton(
onClick = onClick,
modifier = buttonModifier,
enabled = enabled && !isLoading,
contentPadding = if (icon != null) ButtonDefaults.ButtonWithIconContentPadding else ButtonDefaults.ContentPadding,
colors = if (containerColor != null) ButtonDefaults.filledTonalButtonColors(containerColor = containerColor) else ButtonDefaults.filledTonalButtonColors()
) {
ButtonContent(text = text, isLoading = isLoading)
ButtonContent(text = text, isLoading = isLoading, icon = icon)
}
ButtonVariant.OUTLINE -> OutlinedButton(
onClick = onClick,
modifier = buttonModifier,
enabled = enabled && !isLoading
enabled = enabled && !isLoading,
contentPadding = if (icon != null) ButtonDefaults.ButtonWithIconContentPadding else ButtonDefaults.ContentPadding
) {
ButtonContent(text = text, isLoading = isLoading)
ButtonContent(text = text, isLoading = isLoading, icon = icon)
}
ButtonVariant.TEXT -> TextButton(
onClick = onClick,
modifier = buttonModifier,
enabled = enabled && !isLoading
enabled = enabled && !isLoading,
contentPadding = if (icon != null) ButtonDefaults.TextButtonWithIconContentPadding else ButtonDefaults.TextButtonContentPadding
) {
ButtonContent(text = text, isLoading = isLoading)
ButtonContent(text = text, isLoading = isLoading, icon = icon)
}
}
}
@@ -79,15 +84,27 @@ fun MsButton(
@Composable
private fun ButtonContent(
text: String,
isLoading: Boolean
isLoading: Boolean,
icon: ImageVector? = null
) {
if (isLoading) {
CircularProgressIndicator(
modifier = Modifier.padding(2.dp),
strokeWidth = 2.dp
modifier = Modifier.size(18.dp),
strokeWidth = 2.dp,
color = LocalContentColor.current
)
} else {
Text(text)
Row(verticalAlignment = Alignment.CenterVertically) {
if (icon != null) {
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(ButtonDefaults.IconSize)
)
Spacer(Modifier.width(ButtonDefaults.IconSpacing))
}
Text(text)
}
}
}
@@ -57,6 +57,7 @@ fun <T> MsDataTable(
items: List<T>,
columns: List<MsColumnDefinition<T>>,
onRowClick: ((T) -> Unit)? = null,
selectedItem: T? = null,
modifier: Modifier = Modifier,
headerBackgroundColor: Color = MaterialTheme.colorScheme.surfaceVariant,
rowBackgroundColor: Color = MaterialTheme.colorScheme.surface,
@@ -100,7 +101,12 @@ fun <T> MsDataTable(
val state = androidx.compose.foundation.lazy.rememberLazyListState()
LazyColumn(state = state, modifier = Modifier.fillMaxSize()) {
itemsIndexed(items) { index, item ->
val bgColor = if (index % 2 == 0) rowBackgroundColor else alternateRowBackgroundColor
val isSelected = item == selectedItem
val bgColor = when {
isSelected -> MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f)
index % 2 == 0 -> rowBackgroundColor
else -> alternateRowBackgroundColor
}
Surface(
color = bgColor,