Skip to content

feat(webapp): redesign the side menu project and organization menus#4066

Open
samejr wants to merge 51 commits into
mainfrom
samejr/org-menu-update
Open

feat(webapp): redesign the side menu project and organization menus#4066
samejr wants to merge 51 commits into
mainfrom
samejr/org-menu-update

Conversation

@samejr

@samejr samejr commented Jun 28, 2026

Copy link
Copy Markdown
Member

This is a test concept that separates Projects from the Org menu in the main side menu.

Preview URL: https://samejr-org-menu-update.triggerlabs.dev/

samejr added 3 commits June 28, 2026 20:15
The top-left menu now represents the organization: it shows the org name and avatar and opens a flat list of org-level pages (Settings, Usage, Billing, Billing alerts, Team, an Integrations submenu, Switch organization, Account, Logout).

Projects move into a dedicated "Project" section in the menu body: a project picker dropdown with the environment selector directly beneath it.
The Project menu trigger now matches the other side menu items: its label and folder icon are dimmed by default and brighten on hover, instead of staying highlighted.

The environment selector shows a "[name] environment" tooltip on hover. It opens instantly when the side menu is collapsed and after a short delay when expanded.
Add an end tree-connector to the left of the environment selector and remove the gap between it and the project dropdown, so the environment reads as nested under the project in the side menu.
@changeset-bot

changeset-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d012cc9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The org route loader now detects RBAC and SSO plugin availability, exposes both flags in loader data, and adds hooks for reading them. The side menu is reorganized into separate organization and project selectors: the organization popover lists org-level actions, integrations, account, logout, and organization switching, while the project selector shows project-only actions. EnvironmentSelector updates its tooltip behavior and moves branch popover content into BranchesPopoverContent. The help popover label styling and tooltip timing are adjusted, and the navigation note is updated to match the new structure.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is missing the required template sections, including issue reference, checklist, testing steps, changelog, and screenshots. Add the full template: Closes #issue, checklist, Testing, Changelog, and Screenshots sections with concrete details.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main UI redesign of the side menu project and organization menus.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch samejr/org-menu-update

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.

devin-ai-integration[bot]

This comment was marked as resolved.

@samejr samejr added the preview label Jun 28, 2026
@trigger-dot-bot

trigger-dot-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

Preview Deployment

Status Preview Commit Updated
🟢 Ready samejr-org-menu-update.triggerlabs.dev d012cc9 Jul 13, 21:14 UTC

coderabbitai[bot]

This comment was marked as resolved.

samejr added 4 commits June 29, 2026 19:02
Bump the org menu and project picker popover items to a 20px leading icon and a 0.90625rem label so they match the side menu nav items. The project folder icons keep their indigo color and the Vercel and Slack icons keep their smaller size.
…oll area

Move the Project header, project picker, and environment selector into a fixed region so they stay put while the nav list scrolls, and shift the scroll divider down to the top of the scrollable section.
The side menu environment switcher is now a segmented control (Dev, Staging, Prev, Prod) instead of a dropdown, with each segment tinted in its environment color when active.

The Dev segment shows the local dev server connection as a small pulsing dot with a hover tooltip, replacing the old connection button and modal. Preview opens a popover to switch branches and shows the active branch name. When the side menu is collapsed it falls back to the original dropdown selector, which is also still used on the blank-state panels and the Limits page.
- Revert the environment segmented control back to the dropdown selector, restoring the dev connection button and its modal
- Hide the org, project, and environment selector chevrons until hover
- Reorganize the project popover so New project and Project settings sit above a divider, before the project list
- Remove the Environments header from the environment popover
- Fix the dev connection button being clipped and tune the scroll section padding
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

…ide menu

- Brighten the project selector trigger label and icon
- Keep a constant 1px border on the project selector (transparent when collapsed) so it no longer nudges 1px on collapse
- Animate the scroll section left padding in sync with the side menu collapse, matching its duration and easing
- Remove the H shortcut key from the Help & Feedback button and surface it in a 500ms hover tooltip instead, keeping the shortcut working
- Match the Help & Feedback label to the other side menu items (size and dimmed color)
devin-ai-integration[bot]

This comment was marked as resolved.

samejr added 2 commits July 2, 2026 14:07
- Apply the scrollable section left padding to the top Project section (Project header, project selector, environment selector), animated in sync with the collapse
- Keep the menus reducing width instead of shifting right by holding their right edge
- Match the section right and bottom padding to the left padding for symmetry, since there is no scrollbar in this section
- Leave the organization menu unchanged
# Conflicts:
#	apps/webapp/app/components/navigation/SideMenu.tsx
#	apps/webapp/app/routes/_app.orgs.$organizationSlug/route.tsx
@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@trigger.dev/build

