fix(site): show Organizations in admin dropdown for single-org OSS deployments (#25175)

Fixes https://linear.app/codercom/issue/CODAGT-350

On OSS or no-license single-org deployments, the Organizations admin
link was hidden because `canViewOrganizationSettings` was gated on
`showOrganizations`, which requires either a multi-org entitlement or >1
org. The page was still reachable via direct URL, but the members view
displayed a raw "Template RBAC is a Premium feature. Contact sales!"
error from the groups API.

Two fixes:

1. Always render the Organizations link inside the `DeploymentDropdown`.
The dropdown itself is only shown to users with admin-level permissions,
so Organizations is effectively gated on having admin access.

2. Remove `groupsByUserIdQuery.error` from the error chain on the
members page. The groups endpoint is gated behind
`templateRBACEnabledMW` on enterprise, returning a 403 on OSS. The
groups data is already optional, so the page renders fine without it.

> Generated by Coder Agents
This commit is contained in:
Cian Johnston
2026-05-12 12:28:43 +01:00
committed by GitHub
parent 5c3b59151e
commit caabb3c4ab
5 changed files with 27 additions and 19 deletions
+2 -2
View File
@@ -22,10 +22,10 @@ const adminSettings = [
] as const;
async function hasAccessToAdminSettings(page: Page, settings: AdminSetting[]) {
// Organizations and Audit Logs both require a license to be visible
// Audit Logs requires a license to be visible
const visibleSettings = license
? settings
: settings.filter((it) => it !== "Organizations" && it !== "Audit Logs");
: settings.filter((it) => it !== "Audit Logs");
const adminSettingsButton = page.getByRole("button", {
name: "Admin settings",
});
@@ -30,8 +30,8 @@ export const DeploymentDropdown: FC<DeploymentDropdownProps> = ({
if (
!canViewAuditLog &&
!canViewConnectionLog &&
!canViewOrganizations &&
!canViewDeployment &&
!canViewOrganizations &&
!canViewHealth &&
!canViewAIBridge
) {
@@ -63,7 +63,6 @@ export const DeploymentDropdown: FC<DeploymentDropdownProps> = ({
const DeploymentDropdownContent: FC<DeploymentDropdownProps> = ({
canViewDeployment,
canViewOrganizations,
canViewAuditLog,
canViewHealth,
canViewConnectionLog,
@@ -76,11 +75,9 @@ const DeploymentDropdownContent: FC<DeploymentDropdownProps> = ({
<Link to="/deployment">Deployment</Link>
</DropdownMenuItem>
)}
{canViewOrganizations && (
<DropdownMenuItem asChild>
<Link to="/organizations">Organizations</Link>
</DropdownMenuItem>
)}
<DropdownMenuItem asChild>
<Link to="/organizations">Organizations</Link>
</DropdownMenuItem>
{canViewAuditLog && (
<DropdownMenuItem asChild>
<Link to={linkToAuditing}>Audit Logs</Link>
@@ -203,7 +203,6 @@ const ProxySettingsSub: FC<ProxySettingsSubProps> = ({ proxyContextValue }) => {
const AdminSettingsSub: FC<MobileMenuPermissions> = ({
canViewDeployment,
canViewOrganizations,
canViewAuditLog,
canViewConnectionLog,
canViewHealth,
@@ -235,14 +234,12 @@ const AdminSettingsSub: FC<MobileMenuPermissions> = ({
<Link to="/deployment">Deployment</Link>
</DropdownMenuItem>
)}
{canViewOrganizations && (
<DropdownMenuItem
asChild
className={cn(itemStyles.default, itemStyles.sub)}
>
<Link to="/organizations">Organizations</Link>
</DropdownMenuItem>
)}
<DropdownMenuItem
asChild
className={cn(itemStyles.default, itemStyles.sub)}
>
<Link to="/organizations">Organizations</Link>
</DropdownMenuItem>
{canViewAuditLog && (
<DropdownMenuItem
asChild
@@ -84,6 +84,21 @@ export const ForOrgAdmin: Story = {
},
};
export const ForSingleOrgOSSAdmin: Story = {
args: {
canViewAuditLog: false,
canViewOrganizations: false,
canViewConnectionLog: false,
canViewAIBridge: false,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(
canvas.getByRole("button", { name: "Admin settings" }),
);
},
};
export const ForMember: Story = {
args: {
user: MockUserMember,
@@ -102,7 +102,6 @@ const OrganizationMembersPage: FC = () => {
error={
membersQuery.error ??
organizationRolesQuery.error ??
groupsByUserIdQuery.error ??
addMemberMutation.error ??
removeMemberMutation.error ??
updateMemberRolesMutation.error