diff --git a/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementPage.tsx b/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementPage.tsx index 8c3806165..4c7b8104e 100644 --- a/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementPage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementPage.tsx @@ -536,13 +536,12 @@ const UserManagementPage = () => { [user?.employee], ); - const visibleOrganizations = useMemo(() => { - if (isSuperAdmin) { - return organizations; - } - - return organizations.filter((organization) => allowedOrgIds.has(organization.id)); - }, [allowedOrgIds, isSuperAdmin, organizations]); + // Both paths are already scoped server-side: super admins get every org from + // /organizations, org/unit admins get only theirs from my-admin-organizations. + // So no client-side re-filtering (allowedOrgIds, from employee.organizationId, + // wouldn't include orgs administered without an employee record there). + const visibleOrganizations = organizations; + void allowedOrgIds; const selectedOrganization = useMemo( () => visibleOrganizations.find((item) => item.id === selectedOrgId) ?? null, @@ -636,7 +635,12 @@ const UserManagementPage = () => { setLoadError(null); try { - const response = await api.get>("/organizations"); + // Super admins may list every organization (needs can:find_all:organization). + // Org/unit admins are scoped to the orgs they administer via my-admin-organizations. + const endpoint = isSuperAdmin + ? "/organizations" + : "/organizations/my-admin-organizations"; + const response = await api.get>(endpoint); const nextOrganizations = getItems(response.data); setOrganizations(nextOrganizations); } catch (error) { @@ -644,7 +648,7 @@ const UserManagementPage = () => { } finally { setLoading(false); } - }, []); + }, [isSuperAdmin]); const loadOrgEmployees = useCallback(async (organizationId: string) => { setOrgEmployeesLoading(true);