From e93736068e19ceadfc61c9250eb4b6b9ea7a1f96 Mon Sep 17 00:00:00 2001 From: Sean Brydon Date: Mon, 29 Sep 2025 13:25:15 +0100 Subject: [PATCH] add permissions.canUpdateOrganization to show/hide items in org navbar --- .../SettingsLayoutAppDirClient.tsx | 28 ++++++++++++++----- .../settings/(settings-layout)/layout.tsx | 4 ++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx index df73593f683475..c379f2991b18c9 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx @@ -175,6 +175,7 @@ const organizationAdminKeys = ["privacy", "OAuth Clients", "SSO", "directory_syn export interface SettingsPermissions { canViewRoles?: boolean; canViewOrganizationBilling?: boolean; + canUpdateOrganization?: boolean; } const useTabs = ({ @@ -203,10 +204,13 @@ const useTabs = ({ }; } else if (tab.href === "/settings/organizations") { const newArray = (tab?.children ?? []).filter( - (child) => isOrgAdminOrOwner || !organizationAdminKeys.includes(child.name) + (child) => + permissions?.canUpdateOrganization || + isOrgAdminOrOwner || + !organizationAdminKeys.includes(child.name) ); - if (isOrgAdminOrOwner) { + if (permissions?.canUpdateOrganization || isOrgAdminOrOwner) { newArray.splice(4, 0, { name: "attributes", href: "/settings/organizations/attributes", @@ -238,7 +242,7 @@ const useTabs = ({ }); } } else { - if (isOrgAdminOrOwner) { + if (permissions?.canUpdateOrganization || isOrgAdminOrOwner) { newArray.push({ name: "billing", href: "/settings/organizations/billing", @@ -264,7 +268,8 @@ const useTabs = ({ return { ...tab, children: filtered }; } else if (tab.href === "/settings/developer") { const filtered = tab?.children?.filter( - (childTab) => isOrgAdminOrOwner || childTab.name !== "admin_api" + (childTab) => + permissions?.canUpdateOrganization || isOrgAdminOrOwner || childTab.name !== "admin_api" ); return { ...tab, children: filtered }; } @@ -274,12 +279,21 @@ const useTabs = ({ // check if name is in adminRequiredKeys return processedTabs.filter((tab) => { if (organizationRequiredKeys.includes(tab.name)) return !!orgBranding; - if (tab.name === "other_teams" && !isOrgAdminOrOwner) return false; + if (tab.name === "other_teams" && !(permissions?.canUpdateOrganization || isOrgAdminOrOwner)) + return false; if (isAdmin) return true; return !adminRequiredKeys.includes(tab.name); }); - }, [isAdmin, orgBranding, isOrgAdminOrOwner, user, isDelegationCredentialEnabled, isPbacEnabled, permissions]); + }, [ + isAdmin, + orgBranding, + isOrgAdminOrOwner, + user, + isDelegationCredentialEnabled, + isPbacEnabled, + permissions, + ]); return processTabsMemod; }; @@ -643,7 +657,7 @@ const SettingsSidebarContainer = ({ - {(!orgBranding?.id || isOrgAdminOrOwner) && ( + {(!orgBranding?.id || permissions?.canUpdateOrganization || isOrgAdminOrOwner) && ( | null = null; let canViewRoles = false; let canViewOrganizationBilling = false; + let canUpdateOrganization = false; const orgId = session?.user?.profile?.organizationId ?? session?.user.org?.id; // For now we only grab organization features but it would be nice to fetch these on the server side for specific team feature flags @@ -68,6 +69,7 @@ export default async function SettingsLayoutAppDir(props: SettingsLayoutProps) { canViewRoles = roleActions[CrudAction.Read] ?? false; const orgActions = PermissionMapper.toActionMap(organizationPermissions, Resource.Organization); canViewOrganizationBilling = orgActions[CustomAction.ManageBilling] ?? isOrgAdminOrOwner; + canUpdateOrganization = orgActions[CrudAction.Update] ?? isOrgAdminOrOwner; } } @@ -76,7 +78,7 @@ export default async function SettingsLayoutAppDir(props: SettingsLayoutProps) { );