Skip to content

[fix] Switch organizations, not workspaces, in the mobile switcher [AGE-4181] - #6247

Open
ardaerzin wants to merge 4 commits into
mainfrom
fe-fix/mobile-signin-org-project-switch
Open

[fix] Switch organizations, not workspaces, in the mobile switcher [AGE-4181]#6247
ardaerzin wants to merge 4 commits into
mainfrom
fe-fix/mobile-signin-org-project-switch

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

Context

Signing in from a phone appeared not to work, and the reporter could not switch organization or project once inside /m. Switching the browser to desktop mode was the workaround.

Sign-in itself is fine. I verified sign-up, sign-in, sign-out, re-sign-in and the OIDC callback handback on /m against a local EE stack, and they all work. The real problem is that a multi-org account lands in one organization on mobile and has no usable way out, which is what "signing in does not work" felt like. Two separate causes:

The switcher listed workspaces, not organizations. Every organization's default workspace is named Default, so DrawerProjectSwitcher rendered one identical Default row per org. The trigger already named the organization. Only the list did not, so the rows were indistinguishable and picking one was a coin flip.

/m never hid demo projects. The desktop hides them everywhere (projectsAtom) and prefers a non-demo project after login (postLoginRedirect.ts). /m applied neither, so a demo organization sat in the switcher next to the real ones and could win selectContextTarget's post-sign-in resolution, dropping the user into a project the desktop never offers.

Changes

The mobile switcher now groups by organization instead of workspace. groupByOrganization in workspaceGroups.ts keys on organization_id, labels each row with the organization name, and collects every one of that org's projects across all its workspaces. The panel says "Switch organization" like the desktop rail.

The workspace still lives in the URL, so each project row now routes with its own workspace_id rather than the currently active one. That makes an organization with several workspaces switch correctly too. groupByWorkspace stays untouched, because context resolution is workspace-keyed to match /w/:workspace_id/p/:project_id.

Before, in a two-org account:

Workspaces
  D  Default
  D  Default

After:

Organizations
  Q   qa-mobile-1   ✓
  AR  Acme Robotics

For the demo projects, filterOutDemoProjects moved out of oss/src/state/project/selectors/project.ts into @agenta/entities/project, so both shells share one implementation instead of growing a second copy. It is generic over the row type so /m's zod-inferred MobileProject keeps its own shape. /m applies it at the fetch boundary in lib/context.ts, which covers the context resolver, the switcher and post-sign-in landing in one place. OSS keeps a re-export, so nothing there changes behavior.

Tests

  • pnpm --filter @agenta/mobile test: 128 pass, including 4 new cases for groupByOrganization (org naming, multi-workspace collection, unroutable rows, org-less fallback).
  • tsc clean on @agenta/mobile and @agenta/oss; lint clean on every touched file.
  • OSS projectsDemoFilter.test.ts still passes against the relocated function.
  • Browser-verified on a local EE stack with an iPhone user agent and sec-ch-ua-mobile: ?1, using a two-org account: sign-up, sign-in, sign-out, re-sign-in, organization switch in both directions, project switch, and reload continuity. The demo path was proven by flipping project_members.is_demo in Postgres and back.
  • The desktop switcher was re-checked in the same browser for regressions from the extraction. Organizations and projects list as before.

What to QA

Needs an account in two or more organizations. Open the site on a phone, or force the gate with an iPhone user agent plus sec-ch-ua-mobile: ?1.

  • Sign in on /m. Open the drawer, tap the switcher at the bottom, then "Switch organization". The list shows organization names with distinct avatars, not repeated Default rows.
  • Pick the other organization. The URL changes to that org's workspace and project, and the trigger's second line shows the new organization name.
  • Reopen the panel. The checkmark sits on the organization you just entered.
  • In an organization with more than one project, pick a different project from the first panel. It routes to that project and stays inside the same organization.
  • If you have access to a demo organization: it should no longer appear in the mobile switcher, and signing in should not land you in it. This already matched the desktop before this PR.
  • Regression: on desktop, open the rail switcher. Organizations and projects list exactly as before, and demo projects stay hidden.

Fixes #6228

…itcher

