feat(nav): account-centric dropdown menu#404
Conversation
Convert the flat Organizations / Products / Admin sections of the account dropdown into hover submenus: - Organizations: first 5 orgs (by name) then "Add Organization" (when permitted) - Products: first 5 owned products then "All Products" then "Create Product" (when permitted) - Admin: the admin tools (admins only) Resolve org names and owned products server-side in AuthButtons (memberships carry only ids) and pass them to the client dropdown. Add a reusable DropdownSubmenu component sharing a DropdownItems renderer with DropdownSection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @alukach's task in 4m 39s —— View job Claude is reviewing this PR
❌ Changes requested — see findings below.
Everything else looks solid:
Not evaluated: visual/UX behavior (dropdown/mobile sheet appearance), since this is a static diff review — @tylere's UI feedback in the thread is worth addressing separately but isn't a correctness/security bug. |
Address dropdown redesign feedback: - Move View/Edit Profile behind a "Profile" submenu - "Create Organization" / "Create Product" now use a consistent verb and a leading + icon - Always show a divider before Logout (drop UploadsSubmenu's now-redundant trailing separator so it isn't doubled when uploads are active) - Truncate long org/product names so one entry can't blow out the menu width Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
session.memberships includes Invited records (authorized for GetMembership), so an outstanding invite was surfaced as an org the user already belongs to. Filter to state === Member, matching the established pattern in lookups.getManageableAccounts and products/new. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pending invitations: - Red dot on the account avatar when the user has pending invites - "Invitations" section (dot-marked) at the top of the dropdown listing each invite; clicking navigates to the org/product page whose PendingInvitationBanner lets the user accept/decline - Resolve org names and product titles server-side in AuthButtons; a small pure invitationLink() (unit-tested) picks the org- vs product-page route Products link: - Add a prominent "Products" link in the nav next to the account dropdown - Drop the now-redundant "All Products" entry from the Products submenu Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…name - Org/product/invitation names render at medium weight so they read as data, distinct from the menu commands around them - Nav Products link: match the username's size (3) and drop the bold weight for a more prominent, less heavy look Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Show up to 20 orgs/products in their submenus (was 5); fetch 20 owned products - Render entity names in a monospace face - Cap submenu height so long lists scroll instead of overflowing the viewport Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ducts) Replace the separate Profile / Products / Organizations submenus with one list of accounts — yourself plus each org you belong to. Each account is a submenu that links to its page and lists that account's products (up to 20), so you can reach an org's products, not just your own. - AuthButtons resolves products for you and each member org (parallel, cached) - Global "New product" / "New organization" actions (the create form already picks the owner account), permission-gated - Drop "Edit Profile" from the menu (edit from the profile page) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ck in menu - Drop monospace from account/product/invitation names - Label accounts by display name (not id) with a small avatar to the left - Grey "No products yet" when an account has no products - Invitations always shown; grey "No pending invitations" when there are none (red dot only when invites exist) - Move the "Products" (all products) link back to the top of the menu and remove it from the nav bar Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bound the dropdown and submenu content to a max width and let names shrink (min-width: 0) and ellipsize within it, so a long org/product name no longer expands the menu past its default width. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
text-overflow: ellipsis needs a definite width; the min-width:0 approach let the row clip hard instead. Give names a fixed max-width (180px) so they ellipsize, and drop the menu/submenu width caps that caused the hard cutoff. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…le menu - Products link: match the product-list entry headers (var(--gray-a11), weight 600), no uppercase/underline. Inline styles keep it consistent on the marketing page too, where `.landing a` otherwise forces uppercase + underline. - Account dropdown spans nearly the full viewport on phones (<=640px) for a traditional, tap-friendly mobile menu. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ray-12 on hover Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On phones the account controls collapse into a single hamburger that opens a full-screen sheet: Products, your accounts (inline accordions revealing each account's products), create actions, invitations, admin, and logout. Desktop keeps the Products link + account dropdown unchanged. - New MobileMenu (built on the @radix-ui/react-dialog primitive) with a single-open accordion and full-width tap targets - AuthButtons now owns the whole right side and renders desktop vs mobile via responsive display; Products link extracted to ProductsNavLink (reused when logged out too) - Shared useLogout hook (was duplicated logic in the dropdown) - Drop the interim full-width-dropdown CSS; the sheet replaces it Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Switch MobileMenu from the raw @radix-ui/react-dialog primitive to Radix Themes' Dialog. The primitive portals outside the Theme, so tokens were undefined — no sheet background and the avatars rendered unsized. The themed Dialog re-applies the theme inside the portal (fixes both) and supplies the backdrop; content is styled full-screen. - Hide the nav-bar Products link on the marketing homepage (usePathname === '/'), and fold its divider into ProductsNavLink so they hide together. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- useLogout hook (no React hooks inside) → plain logout() function - DropdownItems: drop index-preservation gymnastics; stateless menu items don't need key stability across condition toggles - reuse the .mobileDot class for the invitations dot (drop single-use const) - fix stale "All Products" JSDoc example Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Revert an over-eager ponytail cut: filtering before mapping renumbers React keys, reintroducing the reconcile-wrong-node footgun the original code guarded against. Shared by DropdownSection + DropdownSubmenu, so keep the guard for future callers that may toggle an item's condition. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extract the sheet shell (MobileMenuSheet) so logged-in and logged-out variants share the hamburger/full-screen chrome. When logged out, mobile now shows a hamburger opening a sheet with the Products link and the Log In / Register button (desktop keeps them inline). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rename ProductsNavLink -> NavLinks; it now renders Products + Docs (external docs.source.coop), hidden together on the marketing homepage. Docs row added to both the logged-in and logged-out mobile sheets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New product / New organization now always render in the account dropdown. When the user lacks permission they're disabled with a Radix tooltip explaining why, instead of being hidden. DropdownItem gains a `tooltip` field; disabled+tooltip items wrap a real (padded) disabled menu item in a pointer-events-live span so the tooltip fires (matching SettingsLayout). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Notes from experimenting with the UI:
|
@tylere can you clarify what you mean by the "load web page icon"? |
…to account submenus Addresses review feedback on the account menu: - Products under each account now sit under a "Products" label with a page icon, so they read as products/links (not ambiguous plain text). - "+ New product" moves to the bottom of each account's product list; it links to /products/new?owner=<account> to preselect that owner. - "+ New organization" stays after the list of accounts you belong to. Mobile menu mirrors the same structure (icon + inline New product). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
newProductUrl(ownerAccountId?) appends ?owner=<id>. The new-product page reads it, validates it against the potential owner accounts, and passes it to ProductCreationForm as the initial owner (falling back to the first account otherwise). Opening "New product" from an org menu now defaults the owner to that org. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
By "load web page icon" I mean't the icon that you pointed out during today's Source Sync. (iirc, this was in response to Michelle's comment about how some links modify the page and some open new pages) |
What
Redesigns the nav + account dropdown to make it simple to:
This generally boils down to a UI like this:
How
Navigation→AuthButtons):AuthButtons(server) owns the rightside and switches responsively — desktop shows the Products link + the account
dropdown; mobile collapses to a single hamburger. The Products link
(
ProductsNavLink, Berkeley Mono) is shown to everyone but hidden on themarketing homepage.
AuthButtons): resolves what the client can't (memberships onlycarry ids): the org accounts you belong to, the products owned by you and by
each of those orgs (
listByAccount(id, 20), filtered byGetRepositorysorestricted products you can't access aren't shown), and any pending
invitations — all concurrently. Only org-level memberships (
repository_idundefined) count as orgs you belong to.
AccountDropdown): built fromDropdownSubmenu, whichshares a
DropdownItemsrenderer withDropdownSection(items, thenoptional
actionsafter a separator; hidden when empty).MobileMenu): a full-screen sheet (Radix ThemesDialog) withinline single-open accordions and full-width tap targets — same content as the
dropdown.
Notes / follow-ups
you pick the owner account.
the hover dropdown.
mobile sheet in particular.
DropdownSection.integration.test.tsxfails locally withReact.Children.only— pre-existing/environmental (react-slot duplication, as that test documents);
it fails identically on
mainand is unrelated to this change.Tests
DropdownSection,DropdownSubmenu(visibility + separatorlogic) and
accountMenu(invitationLinkrouting + fallbacks).tscand ESLint clean; 15/15 unit tests pass. (The nav/mobile components areUI-only, covered by manual review rather than unit tests.)
🤖 Generated with Claude Code
closes #232
closes #309