feat(ui): show labels when focused on a session/item#269
Merged
Conversation
Add label display to SessionDetailView header, SessionRow sidebar, and ReviewRow so users get at-a-glance context without switching to a browser. Extracts a reusable LabelPillsView component and refactors TicketCard to use it, eliminating duplication. 🤖 Generated with Claude Code, orchestrated by Crow Co-Authored-By: Claude <noreply@anthropic.com> Crow-Session: E59F89D6-EB56-4E11-BE06-E6D6F22D5311
dhilgaertner
approved these changes
May 14, 2026
Contributor
dhilgaertner
left a comment
There was a problem hiding this comment.
Code & Security Review
Critical Issues
None.
Security Review
Strengths:
- No new external input surface — labels are sourced from already-fetched
AssignedIssue/ReviewRequestmodels and rendered via SwiftUIText, so no injection vectors are introduced. - No new persisted fields, no secrets, no auth surface touched.
- The reverse-lookup helpers are read-only and
@MainActor-safe (consistent with the rest ofAppState).
Concerns:
- None.
Code Quality
Strengths:
- The
LabelPillsViewextraction (Packages/CrowUI/Sources/CrowUI/CorveilTheme.swift:181) is a clean dedup of the priorTicketCard.labelRowbody — same fonts, padding, capsule, overflow+N, andmutedflag mappingisDone. The refactor atPackages/CrowUI/Sources/CrowUI/TicketBoardView.swift:501is behavior-preserving. - Reverse lookup via existing data avoids a stale duplicate of
labelsonSession— good call. - Test coverage in
Packages/CrowCore/Tests/CrowCoreTests/AppStateLookupTests.swiftexercises the positive path, missing ticket URL, no-match, kind filtering, and the issue-vs-review fallback. All 160 tests pass locally.
Consider (non-blocking):
Packages/CrowCore/Sources/CrowCore/AppState.swift:412—reviewRequest(for:)guards onsession.kind == .review, butassignedIssue(for:)at line 406 does not guard on kind. A.reviewsession that happens to have a non-nilticketURLmatching an assigned issue would fall into the issue branch oflabels(forSession:)and show issue labels instead of PR labels. Probably fine in practice (review sessions typically don't carry an issue ticketURL), but worth a brief comment or a kind-aware preference if mixed states are possible.Packages/CrowUI/Sources/CrowUI/CorveilTheme.swift:194—Text(label)has no.lineLimit(1)/.truncationMode. GitHub allows up to 50-char labels; in narrow contexts (SessionRowsidebar,maxVisible: 2) very long labels could push siblings or wrap. This is preserved from the originalTicketCard.labelRow, so not a regression — flagging only.- Lookups are O(n) over
assignedIssues/reviewRequestsper render of each row. Fine at current scale; if these collections grow large, an index keyed by URL would help. - Minor: the helper named pair
assignedIssue(for:)/reviewRequest(for:)usefor:, whilelabels(forSession:)usesforSession:. Not actionable (likely avoiding a label collision), but slightly inconsistent.
Summary Table
| Priority | Issue |
|---|---|
| Red | (none) |
| Yellow | (none) |
| Green | Optional .lineLimit(1) on label Text for narrow contexts; consider kind-aware preference in labels(forSession:) if review sessions can carry a ticketURL; consider a URL-keyed index if assignedIssues/reviewRequests grow. |
Recommendation: Approve. Scope is tight, the refactor is behavior-preserving, test coverage for the new lookups is solid, and there are no security or correctness concerns. The items above are minor consider-level polish, not blockers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
LabelPillsViewcomponent from the existingTicketCard.labelRowpattern, and refactorsTicketCardto use it — eliminating code duplication across 4 viewsAppState(assignedIssue(for:),reviewRequest(for:),labels(forSession:)) to resolve labels from the existingAssignedIssue/ReviewRequestdata without adding new fields to theSessionmodelTest plan
Closes #268
🤖 Generated with Claude Code