From dbf482f8dae53dfd7b80916eea93597c6db702fb Mon Sep 17 00:00:00 2001 From: Ashish Gupta Date: Tue, 30 Sep 2025 20:12:54 +0530 Subject: [PATCH] support owner operation with editOwner and editALL for teams (#23625) * support owner opertaion with editOwner and editALL for teams * remove the isAdmin condition here, as for admin there will be editALL permissionby default * fix the playwright test * used the getPrioritizedEditPermission method for permission check --- .../ui/playwright/e2e/Pages/Teams.spec.ts | 9 ++++++--- .../main/resources/ui/playwright/utils/team.ts | 14 +++++++++++++- .../TeamsHeaderSection/TeamsInfo.component.tsx | 18 +++++++++++------- .../TeamsHeaderSection/TeamsInfo.test.tsx | 7 ------- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts index 38215d55fca..74f8afe2222 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts @@ -798,7 +798,7 @@ test.describe('Teams Page with Data Consumer User', () => { dataConsumerPage.getByTestId('edit-team-name') ).not.toBeVisible(); await expect(dataConsumerPage.getByTestId('add-domain')).not.toBeVisible(); - await expect(dataConsumerPage.getByTestId('edit-owner')).not.toBeVisible(); + await expect(dataConsumerPage.getByTestId('edit-owner')).toBeVisible(); await expect(dataConsumerPage.getByTestId('edit-email')).not.toBeVisible(); await expect( dataConsumerPage.getByTestId('edit-team-subscription') @@ -969,12 +969,12 @@ test.describe('Teams Page action as Owner of Team', () => { state: 'detached', }); + await expect(ownerUserPage.getByTestId('edit-owner')).toBeVisible(); + await expect(ownerUserPage.getByTestId('manage-button')).not.toBeVisible(); await expect(ownerUserPage.getByTestId('add-domain')).not.toBeVisible(); - await expect(ownerUserPage.getByTestId('edit-owner')).not.toBeVisible(); - await expect(ownerUserPage.getByTestId('edit-email')).not.toBeVisible(); await expect( @@ -986,6 +986,7 @@ test.describe('Teams Page action as Owner of Team', () => { await executionOnOwnerTeam(ownerUserPage, team, { domain: domain, email: teamDetails.updatedEmail, + user: user.responseData.displayName, }); }); @@ -993,6 +994,7 @@ test.describe('Teams Page action as Owner of Team', () => { await executionOnOwnerTeam(ownerUserPage, team2, { domain: domain, email: teamDetails.updatedEmail, + user: user.responseData.displayName, }); }); @@ -1000,6 +1002,7 @@ test.describe('Teams Page action as Owner of Team', () => { await executionOnOwnerTeam(ownerUserPage, team3, { domain: domain, email: teamDetails.updatedEmail, + user: user.responseData.displayName, }); }); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/team.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/team.ts index c0d62edc47f..39fd174d3d0 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/team.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/team.ts @@ -13,6 +13,7 @@ import { APIRequestContext, expect, Page } from '@playwright/test'; import { GlobalSettingOptions } from '../constant/settings'; import { Domain } from '../support/domain/Domain'; +import { EntityTypeEndpoint } from '../support/entity/Entity.interface'; import { TableClass } from '../support/entity/TableClass'; import { TeamClass } from '../support/team/TeamClass'; import { UserClass } from '../support/user/UserClass'; @@ -22,7 +23,7 @@ import { toastNotification, uuid, } from './common'; -import { addOwner } from './entity'; +import { addMultiOwner, addOwner } from './entity'; import { validateFormNameFieldInput } from './form'; import { settingClick } from './sidebar'; @@ -447,6 +448,7 @@ export const executionOnOwnerTeam = async ( data: { domain: Domain; email: string; + user: string; } ) => { await team.visitTeamPage(page); @@ -458,6 +460,16 @@ export const executionOnOwnerTeam = async ( await assignDomain(page, data.domain.responseData); + await addMultiOwner({ + page, + ownerNames: [data.user], + activatorBtnDataTestId: 'edit-owner', + resultTestId: 'teams-info-header', + endpoint: EntityTypeEndpoint.Teams, + type: 'Users', + clearAll: false, + }); + await addEmailTeam(page, data.email); await page.getByTestId('add-placeholder-button').click(); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Team/TeamDetails/TeamsHeaderSection/TeamsInfo.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Team/TeamDetails/TeamsHeaderSection/TeamsInfo.component.tsx index f08d3e269ce..e42b505848a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Team/TeamDetails/TeamsHeaderSection/TeamsInfo.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Team/TeamDetails/TeamsHeaderSection/TeamsInfo.component.tsx @@ -28,10 +28,11 @@ import { } from '../../../../../constants/constants'; import { EMAIL_REG_EX } from '../../../../../constants/regex.constants'; import { EntityType } from '../../../../../enums/entity.enum'; +import { Operation } from '../../../../../generated/entity/policies/policy'; import { Team, TeamType } from '../../../../../generated/entity/teams/team'; import { EntityReference } from '../../../../../generated/entity/type'; -import { useAuth } from '../../../../../hooks/authHooks'; import { useApplicationStore } from '../../../../../hooks/useApplicationStore'; +import { getPrioritizedEditPermission } from '../../../../../utils/PermissionsUtils'; import { DomainLabel } from '../../../../common/DomainLabel/DomainLabel.component'; import { OwnerLabel } from '../../../../common/OwnerLabel/OwnerLabel.component'; import TeamTypeSelect from '../../../../common/TeamTypeSelect/TeamTypeSelect.component'; @@ -49,8 +50,6 @@ const TeamsInfo = ({ }: TeamsInfoProps) => { const { t } = useTranslation(); - const { isAdminUser } = useAuth(); - const [isEmailEdit, setIsEmailEdit] = useState(false); const [showTypeSelector, setShowTypeSelector] = useState(false); const [isLoading, setIsLoading] = useState(false); @@ -62,10 +61,12 @@ const TeamsInfo = ({ [currentTeam] ); - const { hasEditPermission, hasAccess } = useMemo( + const { hasEditPermission, hasEditOwnerPermission } = useMemo( () => ({ hasEditPermission: entityPermissions.EditAll && !isTeamDeleted, - hasAccess: isAdminUser && !isTeamDeleted, + hasEditOwnerPermission: + getPrioritizedEditPermission(entityPermissions, Operation.EditOwners) && + !isTeamDeleted, }), [entityPermissions, isTeamDeleted] @@ -307,7 +308,10 @@ const TeamsInfo = ({ ]); return ( - + ({ - useAuth: jest.fn().mockReturnValue({ isAdminUser: true }), -})); - jest.mock('../../../../common/OwnerLabel/OwnerLabel.component', () => ({ OwnerLabel: jest.fn().mockImplementation(() =>
OwnerLabel
), })); @@ -161,8 +156,6 @@ describe('TeamsInfo', () => { }); it('should not show edit button if user does not have permission', () => { - (useAuth as jest.Mock).mockReturnValue({ isAdminUser: false }); - mockEntityPermissions.EditAll = false; const { queryByTestId } = render(); const ownerLabel = queryByTestId('edit-email');