Skip to content

Invite in Sidebar#1789

Open
ignaciojimenezr wants to merge 3 commits intoMCPJam:mainfrom
ignaciojimenezr:codex/sidebar-invite-cta
Open

Invite in Sidebar#1789
ignaciojimenezr wants to merge 3 commits intoMCPJam:mainfrom
ignaciojimenezr:codex/sidebar-invite-cta

Conversation

@ignaciojimenezr
Copy link
Copy Markdown
Collaborator

@ignaciojimenezr ignaciojimenezr commented Apr 14, 2026

Summary

This PR implements the sidebar invite flow from Linear M-263 through M-271.

What changed:

  • Added an Invite team members button to the sidebar footer for signed-in users
  • Clicking it opens the existing workspace share dialog
  • Added a workspace picker in the dialog when the current org has multiple workspaces
  • Kept the picker local to the dialog, so it does not switch the main app workspace
  • Reused the existing invite flow, including invalid email validation and billing gating
  • Fixed first-share/local-fallback edge cases so we do not:
    • switch the app to the wrong workspace
    • show duplicate local + remote versions of the same workspace

Notes

We followed the Linear behavior and scope.

The only thing we did not change is the backend invite result naming. The behavior matches what Linear asked for, but we kept the existing result names instead of renaming them.

Testing

  • use-workspace-state.test.tsx: 30/30 passed
  • ShareWorkspaceDialog.test.tsx + sidebar-invite-cta.test.tsx: 15/15 passed
  • npm run build passed
Screenshot 2026-04-13 at 8 33 04 PM
Screen.Recording.2026-04-13.at.10.37.15.PM.mov
Screen.Recording.2026-04-13.at.10.39.04.PM.mov

Note

Medium Risk
Adds a new sidebar-triggered invite/share entrypoint and refactors the share dialog to support selecting different workspaces, which could affect workspace membership/visibility flows and billing-gated invite behavior if selection or IDs are mishandled.

Overview
Adds an “Invite team members” CTA to the sidebar footer for authenticated users, opening ShareWorkspaceDialog for the active workspace and passing through activeOrganizationName plus a workspace list scoped to the active org.

Upgrades ShareWorkspaceDialog to support multi-workspace invite targeting via an in-dialog workspace picker (without switching the app’s active workspace), adds email format validation, and ensures billing gating/mutations run against the selected workspace’s organizationId/sharedWorkspaceId.

Extends onWorkspaceShared across call sites to include an optional sourceWorkspaceId, and updates use-workspace-state to correctly attach the new sharedWorkspaceId to the originating local workspace when sharing is first created. Includes new/updated tests covering the sidebar CTA, workspace picker behavior, and gating/validation edge cases.

Reviewed by Cursor Bugbot for commit e5afc95. Bugbot is set up for automated code reviews on this repo. Configure here.

@chelojimenez
Copy link
Copy Markdown
Contributor

chelojimenez commented Apr 14, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@ignaciojimenezr
Copy link
Copy Markdown
Collaborator Author

@coderabbitai

review pls

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

The PR description image depicts a "Share 'ws1' Workspace" modal within the MCPJam Inspector UI. It features:

  • A Workspace dropdown pre-selected to ws1
  • An Invite with email field (with role selector defaulting to Editor and an Invite button)
  • A "Need more members?" upsell card noting the org has reached its member limit, with an Upgrade to Starter CTA
  • An Access settings dropdown set to Ignacio's Org
  • A Has access list showing Ignacio Jimenez (you) as Admin

On it — kicking off the review now! 🐇

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

Walkthrough

Adds an "Invite team members" CTA to the sidebar (shown for authenticated users) and wires a ShareWorkspaceDialog into the sidebar. ShareWorkspaceDialog now supports selecting among multiple workspaces and drives member/invite/visibility/mutation logic from the selected workspace. Many components’ onWorkspaceShared callbacks were changed to accept an optional sourceWorkspaceId. The workspace state hook (use-workspace-state) was updated to accept and resolve sourceWorkspaceId and to preserve local-active-workspace behavior during remote mapping. New tests cover the sidebar CTA, expanded dialog flows, billing gates, and workspace-sharing/handoff behaviors.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ignaciojimenezr
Copy link
Copy Markdown
Collaborator Author

@coderabbitai
review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

