aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2020-02-04 11:16:04 +0100
committerSonarTech <sonartech@sonarsource.com>2020-02-20 20:46:17 +0100
commit3c110148c73be5775c03e8ce71ca7d426157d2ae (patch)
tree2d6d3fbe34c67874d81cc5e8fd1d0c0a66aea2d8
parentc1ea335081c7b03b9908f9b397e3993023ee3d62 (diff)
downloadsonarqube-3c110148c73be5775c03e8ce71ca7d426157d2ae.tar.gz
sonarqube-3c110148c73be5775c03e8ce71ca7d426157d2ae.zip
SONAR-13035 Group global ALM related settings into a single category
-rw-r--r--server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java3
-rw-r--r--server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabSettings.java2
-rw-r--r--server/sonar-web/src/main/js/api/alm-settings.ts (renamed from server/sonar-web/src/main/js/api/almSettings.ts)0
-rw-r--r--server/sonar-web/src/main/js/app/styles/init/misc.css12
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/CreateProjectPageSonarQube.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketPersonalAccessTokenForm-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPageSonarQube-test.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx19
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AdditionalCategories-test.tsx.snap29
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap48
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionForm.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationForm.tsx)28
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmDefinitionFormField.tsx)10
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormModalRenderer.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationFormModalRenderer.tsx)34
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormRenderer.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationFormRenderer.tsx)77
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionsTable.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationTable.tsx)33
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegration.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/PullRequestDecoration.tsx)47
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationFeatureBox.tsx67
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationRenderer.tsx185
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmTab.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmTab.tsx)20
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmTabRenderer.tsx160
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AzureForm.tsx)10
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureTab.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AzureTab.tsx)39
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketForm.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/BitbucketForm.tsx)14
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketTab.tsx114
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/DeleteModal.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/DeleteModal.tsx)10
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GithubForm.tsx)16
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubTab.tsx85
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GitlabForm.tsx)10
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabTab.tsx80
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionForm-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationForm-test.tsx)15
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormField-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmDefinitionFormField-test.tsx)13
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormModalRenderer-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationFormModalRenderer-test.tsx)14
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormRenderer-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationFormRenderer-test.tsx)12
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionsTable-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationTable-test.tsx)18
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/PullRequestDecoration-test.tsx)16
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationFeatureBox-test.tsx39
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationRenderer-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/PRDecorationTabs-test.tsx)26
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTab-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmTab-test.tsx)4
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTabRenderer-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmTabRenderer-test.tsx)20
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureForm-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AzureForm-test.tsx)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureTab-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AzureTab-test.tsx)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketForm-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/BitbucketForm-test.tsx)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketTab-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/BitbucketTab-test.tsx)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/DeleteModal-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/DeleteModal-test.tsx)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubForm-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GithubForm-test.tsx)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubTab-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GithubTab-test.tsx)4
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabForm-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GitlabForm-test.tsx)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabTab-test.tsx (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GitlabTab-test.tsx)4
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionForm-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationForm-test.tsx.snap)2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormField-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmDefinitionFormField-test.tsx.snap)6
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormModalRenderer-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationFormModalRenderer-test.tsx.snap)46
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormRenderer-test.tsx.snap161
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionsTable-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationTable-test.tsx.snap)52
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/PullRequestDecoration-test.tsx.snap)4
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationFeatureBox-test.tsx.snap97
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationRenderer-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/PRDecorationTabs-test.tsx.snap)226
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTab-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmTab-test.tsx.snap)0
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap334
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureForm-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AzureForm-test.tsx.snap)16
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureTab-test.tsx.snap42
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap)24
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap112
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/DeleteModal-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/DeleteModal-test.tsx.snap)16
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubForm-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GithubForm-test.tsx.snap)28
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubTab-test.tsx.snap84
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabForm-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GitlabForm-test.tsx.snap)16
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabTab-test.tsx.snap68
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmTabRenderer.tsx136
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/BitbucketTab.tsx57
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GithubTab.tsx57
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GitlabTab.tsx51
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/PRDecorationTabs.tsx186
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationFormRenderer-test.tsx.snap121
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap254
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AzureTab-test.tsx.snap28
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap40
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GithubTab-test.tsx.snap44
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GitlabTab-test.tsx.snap28
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx24
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx20
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx18
-rw-r--r--server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts4
-rw-r--r--server/sonar-web/src/main/js/types/alm-settings.ts46
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties116
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java5
92 files changed, 2407 insertions, 1549 deletions
diff --git a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java
index bd4871eb8a7..21b29139805 100644
--- a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java
+++ b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java
@@ -23,6 +23,7 @@ import java.util.Arrays;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import org.sonar.api.CoreProperties;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.PropertyDefinition;
@@ -42,7 +43,7 @@ public class GitHubSettings {
private static final String ORGANIZATIONS = "sonar.auth.github.organizations";
- private static final String CATEGORY = "security";
+ private static final String CATEGORY = CoreProperties.CATEGORY_ALM_INTEGRATION;
private static final String SUBCATEGORY = "github";
private final Configuration configuration;
diff --git a/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabSettings.java b/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabSettings.java
index 1cb130f662f..860d7e89fae 100644
--- a/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabSettings.java
+++ b/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabSettings.java
@@ -38,7 +38,7 @@ public class GitLabSettings {
static final String GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP = "sonar.auth.gitlab.allowUsersToSignUp";
static final String GITLAB_AUTH_SYNC_USER_GROUPS = "sonar.auth.gitlab.groupsSync";
- private static final String CATEGORY = CoreProperties.CATEGORY_SECURITY;
+ private static final String CATEGORY = CoreProperties.CATEGORY_ALM_INTEGRATION;
private static final String SUBCATEGORY = "gitlab";
private final Configuration configuration;
diff --git a/server/sonar-web/src/main/js/api/almSettings.ts b/server/sonar-web/src/main/js/api/alm-settings.ts
index 6ac6b1c0963..6ac6b1c0963 100644
--- a/server/sonar-web/src/main/js/api/almSettings.ts
+++ b/server/sonar-web/src/main/js/api/alm-settings.ts
diff --git a/server/sonar-web/src/main/js/app/styles/init/misc.css b/server/sonar-web/src/main/js/app/styles/init/misc.css
index c4e543c8f39..bdc61008d39 100644
--- a/server/sonar-web/src/main/js/app/styles/init/misc.css
+++ b/server/sonar-web/src/main/js/app/styles/init/misc.css
@@ -152,6 +152,14 @@ th.hide-overflow {
padding-top: calc(var(--gridSize) / 2) !important;
}
+.big-padded-top {
+ padding-top: calc(2 * var(--gridSize));
+}
+
+.huge-padded-top {
+ padding-top: 40px;
+}
+
td.little-spacer-left {
padding-left: 4px !important;
}
@@ -305,6 +313,10 @@ th.huge-spacer-right {
width: 600px !important;
}
+.abs-height-100 {
+ height: 100% !important;
+}
+
.max-height-100 {
max-height: 100% !important;
}
diff --git a/server/sonar-web/src/main/js/apps/create/project/CreateProjectPageSonarQube.tsx b/server/sonar-web/src/main/js/apps/create/project/CreateProjectPageSonarQube.tsx
index d0a8ced9353..d9a7c160070 100644
--- a/server/sonar-web/src/main/js/apps/create/project/CreateProjectPageSonarQube.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/CreateProjectPageSonarQube.tsx
@@ -22,11 +22,11 @@ import { Helmet } from 'react-helmet-async';
import { WithRouterProps } from 'react-router';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { addWhitePageClass, removeWhitePageClass } from 'sonar-ui-common/helpers/pages';
-import { getAlmSettings } from '../../../api/almSettings';
+import { getAlmSettings } from '../../../api/alm-settings';
import { whenLoggedIn } from '../../../components/hoc/whenLoggedIn';
import { withAppState } from '../../../components/hoc/withAppState';
import { getProjectUrl } from '../../../helpers/urls';
-import { AlmSettingsInstance, ALM_KEYS } from '../../../types/alm-settings';
+import { AlmKeys, AlmSettingsInstance } from '../../../types/alm-settings';
import BitbucketProjectCreate from './BitbucketProjectCreate';
import CreateProjectModeSelection from './CreateProjectModeSelection';
import ManualProjectCreate from './ManualProjectCreate';
@@ -81,7 +81,7 @@ export class CreateProjectPageSonarQube extends React.PureComponent<Props, State
.then(almSettings => {
if (this.mounted) {
this.setState({
- bitbucketSettings: almSettings.filter(s => s.alm === ALM_KEYS.BITBUCKET),
+ bitbucketSettings: almSettings.filter(s => s.alm === AlmKeys.Bitbucket),
loading: false
});
}
diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketPersonalAccessTokenForm-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketPersonalAccessTokenForm-test.tsx
index 316871fe7c5..5dc8bcb0b67 100644
--- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketPersonalAccessTokenForm-test.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketPersonalAccessTokenForm-test.tsx
@@ -23,7 +23,7 @@ import * as React from 'react';
import { SubmitButton } from 'sonar-ui-common/components/controls/buttons';
import { change, submit, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings';
-import { ALM_KEYS } from '../../../../types/alm-settings';
+import { AlmKeys } from '../../../../types/alm-settings';
import BitbucketPersonalAccessTokenForm, {
BitbucketPersonalAccessTokenFormProps
} from '../BitbucketPersonalAccessTokenForm';
@@ -54,7 +54,7 @@ function shallowRender(props: Partial<BitbucketPersonalAccessTokenFormProps> = {
return shallow<BitbucketPersonalAccessTokenFormProps>(
<BitbucketPersonalAccessTokenForm
bitbucketSetting={mockAlmSettingsInstance({
- alm: ALM_KEYS.BITBUCKET,
+ alm: AlmKeys.Bitbucket,
url: 'http://www.example.com'
})}
onPersonalAccessTokenCreate={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx
index 91fb4650308..3d9829f03d5 100644
--- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx
@@ -31,7 +31,7 @@ import {
import { mockBitbucketRepository } from '../../../../helpers/mocks/alm-integrations';
import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings';
import { mockLocation } from '../../../../helpers/testMocks';
-import { ALM_KEYS } from '../../../../types/alm-settings';
+import { AlmKeys } from '../../../../types/alm-settings';
import { BitbucketProjectCreate } from '../BitbucketProjectCreate';
jest.mock('../../../../api/alm-integrations', () => {
@@ -129,7 +129,7 @@ it('should correctly import a repo', async () => {
function shallowRender(props: Partial<BitbucketProjectCreate['props']> = {}) {
return shallow<BitbucketProjectCreate>(
<BitbucketProjectCreate
- bitbucketSettings={[mockAlmSettingsInstance({ alm: ALM_KEYS.BITBUCKET, key: 'foo' })]}
+ bitbucketSettings={[mockAlmSettingsInstance({ alm: AlmKeys.Bitbucket, key: 'foo' })]}
loadingBindings={false}
location={mockLocation()}
onProjectCreate={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx
index 66e237bc92b..e1b5b8537df 100644
--- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx
@@ -25,7 +25,7 @@ import {
mockBitbucketRepository
} from '../../../../helpers/mocks/alm-integrations';
import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings';
-import { ALM_KEYS } from '../../../../types/alm-settings';
+import { AlmKeys } from '../../../../types/alm-settings';
import BitbucketProjectCreateRenderer, {
BitbucketProjectCreateRendererProps
} from '../BitbucketProjectCreateRenderer';
@@ -49,7 +49,7 @@ it('should render correctly', () => {
function shallowRender(props: Partial<BitbucketProjectCreateRendererProps> = {}) {
return shallow<BitbucketProjectCreateRendererProps>(
<BitbucketProjectCreateRenderer
- bitbucketSetting={mockAlmSettingsInstance({ alm: ALM_KEYS.BITBUCKET })}
+ bitbucketSetting={mockAlmSettingsInstance({ alm: AlmKeys.Bitbucket })}
importing={false}
loading={false}
onImportRepository={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPageSonarQube-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPageSonarQube-test.tsx
index dbc4aeff690..e328df5b71a 100644
--- a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPageSonarQube-test.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPageSonarQube-test.tsx
@@ -21,14 +21,14 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import { addWhitePageClass } from 'sonar-ui-common/helpers/pages';
-import { getAlmSettings } from '../../../../api/almSettings';
+import { getAlmSettings } from '../../../../api/alm-settings';
import { mockLocation, mockLoggedInUser, mockRouter } from '../../../../helpers/testMocks';
-import { ALM_KEYS } from '../../../../types/alm-settings';
+import { AlmKeys } from '../../../../types/alm-settings';
import { CreateProjectPageSonarQube } from '../CreateProjectPageSonarQube';
import { CreateProjectModes } from '../types';
-jest.mock('../../../../api/almSettings', () => ({
- getAlmSettings: jest.fn().mockResolvedValue([{ alm: ALM_KEYS.BITBUCKET, key: 'foo' }])
+jest.mock('../../../../api/alm-settings', () => ({
+ getAlmSettings: jest.fn().mockResolvedValue([{ alm: AlmKeys.Bitbucket, key: 'foo' }])
}));
jest.mock('sonar-ui-common/helpers/pages', () => ({
diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap
index f887af050b0..fa62e434607 100644
--- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap
@@ -179,7 +179,7 @@ exports[`should render correctly: invalid config, admin user 1`] = `
Object {
"pathname": "/admin/settings",
"query": Object {
- "category": "pull_request_decoration",
+ "category": "almintegration",
},
}
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx
index ced4af67ee2..ff970731023 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx
@@ -20,16 +20,16 @@
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
import {
+ ALM_INTEGRATION,
ANALYSIS_SCOPE_CATEGORY,
LANGUAGES_CATEGORY,
NEW_CODE_PERIOD_CATEGORY,
- PULL_REQUEST_DECORATION_BINDING_CATEGORY,
- PULL_REQUEST_DECORATION_CATEGORY
+ PULL_REQUEST_DECORATION_BINDING_CATEGORY
} from './AdditionalCategoryKeys';
+import AlmIntegration from './almIntegration/AlmIntegration';
import { AnalysisScope } from './AnalysisScope';
import Languages from './Languages';
import NewCodePeriod from './NewCodePeriod';
-import PullRequestDecoration from './pullRequestDecoration/PullRequestDecoration';
import PullRequestDecorationBinding from './pullRequestDecorationBinding/PRDecorationBinding';
export interface AdditionalCategoryComponentProps {
@@ -73,13 +73,12 @@ export const ADDITIONAL_CATEGORIES: AdditionalCategory[] = [
displayTab: false
},
{
- key: PULL_REQUEST_DECORATION_CATEGORY,
- name: translate('settings.pr_decoration.category'),
- renderComponent: getPullRequestDecorationComponent,
+ key: ALM_INTEGRATION,
+ name: translate('property.category.almintegration'),
+ renderComponent: getAlmIntegrationComponent,
availableGlobally: true,
availableForProject: false,
- displayTab: true,
- requiresBranchesEnabled: true
+ displayTab: false
},
{
key: PULL_REQUEST_DECORATION_BINDING_CATEGORY,
@@ -104,8 +103,8 @@ function getAnalysisScopeComponent(props: AdditionalCategoryComponentProps) {
return <AnalysisScope {...props} />;
}
-function getPullRequestDecorationComponent() {
- return <PullRequestDecoration />;
+function getAlmIntegrationComponent(props: AdditionalCategoryComponentProps) {
+ return <AlmIntegration {...props} />;
}
function getPullRequestDecorationBindingComponent(props: AdditionalCategoryComponentProps) {
diff --git a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts
index b4381b96ade..bea73ef2354 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts
+++ b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+export const ALM_INTEGRATION = 'almintegration';
export const ANALYSIS_SCOPE_CATEGORY = 'exclusions';
export const LANGUAGES_CATEGORY = 'languages';
export const NEW_CODE_PERIOD_CATEGORY = 'new_code_period';
-export const PULL_REQUEST_DECORATION_CATEGORY = 'pull_request_decoration';
export const PULL_REQUEST_DECORATION_BINDING_CATEGORY = 'pull_request_decoration_binding';
diff --git a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx
index f3876806997..49bf0ab7478 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx
@@ -28,6 +28,7 @@ interface Props {
component?: T.Component;
fetchValues: Function;
settings: Array<T.Setting & { definition: T.SettingCategoryDefinition }>;
+ subCategory?: string;
}
export default class SubCategoryDefinitionsList extends React.PureComponent<Props> {
@@ -66,9 +67,12 @@ export default class SubCategoryDefinitionsList extends React.PureComponent<Prop
const sortedSubCategories = sortBy(subCategories, subCategory =>
subCategory.name.toLowerCase()
);
+ const filteredSubCategories = this.props.subCategory
+ ? sortedSubCategories.filter(c => c.key === this.props.subCategory)
+ : sortedSubCategories;
return (
<ul className="settings-sub-categories-list">
- {sortedSubCategories.map(subCategory => (
+ {filteredSubCategories.map(subCategory => (
<li key={subCategory.key}>
<h2 className="settings-sub-category-name">{subCategory.name}</h2>
{subCategory.description != null && (
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx
index 34a2065611b..eb9f80b6741 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx
@@ -22,11 +22,11 @@ import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { mockLocation, mockRouter } from '../../../../helpers/testMocks';
import {
+ ALM_INTEGRATION,
ANALYSIS_SCOPE_CATEGORY,
LANGUAGES_CATEGORY,
NEW_CODE_PERIOD_CATEGORY,
- PULL_REQUEST_DECORATION_BINDING_CATEGORY,
- PULL_REQUEST_DECORATION_CATEGORY
+ PULL_REQUEST_DECORATION_BINDING_CATEGORY
} from '../AdditionalCategoryKeys';
import { App } from '../AppContainer';
@@ -64,9 +64,9 @@ it('should render analysis scope correctly', async () => {
expect(wrapper).toMatchSnapshot();
});
-it('should render pull request decoration correctly', async () => {
+it('should render ALM integration correctly', async () => {
const wrapper = shallowRender({
- location: mockLocation({ query: { category: PULL_REQUEST_DECORATION_CATEGORY } })
+ location: mockLocation({ query: { category: ALM_INTEGRATION } })
});
await waitAndUpdate(wrapper);
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AdditionalCategories-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AdditionalCategories-test.tsx.snap
index 2a421ce756f..803fcbfe625 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AdditionalCategories-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AdditionalCategories-test.tsx.snap
@@ -60,7 +60,34 @@ exports[`should render additional categories component correctly 3`] = `
/>
`;
-exports[`should render additional categories component correctly 4`] = `<PullRequestDecoration />`;
+exports[`should render additional categories component correctly 4`] = `
+<Connect(withAppState(AlmIntegration))
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "organization": "foo",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
+ },
+ ],
+ "tags": Array [],
+ }
+ }
+ selectedCategory="TEST"
+/>
+`;
exports[`should render additional categories component correctly 5`] = `
<PRDecorationBinding
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap
index cabe4ab6945..a650f8e78fa 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should render analysis scope correctly 1`] = `
+exports[`should render ALM integration correctly 1`] = `
<div
className="page page-limited"
id="settings-page"
@@ -22,21 +22,21 @@ exports[`should render analysis scope correctly 1`] = `
>
<Connect(CategoriesList)
defaultCategory="general"
- selectedCategory="exclusions"
+ selectedCategory="almintegration"
/>
</div>
<div
className="side-tabs-main"
>
- <AnalysisScope
- selectedCategory="exclusions"
+ <Connect(withAppState(AlmIntegration))
+ selectedCategory="almintegration"
/>
</div>
</div>
</div>
`;
-exports[`should render default view correctly 1`] = `
+exports[`should render analysis scope correctly 1`] = `
<div
className="page page-limited"
id="settings-page"
@@ -58,21 +58,21 @@ exports[`should render default view correctly 1`] = `
>
<Connect(CategoriesList)
defaultCategory="general"
- selectedCategory="general"
+ selectedCategory="exclusions"
/>
</div>
<div
className="side-tabs-main"
>
- <Connect(SubCategoryDefinitionsList)
- category="general"
+ <AnalysisScope
+ selectedCategory="exclusions"
/>
</div>
</div>
</div>
`;
-exports[`should render languages correctly 1`] = `
+exports[`should render default view correctly 1`] = `
<div
className="page page-limited"
id="settings-page"
@@ -94,21 +94,21 @@ exports[`should render languages correctly 1`] = `
>
<Connect(CategoriesList)
defaultCategory="general"
- selectedCategory="languages"
+ selectedCategory="general"
/>
</div>
<div
className="side-tabs-main"
>
- <withRouter(Connect(Languages))
- selectedCategory="languages"
+ <Connect(SubCategoryDefinitionsList)
+ category="general"
/>
</div>
</div>
</div>
`;
-exports[`should render newCodePeriod correctly 1`] = `
+exports[`should render languages correctly 1`] = `
<div
className="page page-limited"
id="settings-page"
@@ -130,19 +130,21 @@ exports[`should render newCodePeriod correctly 1`] = `
>
<Connect(CategoriesList)
defaultCategory="general"
- selectedCategory="new_code_period"
+ selectedCategory="languages"
/>
</div>
<div
className="side-tabs-main"
>
- <NewCodePeriod />
+ <withRouter(Connect(Languages))
+ selectedCategory="languages"
+ />
</div>
</div>
</div>
`;
-exports[`should render pull request decoration binding correctly 1`] = `
+exports[`should render newCodePeriod correctly 1`] = `
<div
className="page page-limited"
id="settings-page"
@@ -164,21 +166,19 @@ exports[`should render pull request decoration binding correctly 1`] = `
>
<Connect(CategoriesList)
defaultCategory="general"
- selectedCategory="pull_request_decoration_binding"
+ selectedCategory="new_code_period"
/>
</div>
<div
className="side-tabs-main"
>
- <Connect(SubCategoryDefinitionsList)
- category="pull_request_decoration_binding"
- />
+ <NewCodePeriod />
</div>
</div>
</div>
`;
-exports[`should render pull request decoration correctly 1`] = `
+exports[`should render pull request decoration binding correctly 1`] = `
<div
className="page page-limited"
id="settings-page"
@@ -200,13 +200,15 @@ exports[`should render pull request decoration correctly 1`] = `
>
<Connect(CategoriesList)
defaultCategory="general"
- selectedCategory="pull_request_decoration"
+ selectedCategory="pull_request_decoration_binding"
/>
</div>
<div
className="side-tabs-main"
>
- <PullRequestDecoration />
+ <Connect(SubCategoryDefinitionsList)
+ category="pull_request_decoration_binding"
+ />
</div>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionForm.tsx
index 705a1083ad9..1f4de028fe2 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationForm.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionForm.tsx
@@ -19,11 +19,11 @@
*/
import { isEqual, omit } from 'lodash';
import * as React from 'react';
-import { AlmSettingsBinding, ALM_KEYS } from '../../../../types/alm-settings';
-import AlmPRDecorationFormModalRenderer from './AlmPRDecorationFormModalRenderer';
-import AlmPRDecorationFormRenderer from './AlmPRDecorationFormRenderer';
+import { AlmBindingDefinition } from '../../../../types/alm-settings';
+import AlmBindingDefinitionFormModalRenderer from './AlmBindingDefinitionFormModalRenderer';
+import AlmBindingDefinitionFormRenderer from './AlmBindingDefinitionFormRenderer';
-export interface AlmPRDecorationFormChildrenProps<B> {
+export interface AlmBindingDefinitionFormChildrenProps<B> {
formData: B;
hideKeyField?: boolean;
onFieldChange: (fieldId: keyof B, value: string) => void;
@@ -31,9 +31,8 @@ export interface AlmPRDecorationFormChildrenProps<B> {
}
interface Props<B> {
- alm: ALM_KEYS;
bindingDefinition: B;
- children: (props: AlmPRDecorationFormChildrenProps<B>) => React.ReactNode;
+ children: (props: AlmBindingDefinitionFormChildrenProps<B>) => React.ReactNode;
help?: React.ReactNode;
hideKeyField?: boolean;
loading?: boolean;
@@ -51,10 +50,9 @@ interface State<B> {
touched: boolean;
}
-export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends React.PureComponent<
- Props<B>,
- State<B>
-> {
+export default class AlmBindingDefinitionForm<
+ B extends AlmBindingDefinition
+> extends React.PureComponent<Props<B>, State<B>> {
constructor(props: Props<B>) {
super(props);
this.state = { formData: props.bindingDefinition, touched: false };
@@ -115,7 +113,6 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R
render() {
const {
- alm,
bindingDefinition,
children,
help,
@@ -132,9 +129,8 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R
const showDelete = showEdit && this.props.onDelete !== undefined;
return showInModal ? (
- <AlmPRDecorationFormModalRenderer
+ <AlmBindingDefinitionFormModalRenderer
action={bindingDefinition.key ? 'edit' : 'create'}
- alm={alm}
canSubmit={this.canSubmit}
help={help}
onCancel={this.handleCancel}
@@ -143,9 +139,9 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R
formData,
onFieldChange: this.handleFieldChange
})}
- </AlmPRDecorationFormModalRenderer>
+ </AlmBindingDefinitionFormModalRenderer>
) : (
- <AlmPRDecorationFormRenderer
+ <AlmBindingDefinitionFormRenderer
canSubmit={this.canSubmit}
help={help}
loading={loading}
@@ -160,7 +156,7 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R
onFieldChange: this.handleFieldChange,
readOnly
})}
- </AlmPRDecorationFormRenderer>
+ </AlmBindingDefinitionFormRenderer>
);
}
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmDefinitionFormField.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx
index d9733f60808..8cd42e1221f 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmDefinitionFormField.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx
@@ -20,9 +20,9 @@
import * as React from 'react';
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { AlmSettingsBinding } from '../../../../types/alm-settings';
+import { AlmBindingDefinition } from '../../../../types/alm-settings';
-export interface AlmDefinitionFormFieldProps<B extends AlmSettingsBinding> {
+export interface AlmBindingDefinitionFormFieldProps<B extends AlmBindingDefinition> {
autoFocus?: boolean;
help?: React.ReactNode;
id: string;
@@ -34,8 +34,8 @@ export interface AlmDefinitionFormFieldProps<B extends AlmSettingsBinding> {
value: string;
}
-export function AlmDefinitionFormField<B extends AlmSettingsBinding>(
- props: AlmDefinitionFormFieldProps<B>
+export function AlmBindingDefinitionFormField<B extends AlmBindingDefinition>(
+ props: AlmBindingDefinitionFormFieldProps<B>
) {
const {
autoFocus,
@@ -52,7 +52,7 @@ export function AlmDefinitionFormField<B extends AlmSettingsBinding>(
return (
<div className="modal-field">
<label className="display-flex-center" htmlFor={id}>
- {translate('settings.pr_decoration.form', id)}
+ {translate('settings.almintegration.form', id)}
<em className="mandatory spacer-right">*</em>
{help && <HelpTooltip overlay={help} placement="right" />}
</label>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationFormModalRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormModalRenderer.tsx
index 082aa0985d3..75bb9c0d378 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationFormModalRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormModalRenderer.tsx
@@ -23,11 +23,9 @@ import SimpleModal from 'sonar-ui-common/components/controls/SimpleModal';
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { ALM_KEYS } from '../../../../types/alm-settings';
-export interface AlmPRDecorationFormModalProps {
+export interface AlmBindingDefinitionFormModalProps {
action: 'edit' | 'create';
- alm: ALM_KEYS;
canSubmit: () => boolean;
children: React.ReactNode;
help?: React.ReactNode;
@@ -35,14 +33,11 @@ export interface AlmPRDecorationFormModalProps {
onSubmit: () => void;
}
-export default function AlmPRDecorationFormModalRenderer(props: AlmPRDecorationFormModalProps) {
- const { alm, action, children, help } = props;
- const header = translate(
- 'settings',
- alm === ALM_KEYS.GITLAB ? 'mr_decoration' : 'pr_decoration',
- 'form.header',
- action
- );
+export default function AlmBindingDefinitionFormModalRenderer(
+ props: AlmBindingDefinitionFormModalProps
+) {
+ const { action, children, help } = props;
+ const header = translate('settings.almintegration.form.header', action);
return (
<SimpleModal header={header} onClose={props.onCancel} onSubmit={props.onSubmit} size="medium">
@@ -53,18 +48,21 @@ export default function AlmPRDecorationFormModalRenderer(props: AlmPRDecorationF
</div>
<div className="modal-body modal-container">
- {help && (
- <Alert className="big-spacer-bottom" variant="info">
- {help}
- </Alert>
- )}
- {children}
+ <div className="display-flex-start">
+ <div className="flex-1">{children}</div>
+
+ {help && (
+ <Alert className="huge-spacer-left flex-1" variant="info">
+ {help}
+ </Alert>
+ )}
+ </div>
</div>
<div className="modal-foot">
<DeferredSpinner className="spacer-right" loading={submitting} />
<SubmitButton disabled={submitting || !props.canSubmit()}>
- {translate('settings.pr_decoration.form.save')}
+ {translate('settings.almintegration.form.save')}
</SubmitButton>
<ResetButtonLink onClick={onCloseClick}>{translate('cancel')}</ResetButtonLink>
</div>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationFormRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormRenderer.tsx
index e21a1da2872..812ba48a61a 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationFormRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormRenderer.tsx
@@ -24,7 +24,7 @@ import { Alert } from 'sonar-ui-common/components/ui/Alert';
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
-export interface AlmPRDecorationFormRendererProps {
+export interface AlmBindingDefinitionFormRendererProps {
canSubmit: () => boolean;
children: React.ReactNode;
help?: React.ReactNode;
@@ -36,7 +36,9 @@ export interface AlmPRDecorationFormRendererProps {
success: boolean;
}
-export default function AlmPRDecorationFormRenderer(props: AlmPRDecorationFormRendererProps) {
+export default function AlmBindingDefinitionFormRenderer(
+ props: AlmBindingDefinitionFormRendererProps
+) {
const { children, help, loading, success } = props;
return (
@@ -47,40 +49,47 @@ export default function AlmPRDecorationFormRenderer(props: AlmPRDecorationFormRe
e.preventDefault();
props.onSubmit();
}}>
- {help && (
- <Alert className="big-spacer-bottom" variant="info">
- {help}
- </Alert>
- )}
+ <div className="display-flex-start">
+ <div className="flex-1">
+ {children}
- {children}
+ <div className="display-flex-center">
+ {props.onEdit === undefined ? (
+ <SubmitButton disabled={loading || !props.canSubmit()}>
+ {translate('settings.almintegration.form.save')}
+ </SubmitButton>
+ ) : (
+ <Button disabled={loading} onClick={props.onEdit}>
+ {translate('edit')}
+ </Button>
+ )}
+ {props.onDelete && (
+ <Button
+ className="button-red spacer-left"
+ disabled={loading}
+ onClick={props.onDelete}>
+ {translate('delete')}
+ </Button>
+ )}
+ {props.onCancel && (
+ <ResetButtonLink className="spacer-left" onClick={props.onCancel}>
+ {translate('cancel')}
+ </ResetButtonLink>
+ )}
+ {loading && <DeferredSpinner className="spacer-left" />}
+ {!loading && success && (
+ <span className="text-success spacer-left">
+ <AlertSuccessIcon className="spacer-right" />
+ {translate('settings.state.saved')}
+ </span>
+ )}
+ </div>
+ </div>
- <div className="display-flex-center">
- {props.onEdit === undefined ? (
- <SubmitButton disabled={loading || !props.canSubmit()}>
- {translate('settings.pr_decoration.form.save')}
- </SubmitButton>
- ) : (
- <Button disabled={loading} onClick={props.onEdit}>
- {translate('edit')}
- </Button>
- )}
- {props.onDelete && (
- <Button className="button-red spacer-left" disabled={loading} onClick={props.onDelete}>
- {translate('delete')}
- </Button>
- )}
- {props.onCancel && (
- <ResetButtonLink className="spacer-left" onClick={props.onCancel}>
- {translate('cancel')}
- </ResetButtonLink>
- )}
- {loading && <DeferredSpinner className="spacer-left" />}
- {!loading && success && (
- <span className="text-success spacer-left">
- <AlertSuccessIcon className="spacer-right" />
- {translate('settings.state.saved')}
- </span>
+ {help && (
+ <Alert className="huge-spacer-left flex-1" variant="info">
+ {help}
+ </Alert>
)}
</div>
</form>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationTable.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionsTable.tsx
index 4ef416d5ee5..65253c4d6e0 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmPRDecorationTable.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionsTable.tsx
@@ -21,11 +21,12 @@ import * as React from 'react';
import { Button, ButtonIcon, DeleteButton } from 'sonar-ui-common/components/controls/buttons';
import EditIcon from 'sonar-ui-common/components/icons/EditIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { ALM_KEYS } from '../../../../types/alm-settings';
+import { AlmKeys } from '../../../../types/alm-settings';
-export interface AlmPRDecorationTableProps {
+export interface AlmBindingDefinitionsTableProps {
additionalColumnsHeaders: Array<string>;
- alm: ALM_KEYS;
+ additionalTableInfo?: React.ReactNode;
+ alm: AlmKeys;
definitions: Array<{
key: string;
additionalColumns: Array<string>;
@@ -35,36 +36,34 @@ export interface AlmPRDecorationTableProps {
onEdit: (definitionKey: string) => void;
}
-export default function AlmPRDecorationTable(props: AlmPRDecorationTableProps) {
- const { additionalColumnsHeaders, alm, definitions } = props;
+export default function AlmBindingDefinitionsTable(props: AlmBindingDefinitionsTableProps) {
+ const { additionalColumnsHeaders, additionalTableInfo, alm, definitions } = props;
return (
<>
<div className="spacer-top big-spacer-bottom display-flex-space-between">
- <h4 className="display-inline">
- {translate(
- 'settings',
- alm === ALM_KEYS.GITLAB ? 'mr_decoration' : 'pr_decoration',
- 'table.title'
- )}
- </h4>
+ <h2 className="settings-sub-category-name">
+ {translate('settings.almintegration.table.title')}
+ </h2>
<Button data-test="settings__alm-create" onClick={props.onCreate}>
- {translate('settings.pr_decoration.table.create')}
+ {translate('settings.almintegration.table.create')}
</Button>
</div>
+ {additionalTableInfo}
+
<table className="data zebra fixed spacer-bottom">
<thead>
<tr>
- <th>{translate('settings.pr_decoration.table.column.name')}</th>
+ <th>{translate('settings.almintegration.table.column.name')}</th>
{additionalColumnsHeaders.map(h => (
<th key={h}>{h}</th>
))}
<th className="action-small text-center">
- {translate('settings.pr_decoration.table.column.edit')}
+ {translate('settings.almintegration.table.column.edit')}
</th>
<th className="action text-center">
- {translate('settings.pr_decoration.table.column.delete')}
+ {translate('settings.almintegration.table.column.delete')}
</th>
</tr>
</thead>
@@ -72,7 +71,7 @@ export default function AlmPRDecorationTable(props: AlmPRDecorationTableProps) {
{definitions.length === 0 ? (
<tr data-test="settings__alm-empty-table">
<td colSpan={3 + additionalColumnsHeaders.length}>
- {translate('settings.pr_decoration.table.empty', alm)}
+ {translate('settings.almintegration.table.empty', alm)}
</td>
</tr>
) : (
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/PullRequestDecoration.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegration.tsx
index 21484d5c03f..ee060e8f2bf 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/PullRequestDecoration.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegration.tsx
@@ -22,27 +22,33 @@ import {
countBindedProjects,
deleteConfiguration,
getAlmDefinitions
-} from '../../../../api/almSettings';
-import { AlmSettingsBindingDefinitions, ALM_KEYS } from '../../../../types/alm-settings';
-import PRDecorationTabs from './PRDecorationTabs';
+} from '../../../../api/alm-settings';
+import { withAppState } from '../../../../components/hoc/withAppState';
+import { AlmKeys, AlmSettingsBindingDefinitions } from '../../../../types/alm-settings';
+import AlmIntegrationRenderer from './AlmIntegrationRenderer';
+
+interface Props {
+ appState: Pick<T.AppState, 'branchesEnabled' | 'multipleAlmEnabled'>;
+ component?: T.Component;
+}
interface State {
- currentAlm: ALM_KEYS;
+ currentAlm: AlmKeys;
definitionKeyForDeletion?: string;
definitions: AlmSettingsBindingDefinitions;
loading: boolean;
projectCount?: number;
}
-export default class PullRequestDecoration extends React.PureComponent<{}, State> {
+export class AlmIntegration extends React.PureComponent<Props, State> {
mounted = false;
state: State = {
- currentAlm: ALM_KEYS.GITHUB,
+ currentAlm: AlmKeys.GitHub,
definitions: {
- [ALM_KEYS.AZURE]: [],
- [ALM_KEYS.BITBUCKET]: [],
- [ALM_KEYS.GITHUB]: [],
- [ALM_KEYS.GITLAB]: []
+ [AlmKeys.Azure]: [],
+ [AlmKeys.Bitbucket]: [],
+ [AlmKeys.GitHub]: [],
+ [AlmKeys.GitLab]: []
},
loading: true
};
@@ -67,6 +73,14 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State
};
fetchPullRequestDecorationSetting = () => {
+ const {
+ appState: { branchesEnabled }
+ } = this.props;
+
+ if (!branchesEnabled) {
+ return Promise.resolve();
+ }
+
this.setState({ loading: true });
return getAlmDefinitions()
.then(definitions => {
@@ -84,7 +98,7 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State
});
};
- handleSelectAlm = (currentAlm: ALM_KEYS) => {
+ handleSelectAlm = (currentAlm: AlmKeys) => {
this.setState({ currentAlm });
};
@@ -112,8 +126,15 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State
};
render() {
+ const {
+ appState: { branchesEnabled, multipleAlmEnabled },
+ component
+ } = this.props;
return (
- <PRDecorationTabs
+ <AlmIntegrationRenderer
+ branchesEnabled={Boolean(branchesEnabled)}
+ component={component}
+ multipleAlmEnabled={Boolean(multipleAlmEnabled)}
onCancel={this.handleCancel}
onConfirmDelete={this.deleteConfiguration}
onDelete={this.handleDelete}
@@ -124,3 +145,5 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State
);
}
}
+
+export default withAppState(AlmIntegration);
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationFeatureBox.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationFeatureBox.tsx
new file mode 100644
index 00000000000..dfdeb10bbd5
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationFeatureBox.tsx
@@ -0,0 +1,67 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as classNames from 'classnames';
+import * as React from 'react';
+import CheckIcon from 'sonar-ui-common/components/icons/CheckIcon';
+import ClearIcon from 'sonar-ui-common/components/icons/ClearIcon';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { colors } from '../../../../app/theme';
+
+export interface AlmIntegrationFeatureBoxProps {
+ active: boolean;
+ description: React.ReactNode;
+ inactiveReason?: React.ReactNode;
+ name: React.ReactNode;
+}
+
+export default function AlmIntegrationFeatureBox(props: AlmIntegrationFeatureBoxProps) {
+ const { active, description, inactiveReason, name } = props;
+
+ return (
+ <div
+ className={classNames(
+ 'boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered',
+ {
+ 'bg-muted': !active
+ }
+ )}>
+ {active ? (
+ <CheckIcon className="little-spacer-top spacer-right" fill={colors.green} />
+ ) : (
+ <ClearIcon className="little-spacer-top spacer-right" fill={colors.gray60} />
+ )}
+ <div className="display-flex-column abs-height-100">
+ <h4>{name}</h4>
+
+ <div className="spacer-top flex-1">{description}</div>
+
+ <div className="spacer-top">
+ {active ? (
+ <em className="text-success">{translate('settings.almintegration.feature.enabled')}</em>
+ ) : (
+ <em className="text-muted">
+ {inactiveReason || translate('settings.almintegration.feature.disabled')}
+ </em>
+ )}
+ </div>
+ </div>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationRenderer.tsx
new file mode 100644
index 00000000000..c5c64310a4f
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationRenderer.tsx
@@ -0,0 +1,185 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import BoxedTabs from 'sonar-ui-common/components/controls/BoxedTabs';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getBaseUrl } from 'sonar-ui-common/helpers/urls';
+import { AlmKeys, AlmSettingsBindingDefinitions } from '../../../../types/alm-settings';
+import AzureTab from './AzureTab';
+import BitbucketTab from './BitbucketTab';
+import DeleteModal from './DeleteModal';
+import GithubTab from './GithubTab';
+import GitlabTab from './GitlabTab';
+
+export interface AlmIntegrationRendererProps {
+ branchesEnabled: boolean;
+ component?: T.Component;
+ currentAlm: AlmKeys;
+ definitionKeyForDeletion?: string;
+ definitions: AlmSettingsBindingDefinitions;
+ loading: boolean;
+ multipleAlmEnabled: boolean;
+ onCancel: () => void;
+ onConfirmDelete: (definitionKey: string) => void;
+ onDelete: (definitionKey: string) => void;
+ onSelectAlm: (alm: AlmKeys) => void;
+ onUpdateDefinitions: () => void;
+ projectCount?: number;
+}
+
+const tabs = [
+ {
+ key: AlmKeys.GitHub,
+ label: (
+ <>
+ <img
+ alt="github"
+ className="spacer-right"
+ height={16}
+ src={`${getBaseUrl()}/images/alm/github.svg`}
+ />
+ GitHub
+ </>
+ )
+ },
+ {
+ key: AlmKeys.Bitbucket,
+ label: (
+ <>
+ <img
+ alt="bitbucket"
+ className="spacer-right"
+ height={16}
+ src={`${getBaseUrl()}/images/alm/bitbucket.svg`}
+ />
+ Bitbucket Server
+ </>
+ ),
+ requiresBranchesEnabled: true
+ },
+ {
+ key: AlmKeys.Azure,
+ label: (
+ <>
+ <img
+ alt="azure"
+ className="spacer-right"
+ height={16}
+ src={`${getBaseUrl()}/images/alm/azure.svg`}
+ />
+ Azure DevOps Server
+ </>
+ ),
+ requiresBranchesEnabled: true
+ },
+ {
+ key: AlmKeys.GitLab,
+ label: (
+ <>
+ <img
+ alt="gitlab"
+ className="spacer-right"
+ height={16}
+ src={`${getBaseUrl()}/images/alm/gitlab.svg`}
+ />
+ GitLab
+ </>
+ )
+ }
+];
+
+export default function AlmIntegrationRenderer(props: AlmIntegrationRendererProps) {
+ const {
+ component,
+ definitionKeyForDeletion,
+ definitions,
+ currentAlm,
+ loading,
+ branchesEnabled,
+ multipleAlmEnabled,
+ projectCount
+ } = props;
+
+ return (
+ <>
+ <header className="page-header">
+ <h1 className="page-title">{translate('settings.almintegration.title')}</h1>
+ </header>
+
+ <div className="markdown small spacer-top big-spacer-bottom">
+ {translate('settings.almintegration.description')}
+ </div>
+ <BoxedTabs
+ onSelect={props.onSelectAlm}
+ selected={currentAlm}
+ tabs={tabs.filter(tab => !(tab.requiresBranchesEnabled && !branchesEnabled))}
+ />
+
+ {currentAlm === AlmKeys.Azure && (
+ <AzureTab
+ definitions={definitions.azure}
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ />
+ )}
+ {currentAlm === AlmKeys.Bitbucket && (
+ <BitbucketTab
+ definitions={definitions.bitbucket}
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ />
+ )}
+ {currentAlm === AlmKeys.GitHub && (
+ <GithubTab
+ branchesEnabled={branchesEnabled}
+ component={component}
+ definitions={definitions.github}
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ />
+ )}
+ {currentAlm === AlmKeys.GitLab && (
+ <GitlabTab
+ branchesEnabled={branchesEnabled}
+ definitions={definitions.gitlab}
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ />
+ )}
+
+ {definitionKeyForDeletion && (
+ <DeleteModal
+ id={definitionKeyForDeletion}
+ onCancel={props.onCancel}
+ onDelete={props.onConfirmDelete}
+ projectCount={projectCount}
+ />
+ )}
+ </>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmTab.tsx
index de3979ea0cb..6bda165b607 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmTab.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmTab.tsx
@@ -18,18 +18,22 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { AlmSettingsBinding, ALM_KEYS } from '../../../../types/alm-settings';
-import { AlmPRDecorationFormChildrenProps } from './AlmPRDecorationForm';
+import { AlmBindingDefinition, AlmKeys } from '../../../../types/alm-settings';
+import { AlmBindingDefinitionFormChildrenProps } from './AlmBindingDefinitionForm';
+import { AlmIntegrationFeatureBoxProps } from './AlmIntegrationFeatureBox';
import AlmTabRenderer from './AlmTabRenderer';
interface Props<B> {
- alm: ALM_KEYS;
+ alm: AlmKeys;
additionalColumnsHeaders?: string[];
additionalColumnsKeys?: Array<keyof B>;
+ additionalTableInfo?: React.ReactNode;
createConfiguration: (data: B) => Promise<void>;
defaultBinding: B;
definitions: B[];
- form: (props: AlmPRDecorationFormChildrenProps<B>) => React.ReactNode;
+ features?: AlmIntegrationFeatureBoxProps[];
+ form: (props: AlmBindingDefinitionFormChildrenProps<B>) => React.ReactNode;
+ help?: React.ReactNode;
loading: boolean;
multipleAlmEnabled: boolean;
onDelete: (definitionKey: string) => void;
@@ -43,7 +47,7 @@ interface State<B> {
success: boolean;
}
-export default class AlmTab<B extends AlmSettingsBinding> extends React.PureComponent<
+export default class AlmTab<B extends AlmBindingDefinition> extends React.PureComponent<
Props<B>,
State<B>
> {
@@ -100,10 +104,13 @@ export default class AlmTab<B extends AlmSettingsBinding> extends React.PureComp
const {
additionalColumnsHeaders = [],
additionalColumnsKeys = [],
+ additionalTableInfo,
alm,
defaultBinding,
definitions,
+ features,
form,
+ help,
loading,
multipleAlmEnabled
} = this.props;
@@ -113,11 +120,14 @@ export default class AlmTab<B extends AlmSettingsBinding> extends React.PureComp
<AlmTabRenderer
additionalColumnsHeaders={additionalColumnsHeaders}
additionalColumnsKeys={additionalColumnsKeys}
+ additionalTableInfo={additionalTableInfo}
alm={alm}
defaultBinding={defaultBinding}
definitions={definitions}
editedDefinition={editedDefinition}
+ features={features}
form={form}
+ help={help}
loading={loading || submitting}
multipleAlmEnabled={multipleAlmEnabled}
onCancel={this.handleCancel}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmTabRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmTabRenderer.tsx
new file mode 100644
index 00000000000..15dc454fe9c
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmTabRenderer.tsx
@@ -0,0 +1,160 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router';
+import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { AlmBindingDefinition, AlmKeys } from '../../../../types/alm-settings';
+import AlmBindingDefinitionForm, {
+ AlmBindingDefinitionFormChildrenProps
+} from './AlmBindingDefinitionForm';
+import AlmBindingDefinitionsTable from './AlmBindingDefinitionsTable';
+import AlmIntegrationFeatureBox, {
+ AlmIntegrationFeatureBoxProps
+} from './AlmIntegrationFeatureBox';
+
+export interface AlmTabRendererProps<B> {
+ additionalColumnsHeaders: string[];
+ additionalColumnsKeys: Array<keyof B>;
+ additionalTableInfo?: React.ReactNode;
+ alm: AlmKeys;
+ editedDefinition?: B;
+ defaultBinding: B;
+ definitions: B[];
+ features?: AlmIntegrationFeatureBoxProps[];
+ form: (props: AlmBindingDefinitionFormChildrenProps<B>) => React.ReactNode;
+ help?: React.ReactNode;
+ loading: boolean;
+ multipleAlmEnabled: boolean;
+ onCancel: () => void;
+ onCreate: () => void;
+ onDelete: (definitionKey: string) => void;
+ onEdit: (definitionKey: string) => void;
+ onSubmit: (config: B, originalKey: string) => void;
+ success: boolean;
+}
+
+export default function AlmTabRenderer<B extends AlmBindingDefinition>(
+ props: AlmTabRendererProps<B>
+) {
+ const {
+ additionalColumnsHeaders,
+ additionalColumnsKeys,
+ additionalTableInfo,
+ alm,
+ defaultBinding,
+ definitions,
+ editedDefinition,
+ features = [],
+ form,
+ loading,
+ multipleAlmEnabled,
+ success,
+ help = (
+ <FormattedMessage
+ defaultMessage={translate(`settings.almintegration.${alm}.info`)}
+ id={`settings.almintegration.${alm}.info`}
+ values={{
+ link: (
+ <Link target="_blank" to="/documentation/analysis/pr-decoration/">
+ {translate('learn_more')}
+ </Link>
+ )
+ }}
+ />
+ )
+ } = props;
+
+ let definition: B | undefined;
+ let mappedDefinitions: Array<{ key: string; additionalColumns: string[] }> = [];
+ let showEdit: boolean | undefined;
+
+ if (!multipleAlmEnabled) {
+ definition = editedDefinition;
+ if (definition === undefined && definitions.length > 0) {
+ definition = definitions[0];
+ }
+ showEdit = definition && editedDefinition === undefined;
+ } else {
+ mappedDefinitions = definitions.map(({ key, ...properties }) => {
+ const additionalColumns = additionalColumnsKeys.map(k => (properties as any)[k]);
+ return {
+ key,
+ additionalColumns
+ };
+ });
+ }
+
+ return (
+ <div className="big-padded">
+ {multipleAlmEnabled ? (
+ <DeferredSpinner loading={loading}>
+ <AlmBindingDefinitionsTable
+ additionalColumnsHeaders={additionalColumnsHeaders}
+ additionalTableInfo={additionalTableInfo}
+ alm={alm}
+ definitions={mappedDefinitions}
+ onCreate={props.onCreate}
+ onDelete={props.onDelete}
+ onEdit={props.onEdit}
+ />
+
+ {editedDefinition && (
+ <AlmBindingDefinitionForm
+ bindingDefinition={editedDefinition}
+ help={help}
+ onCancel={props.onCancel}
+ onSubmit={props.onSubmit}
+ showInModal={true}>
+ {form}
+ </AlmBindingDefinitionForm>
+ )}
+ </DeferredSpinner>
+ ) : (
+ <AlmBindingDefinitionForm
+ bindingDefinition={definition || defaultBinding}
+ help={help}
+ hideKeyField={true}
+ loading={loading}
+ onCancel={props.onCancel}
+ onDelete={definition ? props.onDelete : undefined}
+ onEdit={showEdit ? props.onEdit : undefined}
+ onSubmit={props.onSubmit}
+ readOnly={showEdit}
+ success={success}>
+ {form}
+ </AlmBindingDefinitionForm>
+ )}
+
+ {features.length > 0 && (
+ <div className="big-spacer-top big-padded-top bordered-top">
+ <h3 className="big-spacer-bottom">{translate('settings.almintegration.features')}</h3>
+
+ <div className="display-flex-wrap">
+ {features.map((feature, i) => (
+ <AlmIntegrationFeatureBox key={i} {...feature} />
+ ))}
+ </div>
+ </div>
+ )}
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AzureForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx
index 5587f6efafe..fef12180192 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AzureForm.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureForm.tsx
@@ -20,7 +20,7 @@
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { AzureBindingDefinition } from '../../../../types/alm-settings';
-import { AlmDefinitionFormField } from './AlmDefinitionFormField';
+import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField';
export interface AzureFormProps {
formData: AzureBindingDefinition;
@@ -35,9 +35,9 @@ export default function AzureForm(props: AzureFormProps) {
return (
<>
{!hideKeyField && (
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help={translate('settings.pr_decoration.form.name.azure.help')}
+ help={translate('settings.almintegration.form.name.azure.help')}
id="name.azure"
onFieldChange={onFieldChange}
propKey="key"
@@ -45,8 +45,8 @@ export default function AzureForm(props: AzureFormProps) {
value={formData.key}
/>
)}
- <AlmDefinitionFormField
- help={translate('settings.pr_decoration.form.personal_access_token.azure.help')}
+ <AlmBindingDefinitionFormField
+ help={translate('settings.almintegration.form.personal_access_token.azure.help')}
id="personal_access_token"
isTextArea={true}
onFieldChange={onFieldChange}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AzureTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureTab.tsx
index ee2711b00de..bf2607a2396 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AzureTab.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/AzureTab.tsx
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { createAzureConfiguration, updateAzureConfiguration } from '../../../../api/almSettings';
-import { ALM_KEYS, AzureBindingDefinition } from '../../../../types/alm-settings';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { createAzureConfiguration, updateAzureConfiguration } from '../../../../api/alm-settings';
+import { AlmKeys, AzureBindingDefinition } from '../../../../types/alm-settings';
import AlmTab from './AlmTab';
import AzureForm from './AzureForm';
@@ -35,17 +36,27 @@ export default function AzureTab(props: AzureTabProps) {
const { multipleAlmEnabled, definitions, loading } = props;
return (
- <AlmTab
- alm={ALM_KEYS.AZURE}
- createConfiguration={createAzureConfiguration}
- defaultBinding={{ key: '', personalAccessToken: '' }}
- definitions={definitions}
- form={childProps => <AzureForm {...childProps} />}
- loading={loading}
- multipleAlmEnabled={multipleAlmEnabled}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- updateConfiguration={updateAzureConfiguration}
- />
+ <div className="bordered">
+ <AlmTab
+ alm={AlmKeys.Azure}
+ createConfiguration={createAzureConfiguration}
+ defaultBinding={{ key: '', personalAccessToken: '' }}
+ definitions={definitions}
+ features={[
+ {
+ name: translate('settings.almintegration.feature.pr_decoration.title'),
+ active: definitions.length > 0,
+ description: translate('settings.almintegration.feature.pr_decoration.description'),
+ inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding')
+ }
+ ]}
+ form={childProps => <AzureForm {...childProps} />}
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ updateConfiguration={updateAzureConfiguration}
+ />
+ </div>
);
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/BitbucketForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketForm.tsx
index 33b1d93eb88..a306bdbabfd 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/BitbucketForm.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketForm.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { BitbucketBindingDefinition } from '../../../../types/alm-settings';
-import { AlmDefinitionFormField } from './AlmDefinitionFormField';
+import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField';
export interface BitbucketFormProps {
formData: BitbucketBindingDefinition;
@@ -36,9 +36,9 @@ export default function BitbucketForm(props: BitbucketFormProps) {
return (
<>
{!hideKeyField && (
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help={translate('settings.pr_decoration.form.name.bitbucket.help')}
+ help={translate('settings.almintegration.form.name.bitbucket.help')}
id="name.bitbucket"
maxLength={100}
onFieldChange={onFieldChange}
@@ -47,11 +47,11 @@ export default function BitbucketForm(props: BitbucketFormProps) {
value={formData.key}
/>
)}
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
help={
<FormattedMessage
- defaultMessage={translate('settings.pr_decoration.form.url.bitbucket.help')}
- id="settings.pr_decoration.form.url.bitbucket.help"
+ defaultMessage={translate('settings.almintegration.form.url.bitbucket.help')}
+ id="settings.almintegration.form.url.bitbucket.help"
values={{ example: 'https://bitbucket-server.your-company.com' }}
/>
}
@@ -62,7 +62,7 @@ export default function BitbucketForm(props: BitbucketFormProps) {
readOnly={readOnly}
value={formData.url}
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="personal_access_token"
isTextArea={true}
onFieldChange={onFieldChange}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketTab.tsx
new file mode 100644
index 00000000000..e7bf53d56e5
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketTab.tsx
@@ -0,0 +1,114 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router';
+import { Alert } from 'sonar-ui-common/components/ui/Alert';
+import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
+import {
+ createBitbucketConfiguration,
+ updateBitbucketConfiguration
+} from '../../../../api/alm-settings';
+import { AlmKeys, BitbucketBindingDefinition } from '../../../../types/alm-settings';
+import AlmTab from './AlmTab';
+import BitbucketForm from './BitbucketForm';
+
+export interface BitbucketTabProps {
+ definitions: BitbucketBindingDefinition[];
+ loading: boolean;
+ multipleAlmEnabled: boolean;
+ onDelete: (definitionKey: string) => void;
+ onUpdateDefinitions: () => void;
+}
+
+export default function BitbucketTab(props: BitbucketTabProps) {
+ const { multipleAlmEnabled, definitions, loading } = props;
+
+ return (
+ <div className="bordered">
+ <AlmTab
+ additionalColumnsHeaders={[translate('settings.almintegration.table.column.bitbucket.url')]}
+ additionalColumnsKeys={['url']}
+ additionalTableInfo={
+ <Alert className="big-spacer-bottom width-50" variant="info">
+ <FormattedMessage
+ defaultMessage={translate(
+ 'settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances'
+ )}
+ id="settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances"
+ values={{
+ feature: (
+ <em>{translate('settings.almintegration.feature.alm_repo_import.title')}</em>
+ )
+ }}
+ />
+ </Alert>
+ }
+ alm={AlmKeys.Bitbucket}
+ createConfiguration={createBitbucketConfiguration}
+ defaultBinding={{ key: '', url: '', personalAccessToken: '' }}
+ definitions={definitions}
+ features={[
+ {
+ name: translate('settings.almintegration.feature.pr_decoration.title'),
+ active: definitions.length > 0,
+ description: translate('settings.almintegration.feature.pr_decoration.description'),
+ inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding')
+ },
+ {
+ name: translate('settings.almintegration.feature.alm_repo_import.title'),
+ active: definitions.length === 1,
+ description: translate('settings.almintegration.feature.alm_repo_import.description'),
+ inactiveReason: translateWithParameters(
+ 'onboarding.create_project.too_many_bbs_instances_X',
+ definitions.length
+ )
+ }
+ ]}
+ form={childProps => <BitbucketForm {...childProps} />}
+ help={
+ <>
+ <h3>{translate('onboarding.create_project.pat_help.title')}</h3>
+
+ <p className="big-spacer-top">
+ {translate('settings.almintegration.bitbucket.help_1')}
+ </p>
+
+ <ul className="big-spacer-top list-styled">
+ <li>{translate('settings.almintegration.bitbucket.help_2')}</li>
+ <li>{translate('settings.almintegration.bitbucket.help_3')}</li>
+ </ul>
+
+ <p className="big-spacer-top big-spacer-bottom">
+ <Link target="_blank" to="/documentation/analysis/pr-decoration/">
+ {translate('learn_more')}
+ </Link>
+ </p>
+ </>
+ }
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ updateConfiguration={updateBitbucketConfiguration}
+ />
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/DeleteModal.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/DeleteModal.tsx
index 5d0791ecf47..f4e4bb9da66 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/DeleteModal.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/DeleteModal.tsx
@@ -31,11 +31,11 @@ export interface DeleteModalProps {
function showProjectCountWarning(projectCount?: number) {
if (projectCount === undefined) {
- return <p>{translate('settings.pr_decoration.delete.no_info')}</p>;
+ return <p>{translate('settings.almintegration.delete.no_info')}</p>;
}
return projectCount ? (
- <p>{translateWithParameters('settings.pr_decoration.delete.info', projectCount)} </p>
+ <p>{translateWithParameters('settings.almintegration.delete.info', projectCount)} </p>
) : null;
}
@@ -44,15 +44,15 @@ export default function DeleteModal({ id, onDelete, onCancel, projectCount }: De
<ConfirmModal
confirmButtonText={translate('delete')}
confirmData={id}
- header={translate('settings.pr_decoration.delete.header')}
+ header={translate('settings.almintegration.delete.header')}
isDestructive={true}
onClose={onCancel}
onConfirm={onDelete}>
<>
<p className="spacer-bottom">
<FormattedMessage
- defaultMessage={translate('settings.pr_decoration.delete.message')}
- id="settings.pr_decoration.delete.message"
+ defaultMessage={translate('settings.almintegration.delete.message')}
+ id="settings.almintegration.delete.message"
values={{ id: <b>{id}</b> }}
/>
</p>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GithubForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx
index 873cc4aa6c2..c4fd9afee57 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GithubForm.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubForm.tsx
@@ -20,7 +20,7 @@
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { GithubBindingDefinition } from '../../../../types/alm-settings';
-import { AlmDefinitionFormField } from './AlmDefinitionFormField';
+import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField';
export interface GithubFormProps {
formData: GithubBindingDefinition;
@@ -35,9 +35,9 @@ export default function GithubForm(props: GithubFormProps) {
return (
<>
{!hideKeyField && (
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help={translate('settings.pr_decoration.form.name.github.help')}
+ help={translate('settings.almintegration.form.name.github.help')}
id="name.github"
onFieldChange={onFieldChange}
propKey="key"
@@ -45,15 +45,15 @@ export default function GithubForm(props: GithubFormProps) {
value={formData.key}
/>
)}
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
help={
<>
- {translate('settings.pr_decoration.form.url.github.help1')}
+ {translate('settings.almintegration.form.url.github.help1')}
<br />
<em>https://github.company.com/api/v3</em>
<br />
<br />
- {translate('settings.pr_decoration.form.url.github.help2')}
+ {translate('settings.almintegration.form.url.github.help2')}
<br />
<em>https://api.github.com/</em>
</>
@@ -65,7 +65,7 @@ export default function GithubForm(props: GithubFormProps) {
readOnly={readOnly}
value={formData.url}
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="app_id"
maxLength={80}
onFieldChange={onFieldChange}
@@ -73,7 +73,7 @@ export default function GithubForm(props: GithubFormProps) {
readOnly={readOnly}
value={formData.appId}
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="private_key"
isTextArea={true}
onFieldChange={onFieldChange}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubTab.tsx
new file mode 100644
index 00000000000..cf9aa3c5cb7
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GithubTab.tsx
@@ -0,0 +1,85 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { createGithubConfiguration, updateGithubConfiguration } from '../../../../api/alm-settings';
+import { AlmKeys, GithubBindingDefinition } from '../../../../types/alm-settings';
+import { ALM_INTEGRATION } from '../AdditionalCategoryKeys';
+import CategoryDefinitionsList from '../CategoryDefinitionsList';
+import AlmTab from './AlmTab';
+import GithubForm from './GithubForm';
+
+export interface GithubTabProps {
+ branchesEnabled: boolean;
+ component?: T.Component;
+ definitions: GithubBindingDefinition[];
+ loading: boolean;
+ multipleAlmEnabled: boolean;
+ onDelete: (definitionKey: string) => void;
+ onUpdateDefinitions: () => void;
+}
+
+export default function GithubTab(props: GithubTabProps) {
+ const { branchesEnabled, component, multipleAlmEnabled, definitions, loading } = props;
+
+ return (
+ <div className="bordered">
+ {branchesEnabled && (
+ <>
+ <AlmTab
+ additionalColumnsHeaders={[
+ translate('settings.almintegration.table.column.github.url'),
+ translate('settings.almintegration.table.column.app_id')
+ ]}
+ additionalColumnsKeys={['appId', 'url']}
+ alm={AlmKeys.GitHub}
+ createConfiguration={createGithubConfiguration}
+ defaultBinding={{ key: '', appId: '', url: '', privateKey: '' }}
+ definitions={definitions}
+ features={[
+ {
+ name: translate('settings.almintegration.feature.pr_decoration.title'),
+ active: definitions.length > 0,
+ description: translate('settings.almintegration.feature.pr_decoration.description'),
+ inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding')
+ }
+ ]}
+ form={childProps => <GithubForm {...childProps} />}
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ updateConfiguration={updateGithubConfiguration}
+ />
+
+ <div className="huge-spacer-top huge-spacer-bottom bordered-top" />
+ </>
+ )}
+
+ <div className="big-padded">
+ <CategoryDefinitionsList
+ category={ALM_INTEGRATION}
+ component={component}
+ subCategory={AlmKeys.GitHub}
+ />
+ </div>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GitlabForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx
index 929ad3c5aa4..65eabba516d 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GitlabForm.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabForm.tsx
@@ -20,7 +20,7 @@
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { GitlabBindingDefinition } from '../../../../types/alm-settings';
-import { AlmDefinitionFormField } from './AlmDefinitionFormField';
+import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField';
export interface GitlabFormProps {
formData: GitlabBindingDefinition;
@@ -35,9 +35,9 @@ export default function GitlabForm(props: GitlabFormProps) {
return (
<>
{!hideKeyField && (
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help={translate('settings.pr_decoration.form.name.gitlab.help')}
+ help={translate('settings.almintegration.form.name.gitlab.help')}
id="name.gitlab"
onFieldChange={onFieldChange}
propKey="key"
@@ -45,8 +45,8 @@ export default function GitlabForm(props: GitlabFormProps) {
value={formData.key}
/>
)}
- <AlmDefinitionFormField
- help={translate('settings.pr_decoration.form.personal_access_token.gitlab.help')}
+ <AlmBindingDefinitionFormField
+ help={translate('settings.almintegration.form.personal_access_token.gitlab.help')}
id="personal_access_token"
isTextArea={true}
onFieldChange={onFieldChange}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabTab.tsx
new file mode 100644
index 00000000000..fab99f0ca6b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/GitlabTab.tsx
@@ -0,0 +1,80 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { createGitlabConfiguration, updateGitlabConfiguration } from '../../../../api/alm-settings';
+import { AlmKeys, GitlabBindingDefinition } from '../../../../types/alm-settings';
+import { ALM_INTEGRATION } from '../AdditionalCategoryKeys';
+import CategoryDefinitionsList from '../CategoryDefinitionsList';
+import AlmTab from './AlmTab';
+import GitlabForm from './GitlabForm';
+
+export interface GitlabTabProps {
+ branchesEnabled: boolean;
+ component?: T.Component;
+ definitions: GitlabBindingDefinition[];
+ loading: boolean;
+ multipleAlmEnabled: boolean;
+ onDelete: (definitionKey: string) => void;
+ onUpdateDefinitions: () => void;
+}
+
+export default function GitlabTab(props: GitlabTabProps) {
+ const { branchesEnabled, component, multipleAlmEnabled, definitions, loading } = props;
+
+ return (
+ <div className="bordered">
+ {branchesEnabled && (
+ <>
+ <AlmTab
+ alm={AlmKeys.GitLab}
+ createConfiguration={createGitlabConfiguration}
+ defaultBinding={{ key: '', personalAccessToken: '' }}
+ definitions={definitions}
+ features={[
+ {
+ name: translate('settings.almintegration.feature.mr_decoration.title'),
+ active: definitions.length > 0,
+ description: translate('settings.almintegration.feature.mr_decoration.description'),
+ inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding')
+ }
+ ]}
+ form={childProps => <GitlabForm {...childProps} />}
+ loading={loading}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ updateConfiguration={updateGitlabConfiguration}
+ />
+
+ <div className="huge-spacer-top huge-spacer-bottom bordered-top" />
+ </>
+ )}
+
+ <div className="big-padded">
+ <CategoryDefinitionsList
+ category={ALM_INTEGRATION}
+ component={component}
+ subCategory={AlmKeys.GitLab}
+ />
+ </div>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionForm-test.tsx
index c3170ef2f31..c8976eefe0f 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationForm-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionForm-test.tsx
@@ -21,8 +21,8 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings';
-import { ALM_KEYS, GithubBindingDefinition } from '../../../../../types/alm-settings';
-import AlmPRDecorationForm from '../AlmPRDecorationForm';
+import { GithubBindingDefinition } from '../../../../../types/alm-settings';
+import AlmBindingDefinitionForm from '../AlmBindingDefinitionForm';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
@@ -121,15 +121,16 @@ it('should (dis)allow submit by validating its state', () => {
expect(wrapper.instance().canSubmit()).toBe(true);
});
-function shallowRender(props: Partial<AlmPRDecorationForm<GithubBindingDefinition>['props']> = {}) {
- return shallow<AlmPRDecorationForm<GithubBindingDefinition>>(
- <AlmPRDecorationForm
- alm={ALM_KEYS.GITHUB}
+function shallowRender(
+ props: Partial<AlmBindingDefinitionForm<GithubBindingDefinition>['props']> = {}
+) {
+ return shallow<AlmBindingDefinitionForm<GithubBindingDefinition>>(
+ <AlmBindingDefinitionForm
bindingDefinition={{ appId: '', key: '', privateKey: '', url: '' }}
onCancel={jest.fn()}
onSubmit={jest.fn()}
{...props}>
{() => null}
- </AlmPRDecorationForm>
+ </AlmBindingDefinitionForm>
);
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmDefinitionFormField-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormField-test.tsx
index 5f25326e5f5..6193e77cdbd 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmDefinitionFormField-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormField-test.tsx
@@ -19,8 +19,11 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { AlmSettingsBinding } from '../../../../../types/alm-settings';
-import { AlmDefinitionFormField, AlmDefinitionFormFieldProps } from '../AlmDefinitionFormField';
+import { AlmBindingDefinition } from '../../../../../types/alm-settings';
+import {
+ AlmBindingDefinitionFormField,
+ AlmBindingDefinitionFormFieldProps
+} from '../AlmBindingDefinitionFormField';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
@@ -42,9 +45,11 @@ it('should call onFieldChange', () => {
expect(onTextAreaChange).toBeCalled();
});
-function shallowRender(props: Partial<AlmDefinitionFormFieldProps<AlmSettingsBinding>> = {}) {
+function shallowRender(
+ props: Partial<AlmBindingDefinitionFormFieldProps<AlmBindingDefinition>> = {}
+) {
return shallow(
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="key"
isTextArea={false}
maxLength={40}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationFormModalRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormModalRenderer-test.tsx
index a1a6a4a2ff5..3095bd43df8 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationFormModalRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormModalRenderer-test.tsx
@@ -19,26 +19,24 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { ALM_KEYS } from '../../../../../types/alm-settings';
-import AlmPRDecorationFormModalRenderer, {
- AlmPRDecorationFormModalProps
-} from '../AlmPRDecorationFormModalRenderer';
+import AlmBindingDefinitionFormModalRenderer, {
+ AlmBindingDefinitionFormModalProps
+} from '../AlmBindingDefinitionFormModalRenderer';
it('should render correctly', () => {
expect(shallowRender().dive()).toMatchSnapshot();
expect(shallowRender({ help: <span>Help me</span> }).dive()).toMatchSnapshot();
});
-function shallowRender(props: Partial<AlmPRDecorationFormModalProps> = {}) {
+function shallowRender(props: Partial<AlmBindingDefinitionFormModalProps> = {}) {
return shallow(
- <AlmPRDecorationFormModalRenderer
+ <AlmBindingDefinitionFormModalRenderer
action="create"
- alm={ALM_KEYS.GITHUB}
canSubmit={jest.fn()}
onCancel={jest.fn()}
onSubmit={jest.fn()}
{...props}>
{() => null}
- </AlmPRDecorationFormModalRenderer>
+ </AlmBindingDefinitionFormModalRenderer>
);
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationFormRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormRenderer-test.tsx
index 1a3f9361430..6774ed436d6 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationFormRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormRenderer-test.tsx
@@ -21,9 +21,9 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import { SubmitButton } from 'sonar-ui-common/components/controls/buttons';
import { submit } from 'sonar-ui-common/helpers/testUtils';
-import AlmPRDecorationFormRenderer, {
- AlmPRDecorationFormRendererProps
-} from '../AlmPRDecorationFormRenderer';
+import AlmBindingDefinitionFormRenderer, {
+ AlmBindingDefinitionFormRendererProps
+} from '../AlmBindingDefinitionFormRenderer';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
@@ -54,15 +54,15 @@ it('should correctly submit the form', () => {
expect(onSubmit).toBeCalled();
});
-function shallowRender(props: Partial<AlmPRDecorationFormRendererProps> = {}) {
+function shallowRender(props: Partial<AlmBindingDefinitionFormRendererProps> = {}) {
return shallow(
- <AlmPRDecorationFormRenderer
+ <AlmBindingDefinitionFormRenderer
canSubmit={jest.fn()}
loading={false}
onSubmit={jest.fn()}
success={false}
{...props}>
{() => null}
- </AlmPRDecorationFormRenderer>
+ </AlmBindingDefinitionFormRenderer>
);
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationTable-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionsTable-test.tsx
index a1f591f1ec9..b75674c56c2 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmPRDecorationTable-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionsTable-test.tsx
@@ -19,22 +19,24 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { ALM_KEYS } from '../../../../../types/alm-settings';
-import AlmPRDecorationTable, { AlmPRDecorationTableProps } from '../AlmPRDecorationTable';
+import { AlmKeys } from '../../../../../types/alm-settings';
+import AlmBindingDefinitionsTable, {
+ AlmBindingDefinitionsTableProps
+} from '../AlmBindingDefinitionsTable';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
expect(
shallowRender({
additionalColumnsHeaders: ['additional1', 'additional2'],
- alm: ALM_KEYS.GITHUB,
+ alm: AlmKeys.GitHub,
definitions: [
{ key: 'definition1', additionalColumns: ['def1-v1', 'def1-v2'] },
{ key: 'definition2', additionalColumns: ['def2-v1', 'def2-v2'] }
]
})
).toMatchSnapshot('additional columns');
- expect(shallowRender({ alm: ALM_KEYS.GITHUB })).toMatchSnapshot('title adjusts for GitLab');
+ expect(shallowRender({ alm: AlmKeys.GitLab })).toMatchSnapshot('title adjusts for GitLab');
});
it('should correctly trigger create, delete, and edit', () => {
@@ -44,7 +46,7 @@ it('should correctly trigger create, delete, and edit', () => {
const wrapper = shallowRender({
additionalColumnsHeaders: [],
- alm: ALM_KEYS.BITBUCKET,
+ alm: AlmKeys.Bitbucket,
definitions: [{ key: 'defKey', additionalColumns: [] }],
onCreate,
onDelete,
@@ -61,11 +63,11 @@ it('should correctly trigger create, delete, and edit', () => {
expect(onEdit).toBeCalledWith('defKey');
});
-function shallowRender(props: Partial<AlmPRDecorationTableProps> = {}) {
+function shallowRender(props: Partial<AlmBindingDefinitionsTableProps> = {}) {
return shallow(
- <AlmPRDecorationTable
+ <AlmBindingDefinitionsTable
additionalColumnsHeaders={[]}
- alm={ALM_KEYS.AZURE}
+ alm={AlmKeys.Azure}
definitions={[]}
onCreate={jest.fn()}
onDelete={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/PullRequestDecoration-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx
index ce41ff990d1..1e6a791f8b5 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/PullRequestDecoration-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx
@@ -24,11 +24,11 @@ import {
countBindedProjects,
deleteConfiguration,
getAlmDefinitions
-} from '../../../../../api/almSettings';
-import { ALM_KEYS } from '../../../../../types/alm-settings';
-import PullRequestDecoration from '../PullRequestDecoration';
+} from '../../../../../api/alm-settings';
+import { AlmKeys } from '../../../../../types/alm-settings';
+import { AlmIntegration } from '../AlmIntegration';
-jest.mock('../../../../../api/almSettings', () => ({
+jest.mock('../../../../../api/alm-settings', () => ({
countBindedProjects: jest.fn().mockResolvedValue(0),
deleteConfiguration: jest.fn().mockResolvedValue(undefined),
getAlmDefinitions: jest.fn().mockResolvedValue({ github: [] })
@@ -45,13 +45,13 @@ it('should render correctly', () => {
it('should handle alm selection', async () => {
const wrapper = shallowRender();
- wrapper.setState({ currentAlm: ALM_KEYS.AZURE });
+ wrapper.setState({ currentAlm: AlmKeys.Azure });
- wrapper.instance().handleSelectAlm(ALM_KEYS.GITHUB);
+ wrapper.instance().handleSelectAlm(AlmKeys.GitHub);
await waitAndUpdate(wrapper);
- expect(wrapper.state().currentAlm).toBe(ALM_KEYS.GITHUB);
+ expect(wrapper.state().currentAlm).toBe(AlmKeys.GitHub);
});
it('should handle delete', async () => {
@@ -90,5 +90,5 @@ it('should fetch settings', async () => {
});
function shallowRender() {
- return shallow<PullRequestDecoration>(<PullRequestDecoration />);
+ return shallow<AlmIntegration>(<AlmIntegration appState={{ branchesEnabled: true }} />);
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationFeatureBox-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationFeatureBox-test.tsx
new file mode 100644
index 00000000000..7366117e6bb
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationFeatureBox-test.tsx
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import AlmIntegrationFeatureBox, {
+ AlmIntegrationFeatureBoxProps
+} from '../AlmIntegrationFeatureBox';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(shallowRender({ active: false })).toMatchSnapshot('inactive');
+ expect(shallowRender({ active: false, inactiveReason: "Bar is foo'd" })).toMatchSnapshot(
+ 'inactive, with reason'
+ );
+});
+
+function shallowRender(props: Partial<AlmIntegrationFeatureBoxProps> = {}) {
+ return shallow<AlmIntegrationFeatureBoxProps>(
+ <AlmIntegrationFeatureBox active={true} description="Foo bar..." name="Foo" {...props} />
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/PRDecorationTabs-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationRenderer-test.tsx
index 4ed69a4feb1..1752860997f 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/PRDecorationTabs-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationRenderer-test.tsx
@@ -19,24 +19,28 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { ALM_KEYS } from '../../../../../types/alm-settings';
-import { PRDecorationTabs, PRDecorationTabsProps } from '../PRDecorationTabs';
+import { AlmKeys } from '../../../../../types/alm-settings';
+import AlmIntegrationRenderer, { AlmIntegrationRendererProps } from '../AlmIntegrationRenderer';
it('should render correctly', () => {
- expect(shallowRender({ loading: true })).toMatchSnapshot();
- expect(shallowRender({ definitionKeyForDeletion: 'keyToDelete' })).toMatchSnapshot();
- expect(shallowRender({ currentAlm: ALM_KEYS.AZURE })).toMatchSnapshot();
- expect(shallowRender({ currentAlm: ALM_KEYS.BITBUCKET })).toMatchSnapshot();
- expect(shallowRender({ currentAlm: ALM_KEYS.GITLAB })).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(shallowRender({ loading: true })).toMatchSnapshot('loading');
+ expect(shallowRender({ definitionKeyForDeletion: 'keyToDelete' })).toMatchSnapshot(
+ 'delete modal'
+ );
+ expect(shallowRender({ currentAlm: AlmKeys.Azure })).toMatchSnapshot('azure');
+ expect(shallowRender({ currentAlm: AlmKeys.Bitbucket })).toMatchSnapshot('bitbucket');
+ expect(shallowRender({ currentAlm: AlmKeys.GitLab })).toMatchSnapshot('gitlab');
});
-function shallowRender(props: Partial<PRDecorationTabsProps> = {}) {
+function shallowRender(props: Partial<AlmIntegrationRendererProps> = {}) {
return shallow(
- <PRDecorationTabs
- appState={{ multipleAlmEnabled: false }}
- currentAlm={ALM_KEYS.GITHUB}
+ <AlmIntegrationRenderer
+ branchesEnabled={true}
+ currentAlm={AlmKeys.GitHub}
definitions={{ azure: [], bitbucket: [], github: [], gitlab: [] }}
loading={false}
+ multipleAlmEnabled={false}
onCancel={jest.fn()}
onConfirmDelete={jest.fn()}
onDelete={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmTab-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTab-test.tsx
index 89969e53fef..4e6fb6289d0 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmTab-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTab-test.tsx
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { mockAzureDefinition } from '../../../../../helpers/mocks/alm-settings';
-import { ALM_KEYS, AzureBindingDefinition } from '../../../../../types/alm-settings';
+import { AlmKeys, AzureBindingDefinition } from '../../../../../types/alm-settings';
import AlmTab from '../AlmTab';
const DEFAULT_BINDING = {
@@ -93,7 +93,7 @@ it('should update config', async () => {
function shallowRender(props: Partial<AlmTab<AzureBindingDefinition>['props']> = {}) {
return shallow<AlmTab<AzureBindingDefinition>>(
<AlmTab
- alm={ALM_KEYS.AZURE}
+ alm={AlmKeys.Azure}
createConfiguration={jest.fn()}
defaultBinding={DEFAULT_BINDING}
definitions={[mockAzureDefinition()]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmTabRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTabRenderer-test.tsx
index 0eeb1fe2d7b..d0fab91181d 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AlmTabRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTabRenderer-test.tsx
@@ -20,7 +20,7 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings';
-import { ALM_KEYS, GithubBindingDefinition } from '../../../../../types/alm-settings';
+import { AlmKeys, GithubBindingDefinition } from '../../../../../types/alm-settings';
import AlmTabRenderer, { AlmTabRendererProps } from '../AlmTabRenderer';
it('should render correctly for multi-ALM binding', () => {
@@ -29,6 +29,22 @@ it('should render correctly for multi-ALM binding', () => {
expect(shallowRender({ editedDefinition: mockGithubDefinition() })).toMatchSnapshot(
'editing a definition'
);
+ expect(
+ shallowRender({
+ features: [
+ {
+ active: true,
+ name: 'Foo',
+ description: 'Bar'
+ },
+ {
+ active: false,
+ name: 'Baz',
+ description: 'Bim'
+ }
+ ]
+ })
+ ).toMatchSnapshot('with features');
});
it('should render correctly for single-ALM binding', () => {
@@ -44,7 +60,7 @@ function shallowRender(props: Partial<AlmTabRendererProps<GithubBindingDefinitio
<AlmTabRenderer
additionalColumnsHeaders={['url', 'app_id']}
additionalColumnsKeys={['url', 'appId']}
- alm={ALM_KEYS.GITHUB}
+ alm={AlmKeys.GitHub}
defaultBinding={mockGithubDefinition()}
definitions={[mockGithubDefinition()]}
form={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AzureForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureForm-test.tsx
index 1d5fbb7472b..1d5fbb7472b 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AzureForm-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureForm-test.tsx
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AzureTab-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureTab-test.tsx
index 16dba8d81cd..16dba8d81cd 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/AzureTab-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureTab-test.tsx
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/BitbucketForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketForm-test.tsx
index de693816844..de693816844 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/BitbucketForm-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketForm-test.tsx
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/BitbucketTab-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketTab-test.tsx
index 1cdb3162ad9..1cdb3162ad9 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/BitbucketTab-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketTab-test.tsx
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/DeleteModal-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/DeleteModal-test.tsx
index dc6292d7cd6..dc6292d7cd6 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/DeleteModal-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/DeleteModal-test.tsx
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GithubForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubForm-test.tsx
index b279b01ea22..b279b01ea22 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GithubForm-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubForm-test.tsx
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GithubTab-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubTab-test.tsx
index 43a689bc702..15d6d36638d 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GithubTab-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubTab-test.tsx
@@ -23,12 +23,14 @@ import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings'
import GithubTab, { GithubTabProps } from '../GithubTab';
it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot('with branch support');
+ expect(shallowRender({ branchesEnabled: false })).toMatchSnapshot('without branch support');
});
function shallowRender(props: Partial<GithubTabProps> = {}) {
return shallow(
<GithubTab
+ branchesEnabled={true}
definitions={[mockGithubDefinition()]}
loading={false}
multipleAlmEnabled={true}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GitlabForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabForm-test.tsx
index 038331bd641..038331bd641 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GitlabForm-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabForm-test.tsx
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GitlabTab-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabTab-test.tsx
index 0325f1b3161..45cc16ed97b 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/GitlabTab-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabTab-test.tsx
@@ -23,12 +23,14 @@ import { mockGitlabDefinition } from '../../../../../helpers/mocks/alm-settings'
import GitlabTab, { GitlabTabProps } from '../GitlabTab';
it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot('with branch support');
+ expect(shallowRender({ branchesEnabled: false })).toMatchSnapshot('without branch support');
});
function shallowRender(props: Partial<GitlabTabProps> = {}) {
return shallow(
<GitlabTab
+ branchesEnabled={true}
definitions={[mockGitlabDefinition()]}
loading={false}
multipleAlmEnabled={true}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionForm-test.tsx.snap
index 98dbf7f493c..58dbf7ad3e5 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationForm-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionForm-test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<AlmPRDecorationFormRenderer
+<AlmBindingDefinitionFormRenderer
canSubmit={[Function]}
loading={false}
onCancel={[Function]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmDefinitionFormField-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormField-test.tsx.snap
index 57a15af1578..7420fe8fc6c 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmDefinitionFormField-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormField-test.tsx.snap
@@ -8,7 +8,7 @@ exports[`should render correctly 1`] = `
className="display-flex-center"
htmlFor="key"
>
- settings.pr_decoration.form.key
+ settings.almintegration.form.key
<em
className="mandatory spacer-right"
>
@@ -37,7 +37,7 @@ exports[`should render correctly 2`] = `
className="display-flex-center"
htmlFor="key"
>
- settings.pr_decoration.form.key
+ settings.almintegration.form.key
<em
className="mandatory spacer-right"
>
@@ -70,7 +70,7 @@ exports[`should render correctly 3`] = `
className="display-flex-center"
htmlFor="key"
>
- settings.pr_decoration.form.key
+ settings.almintegration.form.key
<em
className="mandatory spacer-right"
>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationFormModalRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormModalRenderer-test.tsx.snap
index 8c73cbf6880..acd27e45bd0 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationFormModalRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormModalRenderer-test.tsx.snap
@@ -2,7 +2,7 @@
exports[`should render correctly 1`] = `
<Modal
- contentLabel="settings.pr_decoration.form.header.create"
+ contentLabel="settings.almintegration.form.header.create"
onRequestClose={[MockFunction]}
size="medium"
>
@@ -14,13 +14,21 @@ exports[`should render correctly 1`] = `
className="modal-head"
>
<h2>
- settings.pr_decoration.form.header.create
+ settings.almintegration.form.header.create
</h2>
</div>
<div
className="modal-body modal-container"
>
- <Component />
+ <div
+ className="display-flex-start"
+ >
+ <div
+ className="flex-1"
+ >
+ <Component />
+ </div>
+ </div>
</div>
<div
className="modal-foot"
@@ -33,7 +41,7 @@ exports[`should render correctly 1`] = `
<SubmitButton
disabled={true}
>
- settings.pr_decoration.form.save
+ settings.almintegration.form.save
</SubmitButton>
<ResetButtonLink
onClick={[Function]}
@@ -47,7 +55,7 @@ exports[`should render correctly 1`] = `
exports[`should render correctly 2`] = `
<Modal
- contentLabel="settings.pr_decoration.form.header.create"
+ contentLabel="settings.almintegration.form.header.create"
onRequestClose={[MockFunction]}
size="medium"
>
@@ -59,21 +67,29 @@ exports[`should render correctly 2`] = `
className="modal-head"
>
<h2>
- settings.pr_decoration.form.header.create
+ settings.almintegration.form.header.create
</h2>
</div>
<div
className="modal-body modal-container"
>
- <Alert
- className="big-spacer-bottom"
- variant="info"
+ <div
+ className="display-flex-start"
>
- <span>
- Help me
- </span>
- </Alert>
- <Component />
+ <div
+ className="flex-1"
+ >
+ <Component />
+ </div>
+ <Alert
+ className="huge-spacer-left flex-1"
+ variant="info"
+ >
+ <span>
+ Help me
+ </span>
+ </Alert>
+ </div>
</div>
<div
className="modal-foot"
@@ -86,7 +102,7 @@ exports[`should render correctly 2`] = `
<SubmitButton
disabled={true}
>
- settings.pr_decoration.form.save
+ settings.almintegration.form.save
</SubmitButton>
<ResetButtonLink
onClick={[Function]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormRenderer-test.tsx.snap
new file mode 100644
index 00000000000..8d7b47e2d63
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormRenderer-test.tsx.snap
@@ -0,0 +1,161 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<form
+ className="views-form"
+ data-test="settings__alm-form"
+ onSubmit={[Function]}
+>
+ <div
+ className="display-flex-start"
+ >
+ <div
+ className="flex-1"
+ >
+ <Component />
+ <div
+ className="display-flex-center"
+ >
+ <SubmitButton
+ disabled={true}
+ >
+ settings.almintegration.form.save
+ </SubmitButton>
+ </div>
+ </div>
+ </div>
+</form>
+`;
+
+exports[`should render correctly 2`] = `
+<form
+ className="views-form"
+ data-test="settings__alm-form"
+ onSubmit={[Function]}
+>
+ <div
+ className="display-flex-start"
+ >
+ <div
+ className="flex-1"
+ >
+ <Component />
+ <div
+ className="display-flex-center"
+ >
+ <SubmitButton
+ disabled={true}
+ >
+ settings.almintegration.form.save
+ </SubmitButton>
+ <ResetButtonLink
+ className="spacer-left"
+ onClick={[MockFunction]}
+ >
+ cancel
+ </ResetButtonLink>
+ </div>
+ </div>
+ </div>
+</form>
+`;
+
+exports[`should render correctly 3`] = `
+<form
+ className="views-form"
+ data-test="settings__alm-form"
+ onSubmit={[Function]}
+>
+ <div
+ className="display-flex-start"
+ >
+ <div
+ className="flex-1"
+ >
+ <Component />
+ <div
+ className="display-flex-center"
+ >
+ <SubmitButton
+ disabled={true}
+ >
+ settings.almintegration.form.save
+ </SubmitButton>
+ <Button
+ className="button-red spacer-left"
+ disabled={false}
+ onClick={[MockFunction]}
+ >
+ delete
+ </Button>
+ </div>
+ </div>
+ </div>
+</form>
+`;
+
+exports[`should render correctly 4`] = `
+<form
+ className="views-form"
+ data-test="settings__alm-form"
+ onSubmit={[Function]}
+>
+ <div
+ className="display-flex-start"
+ >
+ <div
+ className="flex-1"
+ >
+ <Component />
+ <div
+ className="display-flex-center"
+ >
+ <SubmitButton
+ disabled={true}
+ >
+ settings.almintegration.form.save
+ </SubmitButton>
+ <span
+ className="text-success spacer-left"
+ >
+ <AlertSuccessIcon
+ className="spacer-right"
+ />
+ settings.state.saved
+ </span>
+ </div>
+ </div>
+ </div>
+</form>
+`;
+
+exports[`should render correctly 5`] = `
+<form
+ className="views-form"
+ data-test="settings__alm-form"
+ onSubmit={[Function]}
+>
+ <div
+ className="display-flex-start"
+ >
+ <div
+ className="flex-1"
+ >
+ <Component />
+ <div
+ className="display-flex-center"
+ >
+ <SubmitButton
+ disabled={true}
+ >
+ settings.almintegration.form.save
+ </SubmitButton>
+ <DeferredSpinner
+ className="spacer-left"
+ timeout={100}
+ />
+ </div>
+ </div>
+ </div>
+</form>
+`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationTable-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionsTable-test.tsx.snap
index bc850412321..ff5dc35a333 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationTable-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionsTable-test.tsx.snap
@@ -5,16 +5,16 @@ exports[`should render correctly 1`] = `
<div
className="spacer-top big-spacer-bottom display-flex-space-between"
>
- <h4
- className="display-inline"
+ <h2
+ className="settings-sub-category-name"
>
- settings.pr_decoration.table.title
- </h4>
+ settings.almintegration.table.title
+ </h2>
<Button
data-test="settings__alm-create"
onClick={[MockFunction]}
>
- settings.pr_decoration.table.create
+ settings.almintegration.table.create
</Button>
</div>
<table
@@ -23,17 +23,17 @@ exports[`should render correctly 1`] = `
<thead>
<tr>
<th>
- settings.pr_decoration.table.column.name
+ settings.almintegration.table.column.name
</th>
<th
className="action-small text-center"
>
- settings.pr_decoration.table.column.edit
+ settings.almintegration.table.column.edit
</th>
<th
className="action text-center"
>
- settings.pr_decoration.table.column.delete
+ settings.almintegration.table.column.delete
</th>
</tr>
</thead>
@@ -44,7 +44,7 @@ exports[`should render correctly 1`] = `
<td
colSpan={3}
>
- settings.pr_decoration.table.empty.azure
+ settings.almintegration.table.empty.azure
</td>
</tr>
</tbody>
@@ -57,16 +57,16 @@ exports[`should render correctly: additional columns 1`] = `
<div
className="spacer-top big-spacer-bottom display-flex-space-between"
>
- <h4
- className="display-inline"
+ <h2
+ className="settings-sub-category-name"
>
- settings.pr_decoration.table.title
- </h4>
+ settings.almintegration.table.title
+ </h2>
<Button
data-test="settings__alm-create"
onClick={[MockFunction]}
>
- settings.pr_decoration.table.create
+ settings.almintegration.table.create
</Button>
</div>
<table
@@ -75,7 +75,7 @@ exports[`should render correctly: additional columns 1`] = `
<thead>
<tr>
<th>
- settings.pr_decoration.table.column.name
+ settings.almintegration.table.column.name
</th>
<th
key="additional1"
@@ -90,12 +90,12 @@ exports[`should render correctly: additional columns 1`] = `
<th
className="action-small text-center"
>
- settings.pr_decoration.table.column.edit
+ settings.almintegration.table.column.edit
</th>
<th
className="action text-center"
>
- settings.pr_decoration.table.column.delete
+ settings.almintegration.table.column.delete
</th>
</tr>
</thead>
@@ -196,16 +196,16 @@ exports[`should render correctly: title adjusts for GitLab 1`] = `
<div
className="spacer-top big-spacer-bottom display-flex-space-between"
>
- <h4
- className="display-inline"
+ <h2
+ className="settings-sub-category-name"
>
- settings.pr_decoration.table.title
- </h4>
+ settings.almintegration.table.title
+ </h2>
<Button
data-test="settings__alm-create"
onClick={[MockFunction]}
>
- settings.pr_decoration.table.create
+ settings.almintegration.table.create
</Button>
</div>
<table
@@ -214,17 +214,17 @@ exports[`should render correctly: title adjusts for GitLab 1`] = `
<thead>
<tr>
<th>
- settings.pr_decoration.table.column.name
+ settings.almintegration.table.column.name
</th>
<th
className="action-small text-center"
>
- settings.pr_decoration.table.column.edit
+ settings.almintegration.table.column.edit
</th>
<th
className="action text-center"
>
- settings.pr_decoration.table.column.delete
+ settings.almintegration.table.column.delete
</th>
</tr>
</thead>
@@ -235,7 +235,7 @@ exports[`should render correctly: title adjusts for GitLab 1`] = `
<td
colSpan={3}
>
- settings.pr_decoration.table.empty.github
+ settings.almintegration.table.empty.gitlab
</td>
</tr>
</tbody>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/PullRequestDecoration-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap
index d41b9e0d342..a056a472a84 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/PullRequestDecoration-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap
@@ -1,7 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<Connect(withAppState(PRDecorationTabs))
+<AlmIntegrationRenderer
+ branchesEnabled={true}
currentAlm="github"
definitions={
Object {
@@ -12,6 +13,7 @@ exports[`should render correctly 1`] = `
}
}
loading={true}
+ multipleAlmEnabled={false}
onCancel={[Function]}
onConfirmDelete={[Function]}
onDelete={[Function]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationFeatureBox-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationFeatureBox-test.tsx.snap
new file mode 100644
index 00000000000..16a177214ae
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationFeatureBox-test.tsx.snap
@@ -0,0 +1,97 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: default 1`] = `
+<div
+ className="boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered"
+>
+ <CheckIcon
+ className="little-spacer-top spacer-right"
+ fill="#00aa00"
+ />
+ <div
+ className="display-flex-column abs-height-100"
+ >
+ <h4>
+ Foo
+ </h4>
+ <div
+ className="spacer-top flex-1"
+ >
+ Foo bar...
+ </div>
+ <div
+ className="spacer-top"
+ >
+ <em
+ className="text-success"
+ >
+ settings.almintegration.feature.enabled
+ </em>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`should render correctly: inactive 1`] = `
+<div
+ className="boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered bg-muted"
+>
+ <ClearIcon
+ className="little-spacer-top spacer-right"
+ fill="#999"
+ />
+ <div
+ className="display-flex-column abs-height-100"
+ >
+ <h4>
+ Foo
+ </h4>
+ <div
+ className="spacer-top flex-1"
+ >
+ Foo bar...
+ </div>
+ <div
+ className="spacer-top"
+ >
+ <em
+ className="text-muted"
+ >
+ settings.almintegration.feature.disabled
+ </em>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`should render correctly: inactive, with reason 1`] = `
+<div
+ className="boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered bg-muted"
+>
+ <ClearIcon
+ className="little-spacer-top spacer-right"
+ fill="#999"
+ />
+ <div
+ className="display-flex-column abs-height-100"
+ >
+ <h4>
+ Foo
+ </h4>
+ <div
+ className="spacer-top flex-1"
+ >
+ Foo bar...
+ </div>
+ <div
+ className="spacer-top"
+ >
+ <em
+ className="text-muted"
+ >
+ Bar is foo'd
+ </em>
+ </div>
+ </div>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/PRDecorationTabs-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationRenderer-test.tsx.snap
index 5590bf87bcb..62430cb1471 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/PRDecorationTabs-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationRenderer-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should render correctly 1`] = `
+exports[`should render correctly: azure 1`] = `
<Fragment>
<header
className="page-header"
@@ -8,17 +8,17 @@ exports[`should render correctly 1`] = `
<h1
className="page-title"
>
- settings.pr_decoration.title
+ settings.almintegration.title
</h1>
</header>
<div
className="markdown small spacer-top big-spacer-bottom"
>
- settings.pr_decoration.description
+ settings.almintegration.description
</div>
<BoxedTabs
onSelect={[MockFunction]}
- selected="github"
+ selected="azure"
tabs={
Array [
Object {
@@ -44,6 +44,7 @@ exports[`should render correctly 1`] = `
/>
Bitbucket Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "azure",
@@ -56,6 +57,7 @@ exports[`should render correctly 1`] = `
/>
Azure DevOps Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "gitlab",
@@ -72,21 +74,17 @@ exports[`should render correctly 1`] = `
]
}
/>
- <div
- className="boxed-group boxed-group-inner"
- >
- <GithubTab
- definitions={Array []}
- loading={true}
- multipleAlmEnabled={false}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- />
- </div>
+ <AzureTab
+ definitions={Array []}
+ loading={false}
+ multipleAlmEnabled={false}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
</Fragment>
`;
-exports[`should render correctly 2`] = `
+exports[`should render correctly: bitbucket 1`] = `
<Fragment>
<header
className="page-header"
@@ -94,17 +92,17 @@ exports[`should render correctly 2`] = `
<h1
className="page-title"
>
- settings.pr_decoration.title
+ settings.almintegration.title
</h1>
</header>
<div
className="markdown small spacer-top big-spacer-bottom"
>
- settings.pr_decoration.description
+ settings.almintegration.description
</div>
<BoxedTabs
onSelect={[MockFunction]}
- selected="github"
+ selected="bitbucket"
tabs={
Array [
Object {
@@ -130,6 +128,7 @@ exports[`should render correctly 2`] = `
/>
Bitbucket Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "azure",
@@ -142,6 +141,7 @@ exports[`should render correctly 2`] = `
/>
Azure DevOps Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "gitlab",
@@ -158,26 +158,17 @@ exports[`should render correctly 2`] = `
]
}
/>
- <div
- className="boxed-group boxed-group-inner"
- >
- <GithubTab
- definitions={Array []}
- loading={false}
- multipleAlmEnabled={false}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- />
- </div>
- <DeleteModal
- id="keyToDelete"
- onCancel={[MockFunction]}
+ <BitbucketTab
+ definitions={Array []}
+ loading={false}
+ multipleAlmEnabled={false}
onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
/>
</Fragment>
`;
-exports[`should render correctly 3`] = `
+exports[`should render correctly: default 1`] = `
<Fragment>
<header
className="page-header"
@@ -185,17 +176,17 @@ exports[`should render correctly 3`] = `
<h1
className="page-title"
>
- settings.pr_decoration.title
+ settings.almintegration.title
</h1>
</header>
<div
className="markdown small spacer-top big-spacer-bottom"
>
- settings.pr_decoration.description
+ settings.almintegration.description
</div>
<BoxedTabs
onSelect={[MockFunction]}
- selected="azure"
+ selected="github"
tabs={
Array [
Object {
@@ -221,6 +212,7 @@ exports[`should render correctly 3`] = `
/>
Bitbucket Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "azure",
@@ -233,6 +225,7 @@ exports[`should render correctly 3`] = `
/>
Azure DevOps Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "gitlab",
@@ -249,21 +242,18 @@ exports[`should render correctly 3`] = `
]
}
/>
- <div
- className="boxed-group boxed-group-inner"
- >
- <AzureTab
- definitions={Array []}
- loading={false}
- multipleAlmEnabled={false}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- />
- </div>
+ <GithubTab
+ branchesEnabled={true}
+ definitions={Array []}
+ loading={false}
+ multipleAlmEnabled={false}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
</Fragment>
`;
-exports[`should render correctly 4`] = `
+exports[`should render correctly: delete modal 1`] = `
<Fragment>
<header
className="page-header"
@@ -271,17 +261,17 @@ exports[`should render correctly 4`] = `
<h1
className="page-title"
>
- settings.pr_decoration.title
+ settings.almintegration.title
</h1>
</header>
<div
className="markdown small spacer-top big-spacer-bottom"
>
- settings.pr_decoration.description
+ settings.almintegration.description
</div>
<BoxedTabs
onSelect={[MockFunction]}
- selected="bitbucket"
+ selected="github"
tabs={
Array [
Object {
@@ -307,6 +297,7 @@ exports[`should render correctly 4`] = `
/>
Bitbucket Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "azure",
@@ -319,6 +310,7 @@ exports[`should render correctly 4`] = `
/>
Azure DevOps Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "gitlab",
@@ -335,21 +327,23 @@ exports[`should render correctly 4`] = `
]
}
/>
- <div
- className="boxed-group boxed-group-inner"
- >
- <BitbucketTab
- definitions={Array []}
- loading={false}
- multipleAlmEnabled={false}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- />
- </div>
+ <GithubTab
+ branchesEnabled={true}
+ definitions={Array []}
+ loading={false}
+ multipleAlmEnabled={false}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
+ <DeleteModal
+ id="keyToDelete"
+ onCancel={[MockFunction]}
+ onDelete={[MockFunction]}
+ />
</Fragment>
`;
-exports[`should render correctly 5`] = `
+exports[`should render correctly: gitlab 1`] = `
<Fragment>
<header
className="page-header"
@@ -357,13 +351,13 @@ exports[`should render correctly 5`] = `
<h1
className="page-title"
>
- settings.pr_decoration.title
+ settings.almintegration.title
</h1>
</header>
<div
className="markdown small spacer-top big-spacer-bottom"
>
- settings.pr_decoration.description
+ settings.almintegration.description
</div>
<BoxedTabs
onSelect={[MockFunction]}
@@ -393,6 +387,7 @@ exports[`should render correctly 5`] = `
/>
Bitbucket Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "azure",
@@ -405,6 +400,7 @@ exports[`should render correctly 5`] = `
/>
Azure DevOps Server
</React.Fragment>,
+ "requiresBranchesEnabled": true,
},
Object {
"key": "gitlab",
@@ -421,16 +417,98 @@ exports[`should render correctly 5`] = `
]
}
/>
+ <GitlabTab
+ branchesEnabled={true}
+ definitions={Array []}
+ loading={false}
+ multipleAlmEnabled={false}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
+</Fragment>
+`;
+
+exports[`should render correctly: loading 1`] = `
+<Fragment>
+ <header
+ className="page-header"
+ >
+ <h1
+ className="page-title"
+ >
+ settings.almintegration.title
+ </h1>
+ </header>
<div
- className="boxed-group boxed-group-inner"
+ className="markdown small spacer-top big-spacer-bottom"
>
- <GitlabTab
- definitions={Array []}
- loading={false}
- multipleAlmEnabled={false}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- />
+ settings.almintegration.description
</div>
+ <BoxedTabs
+ onSelect={[MockFunction]}
+ selected="github"
+ tabs={
+ Array [
+ Object {
+ "key": "github",
+ "label": <React.Fragment>
+ <img
+ alt="github"
+ className="spacer-right"
+ height={16}
+ src="/images/alm/github.svg"
+ />
+ GitHub
+ </React.Fragment>,
+ },
+ Object {
+ "key": "bitbucket",
+ "label": <React.Fragment>
+ <img
+ alt="bitbucket"
+ className="spacer-right"
+ height={16}
+ src="/images/alm/bitbucket.svg"
+ />
+ Bitbucket Server
+ </React.Fragment>,
+ "requiresBranchesEnabled": true,
+ },
+ Object {
+ "key": "azure",
+ "label": <React.Fragment>
+ <img
+ alt="azure"
+ className="spacer-right"
+ height={16}
+ src="/images/alm/azure.svg"
+ />
+ Azure DevOps Server
+ </React.Fragment>,
+ "requiresBranchesEnabled": true,
+ },
+ Object {
+ "key": "gitlab",
+ "label": <React.Fragment>
+ <img
+ alt="gitlab"
+ className="spacer-right"
+ height={16}
+ src="/images/alm/gitlab.svg"
+ />
+ GitLab
+ </React.Fragment>,
+ },
+ ]
+ }
+ />
+ <GithubTab
+ branchesEnabled={true}
+ definitions={Array []}
+ loading={true}
+ multipleAlmEnabled={false}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
</Fragment>
`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTab-test.tsx.snap
index 5d3f8507f61..5d3f8507f61 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmTab-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTab-test.tsx.snap
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap
new file mode 100644
index 00000000000..64f7ac5fa04
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap
@@ -0,0 +1,334 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly for multi-ALM binding: editing a definition 1`] = `
+<div
+ className="big-padded"
+>
+ <DeferredSpinner
+ loading={false}
+ timeout={100}
+ >
+ <AlmBindingDefinitionsTable
+ additionalColumnsHeaders={
+ Array [
+ "url",
+ "app_id",
+ ]
+ }
+ alm="github"
+ definitions={
+ Array [
+ Object {
+ "additionalColumns": Array [
+ "http://github.enterprise.com",
+ "123456",
+ ],
+ "key": "key",
+ },
+ ]
+ }
+ onCreate={[MockFunction]}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+ <AlmBindingDefinitionForm
+ bindingDefinition={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http://github.enterprise.com",
+ }
+ }
+ help={
+ <FormattedMessage
+ defaultMessage="settings.almintegration.github.info"
+ id="settings.almintegration.github.info"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/documentation/analysis/pr-decoration/"
+ >
+ learn_more
+ </Link>,
+ }
+ }
+ />
+ }
+ onCancel={[MockFunction]}
+ onSubmit={[MockFunction]}
+ showInModal={true}
+ >
+ <Component />
+ </AlmBindingDefinitionForm>
+ </DeferredSpinner>
+</div>
+`;
+
+exports[`should render correctly for multi-ALM binding: loaded 1`] = `
+<div
+ className="big-padded"
+>
+ <DeferredSpinner
+ loading={false}
+ timeout={100}
+ >
+ <AlmBindingDefinitionsTable
+ additionalColumnsHeaders={
+ Array [
+ "url",
+ "app_id",
+ ]
+ }
+ alm="github"
+ definitions={
+ Array [
+ Object {
+ "additionalColumns": Array [
+ "http://github.enterprise.com",
+ "123456",
+ ],
+ "key": "key",
+ },
+ ]
+ }
+ onCreate={[MockFunction]}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+ </DeferredSpinner>
+</div>
+`;
+
+exports[`should render correctly for multi-ALM binding: loading 1`] = `
+<div
+ className="big-padded"
+>
+ <DeferredSpinner
+ loading={true}
+ timeout={100}
+ >
+ <AlmBindingDefinitionsTable
+ additionalColumnsHeaders={
+ Array [
+ "url",
+ "app_id",
+ ]
+ }
+ alm="github"
+ definitions={
+ Array [
+ Object {
+ "additionalColumns": Array [
+ "http://github.enterprise.com",
+ "123456",
+ ],
+ "key": "key",
+ },
+ ]
+ }
+ onCreate={[MockFunction]}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+ </DeferredSpinner>
+</div>
+`;
+
+exports[`should render correctly for multi-ALM binding: with features 1`] = `
+<div
+ className="big-padded"
+>
+ <DeferredSpinner
+ loading={false}
+ timeout={100}
+ >
+ <AlmBindingDefinitionsTable
+ additionalColumnsHeaders={
+ Array [
+ "url",
+ "app_id",
+ ]
+ }
+ alm="github"
+ definitions={
+ Array [
+ Object {
+ "additionalColumns": Array [
+ "http://github.enterprise.com",
+ "123456",
+ ],
+ "key": "key",
+ },
+ ]
+ }
+ onCreate={[MockFunction]}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+ </DeferredSpinner>
+ <div
+ className="big-spacer-top big-padded-top bordered-top"
+ >
+ <h3
+ className="big-spacer-bottom"
+ >
+ settings.almintegration.features
+ </h3>
+ <div
+ className="display-flex-wrap"
+ >
+ <AlmIntegrationFeatureBox
+ active={true}
+ description="Bar"
+ key="0"
+ name="Foo"
+ />
+ <AlmIntegrationFeatureBox
+ active={false}
+ description="Bim"
+ key="1"
+ name="Baz"
+ />
+ </div>
+ </div>
+</div>
+`;
+
+exports[`should render correctly for single-ALM binding 1`] = `
+<div
+ className="big-padded"
+>
+ <AlmBindingDefinitionForm
+ bindingDefinition={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http://github.enterprise.com",
+ }
+ }
+ help={
+ <FormattedMessage
+ defaultMessage="settings.almintegration.github.info"
+ id="settings.almintegration.github.info"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/documentation/analysis/pr-decoration/"
+ >
+ learn_more
+ </Link>,
+ }
+ }
+ />
+ }
+ hideKeyField={true}
+ loading={true}
+ onCancel={[MockFunction]}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ onSubmit={[MockFunction]}
+ readOnly={true}
+ success={false}
+ >
+ <Component />
+ </AlmBindingDefinitionForm>
+</div>
+`;
+
+exports[`should render correctly for single-ALM binding 2`] = `
+<div
+ className="big-padded"
+>
+ <AlmBindingDefinitionForm
+ bindingDefinition={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http://github.enterprise.com",
+ }
+ }
+ help={
+ <FormattedMessage
+ defaultMessage="settings.almintegration.github.info"
+ id="settings.almintegration.github.info"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/documentation/analysis/pr-decoration/"
+ >
+ learn_more
+ </Link>,
+ }
+ }
+ />
+ }
+ hideKeyField={true}
+ loading={false}
+ onCancel={[MockFunction]}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ onSubmit={[MockFunction]}
+ readOnly={true}
+ success={false}
+ >
+ <Component />
+ </AlmBindingDefinitionForm>
+</div>
+`;
+
+exports[`should render correctly for single-ALM binding 3`] = `
+<div
+ className="big-padded"
+>
+ <AlmBindingDefinitionForm
+ bindingDefinition={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http://github.enterprise.com",
+ }
+ }
+ help={
+ <FormattedMessage
+ defaultMessage="settings.almintegration.github.info"
+ id="settings.almintegration.github.info"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/documentation/analysis/pr-decoration/"
+ >
+ learn_more
+ </Link>,
+ }
+ }
+ />
+ }
+ hideKeyField={true}
+ loading={false}
+ onCancel={[MockFunction]}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ onSubmit={[MockFunction]}
+ readOnly={true}
+ success={false}
+ >
+ <Component />
+ </AlmBindingDefinitionForm>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AzureForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureForm-test.tsx.snap
index b980d1d72cd..ba43fbcd654 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AzureForm-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureForm-test.tsx.snap
@@ -2,16 +2,16 @@
exports[`should render correctly 1`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.azure.help"
+ help="settings.almintegration.form.name.azure.help"
id="name.azure"
onFieldChange={[MockFunction]}
propKey="key"
value=""
/>
- <AlmDefinitionFormField
- help="settings.pr_decoration.form.personal_access_token.azure.help"
+ <AlmBindingDefinitionFormField
+ help="settings.almintegration.form.personal_access_token.azure.help"
id="personal_access_token"
isTextArea={true}
onFieldChange={[MockFunction]}
@@ -23,16 +23,16 @@ exports[`should render correctly 1`] = `
exports[`should render correctly 2`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.azure.help"
+ help="settings.almintegration.form.name.azure.help"
id="name.azure"
onFieldChange={[MockFunction]}
propKey="key"
value="key"
/>
- <AlmDefinitionFormField
- help="settings.pr_decoration.form.personal_access_token.azure.help"
+ <AlmBindingDefinitionFormField
+ help="settings.almintegration.form.personal_access_token.azure.help"
id="personal_access_token"
isTextArea={true}
onFieldChange={[MockFunction]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureTab-test.tsx.snap
new file mode 100644
index 00000000000..b5eda86fe17
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureTab-test.tsx.snap
@@ -0,0 +1,42 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<div
+ className="bordered"
+>
+ <AlmTab
+ alm="azure"
+ createConfiguration={[Function]}
+ defaultBinding={
+ Object {
+ "key": "",
+ "personalAccessToken": "",
+ }
+ }
+ definitions={
+ Array [
+ Object {
+ "key": "key",
+ "personalAccessToken": "asdf1234",
+ },
+ ]
+ }
+ features={
+ Array [
+ Object {
+ "active": true,
+ "description": "settings.almintegration.feature.pr_decoration.description",
+ "inactiveReason": "settings.almintegration.feature.need_at_least_1_binding",
+ "name": "settings.almintegration.feature.pr_decoration.title",
+ },
+ ]
+ }
+ form={[Function]}
+ loading={false}
+ multipleAlmEnabled={true}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ updateConfiguration={[Function]}
+ />
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap
index 831e13ea2e5..b936abc487c 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap
@@ -2,20 +2,20 @@
exports[`should render correctly 1`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.bitbucket.help"
+ help="settings.almintegration.form.name.bitbucket.help"
id="name.bitbucket"
maxLength={100}
onFieldChange={[MockFunction]}
propKey="key"
value=""
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
help={
<FormattedMessage
- defaultMessage="settings.pr_decoration.form.url.bitbucket.help"
- id="settings.pr_decoration.form.url.bitbucket.help"
+ defaultMessage="settings.almintegration.form.url.bitbucket.help"
+ id="settings.almintegration.form.url.bitbucket.help"
values={
Object {
"example": "https://bitbucket-server.your-company.com",
@@ -29,7 +29,7 @@ exports[`should render correctly 1`] = `
propKey="url"
value=""
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="personal_access_token"
isTextArea={true}
onFieldChange={[MockFunction]}
@@ -41,20 +41,20 @@ exports[`should render correctly 1`] = `
exports[`should render correctly 2`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.bitbucket.help"
+ help="settings.almintegration.form.name.bitbucket.help"
id="name.bitbucket"
maxLength={100}
onFieldChange={[MockFunction]}
propKey="key"
value="key"
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
help={
<FormattedMessage
- defaultMessage="settings.pr_decoration.form.url.bitbucket.help"
- id="settings.pr_decoration.form.url.bitbucket.help"
+ defaultMessage="settings.almintegration.form.url.bitbucket.help"
+ id="settings.almintegration.form.url.bitbucket.help"
values={
Object {
"example": "https://bitbucket-server.your-company.com",
@@ -68,7 +68,7 @@ exports[`should render correctly 2`] = `
propKey="url"
value="http://bbs.enterprise.com"
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="personal_access_token"
isTextArea={true}
onFieldChange={[MockFunction]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap
new file mode 100644
index 00000000000..35279875066
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap
@@ -0,0 +1,112 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<div
+ className="bordered"
+>
+ <AlmTab
+ additionalColumnsHeaders={
+ Array [
+ "settings.almintegration.table.column.bitbucket.url",
+ ]
+ }
+ additionalColumnsKeys={
+ Array [
+ "url",
+ ]
+ }
+ additionalTableInfo={
+ <Alert
+ className="big-spacer-bottom width-50"
+ variant="info"
+ >
+ <FormattedMessage
+ defaultMessage="settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances"
+ id="settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances"
+ values={
+ Object {
+ "feature": <em>
+ settings.almintegration.feature.alm_repo_import.title
+ </em>,
+ }
+ }
+ />
+ </Alert>
+ }
+ alm="bitbucket"
+ createConfiguration={[Function]}
+ defaultBinding={
+ Object {
+ "key": "",
+ "personalAccessToken": "",
+ "url": "",
+ }
+ }
+ definitions={
+ Array [
+ Object {
+ "key": "key",
+ "personalAccessToken": "asdf1234",
+ "url": "http://bbs.enterprise.com",
+ },
+ ]
+ }
+ features={
+ Array [
+ Object {
+ "active": true,
+ "description": "settings.almintegration.feature.pr_decoration.description",
+ "inactiveReason": "settings.almintegration.feature.need_at_least_1_binding",
+ "name": "settings.almintegration.feature.pr_decoration.title",
+ },
+ Object {
+ "active": true,
+ "description": "settings.almintegration.feature.alm_repo_import.description",
+ "inactiveReason": "onboarding.create_project.too_many_bbs_instances_X.1",
+ "name": "settings.almintegration.feature.alm_repo_import.title",
+ },
+ ]
+ }
+ form={[Function]}
+ help={
+ <React.Fragment>
+ <h3>
+ onboarding.create_project.pat_help.title
+ </h3>
+ <p
+ className="big-spacer-top"
+ >
+ settings.almintegration.bitbucket.help_1
+ </p>
+ <ul
+ className="big-spacer-top list-styled"
+ >
+ <li>
+ settings.almintegration.bitbucket.help_2
+ </li>
+ <li>
+ settings.almintegration.bitbucket.help_3
+ </li>
+ </ul>
+ <p
+ className="big-spacer-top big-spacer-bottom"
+ >
+ <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/documentation/analysis/pr-decoration/"
+ >
+ learn_more
+ </Link>
+ </p>
+ </React.Fragment>
+ }
+ loading={false}
+ multipleAlmEnabled={true}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ updateConfiguration={[Function]}
+ />
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/DeleteModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/DeleteModal-test.tsx.snap
index 710915a2ceb..78660781f84 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/DeleteModal-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/DeleteModal-test.tsx.snap
@@ -4,7 +4,7 @@ exports[`should render correctly 1`] = `
<ConfirmModal
confirmButtonText="delete"
confirmData="1"
- header="settings.pr_decoration.delete.header"
+ header="settings.almintegration.delete.header"
isDestructive={true}
onClose={[MockFunction]}
onConfirm={[MockFunction]}
@@ -13,8 +13,8 @@ exports[`should render correctly 1`] = `
className="spacer-bottom"
>
<FormattedMessage
- defaultMessage="settings.pr_decoration.delete.message"
- id="settings.pr_decoration.delete.message"
+ defaultMessage="settings.almintegration.delete.message"
+ id="settings.almintegration.delete.message"
values={
Object {
"id": <b>
@@ -25,7 +25,7 @@ exports[`should render correctly 1`] = `
/>
</p>
<p>
- settings.pr_decoration.delete.info.4
+ settings.almintegration.delete.info.4
</p>
</ConfirmModal>
@@ -35,7 +35,7 @@ exports[`should render correctly 2`] = `
<ConfirmModal
confirmButtonText="delete"
confirmData="1"
- header="settings.pr_decoration.delete.header"
+ header="settings.almintegration.delete.header"
isDestructive={true}
onClose={[MockFunction]}
onConfirm={[MockFunction]}
@@ -44,8 +44,8 @@ exports[`should render correctly 2`] = `
className="spacer-bottom"
>
<FormattedMessage
- defaultMessage="settings.pr_decoration.delete.message"
- id="settings.pr_decoration.delete.message"
+ defaultMessage="settings.almintegration.delete.message"
+ id="settings.almintegration.delete.message"
values={
Object {
"id": <b>
@@ -56,7 +56,7 @@ exports[`should render correctly 2`] = `
/>
</p>
<p>
- settings.pr_decoration.delete.no_info
+ settings.almintegration.delete.no_info
</p>
</ConfirmModal>
`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GithubForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubForm-test.tsx.snap
index 3f4492a255d..4015c170435 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GithubForm-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubForm-test.tsx.snap
@@ -2,25 +2,25 @@
exports[`should render correctly 1`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.github.help"
+ help="settings.almintegration.form.name.github.help"
id="name.github"
onFieldChange={[MockFunction]}
propKey="key"
value=""
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
help={
<React.Fragment>
- settings.pr_decoration.form.url.github.help1
+ settings.almintegration.form.url.github.help1
<br />
<em>
https://github.company.com/api/v3
</em>
<br />
<br />
- settings.pr_decoration.form.url.github.help2
+ settings.almintegration.form.url.github.help2
<br />
<em>
https://api.github.com/
@@ -33,14 +33,14 @@ exports[`should render correctly 1`] = `
propKey="url"
value=""
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="app_id"
maxLength={80}
onFieldChange={[MockFunction]}
propKey="appId"
value=""
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="private_key"
isTextArea={true}
onFieldChange={[MockFunction]}
@@ -52,25 +52,25 @@ exports[`should render correctly 1`] = `
exports[`should render correctly 2`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.github.help"
+ help="settings.almintegration.form.name.github.help"
id="name.github"
onFieldChange={[MockFunction]}
propKey="key"
value="key"
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
help={
<React.Fragment>
- settings.pr_decoration.form.url.github.help1
+ settings.almintegration.form.url.github.help1
<br />
<em>
https://github.company.com/api/v3
</em>
<br />
<br />
- settings.pr_decoration.form.url.github.help2
+ settings.almintegration.form.url.github.help2
<br />
<em>
https://api.github.com/
@@ -83,14 +83,14 @@ exports[`should render correctly 2`] = `
propKey="url"
value="http://github.enterprise.com"
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="app_id"
maxLength={80}
onFieldChange={[MockFunction]}
propKey="appId"
value="123456"
/>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
id="private_key"
isTextArea={true}
onFieldChange={[MockFunction]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubTab-test.tsx.snap
new file mode 100644
index 00000000000..1f1420d5604
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubTab-test.tsx.snap
@@ -0,0 +1,84 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: with branch support 1`] = `
+<div
+ className="bordered"
+>
+ <AlmTab
+ additionalColumnsHeaders={
+ Array [
+ "settings.almintegration.table.column.github.url",
+ "settings.almintegration.table.column.app_id",
+ ]
+ }
+ additionalColumnsKeys={
+ Array [
+ "appId",
+ "url",
+ ]
+ }
+ alm="github"
+ createConfiguration={[Function]}
+ defaultBinding={
+ Object {
+ "appId": "",
+ "key": "",
+ "privateKey": "",
+ "url": "",
+ }
+ }
+ definitions={
+ Array [
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http://github.enterprise.com",
+ },
+ ]
+ }
+ features={
+ Array [
+ Object {
+ "active": true,
+ "description": "settings.almintegration.feature.pr_decoration.description",
+ "inactiveReason": "settings.almintegration.feature.need_at_least_1_binding",
+ "name": "settings.almintegration.feature.pr_decoration.title",
+ },
+ ]
+ }
+ form={[Function]}
+ loading={false}
+ multipleAlmEnabled={true}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ updateConfiguration={[Function]}
+ />
+ <div
+ className="huge-spacer-top huge-spacer-bottom bordered-top"
+ />
+ <div
+ className="big-padded"
+ >
+ <Connect(SubCategoryDefinitionsList)
+ category="almintegration"
+ subCategory="github"
+ />
+ </div>
+</div>
+`;
+
+exports[`should render correctly: without branch support 1`] = `
+<div
+ className="bordered"
+>
+ <div
+ className="big-padded"
+ >
+ <Connect(SubCategoryDefinitionsList)
+ category="almintegration"
+ subCategory="github"
+ />
+ </div>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GitlabForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabForm-test.tsx.snap
index 8c2b54c3887..ff9f07e6dc1 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GitlabForm-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabForm-test.tsx.snap
@@ -2,16 +2,16 @@
exports[`should render correctly 1`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.gitlab.help"
+ help="settings.almintegration.form.name.gitlab.help"
id="name.gitlab"
onFieldChange={[MockFunction]}
propKey="key"
value=""
/>
- <AlmDefinitionFormField
- help="settings.pr_decoration.form.personal_access_token.gitlab.help"
+ <AlmBindingDefinitionFormField
+ help="settings.almintegration.form.personal_access_token.gitlab.help"
id="personal_access_token"
isTextArea={true}
onFieldChange={[MockFunction]}
@@ -23,16 +23,16 @@ exports[`should render correctly 1`] = `
exports[`should render correctly 2`] = `
<Fragment>
- <AlmDefinitionFormField
+ <AlmBindingDefinitionFormField
autoFocus={true}
- help="settings.pr_decoration.form.name.gitlab.help"
+ help="settings.almintegration.form.name.gitlab.help"
id="name.gitlab"
onFieldChange={[MockFunction]}
propKey="key"
value="foo"
/>
- <AlmDefinitionFormField
- help="settings.pr_decoration.form.personal_access_token.gitlab.help"
+ <AlmBindingDefinitionFormField
+ help="settings.almintegration.form.personal_access_token.gitlab.help"
id="personal_access_token"
isTextArea={true}
onFieldChange={[MockFunction]}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabTab-test.tsx.snap
new file mode 100644
index 00000000000..46930b7d06c
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabTab-test.tsx.snap
@@ -0,0 +1,68 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: with branch support 1`] = `
+<div
+ className="bordered"
+>
+ <AlmTab
+ alm="gitlab"
+ createConfiguration={[Function]}
+ defaultBinding={
+ Object {
+ "key": "",
+ "personalAccessToken": "",
+ }
+ }
+ definitions={
+ Array [
+ Object {
+ "key": "foo",
+ "personalAccessToken": "foobar",
+ },
+ ]
+ }
+ features={
+ Array [
+ Object {
+ "active": true,
+ "description": "settings.almintegration.feature.mr_decoration.description",
+ "inactiveReason": "settings.almintegration.feature.need_at_least_1_binding",
+ "name": "settings.almintegration.feature.mr_decoration.title",
+ },
+ ]
+ }
+ form={[Function]}
+ loading={false}
+ multipleAlmEnabled={true}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ updateConfiguration={[Function]}
+ />
+ <div
+ className="huge-spacer-top huge-spacer-bottom bordered-top"
+ />
+ <div
+ className="big-padded"
+ >
+ <Connect(SubCategoryDefinitionsList)
+ category="almintegration"
+ subCategory="gitlab"
+ />
+ </div>
+</div>
+`;
+
+exports[`should render correctly: without branch support 1`] = `
+<div
+ className="bordered"
+>
+ <div
+ className="big-padded"
+ >
+ <Connect(SubCategoryDefinitionsList)
+ category="almintegration"
+ subCategory="gitlab"
+ />
+ </div>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmTabRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmTabRenderer.tsx
deleted file mode 100644
index 3daa7b0ce03..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/AlmTabRenderer.tsx
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { Link } from 'react-router';
-import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { AlmSettingsBinding, ALM_KEYS } from '../../../../types/alm-settings';
-import AlmPRDecorationForm, { AlmPRDecorationFormChildrenProps } from './AlmPRDecorationForm';
-import AlmPRDecorationTable from './AlmPRDecorationTable';
-
-export interface AlmTabRendererProps<B> {
- additionalColumnsHeaders: string[];
- additionalColumnsKeys: Array<keyof B>;
- alm: ALM_KEYS;
- editedDefinition?: B;
- defaultBinding: B;
- definitions: B[];
- form: (props: AlmPRDecorationFormChildrenProps<B>) => React.ReactNode;
- loading: boolean;
- multipleAlmEnabled: boolean;
- onCancel: () => void;
- onCreate: () => void;
- onDelete: (definitionKey: string) => void;
- onEdit: (definitionKey: string) => void;
- onSubmit: (config: B, originalKey: string) => void;
- success: boolean;
-}
-
-export default function AlmTabRenderer<B extends AlmSettingsBinding>(
- props: AlmTabRendererProps<B>
-) {
- const {
- additionalColumnsHeaders,
- additionalColumnsKeys,
- alm,
- defaultBinding,
- definitions,
- editedDefinition,
- form,
- loading,
- multipleAlmEnabled,
- success
- } = props;
-
- let definition: B | undefined;
- let mappedDefinitions: Array<{ key: string; additionalColumns: string[] }> = [];
- let showEdit: boolean | undefined;
-
- if (!multipleAlmEnabled) {
- definition = editedDefinition;
- if (definition === undefined && definitions.length > 0) {
- definition = definitions[0];
- }
- showEdit = definition && editedDefinition === undefined;
- } else {
- mappedDefinitions = definitions.map(({ key, ...properties }) => {
- const additionalColumns = additionalColumnsKeys.map(k => (properties as any)[k]);
- return {
- key,
- additionalColumns
- };
- });
- }
-
- const help = (
- <FormattedMessage
- defaultMessage={translate(`settings.pr_decoration.${alm}.info`)}
- id={`settings.pr_decoration.${alm}.info`}
- values={{
- link: (
- <Link target="_blank" to="/documentation/analysis/pr-decoration/">
- {translate('learn_more')}
- </Link>
- )
- }}
- />
- );
-
- return multipleAlmEnabled ? (
- <DeferredSpinner loading={loading}>
- <AlmPRDecorationTable
- additionalColumnsHeaders={additionalColumnsHeaders}
- alm={alm}
- definitions={mappedDefinitions}
- onCreate={props.onCreate}
- onDelete={props.onDelete}
- onEdit={props.onEdit}
- />
-
- {editedDefinition && (
- <AlmPRDecorationForm
- alm={alm}
- bindingDefinition={editedDefinition}
- help={help}
- onCancel={props.onCancel}
- onSubmit={props.onSubmit}
- showInModal={true}>
- {form}
- </AlmPRDecorationForm>
- )}
- </DeferredSpinner>
- ) : (
- <AlmPRDecorationForm
- alm={alm}
- bindingDefinition={definition || defaultBinding}
- help={help}
- hideKeyField={true}
- loading={loading}
- onCancel={props.onCancel}
- onDelete={definition ? props.onDelete : undefined}
- onEdit={showEdit ? props.onEdit : undefined}
- onSubmit={props.onSubmit}
- readOnly={showEdit}
- success={success}>
- {form}
- </AlmPRDecorationForm>
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/BitbucketTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/BitbucketTab.tsx
deleted file mode 100644
index 9de99d62378..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/BitbucketTab.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import {
- createBitbucketConfiguration,
- updateBitbucketConfiguration
-} from '../../../../api/almSettings';
-import { ALM_KEYS, BitbucketBindingDefinition } from '../../../../types/alm-settings';
-import AlmTab from './AlmTab';
-import BitbucketForm from './BitbucketForm';
-
-export interface BitbucketTabProps {
- definitions: BitbucketBindingDefinition[];
- loading: boolean;
- multipleAlmEnabled: boolean;
- onDelete: (definitionKey: string) => void;
- onUpdateDefinitions: () => void;
-}
-
-export default function BitbucketTab(props: BitbucketTabProps) {
- const { multipleAlmEnabled, definitions, loading } = props;
-
- return (
- <AlmTab
- additionalColumnsHeaders={[translate('settings.pr_decoration.table.column.bitbucket.url')]}
- additionalColumnsKeys={['url']}
- alm={ALM_KEYS.BITBUCKET}
- createConfiguration={createBitbucketConfiguration}
- defaultBinding={{ key: '', url: '', personalAccessToken: '' }}
- definitions={definitions}
- form={childProps => <BitbucketForm {...childProps} />}
- loading={loading}
- multipleAlmEnabled={multipleAlmEnabled}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- updateConfiguration={updateBitbucketConfiguration}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GithubTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GithubTab.tsx
deleted file mode 100644
index 5c10574fa24..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GithubTab.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { createGithubConfiguration, updateGithubConfiguration } from '../../../../api/almSettings';
-import { ALM_KEYS, GithubBindingDefinition } from '../../../../types/alm-settings';
-import AlmTab from './AlmTab';
-import GithubForm from './GithubForm';
-
-export interface GithubTabProps {
- definitions: GithubBindingDefinition[];
- loading: boolean;
- multipleAlmEnabled: boolean;
- onDelete: (definitionKey: string) => void;
- onUpdateDefinitions: () => void;
-}
-
-export default function GithubTab(props: GithubTabProps) {
- const { multipleAlmEnabled, definitions, loading } = props;
-
- return (
- <AlmTab
- additionalColumnsHeaders={[
- translate('settings.pr_decoration.table.column.github.url'),
- translate('settings.pr_decoration.table.column.app_id')
- ]}
- additionalColumnsKeys={['appId', 'url']}
- alm={ALM_KEYS.GITHUB}
- createConfiguration={createGithubConfiguration}
- defaultBinding={{ key: '', appId: '', url: '', privateKey: '' }}
- definitions={definitions}
- form={childProps => <GithubForm {...childProps} />}
- loading={loading}
- multipleAlmEnabled={multipleAlmEnabled}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- updateConfiguration={updateGithubConfiguration}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GitlabTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GitlabTab.tsx
deleted file mode 100644
index 145694a6247..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/GitlabTab.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { createGitlabConfiguration, updateGitlabConfiguration } from '../../../../api/almSettings';
-import { ALM_KEYS, GitlabBindingDefinition } from '../../../../types/alm-settings';
-import AlmTab from './AlmTab';
-import GitlabForm from './GitlabForm';
-
-export interface GitlabTabProps {
- definitions: GitlabBindingDefinition[];
- loading: boolean;
- multipleAlmEnabled: boolean;
- onDelete: (definitionKey: string) => void;
- onUpdateDefinitions: () => void;
-}
-
-export default function GitlabTab(props: GitlabTabProps) {
- const { multipleAlmEnabled, definitions, loading } = props;
-
- return (
- <AlmTab
- alm={ALM_KEYS.GITLAB}
- createConfiguration={createGitlabConfiguration}
- defaultBinding={{ key: '', personalAccessToken: '' }}
- definitions={definitions}
- form={childProps => <GitlabForm {...childProps} />}
- loading={loading}
- multipleAlmEnabled={multipleAlmEnabled}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- updateConfiguration={updateGitlabConfiguration}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/PRDecorationTabs.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/PRDecorationTabs.tsx
deleted file mode 100644
index e55c90e70b9..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/PRDecorationTabs.tsx
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import BoxedTabs from 'sonar-ui-common/components/controls/BoxedTabs';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { getBaseUrl } from 'sonar-ui-common/helpers/urls';
-import { withAppState } from '../../../../components/hoc/withAppState';
-import { AlmSettingsBindingDefinitions, ALM_KEYS } from '../../../../types/alm-settings';
-import AzureTab from './AzureTab';
-import BitbucketTab from './BitbucketTab';
-import DeleteModal from './DeleteModal';
-import GithubTab from './GithubTab';
-import GitlabTab from './GitlabTab';
-
-export interface PRDecorationTabsProps {
- appState: Pick<T.AppState, 'multipleAlmEnabled'>;
- currentAlm: ALM_KEYS;
- definitionKeyForDeletion?: string;
- definitions: AlmSettingsBindingDefinitions;
- loading: boolean;
- onCancel: () => void;
- onConfirmDelete: (definitionKey: string) => void;
- onDelete: (definitionKey: string) => void;
- onSelectAlm: (alm: ALM_KEYS) => void;
- onUpdateDefinitions: () => void;
- projectCount?: number;
-}
-
-export const almName = {
- [ALM_KEYS.AZURE]: 'Azure DevOps Server',
- [ALM_KEYS.BITBUCKET]: 'Bitbucket Server',
- [ALM_KEYS.GITHUB]: 'GitHub',
- [ALM_KEYS.GITLAB]: 'GitLab'
-};
-
-export function PRDecorationTabs(props: PRDecorationTabsProps) {
- const {
- appState: { multipleAlmEnabled },
- definitionKeyForDeletion,
- definitions,
- currentAlm,
- loading,
- projectCount
- } = props;
-
- return (
- <>
- <header className="page-header">
- <h1 className="page-title">{translate('settings.pr_decoration.title')}</h1>
- </header>
-
- <div className="markdown small spacer-top big-spacer-bottom">
- {translate('settings.pr_decoration.description')}
- </div>
- <BoxedTabs
- onSelect={props.onSelectAlm}
- selected={currentAlm}
- tabs={[
- {
- key: ALM_KEYS.GITHUB,
- label: (
- <>
- <img
- alt="github"
- className="spacer-right"
- height={16}
- src={`${getBaseUrl()}/images/alm/github.svg`}
- />
- {almName[ALM_KEYS.GITHUB]}
- </>
- )
- },
- {
- key: ALM_KEYS.BITBUCKET,
- label: (
- <>
- <img
- alt="bitbucket"
- className="spacer-right"
- height={16}
- src={`${getBaseUrl()}/images/alm/bitbucket.svg`}
- />
- {almName[ALM_KEYS.BITBUCKET]}
- </>
- )
- },
- {
- key: ALM_KEYS.AZURE,
- label: (
- <>
- <img
- alt="azure"
- className="spacer-right"
- height={16}
- src={`${getBaseUrl()}/images/alm/azure.svg`}
- />
- {almName[ALM_KEYS.AZURE]}
- </>
- )
- },
- {
- key: ALM_KEYS.GITLAB,
- label: (
- <>
- <img
- alt="gitlab"
- className="spacer-right"
- height={16}
- src={`${getBaseUrl()}/images/alm/gitlab.svg`}
- />
- {almName[ALM_KEYS.GITLAB]}
- </>
- )
- }
- ]}
- />
-
- <div className="boxed-group boxed-group-inner">
- {currentAlm === ALM_KEYS.AZURE && (
- <AzureTab
- definitions={definitions.azure}
- loading={loading}
- multipleAlmEnabled={Boolean(multipleAlmEnabled)}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- />
- )}
- {currentAlm === ALM_KEYS.BITBUCKET && (
- <BitbucketTab
- definitions={definitions.bitbucket}
- loading={loading}
- multipleAlmEnabled={Boolean(multipleAlmEnabled)}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- />
- )}
- {currentAlm === ALM_KEYS.GITHUB && (
- <GithubTab
- definitions={definitions.github}
- loading={loading}
- multipleAlmEnabled={Boolean(multipleAlmEnabled)}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- />
- )}
- {currentAlm === ALM_KEYS.GITLAB && (
- <GitlabTab
- definitions={definitions.gitlab}
- loading={loading}
- multipleAlmEnabled={Boolean(multipleAlmEnabled)}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- />
- )}
- </div>
-
- {definitionKeyForDeletion && (
- <DeleteModal
- id={definitionKeyForDeletion}
- onCancel={props.onCancel}
- onDelete={props.onConfirmDelete}
- projectCount={projectCount}
- />
- )}
- </>
- );
-}
-
-export default withAppState(PRDecorationTabs);
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationFormRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationFormRenderer-test.tsx.snap
deleted file mode 100644
index fddedfb39c2..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmPRDecorationFormRenderer-test.tsx.snap
+++ /dev/null
@@ -1,121 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<form
- className="views-form"
- data-test="settings__alm-form"
- onSubmit={[Function]}
->
- <Component />
- <div
- className="display-flex-center"
- >
- <SubmitButton
- disabled={true}
- >
- settings.pr_decoration.form.save
- </SubmitButton>
- </div>
-</form>
-`;
-
-exports[`should render correctly 2`] = `
-<form
- className="views-form"
- data-test="settings__alm-form"
- onSubmit={[Function]}
->
- <Component />
- <div
- className="display-flex-center"
- >
- <SubmitButton
- disabled={true}
- >
- settings.pr_decoration.form.save
- </SubmitButton>
- <ResetButtonLink
- className="spacer-left"
- onClick={[MockFunction]}
- >
- cancel
- </ResetButtonLink>
- </div>
-</form>
-`;
-
-exports[`should render correctly 3`] = `
-<form
- className="views-form"
- data-test="settings__alm-form"
- onSubmit={[Function]}
->
- <Component />
- <div
- className="display-flex-center"
- >
- <SubmitButton
- disabled={true}
- >
- settings.pr_decoration.form.save
- </SubmitButton>
- <Button
- className="button-red spacer-left"
- disabled={false}
- onClick={[MockFunction]}
- >
- delete
- </Button>
- </div>
-</form>
-`;
-
-exports[`should render correctly 4`] = `
-<form
- className="views-form"
- data-test="settings__alm-form"
- onSubmit={[Function]}
->
- <Component />
- <div
- className="display-flex-center"
- >
- <SubmitButton
- disabled={true}
- >
- settings.pr_decoration.form.save
- </SubmitButton>
- <span
- className="text-success spacer-left"
- >
- <AlertSuccessIcon
- className="spacer-right"
- />
- settings.state.saved
- </span>
- </div>
-</form>
-`;
-
-exports[`should render correctly 5`] = `
-<form
- className="views-form"
- data-test="settings__alm-form"
- onSubmit={[Function]}
->
- <Component />
- <div
- className="display-flex-center"
- >
- <SubmitButton
- disabled={true}
- >
- settings.pr_decoration.form.save
- </SubmitButton>
- <DeferredSpinner
- className="spacer-left"
- timeout={100}
- />
- </div>
-</form>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap
deleted file mode 100644
index 620640396af..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap
+++ /dev/null
@@ -1,254 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly for multi-ALM binding: editing a definition 1`] = `
-<DeferredSpinner
- loading={false}
- timeout={100}
->
- <AlmPRDecorationTable
- additionalColumnsHeaders={
- Array [
- "url",
- "app_id",
- ]
- }
- alm="github"
- definitions={
- Array [
- Object {
- "additionalColumns": Array [
- "http://github.enterprise.com",
- "123456",
- ],
- "key": "key",
- },
- ]
- }
- onCreate={[MockFunction]}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
- <AlmPRDecorationForm
- alm="github"
- bindingDefinition={
- Object {
- "appId": "123456",
- "key": "key",
- "privateKey": "asdf1234",
- "url": "http://github.enterprise.com",
- }
- }
- help={
- <FormattedMessage
- defaultMessage="settings.pr_decoration.github.info"
- id="settings.pr_decoration.github.info"
- values={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/documentation/analysis/pr-decoration/"
- >
- learn_more
- </Link>,
- }
- }
- />
- }
- onCancel={[MockFunction]}
- onSubmit={[MockFunction]}
- showInModal={true}
- >
- <Component />
- </AlmPRDecorationForm>
-</DeferredSpinner>
-`;
-
-exports[`should render correctly for multi-ALM binding: loaded 1`] = `
-<DeferredSpinner
- loading={false}
- timeout={100}
->
- <AlmPRDecorationTable
- additionalColumnsHeaders={
- Array [
- "url",
- "app_id",
- ]
- }
- alm="github"
- definitions={
- Array [
- Object {
- "additionalColumns": Array [
- "http://github.enterprise.com",
- "123456",
- ],
- "key": "key",
- },
- ]
- }
- onCreate={[MockFunction]}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
-</DeferredSpinner>
-`;
-
-exports[`should render correctly for multi-ALM binding: loading 1`] = `
-<DeferredSpinner
- loading={true}
- timeout={100}
->
- <AlmPRDecorationTable
- additionalColumnsHeaders={
- Array [
- "url",
- "app_id",
- ]
- }
- alm="github"
- definitions={
- Array [
- Object {
- "additionalColumns": Array [
- "http://github.enterprise.com",
- "123456",
- ],
- "key": "key",
- },
- ]
- }
- onCreate={[MockFunction]}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
-</DeferredSpinner>
-`;
-
-exports[`should render correctly for single-ALM binding 1`] = `
-<AlmPRDecorationForm
- alm="github"
- bindingDefinition={
- Object {
- "appId": "123456",
- "key": "key",
- "privateKey": "asdf1234",
- "url": "http://github.enterprise.com",
- }
- }
- help={
- <FormattedMessage
- defaultMessage="settings.pr_decoration.github.info"
- id="settings.pr_decoration.github.info"
- values={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/documentation/analysis/pr-decoration/"
- >
- learn_more
- </Link>,
- }
- }
- />
- }
- hideKeyField={true}
- loading={true}
- onCancel={[MockFunction]}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- onSubmit={[MockFunction]}
- readOnly={true}
- success={false}
->
- <Component />
-</AlmPRDecorationForm>
-`;
-
-exports[`should render correctly for single-ALM binding 2`] = `
-<AlmPRDecorationForm
- alm="github"
- bindingDefinition={
- Object {
- "appId": "123456",
- "key": "key",
- "privateKey": "asdf1234",
- "url": "http://github.enterprise.com",
- }
- }
- help={
- <FormattedMessage
- defaultMessage="settings.pr_decoration.github.info"
- id="settings.pr_decoration.github.info"
- values={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/documentation/analysis/pr-decoration/"
- >
- learn_more
- </Link>,
- }
- }
- />
- }
- hideKeyField={true}
- loading={false}
- onCancel={[MockFunction]}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- onSubmit={[MockFunction]}
- readOnly={true}
- success={false}
->
- <Component />
-</AlmPRDecorationForm>
-`;
-
-exports[`should render correctly for single-ALM binding 3`] = `
-<AlmPRDecorationForm
- alm="github"
- bindingDefinition={
- Object {
- "appId": "123456",
- "key": "key",
- "privateKey": "asdf1234",
- "url": "http://github.enterprise.com",
- }
- }
- help={
- <FormattedMessage
- defaultMessage="settings.pr_decoration.github.info"
- id="settings.pr_decoration.github.info"
- values={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/documentation/analysis/pr-decoration/"
- >
- learn_more
- </Link>,
- }
- }
- />
- }
- hideKeyField={true}
- loading={false}
- onCancel={[MockFunction]}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- onSubmit={[MockFunction]}
- readOnly={true}
- success={false}
->
- <Component />
-</AlmPRDecorationForm>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AzureTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AzureTab-test.tsx.snap
deleted file mode 100644
index f73bb4670fe..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/AzureTab-test.tsx.snap
+++ /dev/null
@@ -1,28 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<AlmTab
- alm="azure"
- createConfiguration={[Function]}
- defaultBinding={
- Object {
- "key": "",
- "personalAccessToken": "",
- }
- }
- definitions={
- Array [
- Object {
- "key": "key",
- "personalAccessToken": "asdf1234",
- },
- ]
- }
- form={[Function]}
- loading={false}
- multipleAlmEnabled={true}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- updateConfiguration={[Function]}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap
deleted file mode 100644
index 9d519a62456..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/BitbucketTab-test.tsx.snap
+++ /dev/null
@@ -1,40 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<AlmTab
- additionalColumnsHeaders={
- Array [
- "settings.pr_decoration.table.column.bitbucket.url",
- ]
- }
- additionalColumnsKeys={
- Array [
- "url",
- ]
- }
- alm="bitbucket"
- createConfiguration={[Function]}
- defaultBinding={
- Object {
- "key": "",
- "personalAccessToken": "",
- "url": "",
- }
- }
- definitions={
- Array [
- Object {
- "key": "key",
- "personalAccessToken": "asdf1234",
- "url": "http://bbs.enterprise.com",
- },
- ]
- }
- form={[Function]}
- loading={false}
- multipleAlmEnabled={true}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- updateConfiguration={[Function]}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GithubTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GithubTab-test.tsx.snap
deleted file mode 100644
index 2fc099dd893..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GithubTab-test.tsx.snap
+++ /dev/null
@@ -1,44 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<AlmTab
- additionalColumnsHeaders={
- Array [
- "settings.pr_decoration.table.column.github.url",
- "settings.pr_decoration.table.column.app_id",
- ]
- }
- additionalColumnsKeys={
- Array [
- "appId",
- "url",
- ]
- }
- alm="github"
- createConfiguration={[Function]}
- defaultBinding={
- Object {
- "appId": "",
- "key": "",
- "privateKey": "",
- "url": "",
- }
- }
- definitions={
- Array [
- Object {
- "appId": "123456",
- "key": "key",
- "privateKey": "asdf1234",
- "url": "http://github.enterprise.com",
- },
- ]
- }
- form={[Function]}
- loading={false}
- multipleAlmEnabled={true}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- updateConfiguration={[Function]}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GitlabTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GitlabTab-test.tsx.snap
deleted file mode 100644
index fdee120ed9f..00000000000
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecoration/__tests__/__snapshots__/GitlabTab-test.tsx.snap
+++ /dev/null
@@ -1,28 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<AlmTab
- alm="gitlab"
- createConfiguration={[Function]}
- defaultBinding={
- Object {
- "key": "",
- "personalAccessToken": "",
- }
- }
- definitions={
- Array [
- Object {
- "key": "foo",
- "personalAccessToken": "foobar",
- },
- ]
- }
- form={[Function]}
- loading={false}
- multipleAlmEnabled={true}
- onDelete={[MockFunction]}
- onUpdateDefinitions={[MockFunction]}
- updateConfiguration={[Function]}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx
index 1b1a3914dc1..4fa49ed870c 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx
@@ -26,9 +26,9 @@ import {
setProjectBitbucketBinding,
setProjectGithubBinding,
setProjectGitlabBinding
-} from '../../../../api/almSettings';
+} from '../../../../api/alm-settings';
import throwGlobalError from '../../../../app/utils/throwGlobalError';
-import { AlmSettingsInstance, ALM_KEYS, ProjectAlmBinding } from '../../../../types/alm-settings';
+import { AlmKeys, AlmSettingsInstance, ProjectAlmBinding } from '../../../../types/alm-settings';
import PRDecorationBindingRenderer from './PRDecorationBindingRenderer';
interface Props {
@@ -45,11 +45,11 @@ interface State {
success: boolean;
}
-const FIELDS_BY_ALM: { [almKey in ALM_KEYS]: Array<keyof T.Omit<ProjectAlmBinding, 'key'>> } = {
- [ALM_KEYS.AZURE]: [],
- [ALM_KEYS.BITBUCKET]: ['repository', 'slug'],
- [ALM_KEYS.GITHUB]: ['repository'],
- [ALM_KEYS.GITLAB]: []
+const FIELDS_BY_ALM: { [almKey in AlmKeys]: Array<keyof T.Omit<ProjectAlmBinding, 'key'>> } = {
+ [AlmKeys.Azure]: [],
+ [AlmKeys.Bitbucket]: ['repository', 'slug'],
+ [AlmKeys.GitHub]: ['repository'],
+ [AlmKeys.GitLab]: []
};
export default class PRDecorationBinding extends React.PureComponent<Props, State> {
@@ -133,7 +133,7 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat
};
submitProjectAlmBinding(
- alm: ALM_KEYS,
+ alm: AlmKeys,
key: string,
almSpecificFields?: T.Omit<ProjectAlmBinding, 'key'>
): Promise<void> {
@@ -141,12 +141,12 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat
const project = this.props.component.key;
switch (alm) {
- case ALM_KEYS.AZURE:
+ case AlmKeys.Azure:
return setProjectAzureBinding({
almSetting,
project
});
- case ALM_KEYS.BITBUCKET: {
+ case AlmKeys.Bitbucket: {
if (!almSpecificFields) {
return Promise.reject();
}
@@ -158,7 +158,7 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat
slug
});
}
- case ALM_KEYS.GITHUB: {
+ case AlmKeys.GitHub: {
const repository = almSpecificFields && almSpecificFields.repository;
if (!repository) {
return Promise.reject();
@@ -170,7 +170,7 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat
});
}
- case ALM_KEYS.GITLAB:
+ case AlmKeys.GitLab:
return setProjectGitlabBinding({
almSetting,
project
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
index 5fbb23c1d3c..4a8b1222469 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
@@ -27,7 +27,7 @@ import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon'
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { AlmSettingsInstance, ALM_KEYS, ProjectAlmBinding } from '../../../../types/alm-settings';
+import { AlmKeys, AlmSettingsInstance, ProjectAlmBinding } from '../../../../types/alm-settings';
export interface PRDecorationBindingRendererProps {
formData: ProjectAlmBinding;
@@ -179,7 +179,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe
/>
</div>
- {alm === ALM_KEYS.BITBUCKET && (
+ {alm === AlmKeys.Bitbucket && (
<>
{renderField({
help: true,
@@ -216,7 +216,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe
</>
)}
- {alm === ALM_KEYS.GITHUB &&
+ {alm === AlmKeys.GitHub &&
renderField({
help: true,
helpParams: { example: 'SonarSource/sonarqube' },
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx
index b6447586e5a..4e2e06bdc13 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx
@@ -27,12 +27,12 @@ import {
setProjectAzureBinding,
setProjectBitbucketBinding,
setProjectGithubBinding
-} from '../../../../../api/almSettings';
+} from '../../../../../api/alm-settings';
import { mockComponent } from '../../../../../helpers/testMocks';
-import { ALM_KEYS } from '../../../../../types/alm-settings';
+import { AlmKeys } from '../../../../../types/alm-settings';
import PRDecorationBinding from '../PRDecorationBinding';
-jest.mock('../../../../../api/almSettings', () => ({
+jest.mock('../../../../../api/alm-settings', () => ({
getAlmSettings: jest.fn().mockResolvedValue([]),
getProjectAlmBinding: jest.fn().mockResolvedValue(undefined),
setProjectAzureBinding: jest.fn().mockResolvedValue(undefined),
@@ -53,7 +53,7 @@ it('should render correctly', () => {
it('should fill selects and fill formdata', async () => {
const url = 'github.com';
- const instances = [{ key: 'instance1', url, alm: ALM_KEYS.GITHUB }];
+ const instances = [{ key: 'instance1', url, alm: AlmKeys.GitHub }];
const formdata = {
key: 'instance1',
repository: 'account/repo'
@@ -89,9 +89,9 @@ it('should handle reset', async () => {
describe('handleSubmit', () => {
const instances = [
- { key: 'github', alm: ALM_KEYS.GITHUB },
- { key: 'azure', alm: ALM_KEYS.AZURE },
- { key: 'bitbucket', alm: ALM_KEYS.BITBUCKET }
+ { key: 'github', alm: AlmKeys.GitHub },
+ { key: 'azure', alm: AlmKeys.Azure },
+ { key: 'bitbucket', alm: AlmKeys.Bitbucket }
];
it('should work for github', async () => {
@@ -195,9 +195,9 @@ it('should validate form', async () => {
wrapper.setState({
instances: [
- { key: 'azure', alm: ALM_KEYS.AZURE },
- { key: 'bitbucket', alm: ALM_KEYS.BITBUCKET },
- { key: 'github', alm: ALM_KEYS.GITHUB }
+ { key: 'azure', alm: AlmKeys.Azure },
+ { key: 'bitbucket', alm: AlmKeys.Bitbucket },
+ { key: 'github', alm: AlmKeys.GitHub }
]
});
expect(wrapper.instance().validateForm({ key: 'azure' })).toBe(true);
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
index 19c5dc38a21..dbdbca4378d 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import Select from 'sonar-ui-common/components/controls/Select';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { ALM_KEYS } from '../../../../../types/alm-settings';
+import { AlmKeys } from '../../../../../types/alm-settings';
import PRDecorationBindingRenderer, {
PRDecorationBindingRendererProps
} from '../PRDecorationBindingRenderer';
@@ -35,7 +35,7 @@ it('should render single instance correctly', () => {
const singleInstance = {
key: 'single',
url: 'http://single.url',
- alm: ALM_KEYS.GITHUB
+ alm: AlmKeys.GitHub
};
expect(
shallowRender({
@@ -49,22 +49,22 @@ it('should render multiple instances correctly', () => {
const urls = ['http://github.enterprise.com', 'http://bbs.enterprise.com'];
const instances = [
{
- alm: ALM_KEYS.GITHUB,
+ alm: AlmKeys.GitHub,
key: 'i1',
url: urls[0]
},
{
- alm: ALM_KEYS.GITHUB,
+ alm: AlmKeys.GitHub,
key: 'i2',
url: urls[0]
},
{
- alm: ALM_KEYS.BITBUCKET,
+ alm: AlmKeys.Bitbucket,
key: 'i3',
url: urls[1]
},
{
- alm: ALM_KEYS.AZURE,
+ alm: AlmKeys.Azure,
key: 'i4'
}
];
@@ -96,7 +96,7 @@ it('should render multiple instances correctly', () => {
it('should display action state correctly', () => {
const urls = ['http://url.com'];
- const instances = [{ key: 'key', url: urls[0], alm: ALM_KEYS.GITHUB }];
+ const instances = [{ key: 'key', url: urls[0], alm: AlmKeys.GitHub }];
expect(shallowRender({ instances, loading: false, saving: true })).toMatchSnapshot();
expect(shallowRender({ instances, loading: false, success: true })).toMatchSnapshot();
@@ -112,11 +112,11 @@ it('should display action state correctly', () => {
it('should render select options correctly', async () => {
const instances = [
{
- alm: ALM_KEYS.AZURE,
+ alm: AlmKeys.Azure,
key: 'azure'
},
{
- alm: ALM_KEYS.GITHUB,
+ alm: AlmKeys.GitHub,
key: 'github',
url: 'gh.url.com'
}
diff --git a/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts b/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts
index 6f3320db435..3940ca053da 100644
--- a/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts
+++ b/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts
@@ -18,8 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import {
+ AlmKeys,
AlmSettingsInstance,
- ALM_KEYS,
AzureBindingDefinition,
BitbucketBindingDefinition,
GithubBindingDefinition,
@@ -30,7 +30,7 @@ export function mockAlmSettingsInstance(
overrides: Partial<AlmSettingsInstance> = {}
): AlmSettingsInstance {
return {
- alm: ALM_KEYS.GITHUB,
+ alm: AlmKeys.GitHub,
key: 'key',
...overrides
};
diff --git a/server/sonar-web/src/main/js/types/alm-settings.ts b/server/sonar-web/src/main/js/types/alm-settings.ts
index 427e13293e8..1ff3849237e 100644
--- a/server/sonar-web/src/main/js/types/alm-settings.ts
+++ b/server/sonar-web/src/main/js/types/alm-settings.ts
@@ -17,46 +17,33 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-export const enum ALM_KEYS {
- AZURE = 'azure',
- BITBUCKET = 'bitbucket',
- GITHUB = 'github',
- GITLAB = 'gitlab'
+export const enum AlmKeys {
+ Azure = 'azure',
+ Bitbucket = 'bitbucket',
+ GitHub = 'github',
+ GitLab = 'gitlab'
}
-export interface AlmSettingsBinding {
+export interface AlmBindingDefinition {
key: string;
}
-export interface AlmSettingsInstance {
- alm: ALM_KEYS;
- key: string;
- url?: string;
-}
-
-export interface AlmSettingsBindingDefinitions {
- azure: AzureBindingDefinition[];
- bitbucket: BitbucketBindingDefinition[];
- github: GithubBindingDefinition[];
- gitlab: GitlabBindingDefinition[];
-}
-
-export interface AzureBindingDefinition extends AlmSettingsBinding {
+export interface AzureBindingDefinition extends AlmBindingDefinition {
personalAccessToken: string;
}
-export interface BitbucketBindingDefinition extends AlmSettingsBinding {
+export interface BitbucketBindingDefinition extends AlmBindingDefinition {
personalAccessToken: string;
url: string;
}
-export interface GithubBindingDefinition extends AlmSettingsBinding {
+export interface GithubBindingDefinition extends AlmBindingDefinition {
appId: string;
privateKey: string;
url: string;
}
-export interface GitlabBindingDefinition extends AlmSettingsBinding {
+export interface GitlabBindingDefinition extends AlmBindingDefinition {
personalAccessToken: string;
}
@@ -88,3 +75,16 @@ export interface GitlabProjectAlmBinding {
almSetting: string;
project: string;
}
+
+export interface AlmSettingsInstance {
+ alm: AlmKeys;
+ key: string;
+ url?: string;
+}
+
+export interface AlmSettingsBindingDefinitions {
+ azure: AzureBindingDefinition[];
+ bitbucket: BitbucketBindingDefinition[];
+ github: GithubBindingDefinition[];
+ gitlab: GitlabBindingDefinition[];
+}
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index 12ff218a47f..171b69d4e0a 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -1016,55 +1016,64 @@ settings.new_code_period.description2=This setting is the default for all projec
settings.languages.select_a_language_placeholder=Select a language
-settings.pr_decoration.category=Pull Request Decoration
-settings.pr_decoration.title=Pull Request Decoration
-settings.pr_decoration.description=Pull Request Decoration adds SonarQube analysis and a Quality Gate to your Pull Requests directly in your ALM provider's interface.
-settings.pr_decoration.manage_instances=Manage instances
-settings.pr_decoration.azure.info=Accounts that will be used to decorate Pull Requests need Code: Read & Write permission. {link}
-settings.pr_decoration.bitbucket.info=Accounts that will be used to decorate Pull Requests need write permission. {link}
-settings.pr_decoration.github.info=You need to install a GitHub App with specific settings and permissions to enable Pull Request Decoration on your Organization or Repository. {link}
-settings.pr_decoration.gitlab.info=Accounts that will be used to decorate Merge Requests need comment permissions on projects. The personal key needs the API scope permission. {link}
-settings.pr_decoration.table.title=Pull Request Decoration configurations
-settings.mr_decoration.table.title=Merge Request Decoration configurations
-settings.pr_decoration.table.empty.azure=Create your first Azure DevOps configuration to enable Pull Request Decoration on your projects.
-settings.pr_decoration.table.empty.bitbucket=Create your first Bitbucket configuration to enable Pull Request Decoration on your projects.
-settings.pr_decoration.table.empty.github=Create your first GitHub configuration to enable Pull Request Decoration on your organization or repository.
-settings.pr_decoration.table.empty.gitlab=Create your first GitLab configuration to enable Merge Request Decoration on your repository.
-settings.pr_decoration.table.create=Create configuration
-settings.pr_decoration.table.column.name=Name
-settings.pr_decoration.table.column.bitbucket.url=Bitbucket Server URL
-settings.pr_decoration.table.column.github.url=GitHub Enterprise or GitHub.com URL
-settings.pr_decoration.table.column.app_id=App ID
-settings.pr_decoration.table.column.edit=Edit
-settings.pr_decoration.table.column.delete=Delete
-settings.pr_decoration.delete.header=Delete configuration
-settings.pr_decoration.delete.message=Are you sure you want to delete the {id} configuration?
-settings.pr_decoration.delete.info={0} projects will no longer get Pull Request Decorations.
-settings.pr_decoration.delete.no_info=An unknown number of projects will no longer get Pull Request Decorations.
-settings.pr_decoration.form.header.create=Create a Pull Request Decoration configuration
-settings.mr_decoration.form.header.create=Create a Merge Request Decoration configuration
-settings.pr_decoration.form.header.edit=Edit the Pull Request Decoration configuration
-settings.mr_decoration.form.header.edit=Edit the Merge Request Decoration configuration
-settings.pr_decoration.form.name.azure=Configuration name
-settings.pr_decoration.form.name.azure.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Azure instance for a project.
-settings.pr_decoration.form.name.bitbucket=Configuration name
-settings.pr_decoration.form.name.bitbucket.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Bitbucket instance for a project.
-settings.pr_decoration.form.name.github=Configuration name
-settings.pr_decoration.form.name.github.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitHub App for a project.
-settings.pr_decoration.form.name.gitlab=Configuration name
-settings.pr_decoration.form.name.gitlab.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitLab instance for a project.
-settings.pr_decoration.form.url.bitbucket=Bitbucket Server URL
-settings.pr_decoration.form.url.bitbucket.help=Example: {example}
-settings.pr_decoration.form.url.github=GitHub URL
-settings.pr_decoration.form.url.github.help1=Example for Github Enterprise:
-settings.pr_decoration.form.url.github.help2=If using GitHub.com:
-settings.pr_decoration.form.app_id=GitHub App ID
-settings.pr_decoration.form.private_key=Private Key
-settings.pr_decoration.form.personal_access_token=Personal Access token
-settings.pr_decoration.form.personal_access_token.azure.help=Token of the user that will be used to decorate the Pull Requests. Needs authorized scope: "Code (read and write)".
-settings.pr_decoration.form.personal_access_token.gitlab.help=Token of the user that will be used to decorate the Merge Requests. Needs API scope authorization.
-settings.pr_decoration.form.save=Save configuration
-settings.pr_decoration.form.cancel=Cancel
+settings.almintegration.title=Integration configurations
+settings.almintegration.description=ALM integrations allow SonarQube to interact with your ALM. This enables things like authentication, or providing analysis details and a Quality Gate to your Pull Requests directly in your ALM provider's interface.
+settings.almintegration.manage_instances=Manage instances
+settings.almintegration.azure.info=Accounts that will be used to decorate Pull Requests need Code: Read & Write permission. {link}
+settings.almintegration.github.info=You need to install a GitHub App with specific settings and permissions to enable Pull Request Decoration on your Organization or Repository. {link}
+settings.almintegration.gitlab.info=Accounts that will be used to decorate Merge Requests need comment permissions on projects. The personal key needs the API scope permission. {link}
+settings.almintegration.bitbucket.help_1=SonarQube needs a Personal Access Token to communicate with Bitbucket Server. This token will be used to decorate Pull Requests.
+settings.almintegration.bitbucket.help_2=The account used for integration needs write permission.
+settings.almintegration.bitbucket.help_3=We recommend to integrate with SonarQube using a Bitbucket Server Service Account.
+settings.almintegration.table.title=ALM integration configurations
+settings.almintegration.table.empty.azure=Create your first Azure DevOps configuration to enable Pull Request Decoration on your projects.
+settings.almintegration.table.empty.bitbucket=Create your first Bitbucket configuration to enable Pull Request Decoration on your projects.
+settings.almintegration.table.empty.github=Create your first GitHub configuration to enable Pull Request Decoration on your organization or repository.
+settings.almintegration.table.empty.gitlab=Create your first GitLab configuration to enable Merge Request Decoration on your repository.
+settings.almintegration.table.create=Create configuration
+settings.almintegration.table.column.name=Name
+settings.almintegration.table.column.bitbucket.url=Bitbucket Server URL
+settings.almintegration.table.column.github.url=GitHub Enterprise or GitHub.com URL
+settings.almintegration.table.column.app_id=App ID
+settings.almintegration.table.column.edit=Edit
+settings.almintegration.table.column.delete=Delete
+settings.almintegration.delete.header=Delete configuration
+settings.almintegration.delete.message=Are you sure you want to delete the {id} configuration?
+settings.almintegration.delete.info={0} projects will no longer get Pull Request Decorations.
+settings.almintegration.delete.no_info=An unknown number of projects will no longer get Pull Request Decorations.
+settings.almintegration.form.header.create=Create a configuration
+settings.almintegration.form.header.edit=Edit the configuration
+settings.almintegration.form.name.azure=Configuration name
+settings.almintegration.form.name.azure.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Azure instance for a project.
+settings.almintegration.form.name.bitbucket=Configuration name
+settings.almintegration.form.name.bitbucket.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Bitbucket instance for a project.
+settings.almintegration.form.name.github=Configuration name
+settings.almintegration.form.name.github.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitHub App for a project.
+settings.almintegration.form.name.gitlab=Configuration name
+settings.almintegration.form.name.gitlab.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitLab instance for a project.
+settings.almintegration.form.url.bitbucket=Bitbucket Server URL
+settings.almintegration.form.url.bitbucket.help=Example: {example}
+settings.almintegration.form.url.github=GitHub URL
+settings.almintegration.form.url.github.help1=Example for Github Enterprise:
+settings.almintegration.form.url.github.help2=If using GitHub.com:
+settings.almintegration.form.app_id=GitHub App ID
+settings.almintegration.form.private_key=Private Key
+settings.almintegration.form.personal_access_token=Personal Access token
+settings.almintegration.form.personal_access_token.azure.help=Token of the user that will be used to decorate the Pull Requests. Needs authorized scope: "Code (read and write)".
+settings.almintegration.form.personal_access_token.gitlab.help=Token of the user that will be used to decorate the Merge Requests. Needs API scope authorization.
+settings.almintegration.form.save=Save configuration
+settings.almintegration.form.cancel=Cancel
+settings.almintegration.features=ALM integration features
+settings.almintegration.feature.enabled=This feature is enabled
+settings.almintegration.feature.disabled=This feature is currently disabled
+settings.almintegration.feature.need_at_least_1_binding=You need to have at least 1 binding configured to use this feature
+settings.almintegration.feature.pr_decoration.title=Pull Request Decoration
+settings.almintegration.feature.pr_decoration.description=Add analysis and a Quality Gate to your Pull Requests directly in your ALM provider's interface.
+settings.almintegration.feature.mr_decoration.title=Merge Request Decoration
+settings.almintegration.feature.mr_decoration.description=Add analysis and a Quality Gate to your Merge Requests directly in your ALM provider's interface.
+settings.almintegration.feature.alm_repo_import.title=Import repositories from your ALM
+settings.almintegration.feature.alm_repo_import.description=Select repositories from your ALM, and import them into SonarQube.
+settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances=Connecting to multiple Bitbucket Server instances will deactivate the {feature} feature. Projects will have to be set up manually.
settings.pr_decoration.binding.category=Pull Request Decoration
settings.pr_decoration.binding.no_bindings=This feature must first be enabled in the global settings. {link}
@@ -1088,13 +1097,14 @@ property.category.general.databaseCleaner=Database Cleaner
property.category.general.looknfeel=Look & Feel
property.category.general.issues=Issues
property.category.general.subProjects=Sub-projects
+property.category.almintegration=ALM Integrations
+property.category.almintegration.github=GitHub Authentication
+property.category.almintegration.github.description=In order to enable authentication on GitHub.com or GitHub Enterprise:<ul><li>SonarQube must be publicly accessible through HTTPS only</li><li>The property 'sonar.core.serverBaseURL' must be set to this public HTTPS URL</li><li>In your GitHub profile, you need to create a Developer Application for which the 'Authorization callback URL' must be set to <code>'&lt;value_of_sonar.core.serverBaseURL_property&gt;/oauth2/callback'</code>.</li></ul>
+property.category.almintegration.gitlab=GitLab Authentication
+property.category.almintegration.gitlab.description=In order to enable GitLab authentication, the property 'sonar.core.serverBaseURL' must be set to the public URL
property.category.organizations=Organizations
property.category.security=Security
property.category.security.encryption=Encryption
-property.category.security.github=GitHub
-property.category.security.github.description=In order to enable authentication on GitHub.com or GitHub Enterprise:<ul><li>SonarQube must be publicly accessible through HTTPS only</li><li>The property 'sonar.core.serverBaseURL' must be set to this public HTTPS URL</li><li>In your GitHub profile, you need to create a Developer Application for which the 'Authorization callback URL' must be set to <code>'&lt;value_of_sonar.core.serverBaseURL_property&gt;/oauth2/callback'</code>.</li></ul>
-property.category.security.gitlab=Gitlab
-property.category.security.gitlab.description=In order to enable Gitlab authentication, the property 'sonar.core.serverBaseURL' must be set to the public URL
property.category.security.saml=SAML
property.category.security.saml.description=In order to enable SAML authentication, the property 'sonar.core.serverBaseURL' must be set to the public URL
property.category.java=Java
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
index e409ccad25e..e670edbce3f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
@@ -57,6 +57,11 @@ public interface CoreProperties {
String SUBCATEGORY_DUPLICATIONS = "duplications";
/**
+ * @since 8.2
+ */
+ String CATEGORY_ALM_INTEGRATION = "almintegration";
+
+ /**
* @since 8.1
*/
String CATEGORY_HOUSEKEEPING = "housekeeping";