npm i https://pkg.pr.new/@trigger.dev/build@baeb7bd

trigger.dev

npm i https://pkg.pr.new/trigger.dev@baeb7bd

@trigger.dev/core

npm i https://pkg.pr.new/@trigger.dev/core@baeb7bd

@trigger.dev/python

npm i https://pkg.pr.new/@trigger.dev/python@baeb7bd

@trigger.dev/react-hooks

npm i https://pkg.pr.new/@trigger.dev/react-hooks@baeb7bd

@trigger.dev/redis-worker

npm i https://pkg.pr.new/@trigger.dev/redis-worker@baeb7bd

@trigger.dev/rsc

npm i https://pkg.pr.new/@trigger.dev/rsc@baeb7bd

@trigger.dev/schema-to-json

npm i https://pkg.pr.new/@trigger.dev/schema-to-json@baeb7bd

@trigger.dev/sdk

npm i https://pkg.pr.new/@trigger.dev/sdk@baeb7bd

commit: baeb7bd

samejr added 6 commits July 2, 2026 18:03
- Replace the Ask AI button in the side menu footer with a collapse toggle that mirrors the middle handle (toggles the menu, Collapse/Expand tooltip with the cmd+b shortcut)
- Add an animated LeftSideMenuIcon (scaleX transform so it animates on the compositor and never snaps) that animates on button hover, dimmed by default and bright on hover
- Swap in a static LeftSideMenuCollapsedIcon when the menu is collapsed, and match the tooltip open delay to the Help and Feedback button
- Add LeftSideMenuIcon to the storybook icons route

Removes the Ask AI button and its cmd+i shortcut from the footer.
…r button

The side menu footer collapse button now handles toggling, so the middle-right handle (and its animated chevron) is redundant. The cmd+b shortcut is preserved.
…llapsing

The top section's bottom padding was pb-1 when collapsed and pb-2.5 when open, causing a vertical layout shift below the environment menu on toggle. Make it a constant pb-2.5 so only the horizontal padding animates.
- Add an Account menu (user avatar button) to the top of the side menu, between the organization menu and where the impersonation button used to be
- The menu links to Profile, Personal Access Tokens, and Security, plus Logout
- For admins it adds an Admin dashboard / Stop impersonating item with the cmd+esc shortcut shown inline, replacing the old permanent admin/impersonation button
- Move Logout out of the organization menu into the account menu, and add a divider above Switch organization
Add a ChainLinkIcon and use it for the Private connections item in both the organization settings side menu and the organization dropdown, replacing the heroicons link icon.
…eholder

- Replace the heroicons UserCircleIcon fallback in UserProfilePhoto/UserAvatar with the custom AvatarCircleIcon, matching the account menu Profile item
- Size the account button avatar to match the popover menu item icons (20px)
devin-ai-integration[bot]

This comment was marked as resolved.

samejr added 2 commits July 3, 2026 15:37
Adopt the Security page's row-and-divider pattern on /account: each setting is
a row with the title on the left and its control on the right. Profile picture,
Full name, Email address, and a "Receive onboarding emails" toggle switch sit on
equal-height rows, and the Update button is now a primary button.
…he project menu

Bump the Env popover's item icons (size-5) and labels (text-[0.90625rem]) to
match the Project popover, including the preview/dev branch submenu, its branch
list, and the "Manage branches" footer. Applied only at these call sites so the
shared EnvironmentLabel/EnvironmentCombo defaults used across the app are
unchanged.
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

samejr added 4 commits July 10, 2026 19:38
The Org, Project, Environment, Account, and Help & Feedback trigger
buttons and the collapsible section headers now snap on hover instead of
fading, matching the nav items in the scrollable area. The Project
selector keeps a border-color transition so its outline still fades on
collapse. Help & Feedback also gains the same up/down disclosure chevron
the other menu triggers reveal on hover.
The disclosure chevron is a hover affordance with no meaning in the
collapsed rail, but it was left mounted there. Rendering it only when the
side menu is expanded keeps the collapsed icon clean and stops the chevron
slot from affecting the collapsed button's layout or paint.
SimpleTooltip removed its trigger from the tab order (tabIndex=-1), so
every side menu item wrapped in one (the nav links and the
org/project/environment/account selectors) was skipped when tabbing. Add
an opt-in tabbable prop to SimpleTooltip and set it on those triggers,
give each the focus-custom ring, and turn the collapsible section headers
into real buttons so they are keyboard-operable too. Tab order now follows
the DOM top to bottom in both the expanded and collapsed states.
The shared focus-custom outline sat just outside the border box (offset 0),
so it was clipped by any ancestor with overflow hidden/auto (scroll areas,
the side menu grid) and covered by adjacent elements' backgrounds. Draw it
1px inside instead so the full ring is always visible. Applies everywhere
focus-custom is used.
devin-ai-integration[bot]