Every organization's default workspace is named "Default", so the /m drawer's
second panel rendered one indistinguishable "Default" row per org. A multi-org
account had no way to tell them apart, which read as "the organization does not
switch on mobile" — the trigger already named the org, only the list did not.

Group by organization instead (groupByOrganization), label rows with the org
name, and say "Switch organization" like the desktop rail. The workspace stays
in the URL: each project row now routes with its OWN workspace id, so an org
with several workspaces switches correctly too.

Fixes #6228
The desktop hides demo projects everywhere (projectsAtom) and prefers a
non-demo project post-login. /m applied neither, so an account with a demo org
could sign in on a phone and be resolved straight into a demo project the
desktop never offers, with the demo org sitting in the switcher next to the
real ones.

Move filterOutDemoProjects into @agenta/entities/project — one implementation
both shells share, rather than a second copy — and apply it at /m's fetch
boundary, so the context resolver, the switcher, and post-sign-in landing all
agree with the desktop.

Refs #6228
@linear-code

linear-code Bot commented Aug 24, 2026

Copy link
Copy Markdown

AGE-4181

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Aug 24, 2026
@vercel

vercel Bot commented Aug 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview Aug 24, 2026 12:07pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 37905d65-6d02-4445-9c6f-53cfc1cb15d3

📥 Commits

Reviewing files that changed from the base of the PR and between 0abc6b6 and 7c7b5b5.

📒 Files selected for processing (3)
  • web/mobile/src/features/context/workspaceGroups.ts
  • web/mobile/src/features/nav/DrawerProjectSwitcher.tsx
  • web/mobile/tests/unit/workspaceGroups.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • web/mobile/src/features/nav/DrawerProjectSwitcher.tsx
  • web/mobile/tests/unit/workspaceGroups.test.ts
  • web/mobile/src/features/context/workspaceGroups.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Mobile project switcher now groups projects by organization across workspaces.
    • Organization entries open the organization’s first available project while preserving workspace context.
    • Organization names are resolved consistently, including fallback names when needed.
  • Bug Fixes

    • Demo projects are now hidden when non-demo projects are available.
    • Projects without workspaces are excluded, while organization-less workspace projects remain accessible.
    • Project navigation now preserves each project’s correct workspace context.

Walkthrough

The change adds shared demo-project filtering and changes mobile project switching from workspace groups to organization groups. Organization groups aggregate projects across workspaces and preserve workspace-aware project routing.

Changes

Mobile project navigation

Layer / File(s) Summary
Shared demo-project filtering
web/packages/agenta-entities/src/project/demo.ts, web/packages/agenta-entities/src/project/index.ts, web/oss/src/state/project/selectors/project.ts, web/mobile/src/lib/context.ts
The project package exports filterOutDemoProjects. OSS re-exports the shared helper, and mobile filters successful project results before returning them.
Organization grouping and drawer routing
web/mobile/src/features/context/workspaceGroups.ts, web/mobile/src/features/nav/DrawerProjectSwitcher.tsx, web/mobile/tests/unit/workspaceGroups.test.ts, web/mobile/tests/unit/contextTarget.test.ts
Mobile projects are grouped by organization across workspaces. Projects without workspaces are omitted. The drawer resolves organization entries and routes project selections with workspace IDs. Unit tests cover grouping, ordering, omission, organization-less projects, and updated group data.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 7c7b5

The mobile switcher now groups projects by organization, preserves workspace-specific routing, and hides demo projects consistently with desktop behavior. No actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant MobileProjectContext
  participant groupByOrganization
  participant DrawerProjectSwitcher
  participant ProjectOrgSwitcherView
  MobileProjectContext->>groupByOrganization: provide filtered projects
  groupByOrganization->>DrawerProjectSwitcher: return organization groups
  DrawerProjectSwitcher->>ProjectOrgSwitcherView: render organization entries
  ProjectOrgSwitcherView->>DrawerProjectSwitcher: select organization or project
  DrawerProjectSwitcher->>MobileProjectContext: navigate with project and workspace IDs
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: switching organizations instead of workspaces in the mobile switcher.
Description check ✅ Passed The description directly explains the mobile switching problem, implemented changes, tests, and verification.
Linked Issues check ✅ Passed The PR makes mobile organization and project switching functional and identifiable, directly addressing linked issue #6228.
Out of Scope Changes check ✅ Passed All code changes support mobile switching or shared demo-project filtering required to align mobile behavior with desktop.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fe-fix/mobile-signin-org-project-switch

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c7066b37-dc12-4647-bde8-d7578198d3e9

