Skip to content

feat(web): right-click context menu for sidebar project groups (#881)#955

Open
swear01 wants to merge 1 commit into
tiann:mainfrom
swear01:feat/881-project-group-context-menu
Open

feat(web): right-click context menu for sidebar project groups (#881)#955
swear01 wants to merge 1 commit into
tiann:mainfrom
swear01:feat/881-project-group-context-menu

Conversation

@swear01

@swear01 swear01 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

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

Action Behaviour Availability
Copy Path Copy the group's directory to clipboard Always
Archive All Sessions Archive every active/running session in the group Disabled when nothing is archivable
Delete Group Delete the group and all its sessions Enabled only when every session is already archived (greyed out otherwise)

"New Session" stays as the persistent hover button, as the issue requested.

Why "Delete Group" requires all-archived

lifecycleState === 'archived' is checked explicitly (not just active === 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. SessionActionMenu now reuses it, removing ~90 lines of duplication. The issue called out reusing this exact logic.
  • ProjectGroupActionMenu (new) — mirrors SessionActionMenu'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-brain lifecycleState === 'running'), and getProjectGroupActionAvailability.
  • 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 a ProjectGroupRow component wired with useLongPress. Toggle stays a plain onClick; long-press/right-click only opens the menu, and a menuOpen guard swallows the stray click a mouse long-press emits. Nested controls stop press propagation so taps don't toggle the group.
  • i18n keys added to both en and zh-CN.

Notes / edge cases

  • During an active sidebar search the group contains only matching sessions, so the menu operates on the visible subset.
  • The archive route is idempotent for already-archived rows; bulk archive only targets archivable sessions to avoid pointless 409s.

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 rejection
  • ProjectGroupActionMenu.test.tsx — renders three actions; enable/disable + click wiring
  • Refactored SessionActionMenu still passes its existing suite
  • tsc --noEmit clean; full web suite green (1128 passed)

🤖 Generated with Claude Code

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@swear01

swear01 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Heads-up on the red test check — it's a pre-existing flaky teardown race, not from this PR.

  • The failure is an unhandled async error: ReferenceError: window is not defined thrown by the React scheduler (performWorkUntilDeadline) after the jsdom environment is torn down. Vitest attributes it to src/hooks/useThemeColors.test.ts, a file this PR does not touch. All 1128 tests pass; the run only exits 1 because of the unhandled error.
  • I reproduced it on pristine main (2ab3b39) with none of this PR's changes: 1 of 6 full-suite runs failed with the same window is not defined errors (and intermittently on this branch too). So the flake is unrelated to this change.

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>
@swear01 swear01 force-pushed the feat/881-project-group-context-menu branch from 6908265 to 5aad031 Compare June 19, 2026 16:18

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(web): right-click context menu for project/workspace groups in sidebar

1 participant