feat(web): right-click context menu for sidebar project groups (#881)#955
feat(web): right-click context menu for sidebar project groups (#881)#955swear01 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Findings
No issues found.
Summary
Review mode: initial
Static review of the latest diff found no correctness/security/regression findings above the reporting threshold. Residual risk: I could not execute the web test/typecheck commands in this runner because bun is unavailable.
Testing
Not run (automation: bun not found in runner).
HAPI Bot
|
Heads-up on the red test check — it's a pre-existing flaky teardown race, not from this PR.
Re-triggering CI. If it stays red on the same teardown race, it's safe to re-run. |
…#881) Project/workspace group rows in the sidebar previously had no context menu — only hover buttons for Copy Path and New Session. This adds a right-click / long-press menu mirroring SessionActionMenu: - Copy Path — always available - Archive All Sessions — archives every active/running session in the group; disabled when nothing is archivable - Delete Group — deletes the group and all its sessions; enabled only when every session is already archived (lifecycleState === 'archived'), making deletion a deliberate two-step action Implementation notes: - Extract the menu positioning/dismissal/focus logic into a shared useAnchoredMenu hook; SessionActionMenu now reuses it (removes ~90 lines of duplication). - Bulk ops fan out to existing per-session archive/delete endpoints sequentially (no atomic bulk route); a mid-loop rejection aborts, mirroring single-session behaviour. - Project-group row keeps plain click-to-toggle; long-press/right-click only opens the menu, with a menuOpen guard swallowing the stray mouse-long-press click. Nested controls stop press propagation so taps don't toggle the group. - New i18n keys (en + zh-CN). Tests: projectGroupActions guards, useProjectGroupActions fan-out, and ProjectGroupActionMenu rendering/enablement. Full web suite green (1128). via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
6908265 to
5aad031
Compare
There was a problem hiding this comment.
Findings
No issues found.
Summary
Review mode: follow-up after new commits
Static review of the latest full PR diff found no correctness/security/regression findings above the reporting threshold. Residual risk: I could not execute the web test/typecheck commands in this runner because bun is unavailable.
Testing
Not run (automation: bun not found in runner).
HAPI Bot
Closes #881.
Summary
Project/workspace group rows in the sidebar had no context menu — only hover buttons for Copy Path and New Session, while session rows have a full right-click/long-press menu. This adds a matching context menu to project-group rows.
Menu items
"New Session" stays as the persistent hover button, as the issue requested.
Why "Delete Group" requires all-archived
lifecycleState === 'archived'is checked explicitly (not justactive === false) per the bot's verification note — completed/imported stubs are inactive but never formally archived. This keeps deletion a deliberate two-step action: archive everything, then delete.Implementation
useAnchoredMenu(new hook) — extracts the menu positioning (flip above/below + viewport clamp), outside-click/Escape dismissal, reflow, and focus-first logic.SessionActionMenunow reuses it, removing ~90 lines of duplication. The issue called out reusing this exact logic.ProjectGroupActionMenu(new) — mirrorsSessionActionMenu's markup/positioning with the three items above; disabled items are greyed with a tooltip explaining the precondition.projectGroupActions.ts(new) — pure guards:isSessionArchived,isSessionArchivable(active or split-brainlifecycleState === 'running'), andgetProjectGroupActionAvailability.useProjectGroupActions(new) — bulk archive/delete that fans out to the existing per-session endpoints sequentially (no atomic bulk route exists). A mid-loop rejection aborts, mirroring single-session behaviour; query cache is invalidated/cleared on success.SessionList— project-group header extracted into aProjectGroupRowcomponent wired withuseLongPress. Toggle stays a plainonClick; long-press/right-click only opens the menu, and amenuOpenguard swallows the stray click a mouse long-press emits. Nested controls stop press propagation so taps don't toggle the group.enandzh-CN.Notes / edge cases
Testing
projectGroupActions.test.ts— guard logic (archived/archivable/availability, incl. empty-group and stub cases)useProjectGroupActions.test.tsx— fan-out: archives only archivable sessions, deletes sequentially, aborts mid-loop on rejectionProjectGroupActionMenu.test.tsx— renders three actions; enable/disable + click wiringSessionActionMenustill passes its existing suitetsc --noEmitclean; full web suite green (1128 passed)🤖 Generated with Claude Code