📥 Commits

Reviewing files that changed from the base of the PR and between 753af38 and c01b748.

📒 Files selected for processing (7)
  • web/mobile/src/features/context/workspaceGroups.ts
  • web/mobile/src/features/nav/DrawerProjectSwitcher.tsx
  • web/mobile/src/lib/context.ts
  • web/mobile/tests/unit/workspaceGroups.test.ts
  • web/oss/src/state/project/selectors/project.ts
  • web/packages/agenta-entities/src/project/demo.ts
  • web/packages/agenta-entities/src/project/index.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread web/mobile/src/features/context/workspaceGroups.ts Outdated
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-pr-6247.up.railway.app/w
Project agenta-oss-clone-spike
Image tag pr-6247-8f47ad6
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-08-24T12:13:39.198Z

Review catch: an organization whose FIRST project row carried no name kept the
fallback label even when a later row supplied the real one. Reproduced in a
test, along with a second case the same shape — a blank name ("") slipped past
`??` and rendered an empty switcher row.

Both come from one habit: group-level fields were read off whichever row
happened to arrive first. Restructure so grouping buckets the rows first, then
resolves every group field across the WHOLE bucket. Names go through a
firstNonBlank helper, so blank is treated as missing rather than as a name.

Along the way:
- RoutableProject makes "has a workspace, so it can be routed to" a type, not a
  guard repeated per grouper. Project rows no longer need a workspace_id
  fallback at the call site.
- OrganizationGroup.key is now separate from organizationId, which stays null
  for a workspace-keyed row instead of holding a synthetic "workspace:<id>".
- OrganizationGroup.workspaceId comes from the group's first project, so the
  workspace an org row enters cannot disagree with the project it lands on.
- WorkspaceGroup drops workspaceName and organizationName. Nothing reads them
  since the switcher moved to groupByOrganization, and leaving display fields on
  a routing-only type is what invited the first-row bug.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
web/mobile/src/features/context/workspaceGroups.ts (1)

6-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduce the new multi-line comments.

Keep only short comments for non-obvious constraints. Remove comments that restate the code or product rationale.

  • web/mobile/src/features/context/workspaceGroups.ts#L6-L9: Reduce this routing explanation to one short constraint comment.
  • web/mobile/src/features/context/workspaceGroups.ts#L52-L59: Reduce this grouping rationale to one short constraint comment.
  • web/mobile/src/features/nav/DrawerProjectSwitcher.tsx#L93-L94: Remove or shorten this implementation-history comment.
  • web/mobile/src/features/nav/DrawerProjectSwitcher.tsx#L108-L109: Remove or shorten this UI-description comment.
  • web/mobile/tests/unit/workspaceGroups.test.ts#L89-L91: Remove or shorten this test-behavior comment.

As per coding guidelines, “Keep in-code comments to at most one short line; use longer comments only for genuinely surprising constraints such as bugs, races, or ordering requirements.”

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 80f3f6be-2c0f-4b98-b5a5-e5f1bbc6cf30

📥 Commits

Reviewing files that changed from the base of the PR and between c01b748 and 0abc6b6.

📒 Files selected for processing (4)
  • web/mobile/src/features/context/workspaceGroups.ts
  • web/mobile/src/features/nav/DrawerProjectSwitcher.tsx
  • web/mobile/tests/unit/contextTarget.test.ts
  • web/mobile/tests/unit/workspaceGroups.test.ts
💤 Files with no reviewable changes (1)
  • web/mobile/tests/unit/contextTarget.test.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

web/CLAUDE.md caps in-code comments at one short line. The blocks added in the
previous two commits narrated rationale in prose instead. Cut to one line each,
keeping only the constraints that are not visible in the code.

Leaves the two pre-existing comments in DrawerProjectSwitcher alone. They are
untouched by this PR and rewriting them here would be unrelated diff noise.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug frontend size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] Mobile sign-in does not switch organization or project

2 participants