mirror of
https://github.com/coder/coder.git
synced 2026-11-04 06:44:46 +08:00
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell. ## Problem #27191 fixed the mobile menu missing the **AI** / **AI sessions** items, but did so by duplicating the item list. The desktop `DeploymentDropdown` and mobile `MobileMenu` each hardcode the same Admin settings links and permission gates. That duplication is exactly why the two drifted out of sync in the first place, and it will happen again the next time an item is added. ## Fix Extract a single source of truth in `adminSettings.ts`: - `AdminSettingsPermissions` type shared by both surfaces. - `getAdminSettingsItems(permissions)` builds the ordered item list using conditional spreads, e.g. ```ts ...(canViewAISettings ? [{ label: "AI", to: "/ai/settings" }] : []), ``` - `canViewAdminSettings(permissions)` for the desktop visibility gate. `DeploymentDropdown` and `MobileMenu` now just `.map()` over the shared list, so adding or changing an item is a one-line edit in one place. No backend, permission, routing, or user-visible behavior changes. Item labels, links, and order match the current desktop dropdown (mobile now inherits the same `linkToAuditing` constant instead of a hardcoded `/audit`, same value). <details> <summary>Rationale / approach</summary> Following Larry Wall's virtues: laziness (one list to maintain, not two), impatience (kill the class of bug where the two menus silently diverge), and hubris (leave a shared module nobody has to apologize for). Kept `canViewOrganizations` in the permission type and visibility gate even though Organizations always renders, preserving prior behavior rather than changing it as part of a refactor. Validated with `biome check` and `tsc --noEmit`; existing `MobileMenu.stories.tsx` args already cover the Admin / Auditor / OrgAdmin / Member permission matrices. </details>