This comment was marked as resolved.

Resolves conflicts across the side menu files against main's Tailwind v3 to v4 migration: keep the side menu redesign, resize, keyboard-focus, and account/help menu work; adopt v4 class syntax (h-8! important suffix) and main's functional additions (environment list revalidate-on-open, changelog URL sanitizing). tailwind.config.js is removed (v4 config lives in tailwind.css) and the focus ring inset is re-applied there.
devin-ai-integration[bot]

This comment was marked as resolved.

samejr added 3 commits July 11, 2026 20:22
… menu

The side menu still used the old charcoal-* utility classes and v3 arbitrary spacing after the v4 merge. Switch to the semantic aliases the rest of the app adopted (background-hover, grid-bright, surface-control) and the numeric spacing scale (pl-1.75, min-w-56, min-w-64). No visual change: the aliases resolve to the same underlying shades.
In the Switch organization submenu, New organization now sits above the list of organizations with the divider below it, instead of below the list.
In the dev and preview branch submenus, the Manage branches link now sits above the branch list with the divider below it, instead of below the list.
devin-ai-integration[bot]

This comment was marked as resolved.

samejr added 3 commits July 12, 2026 11:52
When a side menu section is collapsed its items are visually hidden (height 0) but stayed in the DOM, so keyboard and screen-reader users could still focus them. Mark the collapsed content inert so it is removed from both the tab order and the accessibility tree, restoring it when the section expands.
Bump the inset focus-custom ring's border-radius from 3px to 5px so the corners read as slightly rounder now that the ring sits inside the element.
…m pages

Add a 1.5px-stroke variant of the avatar placeholder icon (AvatarCircleIconThin) alongside the 2px default, and a thin prop on UserAvatar/UserProfilePhoto. Use it for the account page's profile picture and the team page member rows; every other avatar keeps the 2px variant.
devin-ai-integration[bot]

This comment was marked as resolved.

samejr added 14 commits July 12, 2026 12:43
Add AvatarCircleIconExtraThin (1.25px stroke) and switch the avatar placeholder's thin boolean to a strokeWidth prop (1.25 | 1.5 | 2). The team page member rows use the 1.25px variant at a slightly smaller size; the account profile picture keeps 1.5px; every other avatar stays at 2px.
…esize

While the side menu is being drag-resized, the account, dev-connection and collapse buttons (each sitting to the right of a primary item) used to stay put and overlap the org, environment and Help items as the row narrowed. Fade them out during the drag and return them on release.
The previous fix faded the account, dev connection and collapse buttons with a
class based opacity transition. During a quick drag that 200ms transition
lagged behind the shrinking row, so the buttons stayed briefly visible and
overlapped the org and Help items (the reported dark overlay).

Drive the account and dev connection opacity from the imperative
--sm-label-opacity variable instead so it tracks the drag frame by frame with no
lag, and hide the collapse button instantly (it cannot use the variable because
it stays visible as the expand button when the menu is collapsed).
…id-drag

Fading the secondary buttons out was not enough: while drag-resizing, the
account, dev connection and collapse buttons and the hover chevrons still held
their full layout width, so as the row narrowed they pushed the primary item's
overflow clip edge into its icon. The org avatar and Help & Feedback icon were
progressively swallowed by the clip and read as a dark panel covering them.

Drive those widths from the per frame --sm-label-opacity variable instead, in
the same curve as the fade, so the space is handed back to the primary item as
the menu narrows and its icon stays fully visible at every width. The collapse
button only shrinks while dragging since it keeps its natural size as the
expand affordance when the menu rests collapsed.
…gging the side menu open

The nav item labels already reveal in real time during a drag-open, but the
org, project, environment and Help & Feedback labels were gated on the
collapsed state, which only flips on release, so they stayed hidden for the
whole drag and popped in at the end.

Drive their width and opacity from the per frame --sm-label-opacity variable
instead, exactly like the nav items, and keep those rows in their expanded
arrangement while a drag is in progress so the revealing label has the layout
it needs in both directions. Outside the resizable side menu the variable is
unset and falls back to fully visible, so the environment selector and help
popover render unchanged everywhere else.
…utton label, env tooltip)

- Flush the side menu preference debounce only on real unmount. The unmount
  effect listed the fetcher in its deps, and useFetcher returns a fresh object
  every render, so the cleanup fired on every re-render and prematurely flushed
  the 500ms debounce. A drag re-renders constantly, so this turned one save into
  many. Hold the flush routine in a ref and give the effect an empty dep array.
