From 4ebc8bfc565e1521cad508e97f7bbc75ab2dd4bc Mon Sep 17 00:00:00 2001 From: guillaume-peoch-sonarsource Date: Fri, 16 Aug 2024 16:48:38 +0200 Subject: [PATCH] SONAR-22559 Remove GitLab auto-provisioning status + Gitlab Binding Banner for non binded project --- .../project/components/PageHeader.tsx | 15 +--- .../components/PermissionsProjectApp.tsx | 30 ++++++- .../PermissionsProjectVisibility.tsx | 11 +-- .../__tests__/PermissionsProject-it.tsx | 64 +++++++------- .../main/js/apps/permissions/test-utils.ts | 1 - .../components/permissions/AllHoldersList.tsx | 3 + .../js/components/permissions/HoldersList.tsx | 83 ++++++++----------- 7 files changed, 104 insertions(+), 103 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.tsx b/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.tsx index 431674c5dec..80aa2ec2b75 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.tsx +++ b/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.tsx @@ -24,7 +24,6 @@ import * as React from 'react'; import { Image } from '~sonar-aligned/components/common/Image'; import { isPortfolioLike } from '~sonar-aligned/helpers/component'; import GitHubSynchronisationWarning from '../../../../app/components/GitHubSynchronisationWarning'; -import GitLabSynchronisationWarning from '../../../../app/components/GitLabSynchronisationWarning'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import { isDefined } from '../../../../helpers/types'; import { @@ -32,27 +31,27 @@ import { useIsGitLabProjectQuery, } from '../../../../queries/devops-integration'; import { useGithubProvisioningEnabledQuery } from '../../../../queries/identity-provider/github'; -import { useGilabProvisioningEnabledQuery } from '../../../../queries/identity-provider/gitlab'; import { isApplication, isProject } from '../../../../types/component'; import { Component } from '../../../../types/types'; import ApplyTemplate from './ApplyTemplate'; interface Props { component: Component; + isProjectManaged: boolean; loadHolders: () => void; } export default function PageHeader(props: Readonly) { - const { component, loadHolders } = props; + const { component, loadHolders, isProjectManaged } = props; const { configuration, key, qualifier, visibility } = component; const [applyTemplateModal, setApplyTemplateModal] = React.useState(false); const { data: isGitHubProject } = useIsGitHubProjectQuery(key); const { data: isGitLabProject } = useIsGitLabProjectQuery(key); const { data: githubProvisioningStatus } = useGithubProvisioningEnabledQuery(); - const { data: gitlabProvisioningStatus } = useGilabProvisioningEnabledQuery(); + // to know if we are provisioning with GitLab: managed + GitLab project const provisionedByGitHub = isGitHubProject && !!githubProvisioningStatus; - const provisionedByGitLab = isGitLabProject && !!gitlabProvisioningStatus; + const provisionedByGitLab = isGitLabProject && isProjectManaged; const provisioned = provisionedByGitHub || provisionedByGitLab; const canApplyPermissionTemplate = configuration?.canApplyPermissionTemplate && !provisioned; @@ -107,7 +106,6 @@ export default function PageHeader(props: Readonly) {

{provisionedByGitHub && } - {provisionedByGitLab && }
)} @@ -116,11 +114,6 @@ export default function PageHeader(props: Readonly) { {translate('project_permission.local_project_with_github_provisioning')} )} - {gitlabProvisioningStatus && !isGitLabProject && ( - - {translate('project_permission.local_project_with_gitlab_provisioning')} - - )} {canApplyPermissionTemplate && ( diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectApp.tsx b/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectApp.tsx index c1e5708966a..c0d22a92660 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectApp.tsx +++ b/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectApp.tsx @@ -21,8 +21,9 @@ import { LargeCenteredLayout, PageContentFontWrapper } from 'design-system'; import { noop, without } from 'lodash'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; -import { Visibility } from '~sonar-aligned/types/component'; +import { ComponentQualifier, Visibility } from '~sonar-aligned/types/component'; import * as api from '../../../../api/permissions'; +import { getComponents } from '../../../../api/project-management'; import withComponentContext from '../../../../app/components/componentContext/withComponentContext'; import AllHoldersList from '../../../../components/permissions/AllHoldersList'; import { FilterOption } from '../../../../components/permissions/SearchForm'; @@ -48,6 +49,7 @@ interface State { filter: FilterOption; groups: PermissionGroup[]; groupsPaging?: Paging; + isProjectManaged: boolean; loading: boolean; query: string; selectedPermission?: string; @@ -67,12 +69,14 @@ class PermissionsProjectApp extends React.PureComponent { loading: true, query: '', users: [], + isProjectManaged: false, }; } componentDidMount() { this.mounted = true; this.loadHolders(); + this.getIsProjectManaged(); } componentWillUnmount() { @@ -122,6 +126,21 @@ class PermissionsProjectApp extends React.PureComponent { }, this.stopLoading); }; + getIsProjectManaged = () => { + if (this.props.component.qualifier === ComponentQualifier.Project) { + getComponents({ projects: this.props.component.key }) + .then((response) => { + if (this.mounted) { + const { managed } = response.components[0]; + this.setState({ + isProjectManaged: !!managed, + }); + } + }) + .catch(noop); + } + }; + handleLoadMore = () => { const { usersPaging, groupsPaging } = this.state; this.setState({ loading: true }); @@ -332,6 +351,7 @@ class PermissionsProjectApp extends React.PureComponent { users, usersPaging, groupsPaging, + isProjectManaged, } = this.state; let order = PERMISSIONS_ORDER_BY_QUALIFIER[component.qualifier]; @@ -345,9 +365,14 @@ class PermissionsProjectApp extends React.PureComponent { - +
{ users={users} usersPaging={usersPaging} permissions={permissions} + isProjectManaged={isProjectManaged} /> diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectVisibility.tsx b/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectVisibility.tsx index 8cde3d10676..abb7a4706f0 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectVisibility.tsx +++ b/server/sonar-web/src/main/js/apps/permissions/project/components/PermissionsProjectVisibility.tsx @@ -25,29 +25,26 @@ import { useIsGitLabProjectQuery, } from '../../../../queries/devops-integration'; import { useGithubProvisioningEnabledQuery } from '../../../../queries/identity-provider/github'; -import { useGilabProvisioningEnabledQuery } from '../../../../queries/identity-provider/gitlab'; import { Component } from '../../../../types/types'; interface Props { component: Component; handleVisibilityChange: (visibility: string) => void; isLoading: boolean; + isProjectManaged: boolean; } export default function PermissionsProjectVisibility(props: Readonly) { - const { component, handleVisibilityChange, isLoading } = props; + const { component, handleVisibilityChange, isLoading, isProjectManaged } = props; const canTurnToPrivate = component.configuration?.canUpdateProjectVisibilityToPrivate; const { data: isGitHubProject } = useIsGitHubProjectQuery(component.key); const { data: isGitLabProject } = useIsGitLabProjectQuery(component.key); const { data: gitHubProvisioningStatus, isFetching: isFetchingGitHubProvisioningStatus } = useGithubProvisioningEnabledQuery(); - const { data: gitLabProvisioningStatus, isFetching: isFetchingGitLabProvisioningStatus } = - useGilabProvisioningEnabledQuery(); - const isFetching = isFetchingGitHubProvisioningStatus || isFetchingGitLabProvisioningStatus; + const isFetching = isFetchingGitHubProvisioningStatus; const isDisabled = - (isGitHubProject && !!gitHubProvisioningStatus) || - (isGitLabProject && !!gitLabProvisioningStatus); + (isGitHubProject && !!gitHubProvisioningStatus) || (isGitLabProject && isProjectManaged); return ( { serviceMock = new PermissionsServiceMock(); @@ -63,8 +64,9 @@ beforeAll(() => { githubHandler = new GithubProvisioningServiceMock(dopTranslationHandler); gitlabHandler = new GitlabProvisioningServiceMock(); almHandler = new AlmSettingsServiceMock(); + settingsHandler = new SettingsServiceMock(); + projectHandler = new ProjectManagementServiceMock(settingsHandler); systemHandler = new SystemServiceMock(); - computeEngineHandler = new ComputeEngineServiceMock(); }); afterEach(() => { @@ -73,7 +75,8 @@ afterEach(() => { githubHandler.reset(); gitlabHandler.reset(); almHandler.reset(); - computeEngineHandler.reset(); + settingsHandler.reset(); + projectHandler.reset(); }); describe('rendering', () => { @@ -451,17 +454,13 @@ describe('GitHub provisioning', () => { describe('GitLab provisioning', () => { beforeEach(() => { systemHandler.setProvider(Provider.Gitlab); - computeEngineHandler.addTask({ - status: TaskStatuses.InProgress, - executedAt: '2022-02-03T11:55:35+0200', - type: TaskTypes.GitlabProvisioning, - }); - computeEngineHandler.addTask({ - status: TaskStatuses.Failed, - executedAt: '2022-02-03T11:45:35+0200', - errorMessage: "T'es mauvais Jacques", - type: TaskTypes.GitlabProvisioning, + almHandler.handleSetProjectBinding(AlmKeys.GitLab, { + almSetting: 'test', + repository: 'test', + monorepo: false, + project: 'my-project', }); + projectHandler.setProjects([mockProject({ key: 'my-project', managed: true })]); }); it('should not allow to change visibility for GitLab Project with auto-provisioning', async () => { @@ -470,9 +469,6 @@ describe('GitLab provisioning', () => { dopTranslationHandler.gitHubConfigurations.push( mockGitHubConfiguration({ provisioningType: ProvisioningType.jit }), ); - gitlabHandler.setGitlabConfigurations([ - mockGitlabConfiguration({ id: '1', enabled: true, provisioningType: ProvisioningType.auto }), - ]); almHandler.handleSetProjectBinding(AlmKeys.GitLab, { almSetting: 'test', repository: 'test', @@ -493,9 +489,6 @@ describe('GitLab provisioning', () => { it('should allow to change visibility for non-GitLab Project', async () => { const user = userEvent.setup(); const ui = getPageObject(user); - gitlabHandler.setGitlabConfigurations([ - mockGitlabConfiguration({ id: '1', enabled: true, provisioningType: ProvisioningType.auto }), - ]); almHandler.handleSetProjectBinding(AlmKeys.GitHub, { almSetting: 'test', repository: 'test', @@ -515,15 +508,13 @@ describe('GitLab provisioning', () => { it('should allow to change visibility for GitLab Project with disabled auto-provisioning', async () => { const user = userEvent.setup(); const ui = getPageObject(user); - gitlabHandler.setGitlabConfigurations([ - mockGitlabConfiguration({ id: '1', enabled: true, provisioningType: ProvisioningType.jit }), - ]); almHandler.handleSetProjectBinding(AlmKeys.GitLab, { almSetting: 'test', repository: 'test', monorepo: false, project: 'my-project', }); + projectHandler.setProjects([mockProject({ key: 'my-project', managed: false })]); renderPermissionsProjectApp({}, { featureList: [Feature.GitlabProvisioning] }); await ui.appLoaded(); @@ -537,9 +528,6 @@ describe('GitLab provisioning', () => { it('should have disabled permissions for GitLab Project', async () => { const user = userEvent.setup(); const ui = getPageObject(user); - gitlabHandler.setGitlabConfigurations([ - mockGitlabConfiguration({ id: '1', enabled: true, provisioningType: ProvisioningType.auto }), - ]); almHandler.handleSetProjectBinding(AlmKeys.GitLab, { almSetting: 'test', repository: 'test', @@ -614,9 +602,8 @@ describe('GitLab provisioning', () => { it('should allow to change permissions for GitLab Project without auto-provisioning', async () => { const user = userEvent.setup(); const ui = getPageObject(user); - gitlabHandler.setGitlabConfigurations([ - mockGitlabConfiguration({ id: '1', enabled: true, provisioningType: ProvisioningType.jit }), - ]); + + projectHandler.setProjects([mockProject({ key: 'my-project', managed: false })]); almHandler.handleSetProjectBinding(AlmKeys.GitLab, { almSetting: 'test', repository: 'test', @@ -644,15 +631,22 @@ describe('GitLab provisioning', () => { it('should allow to change permissions for non-GitLab Project', async () => { const user = userEvent.setup(); + projectHandler.reset(); + projectHandler.setProjects([mockProject({ key: 'my-project', managed: false })]); + almHandler.reset(); + almHandler.handleSetProjectBinding(AlmKeys.BitbucketServer, { + almSetting: 'test', + repository: 'test', + monorepo: false, + project: 'my-project', + }); + const ui = getPageObject(user); - gitlabHandler.setGitlabConfigurations([ - mockGitlabConfiguration({ id: '1', enabled: true, provisioningType: ProvisioningType.auto }), - ]); + renderPermissionsProjectApp({}, { featureList: [Feature.GitlabProvisioning] }); await ui.appLoaded(); expect(ui.pageTitle.get()).toBeInTheDocument(); - expect(ui.nonGitLabProjectWarning.get()).toBeInTheDocument(); expect(ui.pageTitle.byRole('img').query()).not.toBeInTheDocument(); expect(ui.applyTemplateBtn.get()).toBeInTheDocument(); diff --git a/server/sonar-web/src/main/js/apps/permissions/test-utils.ts b/server/sonar-web/src/main/js/apps/permissions/test-utils.ts index 80b95d13e2c..3c0f93d2bec 100644 --- a/server/sonar-web/src/main/js/apps/permissions/test-utils.ts +++ b/server/sonar-web/src/main/js/apps/permissions/test-utils.ts @@ -48,7 +48,6 @@ export function getPageObject(user: UserEvent) { name: 'project_permission.remove_only_confirmation_title', }), nonGHProjectWarning: byText('project_permission.local_project_with_github_provisioning'), - nonGitLabProjectWarning: byText('project_permission.local_project_with_gitlab_provisioning'), makePublicDisclaimer: byText( 'projects_role.are_you_sure_to_turn_project_to_public.warning.TRK', ), diff --git a/server/sonar-web/src/main/js/components/permissions/AllHoldersList.tsx b/server/sonar-web/src/main/js/components/permissions/AllHoldersList.tsx index 9ee04386a93..3828b10a77b 100644 --- a/server/sonar-web/src/main/js/components/permissions/AllHoldersList.tsx +++ b/server/sonar-web/src/main/js/components/permissions/AllHoldersList.tsx @@ -34,6 +34,7 @@ interface Props { filter: FilterOption; groups: PermissionGroup[]; groupsPaging?: Paging; + isProjectManaged?: boolean; loading?: boolean; onFilter: (filter: string) => void; onGrantPermissionToGroup: (group: string, permission: string) => Promise; @@ -96,6 +97,7 @@ export default class AllHoldersList extends React.PureComponent { permissions, selectedPermission, loading = false, + isProjectManaged, } = this.props; const { count, total } = this.getPaging(); @@ -114,6 +116,7 @@ export default class AllHoldersList extends React.PureComponent {
void; onToggleGroup: (group: PermissionGroup, permission: string) => Promise; @@ -108,58 +108,47 @@ export default class HoldersList extends React.PureComponent< } renderItem(item: PermissionUser | PermissionGroup, permissions: PermissionDefinitions) { - const { selectedPermission, isComponentPrivate } = this.props; + const { selectedPermission, isComponentPrivate, isProjectManaged } = this.props; + return ( {({ data: isGitHubProject }) => ( {({ data: isGitLabProject }) => ( - - {({ data: gitlabProvisioningStatus }) => ( - - {({ data: githubProvisioningStatus }) => ( - <> - {this.isPermissionUser(item) ? ( - - ) : ( - - )} - + + {({ data: githubProvisioningStatus }) => ( + <> + {this.isPermissionUser(item) ? ( + + ) : ( + )} - + )} )} -- 2.39.5