fix(kanban): localize activity event labels (#1137)

This commit is contained in:
M57 committed 2026-09-16 21:56:51 +03:00
1 parent 1735de7d9d
commit d357d604c7
6 files changed
+230 -12

No files matched your search

@@ -6,9 +6,33 @@ import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
enum class KanbanEventMessage {
CREATED,
CREATED_BY,
MOVED,
ASSIGNED,
UNASSIGNED,
COMMENTED,
CLAIMED_REVIEW,
CLAIMED_WORKER,
WORKER_STARTED,
COMPLETED,
BLOCKED,
UNBLOCKED,
RECLAIMED,
SPECIFIED,
PROMOTED,
SCHEDULED,
ARCHIVED,
PRIORITY,
UNKNOWN,
}
data class FormattedKanbanEvent(
val label: String,
val detail: String? = null,
val message: KanbanEventMessage = KanbanEventMessage.UNKNOWN,
val arguments: List<String> = emptyList(),
)
object KanbanEventFormatter {
@@ -51,7 +75,11 @@ object KanbanEventFormatter {
val status = col("status") ?: "Todo"
val assignee = str("assignee")
val label = if (assignee != null) "Created in $status by $assignee" else "Created in $status"
FormattedKanbanEvent(label = label)
FormattedKanbanEvent(
label = label,
message = if (assignee != null) KanbanEventMessage.CREATED_BY else KanbanEventMessage.CREATED,
arguments = listOfNotNull(status, assignee),
)
}
"status" -> {
@@ -66,6 +94,8 @@ object KanbanEventFormatter {
FormattedKanbanEvent(
label = "Moved to $targetStatus",
detail = detail,
message = KanbanEventMessage.MOVED,
arguments = listOf(targetStatus),
)
}
@@ -73,18 +103,32 @@ object KanbanEventFormatter {
val assignee = str("assignee")
FormattedKanbanEvent(
label = if (assignee != null) "Assigned to $assignee" else "Unassigned",
message = if (assignee != null) KanbanEventMessage.ASSIGNED else KanbanEventMessage.UNASSIGNED,
arguments = listOfNotNull(assignee),
)
}
"commented" -> {
val author = str("author") ?: "someone"
FormattedKanbanEvent(label = "Comment by $author")
FormattedKanbanEvent(
label = "Comment by $author",
message = KanbanEventMessage.COMMENTED,
arguments = listOf(author),
)
}
"claimed" -> {
val source = str("source_status")
FormattedKanbanEvent(
label = if (source == "review") "Claimed for review" else "Claimed by worker",
message =
if (source ==
"review"
) {
KanbanEventMessage.CLAIMED_REVIEW
} else {
KanbanEventMessage.CLAIMED_WORKER
},
)
}
@@ -93,49 +137,59 @@ object KanbanEventFormatter {
FormattedKanbanEvent(
label = "Worker started",
detail = if (pid != null && pid != "null") "PID $pid" else null,
message = KanbanEventMessage.WORKER_STARTED,
arguments = listOfNotNull(pid?.takeIf { it != "null" }),
)
}
"completed" -> {
FormattedKanbanEvent(label = "Completed")
FormattedKanbanEvent(label = "Completed", message = KanbanEventMessage.COMPLETED)
}
"blocked" -> {
val reason = str("reason")
FormattedKanbanEvent(label = "Blocked", detail = reason)
FormattedKanbanEvent(label = "Blocked", detail = reason, message = KanbanEventMessage.BLOCKED)
}
"unblocked" -> {
val status = col("status")
val label = if (status != null) "Unblocked ($status)" else "Unblocked"
FormattedKanbanEvent(label = label)
FormattedKanbanEvent(
label = label,
message = KanbanEventMessage.UNBLOCKED,
arguments = listOfNotNull(status),
)
}
"reclaimed" -> {
val reason = str("reason")
FormattedKanbanEvent(label = "Reclaimed", detail = reason)
FormattedKanbanEvent(label = "Reclaimed", detail = reason, message = KanbanEventMessage.RECLAIMED)
}
"specified" -> {
FormattedKanbanEvent(label = "Specified")
FormattedKanbanEvent(label = "Specified", message = KanbanEventMessage.SPECIFIED)
}
"promoted" -> {
FormattedKanbanEvent(label = "Promoted to ready")
FormattedKanbanEvent(label = "Promoted to ready", message = KanbanEventMessage.PROMOTED)
}
"scheduled" -> {
val reason = str("reason")
FormattedKanbanEvent(label = "Scheduled", detail = reason)
FormattedKanbanEvent(label = "Scheduled", detail = reason, message = KanbanEventMessage.SCHEDULED)
}
"archived" -> {
FormattedKanbanEvent(label = "Archived")
FormattedKanbanEvent(label = "Archived", message = KanbanEventMessage.ARCHIVED)
}
"reprioritized" -> {
val priority = str("priority") ?: payloadMap["priority"]?.toString() ?: "?"
FormattedKanbanEvent(label = "Priority set to $priority")
FormattedKanbanEvent(
label = "Priority set to $priority",
message = KanbanEventMessage.PRIORITY,
arguments = listOf(priority),
)
}
else -> {
@@ -882,6 +882,94 @@ private fun TaskRunsTab(
}
}
@Composable
private fun localizedKanbanEventLabel(event: FormattedKanbanEvent): String =
when (event.message) {
KanbanEventMessage.CREATED -> {
stringResource(R.string.kanban_event_created, event.arguments.getOrElse(0) { "Todo" })
}
KanbanEventMessage.CREATED_BY -> {
stringResource(
R.string.kanban_event_created_by,
event.arguments.getOrElse(0) { "Todo" },
event.arguments.getOrElse(1) { "" },
)
}
KanbanEventMessage.MOVED -> {
stringResource(R.string.kanban_event_moved, event.arguments.getOrElse(0) { "?" })
}
KanbanEventMessage.ASSIGNED -> {
stringResource(R.string.kanban_event_assigned, event.arguments.getOrElse(0) { "" })
}
KanbanEventMessage.UNASSIGNED -> {
stringResource(R.string.kanban_event_unassigned)
}
KanbanEventMessage.COMMENTED -> {
stringResource(R.string.kanban_event_commented, event.arguments.getOrElse(0) { "someone" })
}
KanbanEventMessage.CLAIMED_REVIEW -> {
stringResource(R.string.kanban_event_claimed_review)
}
KanbanEventMessage.CLAIMED_WORKER -> {
stringResource(R.string.kanban_event_claimed_worker)
}
KanbanEventMessage.WORKER_STARTED -> {
stringResource(R.string.kanban_event_worker_started)
}
KanbanEventMessage.COMPLETED -> {
stringResource(R.string.kanban_event_completed)
}
KanbanEventMessage.BLOCKED -> {
stringResource(R.string.kanban_event_blocked)
}
KanbanEventMessage.UNBLOCKED -> {
if (event.arguments.isEmpty()) {
stringResource(R.string.kanban_event_unblocked)
} else {
stringResource(R.string.kanban_event_unblocked_to, event.arguments[0])
}
}
KanbanEventMessage.RECLAIMED -> {
stringResource(R.string.kanban_event_reclaimed)
}
KanbanEventMessage.SPECIFIED -> {
stringResource(R.string.kanban_event_specified)
}
KanbanEventMessage.PROMOTED -> {
stringResource(R.string.kanban_event_promoted)
}
KanbanEventMessage.SCHEDULED -> {
stringResource(R.string.kanban_event_scheduled)
}
KanbanEventMessage.ARCHIVED -> {
stringResource(R.string.kanban_event_archived)
}
KanbanEventMessage.PRIORITY -> {
stringResource(R.string.kanban_event_priority, event.arguments.getOrElse(0) { "?" })
}
KanbanEventMessage.UNKNOWN -> {
event.label
}
}
@Composable
private fun TaskActivityTab(
events: List<com.m57.hermescontrol.data.model.KanbanDetailEvent>,
@@ -920,7 +1008,7 @@ private fun TaskActivityTab(
Spacer(modifier = Modifier.width(10.dp))
Column(modifier = Modifier.weight(1f)) {
Text(
text = formatted.label,
text = localizedKanbanEventLabel(formatted),
style = MaterialTheme.typography.bodySmall,
fontWeight = FontWeight.SemiBold,
)