Ubisam-MobileGit/tasks/042-workitem-status-badges.md
choiminyeong ca999a7bb8 TASK-042 follow-up: colored status badges on NotificationsScreen
Closes the known limitation from the previous commit: NotificationsScreen
had the identical plain-text state-label gap, in a separate screen/enum
(NotificationSubjectState, which also has an UNKNOWN case). Adds its own
StatusBadge composable with the same color roles, mapping UNKNOWN to the
neutral surfaceVariant treatment VisibilityBadge already uses for private.

Live-verified on-device: notifications 전체 list shows all three real
colors side by side (닫힘/병합됨/열림).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 22:44:00 +09:00

6.4 KiB
Raw Blame History

TASK-042: Colored status badges for issue/PR state (열림/닫힘/병합됨)

Status: implemented; all required checks pass; live-confirmed on the human product owner's device Owner: Claude Reviewer: Codex

Outcome

Design-review follow-up (continuing the "앱의 아이콘부터 해서 전체적으로 확인해보고 부족한 부분 고쳐줘" pass from TASK-039). While verifying that issue/PR body text renders correctly for real content (it does — confirmed against a real issue with a multi-paragraph body and an embedded code block), noticed the 열림/닫힘/병합됨 state label next to each issue/PR — in both the list row and the detail header — rendered as a plain, uncolored bodySmall line, visually no more prominent than the #12 issue number sitting right next to it. Gitea's own web UI (and GitHub's, which established the convention) colors this label so it reads at a glance while scanning a list. Replaced the plain text with a compact colored badge, reusing the VisibilityBadge pattern TASK-039 already established for 공개/비공개 on the repository list.

Scope

  • Included: feature/workitems/WorkItemsScreen.kt — new private StatusBadge composable (two overloads, one per state enum, sharing one color-agnostic rendering implementation) replacing the four plain-Text state-label call sites: IssueRow, PullRequestRow, IssueDetailView, PullRequestDetailView.
  • Excluded: NotificationsScreen.kt's own PR/이슈 state labels (a separate screen/composable, out of scope for this pass — noted below as a known limitation, not silently left inconsistent). ReviewState labels (승인/변경 요청/etc. on ReviewRow) — these are a different kind of status with no obvious two/three-color GitHub/Gitea convention to borrow, left as plain text.

Design notes

  • Reused existing theme roles instead of introducing new colors. OPEN gets primaryContainer/onPrimaryContainer — the same green VisibilityBadge already uses for a public repository's affirmative state. CLOSED gets errorContainer/onErrorContainer — the baseline Material3 red Theme.kt deliberately left untouched for exactly this kind of closed/removed state. MERGED — a third state GitHub/Gitea conventionally color purple, which this app's green/teal-accented theme has no role for — gets tertiaryContainer/onTertiaryContainer (teal) rather than a one-off hardcoded color with no theme backing (and no dark-mode variant of its own to get wrong).
  • One rendering composable, two small color-mapping overloads. IssueState and PullRequestState are different enums (PullRequestState has the extra MERGED case), so a single when couldn't cover both — instead each enum gets its own thin StatusBadge(state, modifier) overload that maps to a container/content color pair and delegates to the same private StatusBadge(label, container, content, modifier) for the actual Surface + Text rendering, keeping the visual treatment (rounded 4dp corner, labelSmall, 6dp/2dp padding) defined in exactly one place.

Acceptance criteria

  • Issue list rows show a colored badge (not plain text) for 열림/닫힘.
  • PR list rows show a colored badge for 열림/닫힘/병합됨.
  • Issue detail header shows the same colored badge as its list row.
  • PR detail header shows the same colored badge as its list row.
  • Colors are pulled from the existing Material3 theme (no new hardcoded colors), so dark mode is handled automatically.
  • Build, unit tests, and lint pass.
  • Live-confirmed on the human product owner's device: PR list showing 병합됨 (teal) ×2 and 열림 (green) ×1 side by side; PR detail header showing the same teal 병합됨 badge; both re-confirmed unchanged under forced dark mode.

Required checks

./gradlew compileDebugKotlin compileDebugUnitTestKotlin testDebugUnitTest assembleDebug lintDebug

Evidence

  • feature/workitems/WorkItemsScreen.kt: StatusBadge composable (two state-typed overloads + one shared rendering implementation) added; IssueRow, PullRequestRow, IssueDetailView, PullRequestDetailView each call it in place of a plain Text(stringResource(state.labelResource)).
  • ./gradlew compileDebugKotlin compileDebugUnitTestKotlin testDebugUnitTest assembleDebug lintDebug: BUILD SUCCESSFUL, all unit tests passing (no test changes needed — this is a pure presentation change with no new branching logic to cover beyond what the enum whens already exhaustively check at compile time), 0 lint errors.
  • Live device: installed over wireless adb. Notifications → PostActivated 관련 추가 필요 이슈 detail: confirmed the issue body (multi-paragraph Korean text plus an indented C# code block) renders correctly end to end — this was the original investigation trigger, and it surfaced no bug on its own. RobotAutomationDevelopment-Dept/OC5-PilotLine-RectangleTypeWelder PR tab: #6/#5 both show a teal "병합됨" badge, #4 shows a green "열림" badge (screenshot); opened #6's detail view and confirmed the same teal badge appears in the header (screenshot). Forced dark mode (adb shell cmd uimode night yes) and reconfirmed the same PR list — both badge colors keep good contrast against the dark surface (screenshot) — then restored night no.

Known limitations

None outstanding for this task — see the follow-up below, which closed the one gap originally recorded here.

Follow-up (same session): NotificationsScreen

NotificationsScreen.kt's own PR/이슈 상태 column had the identical gap (plain-text state label) in a separate screen this task didn't originally touch. Added a second, independent StatusBadge composable there (for NotificationSubjectState, a different enum with its own UNKNOWN case — mapped to the neutral surfaceVariant/onSurfaceVariant VisibilityBadge already uses for "private", since an unrecognized state isn't one to visually emphasize either direction) rather than sharing code across the two feature packages. Build/test/lint re-run clean; live-verified on-device: the notifications 전체 list now shows all three real colors side by side — red "닫힘", teal "병합됨", green "열림" — which also closes the "never visually confirmed the red CLOSED badge live" gap originally recorded here, since these are the same errorContainer/onErrorContainer roles used by the work-items screens' badge.

Review findings

None yet — pending Codex/human review.