+
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/DoneNextSteps.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/DoneNextSteps.tsx
new file mode 100644
index 00000000000..729bd9cbfb7
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/DoneNextSteps.tsx
@@ -0,0 +1,115 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { translate } from 'sonar-ui-common/helpers/l10n';
+import { PULL_REQUEST_DECORATION_BINDING_CATEGORY } from '../../../apps/settings/components/AdditionalCategoryKeys';
+import { getProjectSettingsUrl } from '../../../helpers/urls';
+
+export interface DoneNextStepsProps {
+ component: T.Component;
+}
+
+export default function DoneNextSteps({ component }: DoneNextStepsProps) {
+ const tutorialsLink = (
+
+ {translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.see_tutorials'
+ )}
+
+ );
+ const isProjectAdmin = component.configuration?.showSettings;
+
+ return (
+ <>
+
+
+
+ >
+ );
+}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/__tests__/DoneNextSteps-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/__tests__/DoneNextSteps-test.tsx
new file mode 100644
index 00000000000..9c391389bd5
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/__tests__/DoneNextSteps-test.tsx
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { mockComponent } from '../../../../helpers/testMocks';
+import DoneNextSteps, { DoneNextStepsProps } from '../DoneNextSteps';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(
+ shallowRender({ component: mockComponent({ configuration: { showSettings: true } }) })
+ ).toMatchSnapshot('project admin');
+});
+
+function shallowRender(props: Partial = {}) {
+ return shallow();
+}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/__tests__/__snapshots__/DoneNextSteps-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/__tests__/__snapshots__/DoneNextSteps-test.tsx.snap
new file mode 100644
index 00000000000..0b6489a943d
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/__tests__/__snapshots__/DoneNextSteps-test.tsx.snap
@@ -0,0 +1,158 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: default 1`] = `
+
+
+
+
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/Other-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/Other-test.tsx.snap
index 2d3b3086434..bea3152d2d9 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/Other-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/Other-test.tsx.snap
@@ -6,9 +6,30 @@ exports[`renders correctly 1`] = `
os="linux"
/>
diff --git a/server/sonar-web/src/main/js/components/tutorials/types.ts b/server/sonar-web/src/main/js/components/tutorials/types.ts
index 364d8886ab5..cd79f043667 100644
--- a/server/sonar-web/src/main/js/components/tutorials/types.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/types.ts
@@ -23,7 +23,8 @@ export enum TutorialModes {
BitbucketPipelines = 'bitbucket-pipelines',
GitLabCI = 'gitlab-ci',
GitHubActions = 'github-actions',
- AzurePipelines = 'azure-pipelines'
+ AzurePipelines = 'azure-pipelines',
+ OtherCI = 'other-ci'
}
export enum BuildTools {
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/urls-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/urls-test.ts
index bed9b1df8fb..de610e43f4e 100644
--- a/server/sonar-web/src/main/js/helpers/__tests__/urls-test.ts
+++ b/server/sonar-web/src/main/js/helpers/__tests__/urls-test.ts
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { AlmKeys } from '../../types/alm-settings';
import { ComponentQualifier } from '../../types/component';
import { IssueType } from '../../types/issues';
import {
@@ -25,7 +26,9 @@ import {
getComponentIssuesUrl,
getComponentOverviewUrl,
getComponentSecurityHotspotsUrl,
+ getGlobalSettingsUrl,
getIssuesUrl,
+ getProjectSettingsUrl,
getQualityGatesUrl,
getQualityGateUrl,
stripTrailingSlash
@@ -67,7 +70,7 @@ describe('#getComponentIssuesUrl', () => {
});
});
-describe('getComponentSecurityHotspotsUrl', () => {
+describe('#getComponentSecurityHotspotsUrl', () => {
it('should work with no extra parameters', () => {
expect(getComponentSecurityHotspotsUrl(SIMPLE_COMPONENT_KEY, {})).toEqual({
pathname: '/security_hotspots',
@@ -88,7 +91,7 @@ describe('getComponentSecurityHotspotsUrl', () => {
});
});
-describe('getComponentOverviewUrl', () => {
+describe('#getComponentOverviewUrl', () => {
it('should return a portfolio url for a portfolio', () => {
expect(getComponentOverviewUrl(SIMPLE_COMPONENT_KEY, ComponentQualifier.Portfolio)).toEqual({
pathname: '/portfolio',
@@ -142,7 +145,7 @@ describe('#getQualityGate(s)Url', () => {
});
});
-describe('getIssuesUrl', () => {
+describe('#getIssuesUrl', () => {
it('should work as expected', () => {
const type = IssueType.Bug;
expect(getIssuesUrl({ type })).toEqual({
@@ -151,3 +154,29 @@ describe('getIssuesUrl', () => {
});
});
});
+
+describe('#getGlobalSettingsUrl', () => {
+ it('should work as expected', () => {
+ expect(getGlobalSettingsUrl('foo')).toEqual({
+ pathname: '/admin/settings',
+ query: { category: 'foo' }
+ });
+ expect(getGlobalSettingsUrl('foo', { alm: AlmKeys.GitHub })).toEqual({
+ pathname: '/admin/settings',
+ query: { category: 'foo', alm: AlmKeys.GitHub }
+ });
+ });
+});
+
+describe('#getProjectSettingsUrl', () => {
+ it('should work as expected', () => {
+ expect(getProjectSettingsUrl('foo')).toEqual({
+ pathname: '/project/settings',
+ query: { id: 'foo' }
+ });
+ expect(getProjectSettingsUrl('foo', 'bar')).toEqual({
+ pathname: '/project/settings',
+ query: { id: 'foo', category: 'bar' }
+ });
+ });
+});
diff --git a/server/sonar-web/src/main/js/helpers/urls.ts b/server/sonar-web/src/main/js/helpers/urls.ts
index 1adb6ee8ec6..992c0f76a90 100644
--- a/server/sonar-web/src/main/js/helpers/urls.ts
+++ b/server/sonar-web/src/main/js/helpers/urls.ts
@@ -221,6 +221,23 @@ export function getQualityGatesUrl(): Location {
};
}
+export function getGlobalSettingsUrl(
+ category?: string,
+ query?: T.Dict
+): Location {
+ return {
+ pathname: '/admin/settings',
+ query: { category, ...query }
+ };
+}
+
+export function getProjectSettingsUrl(id: string, category?: string): Location {
+ return {
+ pathname: '/project/settings',
+ query: { id, category }
+ };
+}
+
/**
* Generate URL for the rules page
*/
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 8653a010414..496f4b491c4 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -3366,7 +3366,15 @@ onboarding.tutorial.env_variables.field=Value
onboarding.tutorial.env_variables.token_generator.value=an existing token, or a newly generated one:
onboarding.analysis.header=Run analysis on your project
-onboarding.analysis.auto_refresh_after_analysis=Once the analysis is completed, this page will automatically refresh and you will be able to browse the analysis results.
+onboarding.analysis.auto_refresh_after_analysis.done=Is my analysis done?
+onboarding.analysis.auto_refresh_after_analysis.auto_refresh=If your analysis is successful, this page will automatically refresh in a few moments.
+onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.admin=You can set up Pull Request Decoration under the {link_project_settings}. To set up analysis with your favorite CI tool, {link_see_tutorials}.
+onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci=You can request from a project administrator to set up Pull Request Decoration. To set up analysis with your favorite CI tool, {link_see_tutorials}.
+onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.project_settings=project settings
+onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.see_tutorials=see the tutorials
+onboarding.analysis.auto_refresh_after_analysis.check_these_links=Check these useful links while you wait: {link_branches}, {link_pr_analysis}.
+onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis=Pull Request Analysis
+onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches=Branch Analysis
onboarding.build=What option best describes your build?
onboarding.build.maven=Maven
@@ -3400,7 +3408,7 @@ onboarding.analysis.build_wrapper.docs=Please visit the {link} of the Build Wra
onboarding.analysis.build_wrapper.docs_link=official documentation
-onboarding.analysis.java.maven.header=Execute the Scanner for Maven from your computer
+onboarding.analysis.java.maven.header=Execute the Scanner for Maven
onboarding.analysis.java.maven.header.ci=Execute the Scanner for Maven from your CI
onboarding.analysis.java.maven.text=Running a {instance} analysis with Maven is straighforward. You just need to run the following command in your project's folder.
onboarding.analysis.java.maven.docs_link=official documentation of the Scanner for Maven
@@ -3409,7 +3417,7 @@ onboarding.analysis.java.maven.text.custom.ci=Run the following command in the p
onboarding.analysis.java.maven.header.sonarcloud=Execute the Scanner for Maven from Travis
onboarding.analysis.java.maven.text.sonarcloud=Add the following lines to your .travis.yml file:
-onboarding.analysis.java.gradle.header=Execute the Scanner for Gradle from your computer
+onboarding.analysis.java.gradle.header=Execute the Scanner for Gradle
onboarding.analysis.java.gradle.header.ci=Execute the Scanner for Gradle from your CI
onboarding.analysis.java.gradle.text.1=Running an analysis with Gradle is straighforward. You just need to declare the {plugin_code} plugin in your {filename} file:
onboarding.analysis.java.gradle.text.2=and run the following command:
@@ -3421,7 +3429,7 @@ onboarding.analysis.java.gradle.text.2.sonarcloud=and add the following lines to
onboarding.analysis.msbuild.header=Download and unzip the Scanner for .NET
onboarding.analysis.msbuild.text=Visit the {link} to download the latest version, and add the executable's directory to the {code} environment variable
-onboarding.analysis.msbuild.execute=Execute the Scanner for .NET from your computer
+onboarding.analysis.msbuild.execute=Execute the Scanner for .NET
onboarding.analysis.msbuild.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands at the root of your solution.
onboarding.analysis.msbuild.docs_link=official documentation of the Scanner for .NET
@@ -3429,7 +3437,7 @@ onboarding.analysis.sq_scanner.header.linux=Download and unzip the Scanner for L
onboarding.analysis.sq_scanner.header.win=Download and unzip the Scanner for Windows
onboarding.analysis.sq_scanner.header.mac=Download and unzip the Scanner for macOS
onboarding.analysis.sq_scanner.text=Visit the {link} to download the latest version, and add the {dir} directory to the {env_var} environment variable
-onboarding.analysis.sq_scanner.execute=Execute the Scanner from your computer
+onboarding.analysis.sq_scanner.execute=Execute the Scanner
onboarding.analysis.sq_scanner.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands in your project's folder.
onboarding.analysis.sq_scanner.execute.text.custom=Run the following commands in your project's folder.
onboarding.analysis.sq_scanner.docs=Please visit the {link} for more details.
@@ -3453,12 +3461,13 @@ onboarding.tutorial.ci_outro.refresh.why=If the page doesn't refresh after a whi
onboarding.tutorial.other.project_key.sentence=Create a {file} file in your repository and paste the following code:
onboarding.tutorial.choose_method=How do you want to analyze your repository?
-onboarding.tutorial.choose_method.manual=Manually
+onboarding.tutorial.choose_method.manual=Locally
+onboarding.tutorial.choose_method.other-ci=Other CI
onboarding.tutorial.choose_method.jenkins=With Jenkins
-onboarding.tutorial.choose_method.github_action=With GitHub Actions
-onboarding.tutorial.choose_method.gitlab_ci=With GitLab CI
-onboarding.tutorial.choose_method.azure_pipelines=With Azure Pipelines
-onboarding.tutorial.choose_method.bitbucket_pipelines=With Bitbucket Pipelines
+onboarding.tutorial.choose_method.github-actions=With GitHub Actions
+onboarding.tutorial.choose_method.gitlab-ci=With GitLab CI
+onboarding.tutorial.choose_method.azure-pipelines=With Azure Pipelines
+onboarding.tutorial.choose_method.bitbucket-pipelines=With Bitbucket Pipelines
onboarding.tutorial.with.yaml.maven.pom=Update your {pom} file with the following properties: