From c5b7716f742a2be83410d62fde138db338f7fbb0 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg Date: Thu, 20 Aug 2026 22:15:03 +0200 Subject: [PATCH] revert(nav): keep company switching in the bottom user block only (#1775) Reverts #1765, which mounted the CompanySwitcher at the top of the expanded desktop sidebar. Seen live, the top slot is the wrong home for it: the sidebar head stays brand + collapse control, and the nav starts directly below it. Switching keeps its single home in the bottom user block (UserMenu flyout), which is also what the collapsed 64px rail and every existing muscle memory already use. The mobile sheet's switcher is untouched. The logo title tooltip and the source-shape regression test go back with it: both shipped inside the same commit and both exist only to pin the top placement. DECISIONS.md records that #1664's "one-click from the top" framing is declined rather than merely unimplemented, so the issue does not get re-opened into the same PR. Reverts 72181e49bd4b97f03e0e719ec6664832e2e2267c Claude-Session: https://claude.ai/code/session_01LcwpT82qwHhtTAFeU47Ay1 Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) --- DECISIONS.md | 1 + components/dashboard/DashboardNav.tsx | 17 ----- .../sidebar-company-switcher.test.ts | 69 ------------------- 3 files changed, 1 insertion(+), 86 deletions(-) delete mode 100644 components/dashboard/__tests__/sidebar-company-switcher.test.ts diff --git a/DECISIONS.md b/DECISIONS.md index 18805258..fcceefaa 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -1134,3 +1134,4 @@ One line per decision: `[YYYY-MM-DD] : `. Appended by agents and [2026-08-19] Sidebar company switch (#1664): reinstated the existing CompanySwitcher at the top of the expanded desktop sidebar instead of turning the logo slot into the switcher (the issue offered both); the logo keeps its home link plus a native title tooltip, the user-menu flyout stays as the secondary path, and the collapsed rail relies on the UserMenu avatar since 64px has no room for a labeled switcher. [2026-08-19] #1674 audit fixed the in-repo disclosures only (privacy sub-processor Bedrock row now names Anthropic as model vendor, replay paragraph states the deny-by-default guarantee, both locked by app/(public)/privacy/__tests__): Anthropic was deliberately NOT added as its own sub-processor row because no code path sends data to Anthropic (hosted uses Bedrock in eu-north-1, lib/ai/provider.ts); the artifact the prospect actually read (published DPA PDF or marketing security page listing Anthropic/OpenAI in the US) lives outside this repo and needs founder/legal action, as does any underbitraede-list wording. [2026-08-19] #1674 audit fixed the in-repo disclosures only (privacy sub-processor Bedrock row now says AI requests go to Amazon Bedrock and the models are Anthropics Claude running inside Bedrock, replay paragraph states the deny-by-default guarantee, both locked by app/(public)/privacy/__tests__): Anthropic was not added as its own sub-processor row because the HOSTED posture is Bedrock by credential precedence (lib/ai/provider.ts: static AWS keys select Bedrock, region is AWS_REGION with eu-north-1 as the default, not a guarantee); a direct Anthropic API path DOES exist in code for self-hosted deployments (AI_PROVIDER=anthropic, or ANTHROPIC_API_KEY without static AWS keys), so "no code path sends data to Anthropic" would be false and the page asserts nothing about Anthropics underbitraede status either way; whether Anthropic is an underbitraede, plus aligning the published DPA PDF / marketing security page (which listed Anthropic/OpenAI in the US), is founder/legal action outside this repo. +[2026-08-20] Reverted #1765: the company switcher is NOT mounted at the top of the desktop sidebar. Founder call after seeing it live: switching belongs in the bottom user block only (the UserMenu flyout), so the sidebar top stays brand + collapse and the nav starts immediately below. #1664's "one-click from the top" framing is therefore declined, not merely unimplemented; the logo title tooltip went back with the revert since it shipped inside the same commit. Do not re-add a top-of-sidebar switcher from #1664 without a new founder decision. diff --git a/components/dashboard/DashboardNav.tsx b/components/dashboard/DashboardNav.tsx index b0bc52bf..79b97793 100644 --- a/components/dashboard/DashboardNav.tsx +++ b/components/dashboard/DashboardNav.tsx @@ -706,13 +706,9 @@ export default function DashboardNav({ companyName: _companyName, entityType, pa : 'justify-between pl-5 pr-3', )} > - {/* Native title tooltip (same convention as the collapsed rail - items) so the logo square is labeled on hover, not a mystery - mark (#1664). */} - {/* One-click company switch pinned at the top of the sidebar - (#1664): consultants hop between companies constantly, and the - user-menu flyout costs three clicks. That flyout stays as the - secondary path. Hidden on the collapsed rail (no room at 64px); - the UserMenu avatar still reaches the same switch there. Kept - outside the data-ph-unmask navs so the company name stays - masked in replays, like the mobile sheet's switcher. */} - {!collapsed && ( -
- -
- )} - {/* Nav items in their own scroll container so the user block below stays sticky (concept PR 2). */}
diff --git a/components/dashboard/__tests__/sidebar-company-switcher.test.ts b/components/dashboard/__tests__/sidebar-company-switcher.test.ts deleted file mode 100644 index b0604eff..00000000 --- a/components/dashboard/__tests__/sidebar-company-switcher.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { describe, it, expect } from 'vitest' -import fs from 'node:fs' -import path from 'node:path' - -const NAV_SRC = fs.readFileSync( - path.resolve(__dirname, '../DashboardNav.tsx'), - 'utf8', -) -const USER_MENU_SRC = fs.readFileSync( - path.resolve(__dirname, '../UserMenu.tsx'), - 'utf8', -) - -/** - * Regression pin for one-click company switching in the sidebar (#1664). - * - * The switch was folded into the bottom-of-sidebar user popover as a nested - * flyout (avatar, then "Byt foretag", then the company): three clicks per - * switch, which consultants who hop between companies do constantly. The - * one-click CompanySwitcher must stay mounted at the top of the desktop - * sidebar, with the user-menu flyout as the secondary path. The repo does - * not render components in tests, so pin the source shape instead, the same - * way JournalEntryList's copy affordance is pinned. - */ -describe('DashboardNav sidebar company switcher (#1664)', () => { - const asideStart = NAV_SRC.indexOf(' { - expect(asideStart).toBeGreaterThan(-1) - expect(mobileNavStart).toBeGreaterThan(asideStart) - expect(desktopScrollStart).toBeGreaterThan(asideStart) - expect(desktopScrollStart).toBeLessThan(mobileNavStart) - }) - - it('renders CompanySwitcher inside the desktop sidebar, not only the mobile sheet', () => { - const desktopSwitcher = NAV_SRC.indexOf('', asideStart) - expect(desktopSwitcher).toBeGreaterThan(asideStart) - expect(desktopSwitcher).toBeLessThan(mobileNavStart) - }) - - it('pins the desktop switcher to the top of the sidebar, above the nav scroll container', () => { - const desktopSwitcher = NAV_SRC.indexOf('', asideStart) - expect(desktopSwitcher).toBeLessThan(desktopScrollStart) - }) - - it('keeps the mobile sheet switcher as well', () => { - const desktopSwitcher = NAV_SRC.indexOf('', asideStart) - const mobileSwitcher = NAV_SRC.indexOf('', mobileNavStart) - expect(mobileSwitcher).toBeGreaterThan(desktopSwitcher) - }) - - it('labels the brand logo link with a visible title tooltip and aria-label', () => { - const logoLink = NAV_SRC.slice( - NAV_SRC.indexOf('', asideStart), - ) - expect(logoLink).toContain('aria-label={getBranding().appName}') - expect(logoLink).toContain('title={getBranding().appName}') - }) - - it('keeps the user-menu company flyout as the secondary switch path', () => { - expect(USER_MENU_SRC).toContain('performCompanySwitch') - expect(USER_MENU_SRC).toContain('setCompaniesOpen') - }) -})