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,
)
+19
View File
@@ -432,6 +432,25 @@
<string name="kanban_filters">عوامل التصفية</string>
<string name="kanban_confirm_action">تأكيد الإجراء</string>
<string name="kanban_edit_description">تعديل الوصف</string>
<string name="kanban_event_created">أُنشئت في %1$s</string>
<string name="kanban_event_created_by">أُنشئت في %1$s بواسطة %2$s</string>
<string name="kanban_event_moved">نُقلت إلى %1$s</string>
<string name="kanban_event_assigned">عُيّنت إلى %1$s</string>
<string name="kanban_event_unassigned">غير معيّنة</string>
<string name="kanban_event_commented">تعليق بواسطة %1$s</string>
<string name="kanban_event_claimed_review">تمت المطالبة للمراجعة</string>
<string name="kanban_event_claimed_worker">تمت المطالبة بواسطة العامل</string>
<string name="kanban_event_worker_started">بدأ العامل</string>
<string name="kanban_event_completed">مكتملة</string>
<string name="kanban_event_blocked">محظورة</string>
<string name="kanban_event_unblocked">أزيل حظرها</string>
<string name="kanban_event_unblocked_to">أزيل حظرها (%1$s)</string>
<string name="kanban_event_reclaimed">تمت الاستعادة</string>
<string name="kanban_event_specified">تم التحديد</string>
<string name="kanban_event_promoted">تمت الترقية إلى جاهزة</string>
<string name="kanban_event_scheduled">مجدولة</string>
<string name="kanban_event_archived">مؤرشفة</string>
<string name="kanban_event_priority">تم ضبط الأولوية على %1$s</string>
<string name="kanban_workspace_scratch">مؤقت (افتراضي)</string>
<string name="kanban_workspace_worktree">شجرة عمل</string>
<string name="kanban_workspace_dir">مجلد</string>
+19
View File
@@ -430,6 +430,25 @@
<string name="kanban_filters">필터</string>
<string name="kanban_confirm_action">작업 확인</string>
<string name="kanban_edit_description">설명 편집</string>
<string name="kanban_event_created">%1$s에서 생성됨</string>
<string name="kanban_event_created_by">%1$s에서 %2$s가 생성함</string>
<string name="kanban_event_moved">%1$s로 이동됨</string>
<string name="kanban_event_assigned">%1$s에게 할당됨</string>
<string name="kanban_event_unassigned">미지정</string>
<string name="kanban_event_commented">%1$s의 댓글</string>
<string name="kanban_event_claimed_review">검토를 위해 할당됨</string>
<string name="kanban_event_claimed_worker">워커가 할당함</string>
<string name="kanban_event_worker_started">워커 시작됨</string>
<string name="kanban_event_completed">완료됨</string>
<string name="kanban_event_blocked">차단됨</string>
<string name="kanban_event_unblocked">차단 해제됨</string>
<string name="kanban_event_unblocked_to">차단 해제됨 (%1$s)</string>
<string name="kanban_event_reclaimed">회수됨</string>
<string name="kanban_event_specified">지정됨</string>
<string name="kanban_event_promoted">준비 상태로 승격됨</string>
<string name="kanban_event_scheduled">예약됨</string>
<string name="kanban_event_archived">보관됨</string>
<string name="kanban_event_priority">우선순위가 %1$s로 설정됨</string>
<string name="kanban_workspace_scratch">임시 (기본값)</string>
<string name="kanban_workspace_worktree">작업 트리</string>
<string name="kanban_workspace_dir">디렉터리</string>
+19
View File
@@ -431,6 +431,25 @@
<string name="kanban_filters">筛选</string>
<string name="kanban_confirm_action">确认操作</string>
<string name="kanban_edit_description">编辑描述</string>
<string name="kanban_event_created">创建于 %1$s</string>
<string name="kanban_event_created_by">由 %2$s 创建于 %1$s</string>
<string name="kanban_event_moved">移动到 %1$s</string>
<string name="kanban_event_assigned">分配给 %1$s</string>
<string name="kanban_event_unassigned">未分配</string>
<string name="kanban_event_commented">%1$s 的评论</string>
<string name="kanban_event_claimed_review">已领取进行审核</string>
<string name="kanban_event_claimed_worker">已由工作器领取</string>
<string name="kanban_event_worker_started">工作器已启动</string>
<string name="kanban_event_completed">已完成</string>
<string name="kanban_event_blocked">已阻塞</string>
<string name="kanban_event_unblocked">已解除阻塞</string>
<string name="kanban_event_unblocked_to">已解除阻塞(%1$s)</string>
<string name="kanban_event_reclaimed">已回收</string>
<string name="kanban_event_specified">已指定</string>
<string name="kanban_event_promoted">已提升为就绪</string>
<string name="kanban_event_scheduled">已计划</string>
<string name="kanban_event_archived">已归档</string>
<string name="kanban_event_priority">优先级设置为 %1$s</string>
<string name="kanban_workspace_scratch">临时(默认)</string>
<string name="kanban_workspace_worktree">工作树</string>
<string name="kanban_workspace_dir">目录</string>
+19
View File
@@ -467,6 +467,25 @@
<string name="kanban_filters">Filters</string>
<string name="kanban_confirm_action">Confirm action</string>
<string name="kanban_edit_description">Edit Description</string>
<string name="kanban_event_created">Created in %1$s</string>
<string name="kanban_event_created_by">Created in %1$s by %2$s</string>
<string name="kanban_event_moved">Moved to %1$s</string>
<string name="kanban_event_assigned">Assigned to %1$s</string>
<string name="kanban_event_unassigned">Unassigned</string>
<string name="kanban_event_commented">Comment by %1$s</string>
<string name="kanban_event_claimed_review">Claimed for review</string>
<string name="kanban_event_claimed_worker">Claimed by worker</string>
<string name="kanban_event_worker_started">Worker started</string>
<string name="kanban_event_completed">Completed</string>
<string name="kanban_event_blocked">Blocked</string>
<string name="kanban_event_unblocked">Unblocked</string>
<string name="kanban_event_unblocked_to">Unblocked (%1$s)</string>
<string name="kanban_event_reclaimed">Reclaimed</string>
<string name="kanban_event_specified">Specified</string>
<string name="kanban_event_promoted">Promoted to ready</string>
<string name="kanban_event_scheduled">Scheduled</string>
<string name="kanban_event_archived">Archived</string>
<string name="kanban_event_priority">Priority set to %1$s</string>
<string name="kanban_workspace_scratch">Scratch (Default)</string>
<string name="kanban_workspace_worktree">Worktree</string>
<string name="kanban_workspace_dir">Dir</string>