refactor(sessions): show job name in automation groups and preserve action labels

This commit is contained in:
M57 committed 2026-09-05 23:02:46 +03:00
1 parent acc9c7ce9a
commit 1135f05011
4 files changed
+42 -11

No files matched your search

@@ -6,6 +6,7 @@ internal data class AutomationSessionGroup(
val key: String,
val jobId: String?,
val sessions: List<SessionInfo>,
val title: String? = null,
)
// cron.scheduler mints durable run IDs as cron_{job_id}_{YYYYMMDD_HHMMSS}.
@@ -20,9 +21,18 @@ internal fun automationGroups(sessions: List<SessionInfo>): List<AutomationSessi
if (session.source == "cron") CRON_RUN_ID.matchEntire(session.id)?.groupValues?.get(1) else null
jobId?.let { "job:$it" } ?: "session:${session.id}"
}.map { (key, runs) ->
val jobId = key.takeIf { it.startsWith("job:") }?.removePrefix("job:")
val title =
runs
.mapNotNull { it.title?.takeIf(String::isNotBlank) }
.firstOrNull()
?.substringBeforeLast(" · ")
?.trim()
?.takeIf(String::isNotBlank)
AutomationSessionGroup(
key = key,
jobId = key.takeIf { it.startsWith("job:") }?.removePrefix("job:"),
jobId = jobId,
title = title,
sessions = runs,
)
}
@@ -617,7 +617,7 @@ fun SessionsScreen(
modifier = Modifier.size(18.dp),
)
Spacer(modifier = Modifier.width(spacing.xs))
Text(stringResource(R.string.sessions_empty_cleanup_all_history))
Text(stringResource(R.string.sessions_empty_cleanup_desc))
}
}
}
@@ -823,7 +823,7 @@ fun SessionsScreen(
modifier = Modifier.size(20.dp),
)
Text(
text = stringResource(R.string.sessions_action_prune_all_history),
text = stringResource(R.string.sessions_action_prune),
style = MaterialTheme.typography.labelMedium,
color = statusColors.warning,
fontWeight = FontWeight.SemiBold,
@@ -946,12 +946,13 @@ fun SessionsScreen(
Column {
Text(
text =
group.jobId?.let {
stringResource(
R.string.sessions_section_automation_job,
it,
)
} ?: stringResource(
group.title
?: group.jobId?.let {
stringResource(
R.string.sessions_section_automation_job,
it,
)
} ?: stringResource(
R.string.sessions_section_automation_unknown,
),
style = MaterialTheme.typography.titleSmall,
-2
View File
@@ -590,13 +590,11 @@
<string name="sessions_section_automation_unknown">Automation run</string>
<string name="sessions_section_automation_runs">%1$d loaded run(s)</string>
<string name="sessions_action_prune">Prune</string>
<string name="sessions_action_prune_all_history">Prune all history</string>
<string name="sessions_prune_title">Prune Old Sessions</string>
<string name="sessions_prune_desc">Delete sessions older than the specified number of days.</string>
<string name="sessions_prune_days_label">Days threshold</string>
<string name="sessions_prune_confirm">Prune</string>
<string name="sessions_empty_cleanup_desc">Empty</string>
<string name="sessions_empty_cleanup_all_history">Empty in all history</string>
<string name="sessions_empty_cleanup_title">Delete empty sessions?</string>
<string name="sessions_empty_cleanup_message">Delete %1$d empty session(s). Active and archived sessions are kept.</string>
<string name="sessions_empty_cleanup_confirm">Delete</string>
@@ -53,4 +53,26 @@ class HistorySessionGroupsTest {
val groups = automationGroups(listOf(SessionInfo("cron_job_20260905_100000", source = "cli")))
assertNull(groups.single().jobId)
}
@Test
fun derivesJobTitleFromLatestSessionWhileGroupingByJobId() {
val groups =
automationGroups(
listOf(
SessionInfo(
"cron_nightly_20260905_100000",
title = "Nightly Backup · Sep 05 10:00",
source = "cron",
),
SessionInfo(
"cron_nightly_20260905_090000",
title = "Nightly Backup · Sep 05 09:00",
source = "cron",
),
),
)
assertEquals(1, groups.size)
assertEquals("nightly", groups.single().jobId)
assertEquals("Nightly Backup", groups.single().title)
}
}