feat: yellow RDG flap badge on dashboard and events (0.5.9)

Match SAC styling for RDG session flap events on the home screen and events list.
This commit is contained in:
PTah
2026-06-20 19:13:58 +10:00
parent 23d5cd271b
commit c040b7a6c6
4 changed files with 80 additions and 16 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
Android-клиент [Security Alert Center (SAC)](https://git.kalinamall.ru/PapaTramp/security-alert-center). Android-клиент [Security Alert Center (SAC)](https://git.kalinamall.ru/PapaTramp/security-alert-center).
**Версия:** `0.5.8` (versionCode 22) **Версия:** `0.5.9` (versionCode 23)
## Возможности ## Возможности
+2 -2
View File
@@ -13,8 +13,8 @@ android {
applicationId = "ru.kalinamall.seaca" applicationId = "ru.kalinamall.seaca"
minSdk = 26 minSdk = 26
targetSdk = 35 targetSdk = 35
versionCode = 22 versionCode = 23
versionName = "0.5.8" versionName = "0.5.9"
} }
buildTypes { buildTypes {
@@ -0,0 +1,43 @@
package ru.kalinamall.seaca.ui.components
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
private val RdgFlapText = Color(0xFFF0C674)
private val RdgFlapBackground = Color(0x1FF0C674)
private val RdgFlapBorder = Color(0x73F0C674)
@Composable
fun RdgFlapBadge(
modifier: Modifier = Modifier,
pairEventId: Long? = null,
) {
val label = buildString {
append("RDG FLAP")
if (pairEventId != null) append(" #$pairEventId")
}
Surface(
modifier = modifier
.border(1.dp, RdgFlapBorder, RoundedCornerShape(4.dp)),
shape = RoundedCornerShape(4.dp),
color = RdgFlapBackground,
) {
Text(
text = label,
modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp),
color = RdgFlapText,
fontSize = 11.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = 0.3.sp,
)
}
}
@@ -46,6 +46,7 @@ import ru.kalinamall.seaca.data.HostSummary
import ru.kalinamall.seaca.data.ProblemSummary import ru.kalinamall.seaca.data.ProblemSummary
import ru.kalinamall.seaca.data.SacRepository import ru.kalinamall.seaca.data.SacRepository
import ru.kalinamall.seaca.ui.components.BackArrowButton import ru.kalinamall.seaca.ui.components.BackArrowButton
import ru.kalinamall.seaca.ui.components.RdgFlapBadge
import ru.kalinamall.seaca.ui.components.ForwardArrowButton import ru.kalinamall.seaca.ui.components.ForwardArrowButton
import ru.kalinamall.seaca.ui.util.SacDateTimes import ru.kalinamall.seaca.ui.util.SacDateTimes
import ru.kalinamall.seaca.ui.util.hasRdgFlapUi import ru.kalinamall.seaca.ui.util.hasRdgFlapUi
@@ -122,12 +123,16 @@ fun DashboardScreen(repo: SacRepository, refreshKey: Int = 0) {
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.Top, verticalAlignment = Alignment.Top,
) { ) {
Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(4.dp)) {
if (hasRdgFlapUi(e)) {
RdgFlapBadge(pairEventId = e.rdgFlapPairEventId)
}
Text( Text(
dashboardRecentEventLine(e), dashboardRecentEventLine(e),
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.weight(1f),
) )
}
Text( Text(
SacDateTimes.format(e.occurredAt, dateMode), SacDateTimes.format(e.occurredAt, dateMode),
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
@@ -190,11 +195,10 @@ fun EventsScreen(repo: SacRepository, onOpen: (Long) -> Unit) {
res.items to res.total res.items to res.total
}, },
itemKey = EventSummary::id, itemKey = EventSummary::id,
itemLabel = { itemLabel = { "${it.severity} · ${it.title}" },
val prefix = if (hasRdgFlapUi(it)) "RDG flap · " else ""
"$prefix${it.severity} · ${it.title}"
},
itemSub = { "${it.hostname} · ${SacDateTimes.format(it.occurredAt, dateMode)}" }, itemSub = { "${it.hostname} · ${SacDateTimes.format(it.occurredAt, dateMode)}" },
itemRdgFlap = { hasRdgFlapUi(it) },
itemRdgFlapPairId = { it.rdgFlapPairEventId },
onOpen = onOpen, onOpen = onOpen,
severities = listOf(null, "info", "warning", "high", "critical"), severities = listOf(null, "info", "warning", "high", "critical"),
hostnameFilter = hostname, hostnameFilter = hostname,
@@ -331,6 +335,8 @@ private fun <T> PagedListScreen(
itemSub: (T) -> String, itemSub: (T) -> String,
onOpen: (Long) -> Unit, onOpen: (Long) -> Unit,
severities: List<String?>, severities: List<String?>,
itemRdgFlap: ((T) -> Boolean)? = null,
itemRdgFlapPairId: ((T) -> Long?)? = null,
filterLabel: String = "Severity", filterLabel: String = "Severity",
hostnameFilter: String = "", hostnameFilter: String = "",
headerContent: @Composable () -> Unit = {}, headerContent: @Composable () -> Unit = {},
@@ -389,7 +395,13 @@ private fun <T> PagedListScreen(
) { ) {
LazyColumn { LazyColumn {
items(items, key = { itemKey(it) }) { item -> items(items, key = { itemKey(it) }) { item ->
ListRow(itemLabel(item), itemSub(item)) { onOpen(itemKey(item)) } ListRow(
title = itemLabel(item),
subtitle = itemSub(item),
onClick = { onOpen(itemKey(item)) },
rdgFlap = itemRdgFlap?.invoke(item) == true,
rdgFlapPairId = itemRdgFlapPairId?.invoke(item),
)
} }
} }
} }
@@ -398,7 +410,13 @@ private fun <T> PagedListScreen(
} }
@Composable @Composable
private fun ListRow(title: String, subtitle: String, onClick: () -> Unit) { private fun ListRow(
title: String,
subtitle: String,
onClick: () -> Unit,
rdgFlap: Boolean = false,
rdgFlapPairId: Long? = null,
) {
Card( Card(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -409,7 +427,10 @@ private fun ListRow(title: String, subtitle: String, onClick: () -> Unit) {
contentColor = MaterialTheme.colorScheme.onSurface, contentColor = MaterialTheme.colorScheme.onSurface,
), ),
) { ) {
Column(Modifier.padding(12.dp)) { Column(Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(4.dp)) {
if (rdgFlap) {
RdgFlapBadge(pairEventId = rdgFlapPairId)
}
Text(title, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurface) Text(title, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurface)
Text(subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) Text(subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
} }