From 1135f05011b00bdf68ceb9f15ce1e32f6e0006a4 Mon Sep 17 00:00:00 2001 From: M57 <41645758+Hy4ri@users.noreply.github.com> Date: Sat, 5 Sep 2026 23:02:46 +0300 Subject: [PATCH] refactor(sessions): show job name in automation groups and preserve action labels --- .../ui/sessions/AutomationSessionGroup.kt | 12 +++++++++- .../ui/sessions/SessionsScreen.kt | 17 +++++++------- app/src/main/res/values/strings.xml | 2 -- .../ui/sessions/HistorySessionGroupsTest.kt | 22 +++++++++++++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/m57/hermescontrol/ui/sessions/AutomationSessionGroup.kt b/app/src/main/java/com/m57/hermescontrol/ui/sessions/AutomationSessionGroup.kt index 226b890b..1b2b86f5 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/sessions/AutomationSessionGroup.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/sessions/AutomationSessionGroup.kt @@ -6,6 +6,7 @@ internal data class AutomationSessionGroup( val key: String, val jobId: String?, val sessions: List, + 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): List + 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, ) } diff --git a/app/src/main/java/com/m57/hermescontrol/ui/sessions/SessionsScreen.kt b/app/src/main/java/com/m57/hermescontrol/ui/sessions/SessionsScreen.kt index 50f3e8f3..2db365ce 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/sessions/SessionsScreen.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/sessions/SessionsScreen.kt @@ -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, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 038ef2bb..995ed704 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -590,13 +590,11 @@ Automation run %1$d loaded run(s) Prune - Prune all history Prune Old Sessions Delete sessions older than the specified number of days. Days threshold Prune Empty - Empty in all history Delete empty sessions? Delete %1$d empty session(s). Active and archived sessions are kept. Delete diff --git a/app/src/test/java/com/m57/hermescontrol/ui/sessions/HistorySessionGroupsTest.kt b/app/src/test/java/com/m57/hermescontrol/ui/sessions/HistorySessionGroupsTest.kt index 454a0a46..c70b80c4 100644 --- a/app/src/test/java/com/m57/hermescontrol/ui/sessions/HistorySessionGroupsTest.kt +++ b/app/src/test/java/com/m57/hermescontrol/ui/sessions/HistorySessionGroupsTest.kt @@ -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) + } }