feat(web): tap-to-assign on board cards for mobile + a11y #1116
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!1116
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/board-tap-to-assign"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
draggable={!isMobile}) doesn't fire on touch, the keyboardashortcut needs a keyboard, and the card had no tap affordance.AgentSlot(default density) and a new icon-onlyCompactAssignButton(compact density) are now real<button>s that open the existingBoardAgentPickerdialog.openAgentPicker(card)returned fromuseBoardKeymap— single source of truth for picker open state.e.stopPropagation()ononClick+onPointerDownkeeps the card-click → side-panel path and drag-start untouched.A11y
UserPlusicon + "Assign…" label, clearly affording action.aria-label="Assign agent"/"Reassign agent (currently @x)".min-h-8touch target,focus-visible:outline-accent.ashortcut) unchanged.Test plan
bun run test— 1079/1079 web tests pass, including newboard.test.tsxcase "tap on AgentSlot opens agent picker".ashortcut test still green.just qa— lint + typecheck clean (paraglidefr.jsonwarning is pre-existing, unrelated).🤖 Generated with Claude Code
Review: APPROVED ✅
CI green, mergeable, implementation is clean. A few nits worth noting for future cleanup — none are blockers.
✅ What works well
openAgentPickersurfaced fromuseBoardKeymapmeans theashortcut and the tap path share the same state; no duplication.stopPropagationon bothonClickandonPointerDown— correctly prevents card-click-to-panel and drag-start from firing when the assign button is the intended target.e.target === e.currentTargetbackdrop dismiss — correct pattern; won't fire when clicking inside the inner panel.aria-labelcoverage — both assigned (Reassign agent (currently @x)) and unassigned (Assign agent) states are annotated. Visible "Assign…" text plusUserPlusicon gives good sighted affordance.data-testidselectors consistently.🔸 Nits (non-blocking)
1.
data-testid-assign-trigger="true"is never readBoth the interactive
AgentSlotbutton andCompactAssignButtoncarry this attribute, but no test or application code queries for it. Either wire it up (e.g. as a selector in a future test) or drop it to avoid dead HTML.2. Redundant
agentInstance/assigneeprops onAgentSlotAgentSlotnow always receivescard, soagentInstance={card.agent_instance}andassignee={card.assignee}at the call-site are redundant — the component could read them directly offcard. Harmless, but the interface could be simplified to just{ card, onRequestAssign? }.3. IIFE for
innerreduces readabilityA tiny named helper (e.g.
function AssignedLabel({ label })) or auseMemo-style block before the conditional would be easier to scan. Not urgent.4. No test for compact density path
CompactAssignButtonis exercised visually but not by a dedicated test. The default-density coverage is sufficient for now; just flagging in case the compact path diverges later.Merging now.