refactor(desktop, core): Onboarding zu DeviceInitialization umbenannt, Navigation und Screens angepasst
Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
package at.mocode.ping.feature.presentation
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.HealthAndSafety
|
||||
import androidx.compose.material.icons.filled.Lock
|
||||
import androidx.compose.material.icons.filled.NetworkCheck
|
||||
import androidx.compose.material.icons.filled.Sync
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
|
||||
/**
|
||||
* Eine modulare Gruppe von Test-Buttons für die Konnektivitäts-Diagnose.
|
||||
* Plug-and-Play fähig für Ping-Screen oder Sidebar.
|
||||
*/
|
||||
@Composable
|
||||
fun PingActionGroup(
|
||||
viewModel: PingViewModel,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val uiState = viewModel.uiState
|
||||
|
||||
Column(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(Dimens.SpacingS)
|
||||
) {
|
||||
Text(
|
||||
text = "DIAGNOSE-TESTS",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold,
|
||||
modifier = Modifier.padding(bottom = Dimens.SpacingXS)
|
||||
)
|
||||
|
||||
// Grid-ähnliches Layout für die Buttons
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(Dimens.SpacingS)) {
|
||||
PingTestButton(
|
||||
text = "Simple Ping",
|
||||
icon = Icons.Default.NetworkCheck,
|
||||
onClick = { viewModel.performSimplePing() },
|
||||
isLoading = uiState.isLoading,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
PingTestButton(
|
||||
text = "Secure Ping",
|
||||
icon = Icons.Default.Lock,
|
||||
onClick = { viewModel.performSecurePing() },
|
||||
isLoading = uiState.isLoading,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(Dimens.SpacingS)) {
|
||||
PingTestButton(
|
||||
text = "Health Check",
|
||||
icon = Icons.Default.HealthAndSafety,
|
||||
onClick = { viewModel.performHealthCheck() },
|
||||
isLoading = uiState.isLoading,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
PingTestButton(
|
||||
text = "Delta Sync",
|
||||
icon = Icons.Default.Sync,
|
||||
onClick = { viewModel.triggerSync() },
|
||||
isLoading = uiState.isSyncing,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
|
||||
// Zusätzlicher Button für Enhanced Ping (Circuit Breaker Test)
|
||||
OutlinedButton(
|
||||
onClick = { viewModel.performEnhancedPing() },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isLoading
|
||||
) {
|
||||
Text("Enhanced Ping (Simulation)", fontSize = 12.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PingTestButton(
|
||||
text: String,
|
||||
icon: androidx.compose.ui.graphics.vector.ImageVector,
|
||||
onClick: () -> Unit,
|
||||
isLoading: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Button(
|
||||
onClick = onClick,
|
||||
modifier = modifier.height(48.dp),
|
||||
enabled = !isLoading,
|
||||
contentPadding = PaddingValues(horizontal = Dimens.SpacingS)
|
||||
) {
|
||||
Icon(icon, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||
Spacer(Modifier.width(Dimens.SpacingXS))
|
||||
Text(text, fontSize = 12.sp, maxLines = 1)
|
||||
}
|
||||
}
|
||||
+22
-82
@@ -2,8 +2,6 @@ package at.mocode.ping.feature.presentation
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
@@ -11,21 +9,22 @@ 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.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import at.mocode.frontend.core.designsystem.components.ButtonSize
|
||||
import at.mocode.frontend.core.designsystem.components.MsButton
|
||||
import at.mocode.frontend.core.auth.presentation.AuthStatusCard
|
||||
import at.mocode.frontend.core.auth.presentation.LoginViewModel
|
||||
import at.mocode.frontend.core.designsystem.components.MsCard
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@Composable
|
||||
fun PingScreen(
|
||||
viewModel: PingViewModel,
|
||||
onBack: () -> Unit = {}
|
||||
onBack: () -> Unit = {},
|
||||
onNavigateToLogin: () -> Unit = {}
|
||||
) {
|
||||
val uiState = viewModel.uiState
|
||||
val authViewModel: LoginViewModel = koinInject()
|
||||
|
||||
// Wir nutzen jetzt das globale Theme (Hintergrund kommt vom Theme)
|
||||
Column(
|
||||
@@ -43,7 +42,15 @@ fun PingScreen(
|
||||
|
||||
Spacer(Modifier.height(Dimens.SpacingS))
|
||||
|
||||
// 2. Main Dashboard Area (Split View)
|
||||
// 2. Auth Status Area (Plug-and-Play)
|
||||
AuthStatusCard(
|
||||
viewModel = authViewModel,
|
||||
onLoginClick = onNavigateToLogin
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(Dimens.SpacingS))
|
||||
|
||||
// 3. Main Dashboard Area (Split View)
|
||||
Row(modifier = Modifier.weight(1f)) {
|
||||
// Left Panel: Controls & Status Grid (60%)
|
||||
Column(
|
||||
@@ -52,26 +59,24 @@ fun PingScreen(
|
||||
.fillMaxHeight()
|
||||
.padding(end = Dimens.SpacingS)
|
||||
) {
|
||||
ActionToolbar(viewModel)
|
||||
PingActionGroup(viewModel)
|
||||
Spacer(Modifier.height(Dimens.SpacingS))
|
||||
StatusGrid(uiState)
|
||||
}
|
||||
|
||||
// Right Panel: Terminal Log (40%)
|
||||
// Hier nutzen wir bewusst einen dunklen "Terminal"-Look, unabhängig vom Theme
|
||||
MsCard(
|
||||
TerminalConsole(
|
||||
logs = uiState.logs,
|
||||
onClear = { viewModel.clearLogs() },
|
||||
modifier = Modifier
|
||||
.weight(0.4f)
|
||||
.fillMaxHeight()
|
||||
) {
|
||||
LogHeader(onClear = { viewModel.clearLogs() })
|
||||
LogConsole(uiState.logs)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(Dimens.SpacingXS))
|
||||
|
||||
// 3. Footer
|
||||
// 4. Footer
|
||||
PingStatusBar(uiState.lastSyncResult)
|
||||
}
|
||||
}
|
||||
@@ -90,7 +95,7 @@ private fun PingHeader(
|
||||
Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back", tint = MaterialTheme.colorScheme.onBackground)
|
||||
}
|
||||
Text(
|
||||
"PING SERVICE // DASHBOARD",
|
||||
"KONNEKTIVITÄTS-DIAGNOSE // DASHBOARD",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
modifier = Modifier.weight(1f).padding(start = Dimens.SpacingS)
|
||||
@@ -131,27 +136,6 @@ private fun StatusBadge(text: String, color: Color) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ActionToolbar(viewModel: PingViewModel) {
|
||||
// Wrap buttons to avoid overflow on small screens
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
FlowRow(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(Dimens.SpacingXS),
|
||||
verticalArrangement = Arrangement.spacedBy(Dimens.SpacingXS)
|
||||
) {
|
||||
MsButton(text = "Simple", size = ButtonSize.SMALL, onClick = { viewModel.performSimplePing() })
|
||||
MsButton(text = "Enhanced", size = ButtonSize.SMALL, onClick = { viewModel.performEnhancedPing() })
|
||||
MsButton(text = "Secure", size = ButtonSize.SMALL, onClick = { viewModel.performSecurePing() })
|
||||
MsButton(text = "Health", size = ButtonSize.SMALL, onClick = { viewModel.performHealthCheck() })
|
||||
MsButton(
|
||||
text = "Sync",
|
||||
size = ButtonSize.SMALL,
|
||||
onClick = { viewModel.triggerSync() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatusGrid(uiState: PingUiState) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(Dimens.SpacingS)) {
|
||||
@@ -237,50 +221,6 @@ private fun KeyValueRow(key: String, value: String) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Log Components (Terminal Style - intentionally distinct) ---
|
||||
|
||||
@Composable
|
||||
private fun LogHeader(onClear: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = Dimens.SpacingXS),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text("EVENT LOG", style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold)
|
||||
TextButton(
|
||||
onClick = onClear,
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
modifier = Modifier.height(24.dp)
|
||||
) {
|
||||
Text("CLEAR", style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LogConsole(logs: List<LogEntry>) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color(0xFF1E1E1E)) // Always dark for terminal
|
||||
.padding(Dimens.SpacingXS),
|
||||
reverseLayout = false
|
||||
) {
|
||||
items(logs) { log ->
|
||||
val color = if (log.isError) Color(0xFFFF5555) else Color(0xFF55FF55)
|
||||
Text(
|
||||
text = "[${log.timestamp}] [${log.source}] ${log.message}",
|
||||
color = color,
|
||||
fontSize = 11.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
lineHeight = 14.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PingStatusBar(lastSync: String?) {
|
||||
Surface(
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package at.mocode.ping.feature.presentation
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
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.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
|
||||
/**
|
||||
* Eine universelle Terminal-Konsole zur Anzeige von Log-Einträgen.
|
||||
* Plug-and-Play ist fähig für verschiedene Features (Ping, Sync, Auth-Logs).
|
||||
*/
|
||||
@Composable
|
||||
fun TerminalConsole(
|
||||
logs: List<LogEntry>,
|
||||
modifier: Modifier = Modifier,
|
||||
onClear: () -> Unit = {}
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = Dimens.SpacingXS),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text("EVENT LOG", style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold)
|
||||
TextButton(
|
||||
onClick = onClear,
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
modifier = Modifier.height(24.dp)
|
||||
) {
|
||||
Text("CLEAR", style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color(0xFF1E1E1E)) // Terminallook (Dunkel)
|
||||
.padding(Dimens.SpacingXS)
|
||||
) {
|
||||
items(logs) { log ->
|
||||
val color = if (log.isError) Color(0xFFFF5555) else Color(0xFF55FF55)
|
||||
Text(
|
||||
text = "[${log.timestamp}] [${log.source}] ${log.message}",
|
||||
color = color,
|
||||
fontSize = 11.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
lineHeight = 14.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user