The PR description image shows the MCPJam sidebar with a new "Invite team members" CTA at the bottom left, and the resulting "Share 'ws1' Workspace" modal — complete with a workspace picker dropdown, email invite field with role selector, a billing upsell card ("Need more members?"), access-settings dropdown, and the current member list. Looks sharp, @ignaciojimenezr — triggering the full review now! 🐇

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ignaciojimenezr ignaciojimenezr changed the title initial commit Invite in Sidebar Apr 14, 2026
@ignaciojimenezr ignaciojimenezr marked this pull request as ready for review April 14, 2026 17:15
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. labels Apr 14, 2026
@ignaciojimenezr
Copy link
Copy Markdown
Collaborator Author

@cursor review

@dosubot dosubot bot added the enhancement New feature or request label Apr 14, 2026
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e5afc95. Configure here.

dispatch({
type: "UPDATE_WORKSPACE",
workspaceId: appState.activeWorkspaceId,
workspaceId: sourceWorkspaceId ?? appState.activeWorkspaceId,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Authenticated path ignores sourceWorkspaceId on first share

Medium Severity

handleWorkspaceShared completely ignores the new sourceWorkspaceId parameter in the isAuthenticated branch, always calling setConvexActiveWorkspaceId(convexWorkspaceId). This contradicts the PR's stated goal of not switching the app to the wrong workspace. If an authenticated user in local-fallback mode shares a non-active workspace via the new dialog picker, the app switches to the newly created remote workspace instead of staying on the current one. The sourceWorkspaceId parameter was introduced to fix exactly this class of bug but is only wired up in the else (non-authenticated) branch.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e5afc95. Configure here.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
mcpjam-inspector/client/src/hooks/__tests__/use-workspace-state.test.tsx (1)

1225-1256: Strengthen the “active workspace unchanged” proof by seeding prior storage state.

The localStorage assertion currently passes even if nothing happened, because storage is cleared in setup. Seed a known active ID first, then assert it is preserved after sharing a different workspace.

Proposed test hardening
   it("keeps the active workspace unchanged when sharing a different local workspace", async () => {
+    localStorage.setItem("convex-active-workspace-id", "workspace-a");
     const appState = createAppState({
       "workspace-a": createLocalWorkspace("workspace-a", {
         name: "Workspace A",
         organizationId: "org-owner",
       }),
@@
-    expect(localStorage.getItem("convex-active-workspace-id")).toBeNull();
+    expect(localStorage.getItem("convex-active-workspace-id")).toBe("workspace-a");
+    expect(result.current.effectiveActiveWorkspaceId).toBe("workspace-a");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcpjam-inspector/client/src/hooks/__tests__/use-workspace-state.test.tsx`
around lines 1225 - 1256, Seed localStorage with a known active ID before
invoking the hook so the test actually verifies preservation: in the test that
calls renderUseWorkspaceState and result.current.handleWorkspaceShared, set
localStorage.setItem("convex-active-workspace-id", "existing-active-id") (or
similar) prior to the act(), then after handleWorkspaceShared assert that
localStorage.getItem("convex-active-workspace-id") still equals that seeded
value; update references to renderUseWorkspaceState and handleWorkspaceShared in
the test and keep the existing assertions for dispatch and logger.info.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@mcpjam-inspector/client/src/hooks/__tests__/use-workspace-state.test.tsx`:
- Around line 1225-1256: Seed localStorage with a known active ID before
invoking the hook so the test actually verifies preservation: in the test that
calls renderUseWorkspaceState and result.current.handleWorkspaceShared, set
localStorage.setItem("convex-active-workspace-id", "existing-active-id") (or
similar) prior to the act(), then after handleWorkspaceShared assert that
localStorage.getItem("convex-active-workspace-id") still equals that seeded
value; update references to renderUseWorkspaceState and handleWorkspaceShared in
the test and keep the existing assertions for dispatch and logger.info.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2c96327e-e0f8-436e-b5ef-aa05d9d7fd3f

📥 Commits

Reviewing files that changed from the base of the PR and between 3fbd489 and 68b2495.

📒 Files selected for processing (2)
  • mcpjam-inspector/client/src/hooks/__tests__/use-workspace-state.test.tsx
  • mcpjam-inspector/client/src/hooks/use-workspace-state.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • mcpjam-inspector/client/src/hooks/use-workspace-state.ts

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

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants