WH-093: Move +tag feature to properties bar styling#97
Conversation
Resolve conflicts: - prisma/schema.prisma: keep both Tag relation (from branch) and CardCodeSequence model (from main) - CardTab.tsx: keep TagRef import (from branch) and handleListKeyDown import (from main), drop unused cn import https://claude.ai/code/session_01CK4Moj5ruNjru984fQHGgh
|
🦸 Review Hero Summary Below consensus threshold (7 unique issues not confirmed by majority)
Nitpicks
Local fix prompt (copy to your coding agent)Fix these issues identified on the pull request. One commit per issue fixed.
|
|
🦸 Review Hero Summary Below consensus threshold (4 unique issues not confirmed by majority)
Local fix prompt (copy to your coding agent)Fix these issues identified on the pull request. One commit per issue fixed.
|
…nto workhorse/wh-093-spec
…ntial/workhorse into workhorse/wh-093-spec # Conflicts: # src/components/card/CardTab.tsx
|
🦸 Review Hero Summary Below consensus threshold (7 unique issues not confirmed by majority)
Nitpicks
Local fix prompt (copy to your coding agent)Fix these issues identified on the pull request. One commit per issue fixed.
|
|
🦸 Review Hero (could not post inline comments — showing here instead)
[Bugs & Correctness] Stale type:
[Bugs & Correctness]
[Bugs & Correctness]
[Design & Architecture] Card creation (
[Frontend Snappiness] Redundant DB roundtrip:
[Frontend Snappiness]
|
|
🦸 Review Hero Summary Below consensus threshold (7 unique issues not confirmed by majority)
Nitpicks
Local fix prompt (copy to your coding agent)Fix these issues identified on the pull request. One commit per issue fixed.
|
| } | ||
| commitTag() | ||
| } | ||
| function handleTagCreate(name: string) { |
There was a problem hiding this comment.
[Design & Architecture] suggestion
The temp-ID optimistic lifecycle is split across three functions (handleTagCreate, handleTagRemove, handleTagAdd) and leaks into TagDropdown via the cardTagNames set. Consider extracting the tag optimistic state into a custom hook (e.g. useOptimisticTags) that encapsulates temp-ID creation, reconciliation, and rollback. This would co-locate the related logic, keep CardTab consistent with how it handles other properties, and let TagDropdown work purely with stable IDs.
| const tag = await createTagAndAddToCard(card.id, name) | ||
| // Replace temp entry with real one — if the temp ID was removed | ||
| // (user toggled it off while create was in-flight), remove server-side too | ||
| let needsServerCleanup = false |
There was a problem hiding this comment.
[Design & Architecture] suggestion
The needsServerCleanup flag set inside a setCardTags updater and read outside it is a side-channel that couples the cleanup decision to React's synchronous updater execution. A clearer approach: use a ref (e.g. removedTempIds) that handleTagRemove writes to, and check it here after the await. That keeps the state setter pure and makes the control flow explicit.
| setSearch('') | ||
| } | ||
|
|
||
| function openDropdown(e: React.MouseEvent) { |
There was a problem hiding this comment.
[Design & Architecture] suggestion
stopPropagation on the overflow chip's click is a workaround for usePortalMenu's click-outside handler firing on sibling elements. This creates a fragile coupling — any future trigger element near the dropdown will need the same workaround. Consider making usePortalMenu's click-outside handler ignore clicks on elements that are children of the same logical container, or pass a containsRef so it can exclude known siblings.
|
|
||
| const MAX_TAG_NAME_LENGTH = 100 | ||
|
|
||
| async function requireCardProjectAccess(cardId: string) { |
There was a problem hiding this comment.
[Frontend Snappiness] suggestion
Every tag mutation (add, remove, create) independently calls requireCardProjectAccess, which loads the card with nested team+project joins AND makes an external GitHub API call via hasProjectAccess. When a user rapidly toggles several tags in the dropdown, each toggle fires a separate server action, so toggling 5 tags triggers 5 redundant card lookups and 5 GitHub HTTP round-trips for the same card and the same user. Consider accepting a batch of tag changes in a single action, or at minimum caching the project-access check for the duration of a request (e.g. a per-request memo keyed on userId+projectId).
|
🦸 Review Hero Summary Below consensus threshold (10 unique issues not confirmed by majority)
Nitpicks
Local fix prompt (copy to your coding agent)Fix these issues identified on the pull request. One commit per issue fixed.
|
Summary
Restyle the "+tag" feature to sit in properties bar and match nice aesthetic of other properties
Journey
Specs
.workhorse/specs/card-tab.mdChanged files
prisma/schema.prismasrc/app/api/card-detail/route.tssrc/app/api/project-board/route.tssrc/components/BoardColumn.tsxsrc/components/CardItem.tsxsrc/components/card/CardDetailPage.tsxsrc/components/card/CardTab.tsxsrc/components/card/TagDropdown.tsxsrc/lib/actions/tags.tssrc/lib/hooks/queries.tsTest plan
Review Hero