- Give the dev server connection button an accessible name so screen readers
  announce it (it was icon only).
- Only show the environment selector tooltip on the collapsed rail, matching the
  org and project selectors. It had switched to an always-on delayed tooltip,
  which also leaked into the blank-state panels and Limits page that reuse this
  selector.
While the side menu is dragged or animated between open and collapsed, the
button and nav labels used to shrink their text box in lockstep with the fade,
so the text visibly truncated (with an ellipsis) as the row narrowed. Drive the
visible fade purely by opacity so the text stays at full width and simply fades
in place. Labels that are wider than the row still clip at its edge, now without
an ellipsis.

The selector label width cap still scales to zero as the label finishes fading,
so an invisible label never holds layout width (which would push the row's clip
edge into the icon). EnvironmentLabel gains a `truncate` prop (default true) so
only the side menu opts out; every other usage is unchanged.
…enu open

The collapse/expand button shrank its width and opacity with the
--sm-label-opacity variable during any drag. On a close drag that fades it out
so it does not overlap Help & Feedback as the row narrows, which is correct. But
on an open drag from collapsed, the same variable runs 0 to 1, so the button
(which when collapsed is the expand affordance) started at zero width and only
scaled back in near the end of the drag, so its icon appeared to grow from
nothing. Only apply the shrink while dragging closed; while dragging open the
button keeps its natural size and stays visible throughout.
…lapse

The left padding of the scroll body interpolated smoothly with --sm-collapse,
but the right-hand spacing came from a reserved scrollbar gutter that is a fixed
width and gets dropped abruptly when the scrollbar is hidden on collapse, so it
jumped instead of animating. Drop the reserved gutter and drive the right
padding with the same variable as the left, so both edges animate together. The
thin scrollbar still appears when the nav list overflows; it just no longer
reserves a fixed gutter while idle.
…the collapse animation

Restores the no-layout-shift behavior (the scroll body no longer jumps sideways
when the nav list starts or stops overflowing) that was dropped when the right
padding was made to animate. The two conflict directly: a reserved gutter is a
fixed width that cannot animate to the collapsed inset.

Resolve it with a handoff. The gutter is reserved (scrollbar-gutter: stable)
only while the menu is fully settled open; during any drag or open/close
animation it is dropped and the right padding takes over, interpolating from the
gutter's own width down to the collapsed inset so the swap has no seam. The
gutter width is platform dependent, so it is measured once on mount and exposed
as --sm-sb-gutter. An isAnimating flag keeps the gutter from being reserved
mid-animation, which would otherwise cramp the narrow menu during a button/hotkey
expand.
When the side menu is collapsed the standalone account button is hidden, so the
account actions (Profile, Personal Access Tokens, Security, Logout, and the
admin/impersonation entries) were only reachable by expanding the menu first.

Surface them on the collapsed rail: the org popover (the one menu always
reachable when collapsed) now shows an "Account" item at the top, divided from
the org items, that opens the full account menu as a submenu.

To keep it maintainable the account entries are extracted into a shared
AccountMenuItems component used by both the standalone account popover and the
submenu, and the hover submenu behind Switch organization and Integrations is
generalized into a shared SideMenuPopoverSubMenu, so new nested menus and
account entries are easy to add in one place.
… org menu

Moves the "Account" submenu shown on the collapsed rail from the top of the org
popover to the bottom, with the divider now above it instead of below.
The admin shortcut (Cmd/Ctrl+Esc to open the admin dashboard, or to stop
impersonating while impersonating) was registered inside the account menu, which
only mounts on project pages. So it did nothing on the account, organization
settings and admin pages.

Move it into a GlobalShortcuts component mounted once at the app root, so it
works on every page regardless of which side menu is rendered, and remove the
account-menu registration so it never fires twice. GlobalShortcuts is the place
to add future app-wide shortcuts.
…apturable)

Cmd+Esc can't be captured on Chrome/macOS: the browser doesn't deliver an
Escape keydown to the page while a modifier is held, so no listener ever sees
it (confirmed with a Radix dialog, which closes on any Escape keydown, not
closing on Cmd+Esc). That is why the admin shortcut did nothing.

Switch it to Cmd+Option+A (Ctrl+Alt+A on Windows): an admin-only, two-modifier
combo that no user-facing or browser shortcut uses, and which is actually
delivered because it is a letter key. It is matched on event.code (KeyA) so it
still works when Option makes the key report an alternate character on macOS,
which is why it is a small raw listener in GlobalShortcuts rather than the
key-based shortcut hook. The account-menu badge now reads Cmd Option A.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant