aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2021-06-15 09:43:43 +0200
committersonartech <sonartech@sonarsource.com>2021-06-17 20:03:07 +0000
commitdee4f363b8bdebe59126a5464e1ebc4fc3202932 (patch)
treefbe1296dd813a2db3f232cf199755bab0980d887 /server
parentcf6800f19682deb0450bcd2269910cf3e1fb2bdb (diff)
downloadsonarqube-dee4f363b8bdebe59126a5464e1ebc4fc3202932.tar.gz
sonarqube-dee4f363b8bdebe59126a5464e1ebc4fc3202932.zip
SONAR-14934 Improve the manual tutorial
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNavProjectBindingErrorNotif.tsx7
-rw-r--r--server/sonar-web/src/main/js/app/styles/init/type.css4
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/WrongBindingCountAlert.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx39
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap24
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx10
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx135
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx10
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap170
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/DoneNextSteps.tsx115
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/__tests__/DoneNextSteps-test.tsx35
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/__tests__/__snapshots__/DoneNextSteps-test.tsx.snap158
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/AnalysisCommand.tsx11
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/ClangGCCCommand.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNet.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetCore.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetExecute.tsx5
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetFramework.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/ExecScanner.tsx11
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaGradle.tsx11
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaMaven.tsx11
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/Other.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/CLangGCCCommand-test.tsx12
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNet-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetExecute-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetFramework-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotnetCore-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/ExecScanner-test.tsx13
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaGradle-test.tsx5
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaMaven-test.tsx5
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/Other-test.tsx9
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap115
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/CLangGCCCommand-test.tsx.snap25
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNet-test.tsx.snap25
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetExecute-test.tsx.snap26
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetFramework-test.tsx.snap24
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotnetCore-test.tsx.snap24
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/ExecScanner-test.tsx.snap124
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap29
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap29
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/Other-test.tsx.snap23
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/types.ts3
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/urls-test.ts35
-rw-r--r--server/sonar-web/src/main/js/helpers/urls.ts17
44 files changed, 1102 insertions, 260 deletions
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavProjectBindingErrorNotif.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavProjectBindingErrorNotif.tsx
index e420188b893..0308b9ede48 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavProjectBindingErrorNotif.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavProjectBindingErrorNotif.tsx
@@ -23,6 +23,7 @@ import { Link } from 'react-router';
import { Alert } from 'sonar-ui-common/components/ui/Alert';
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 ComponentNavProjectBindingErrorNotifProps {
component: T.Component;
@@ -36,11 +37,7 @@ export function ComponentNavProjectBindingErrorNotif(
if (component.configuration?.showSettings) {
action = (
- <Link
- to={{
- pathname: '/project/settings',
- query: { category: PULL_REQUEST_DECORATION_BINDING_CATEGORY, id: component.key }
- }}>
+ <Link to={getProjectSettingsUrl(component.key, PULL_REQUEST_DECORATION_BINDING_CATEGORY)}>
{translate('component_navigation.pr_deco.action.check_project_settings')}
</Link>
);
diff --git a/server/sonar-web/src/main/js/app/styles/init/type.css b/server/sonar-web/src/main/js/app/styles/init/type.css
index b03a9fcd4df..0ce0bb1a647 100644
--- a/server/sonar-web/src/main/js/app/styles/init/type.css
+++ b/server/sonar-web/src/main/js/app/styles/init/type.css
@@ -179,6 +179,10 @@ small,
font-size: var(--hugeFontSize);
}
+.gigantic {
+ font-size: var(--giganticFontSize);
+}
+
.zero-font-size {
font-size: 0 !important;
}
diff --git a/server/sonar-web/src/main/js/apps/create/project/WrongBindingCountAlert.tsx b/server/sonar-web/src/main/js/apps/create/project/WrongBindingCountAlert.tsx
index 52ff4f36c77..670a81e7d42 100644
--- a/server/sonar-web/src/main/js/apps/create/project/WrongBindingCountAlert.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/WrongBindingCountAlert.tsx
@@ -22,6 +22,7 @@ import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router';
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getGlobalSettingsUrl } from '../../../helpers/urls';
import { AlmKeys } from '../../../types/alm-settings';
import { ALM_INTEGRATION } from '../../settings/components/AdditionalCategoryKeys';
@@ -42,13 +43,7 @@ export default function WrongBindingCountAlert(props: WrongBindingCountAlertProp
values={{
alm: translate('onboarding.alm', alm),
url: (
- <Link
- to={{
- pathname: '/admin/settings',
- query: { category: ALM_INTEGRATION }
- }}>
- {translate('settings.page')}
- </Link>
+ <Link to={getGlobalSettingsUrl(ALM_INTEGRATION)}>{translate('settings.page')}</Link>
)
}}
/>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx
index b3044c5f82e..00d96a02c90 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx
@@ -22,6 +22,7 @@ import { sortBy } from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import { IndexLink } from 'react-router';
+import { getGlobalSettingsUrl, getProjectSettingsUrl } from '../../../helpers/urls';
import { getAppState, getSettingsAppAllCategories, Store } from '../../../store/rootReducer';
import { getCategoryName } from '../utils';
import { ADDITIONAL_CATEGORIES } from './AdditionalCategories';
@@ -37,7 +38,6 @@ export interface CategoriesListProps {
export function CategoriesList(props: CategoriesListProps) {
const { branchesEnabled, categories, component, defaultCategory, selectedCategory } = props;
- const pathname = component ? '/project/settings' : '/settings';
const categoriesWithName = categories
.filter(key => !CATEGORY_OVERRIDES[key.toLowerCase()])
@@ -60,24 +60,25 @@ export function CategoriesList(props: CategoriesListProps) {
return (
<ul className="side-tabs-menu">
- {sortedCategories.map(category => (
- <li key={category.key}>
- <IndexLink
- className={classNames({
- active: category.key.toLowerCase() === selectedCategory.toLowerCase()
- })}
- title={category.name}
- to={{
- pathname,
- query: {
- category: category.key !== defaultCategory ? category.key.toLowerCase() : undefined,
- id: component && component.key
- }
- }}>
- {category.name}
- </IndexLink>
- </li>
- ))}
+ {sortedCategories.map(c => {
+ const category = c.key !== defaultCategory ? c.key.toLowerCase() : undefined;
+ return (
+ <li key={c.key}>
+ <IndexLink
+ className={classNames({
+ active: c.key.toLowerCase() === selectedCategory.toLowerCase()
+ })}
+ title={c.name}
+ to={
+ component
+ ? getProjectSettingsUrl(component.key, category)
+ : getGlobalSettingsUrl(category)
+ }>
+ {c.name}
+ </IndexLink>
+ </li>
+ );
+ })}
</ul>
);
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap
index 161cb051782..bc199c6498d 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap
@@ -12,10 +12,9 @@ exports[`should render correctly: branches disabled 1`] = `
title="CAT_2_NAME"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": "cat_2",
- "id": undefined,
},
}
}
@@ -31,10 +30,9 @@ exports[`should render correctly: branches disabled 1`] = `
title="general"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": undefined,
- "id": undefined,
},
}
}
@@ -57,10 +55,9 @@ exports[`should render correctly: global mode 1`] = `
title="CAT_1_NAME"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": "cat_1",
- "id": undefined,
},
}
}
@@ -76,10 +73,9 @@ exports[`should render correctly: global mode 1`] = `
title="CAT_2_NAME"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": "cat_2",
- "id": undefined,
},
}
}
@@ -95,10 +91,9 @@ exports[`should render correctly: global mode 1`] = `
title="general"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": undefined,
- "id": undefined,
},
}
}
@@ -185,10 +180,9 @@ exports[`should render correctly: selected category 1`] = `
title="CAT_1_NAME"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": "cat_1",
- "id": undefined,
},
}
}
@@ -204,10 +198,9 @@ exports[`should render correctly: selected category 1`] = `
title="CAT_2_NAME"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": "cat_2",
- "id": undefined,
},
}
}
@@ -223,10 +216,9 @@ exports[`should render correctly: selected category 1`] = `
title="general"
to={
Object {
- "pathname": "/settings",
+ "pathname": "/admin/settings",
"query": Object {
"category": undefined,
- "id": undefined,
},
}
}
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 92aba7659fa..84567b02dbc 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
@@ -28,6 +28,7 @@ import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import MandatoryFieldMarker from 'sonar-ui-common/components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from 'sonar-ui-common/components/ui/MandatoryFieldsExplanation';
import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getGlobalSettingsUrl } from '../../../../helpers/urls';
import {
AlmSettingsInstance,
ProjectAlmBindingConfigurationErrors,
@@ -216,14 +217,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe
)}
values={{
link: (
- <Link
- to={{
- pathname: '/admin/settings',
- query: {
- category: ALM_INTEGRATION,
- alm
- }
- }}>
+ <Link to={getGlobalSettingsUrl(ALM_INTEGRATION, { alm })}>
{translate(
'settings.pr_decoration.binding.check_configuration.failure.check_global_settings.link'
)}
diff --git a/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx b/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx
index b0c4eeacdfc..5d0847a1b69 100644
--- a/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx
@@ -40,6 +40,29 @@ export interface TutorialSelectionRendererProps {
selectedTutorial?: TutorialModes;
}
+const DEFAULT_ICON_SIZE = 80;
+const GH_ACTION_ICON_SIZE = 64;
+
+function renderButton(
+ mode: TutorialModes,
+ onSelectTutorial: (mode: TutorialModes) => void,
+ icon: React.ReactNode
+) {
+ return (
+ <button
+ className={`button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-${mode}`}
+ // Currently, OtherCI is the same tutorial as Manual. We might update it to its own stand-alone
+ // tutorial in the future.
+ onClick={() => onSelectTutorial(mode === TutorialModes.OtherCI ? TutorialModes.Manual : mode)}
+ type="button">
+ {icon}
+ <div className="medium big-spacer-top">
+ {translate('onboarding.tutorial.choose_method', mode)}
+ </div>
+ </button>
+ );
+}
+
export default function TutorialSelectionRenderer(props: TutorialSelectionRendererProps) {
const {
almBinding,
@@ -84,100 +107,82 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender
</h1>
</header>
- <div className="display-flex-justify-center">
- <button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-manual"
- onClick={() => props.onSelectTutorial(TutorialModes.Manual)}
- type="button">
+ <div className="display-flex-justify-center display-flex-wrap">
+ {renderButton(
+ TutorialModes.Manual,
+ props.onSelectTutorial,
<img
alt="" // Should be ignored by screen readers
- height={80}
+ height={DEFAULT_ICON_SIZE}
src={`${getBaseUrl()}/images/tutorials/manual.svg`}
/>
- <div className="medium big-spacer-top">
- {translate('onboarding.tutorial.choose_method.manual')}
- </div>
- </button>
-
- {showAzurePipelines && (
- <button
- className="button button-huge display-flex-column spacer-left spacer-right azure-pipelines"
- onClick={() => props.onSelectTutorial(TutorialModes.AzurePipelines)}
- type="button">
+ )}
+
+ {showAzurePipelines &&
+ renderButton(
+ TutorialModes.AzurePipelines,
+ props.onSelectTutorial,
<img
alt="" // Should be ignored by screen readers
- height={80}
+ height={DEFAULT_ICON_SIZE}
src={`${getBaseUrl()}/images/tutorials/azure-pipelines.svg`}
/>
- <div className="medium big-spacer-top">
- {translate('onboarding.tutorial.choose_method.azure_pipelines')}
- </div>
- </button>
- )}
+ )}
- {showBitbucketPipelines && (
- <button
- className="button button-huge display-flex-column spacer-left spacer-right bitbucket-pipelines"
- onClick={() => props.onSelectTutorial(TutorialModes.BitbucketPipelines)}
- type="button">
+ {showBitbucketPipelines &&
+ renderButton(
+ TutorialModes.BitbucketPipelines,
+ props.onSelectTutorial,
<img
alt="" // Should be ignored by screen readers
- height={80}
+ height={DEFAULT_ICON_SIZE}
src={`${getBaseUrl()}/images/alm/bitbucket.svg`}
/>
- <div className="medium big-spacer-top">
- {translate('onboarding.tutorial.choose_method.bitbucket_pipelines')}
- </div>
- </button>
- )}
+ )}
- {showGitHubActions && (
- <button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-github"
- onClick={() => props.onSelectTutorial(TutorialModes.GitHubActions)}
- type="button">
+ {showGitHubActions &&
+ renderButton(
+ TutorialModes.GitHubActions,
+ props.onSelectTutorial,
<img
alt="" // Should be ignored by screen readers
- height={64}
+ height={GH_ACTION_ICON_SIZE}
className="spacer-bottom spacer-top"
src={`${getBaseUrl()}/images/tutorials/github-actions.svg`}
/>
- <div className="medium big-spacer-top">
- {translate('onboarding.tutorial.choose_method.github_action')}
- </div>
- </button>
- )}
+ )}
- {showGitLabCICD && (
- <button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-gitlab"
- onClick={() => props.onSelectTutorial(TutorialModes.GitLabCI)}
- type="button">
+ {showGitLabCICD &&
+ renderButton(
+ TutorialModes.GitLabCI,
+ props.onSelectTutorial,
<img
alt="" // Should be ignored by screen readers
- height={80}
+ height={DEFAULT_ICON_SIZE}
src={`${getBaseUrl()}/images/alm/gitlab.svg`}
/>
- <div className="medium big-spacer-top">
- {translate('onboarding.tutorial.choose_method.gitlab_ci')}
- </div>
- </button>
- )}
+ )}
- {showJenkins && (
- <button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-jenkins"
- onClick={() => props.onSelectTutorial(TutorialModes.Jenkins)}
- type="button">
+ {showJenkins &&
+ renderButton(
+ TutorialModes.Jenkins,
+ props.onSelectTutorial,
<img
alt="" // Should be ignored by screen readers
- height={80}
+ height={DEFAULT_ICON_SIZE}
src={`${getBaseUrl()}/images/tutorials/jenkins.svg`}
/>
- <div className="medium big-spacer-top">
- {translate('onboarding.tutorial.choose_method.jenkins')}
- </div>
- </button>
+ )}
+
+ {renderButton(
+ TutorialModes.OtherCI,
+ props.onSelectTutorial,
+ <span
+ aria-disabled={true}
+ className="display-flex-center gigantic"
+ style={{ height: DEFAULT_ICON_SIZE }}>
+ &hellip;
+ </span>
)}
</div>
</div>
diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx
index 74460e6a4a4..70c2829493a 100644
--- a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx
@@ -102,10 +102,10 @@ it('should allow mode selection for Github', () => {
click(wrapper.find('button.tutorial-mode-manual'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Manual);
- click(wrapper.find('button.tutorial-mode-github'));
+ click(wrapper.find('button.tutorial-mode-github-actions'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.GitHubActions);
- click(wrapper.find('button.azure-pipelines'));
+ click(wrapper.find('button.tutorial-mode-azure-pipelines'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.AzurePipelines);
});
@@ -119,7 +119,7 @@ it('should allow mode selection for GitLab', () => {
click(wrapper.find('button.tutorial-mode-jenkins'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins);
- click(wrapper.find('button.tutorial-mode-gitlab'));
+ click(wrapper.find('button.tutorial-mode-gitlab-ci'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.GitLabCI);
click(wrapper.find('button.tutorial-mode-manual'));
@@ -136,7 +136,7 @@ it('should allow mode selection for Bitbucket pipepline', () => {
click(wrapper.find('button.tutorial-mode-jenkins'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins);
- click(wrapper.find('button.bitbucket-pipelines'));
+ click(wrapper.find('button.tutorial-mode-bitbucket-pipelines'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.BitbucketPipelines);
click(wrapper.find('button.tutorial-mode-manual'));
@@ -150,7 +150,7 @@ it('should allow mode selection for Azure DevOps', () => {
projectBinding: mockProjectAzureBindingResponse()
});
- click(wrapper.find('button.azure-pipelines'));
+ click(wrapper.find('button.tutorial-mode-azure-pipelines'));
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.AzurePipelines);
click(wrapper.find('button.tutorial-mode-manual'));
diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap
index 5fe73834477..0422dc2c2ae 100644
--- a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap
@@ -15,10 +15,10 @@ exports[`should render correctly for azure 1`] = `
</h1>
</header>
<div
- className="display-flex-justify-center"
+ className="display-flex-justify-center display-flex-wrap"
>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-manual"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-manual"
onClick={[Function]}
type="button"
>
@@ -34,7 +34,7 @@ exports[`should render correctly for azure 1`] = `
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right azure-pipelines"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-azure-pipelines"
onClick={[Function]}
type="button"
>
@@ -46,7 +46,29 @@ exports[`should render correctly for azure 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.azure_pipelines
+ onboarding.tutorial.choose_method.azure-pipelines
+ </div>
+ </button>
+ <button
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-other-ci"
+ onClick={[Function]}
+ type="button"
+ >
+ <span
+ aria-disabled={true}
+ className="display-flex-center gigantic"
+ style={
+ Object {
+ "height": 80,
+ }
+ }
+ >
+ …
+ </span>
+ <div
+ className="medium big-spacer-top"
+ >
+ onboarding.tutorial.choose_method.other-ci
</div>
</button>
</div>
@@ -69,10 +91,10 @@ exports[`should render correctly for bitbucket server 1`] = `
</h1>
</header>
<div
- className="display-flex-justify-center"
+ className="display-flex-justify-center display-flex-wrap"
>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-manual"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-manual"
onClick={[Function]}
type="button"
>
@@ -88,7 +110,7 @@ exports[`should render correctly for bitbucket server 1`] = `
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-jenkins"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-jenkins"
onClick={[Function]}
type="button"
>
@@ -103,6 +125,28 @@ exports[`should render correctly for bitbucket server 1`] = `
onboarding.tutorial.choose_method.jenkins
</div>
</button>
+ <button
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-other-ci"
+ onClick={[Function]}
+ type="button"
+ >
+ <span
+ aria-disabled={true}
+ className="display-flex-center gigantic"
+ style={
+ Object {
+ "height": 80,
+ }
+ }
+ >
+ …
+ </span>
+ <div
+ className="medium big-spacer-top"
+ >
+ onboarding.tutorial.choose_method.other-ci
+ </div>
+ </button>
</div>
</div>
</Fragment>
@@ -123,10 +167,10 @@ exports[`should render correctly for github 1`] = `
</h1>
</header>
<div
- className="display-flex-justify-center"
+ className="display-flex-justify-center display-flex-wrap"
>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-manual"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-manual"
onClick={[Function]}
type="button"
>
@@ -142,7 +186,7 @@ exports[`should render correctly for github 1`] = `
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right azure-pipelines"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-azure-pipelines"
onClick={[Function]}
type="button"
>
@@ -154,11 +198,11 @@ exports[`should render correctly for github 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.azure_pipelines
+ onboarding.tutorial.choose_method.azure-pipelines
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-github"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-github-actions"
onClick={[Function]}
type="button"
>
@@ -171,11 +215,11 @@ exports[`should render correctly for github 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.github_action
+ onboarding.tutorial.choose_method.github-actions
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-jenkins"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-jenkins"
onClick={[Function]}
type="button"
>
@@ -190,6 +234,28 @@ exports[`should render correctly for github 1`] = `
onboarding.tutorial.choose_method.jenkins
</div>
</button>
+ <button
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-other-ci"
+ onClick={[Function]}
+ type="button"
+ >
+ <span
+ aria-disabled={true}
+ className="display-flex-center gigantic"
+ style={
+ Object {
+ "height": 80,
+ }
+ }
+ >
+ …
+ </span>
+ <div
+ className="medium big-spacer-top"
+ >
+ onboarding.tutorial.choose_method.other-ci
+ </div>
+ </button>
</div>
</div>
</Fragment>
@@ -210,10 +276,10 @@ exports[`should render correctly for gitlab 1`] = `
</h1>
</header>
<div
- className="display-flex-justify-center"
+ className="display-flex-justify-center display-flex-wrap"
>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-manual"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-manual"
onClick={[Function]}
type="button"
>
@@ -229,7 +295,7 @@ exports[`should render correctly for gitlab 1`] = `
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-gitlab"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-gitlab-ci"
onClick={[Function]}
type="button"
>
@@ -241,11 +307,11 @@ exports[`should render correctly for gitlab 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.gitlab_ci
+ onboarding.tutorial.choose_method.gitlab-ci
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-jenkins"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-jenkins"
onClick={[Function]}
type="button"
>
@@ -260,6 +326,28 @@ exports[`should render correctly for gitlab 1`] = `
onboarding.tutorial.choose_method.jenkins
</div>
</button>
+ <button
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-other-ci"
+ onClick={[Function]}
+ type="button"
+ >
+ <span
+ aria-disabled={true}
+ className="display-flex-center gigantic"
+ style={
+ Object {
+ "height": 80,
+ }
+ }
+ >
+ …
+ </span>
+ <div
+ className="medium big-spacer-top"
+ >
+ onboarding.tutorial.choose_method.other-ci
+ </div>
+ </button>
</div>
</div>
</Fragment>
@@ -499,10 +587,10 @@ exports[`should render correctly: selection 1`] = `
</h1>
</header>
<div
- className="display-flex-justify-center"
+ className="display-flex-justify-center display-flex-wrap"
>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-manual"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-manual"
onClick={[Function]}
type="button"
>
@@ -518,7 +606,7 @@ exports[`should render correctly: selection 1`] = `
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right azure-pipelines"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-azure-pipelines"
onClick={[Function]}
type="button"
>
@@ -530,11 +618,11 @@ exports[`should render correctly: selection 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.azure_pipelines
+ onboarding.tutorial.choose_method.azure-pipelines
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right bitbucket-pipelines"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-bitbucket-pipelines"
onClick={[Function]}
type="button"
>
@@ -546,11 +634,11 @@ exports[`should render correctly: selection 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.bitbucket_pipelines
+ onboarding.tutorial.choose_method.bitbucket-pipelines
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-github"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-github-actions"
onClick={[Function]}
type="button"
>
@@ -563,11 +651,11 @@ exports[`should render correctly: selection 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.github_action
+ onboarding.tutorial.choose_method.github-actions
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-gitlab"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-gitlab-ci"
onClick={[Function]}
type="button"
>
@@ -579,11 +667,11 @@ exports[`should render correctly: selection 1`] = `
<div
className="medium big-spacer-top"
>
- onboarding.tutorial.choose_method.gitlab_ci
+ onboarding.tutorial.choose_method.gitlab-ci
</div>
</button>
<button
- className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-jenkins"
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-jenkins"
onClick={[Function]}
type="button"
>
@@ -598,6 +686,28 @@ exports[`should render correctly: selection 1`] = `
onboarding.tutorial.choose_method.jenkins
</div>
</button>
+ <button
+ className="button button-huge display-flex-column spacer-left spacer-right huge-spacer-bottom tutorial-mode-other-ci"
+ onClick={[Function]}
+ type="button"
+ >
+ <span
+ aria-disabled={true}
+ className="display-flex-center gigantic"
+ style={
+ Object {
+ "height": 80,
+ }
+ }
+ >
+ …
+ </span>
+ <div
+ className="medium big-spacer-top"
+ >
+ onboarding.tutorial.choose_method.other-ci
+ </div>
+ </button>
</div>
</div>
</Fragment>
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 = (
+ <Link to={{ pathname: '/tutorials', query: { id: component.key } }}>
+ {translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.see_tutorials'
+ )}
+ </Link>
+ );
+ const isProjectAdmin = component.configuration?.showSettings;
+
+ return (
+ <>
+ <hr className="big-spacer-top big-spacer-bottom" />
+
+ <p>
+ <strong>{translate('onboarding.analysis.auto_refresh_after_analysis.done')}</strong>{' '}
+ {translate('onboarding.analysis.auto_refresh_after_analysis.auto_refresh')}
+ </p>
+ <p className="big-spacer-top">
+ {isProjectAdmin ? (
+ <FormattedMessage
+ defaultMessage={translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.admin'
+ )}
+ id="onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.admin"
+ values={{
+ link_project_settings: (
+ <Link
+ to={getProjectSettingsUrl(
+ component.key,
+ PULL_REQUEST_DECORATION_BINDING_CATEGORY
+ )}>
+ {translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.project_settings'
+ )}
+ </Link>
+ ),
+ link_see_tutorials: tutorialsLink
+ }}
+ />
+ ) : (
+ <FormattedMessage
+ defaultMessage={translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci'
+ )}
+ id="onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci"
+ values={{
+ link_see_tutorials: tutorialsLink
+ }}
+ />
+ )}
+ </p>
+ <p className="big-spacer-top">
+ <FormattedMessage
+ defaultMessage={translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.check_these_links'
+ )}
+ id="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
+ values={{
+ link_branches: (
+ <Link
+ to="/documentation/branches/overview/"
+ target="_blank"
+ rel="noopener noreferrer">
+ {translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches'
+ )}
+ </Link>
+ ),
+ link_pr_analysis: (
+ <Link
+ to="/documentation/analysis/pull-request/"
+ target="_blank"
+ rel="noopener noreferrer">
+ {translate(
+ 'onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis'
+ )}
+ </Link>
+ )
+ }}
+ />
+ </p>
+ </>
+ );
+}
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<DoneNextStepsProps> = {}) {
+ return shallow<DoneNextStepsProps>(<DoneNextSteps component={mockComponent()} {...props} />);
+}
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`] = `
+<Fragment>
+ <hr
+ className="big-spacer-top big-spacer-bottom"
+ />
+ <p>
+ <strong>
+ onboarding.analysis.auto_refresh_after_analysis.done
+ </strong>
+
+ onboarding.analysis.auto_refresh_after_analysis.auto_refresh
+ </p>
+ <p
+ className="big-spacer-top"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci"
+ id="onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci"
+ values={
+ Object {
+ "link_see_tutorials": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/tutorials",
+ "query": Object {
+ "id": "my-project",
+ },
+ }
+ }
+ >
+ onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.see_tutorials
+ </Link>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
+ id="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
+ values={
+ Object {
+ "link_branches": <Link
+ onlyActiveOnIndex={false}
+ rel="noopener noreferrer"
+ style={Object {}}
+ target="_blank"
+ to="/documentation/branches/overview/"
+ >
+ onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches
+ </Link>,
+ "link_pr_analysis": <Link
+ onlyActiveOnIndex={false}
+ rel="noopener noreferrer"
+ style={Object {}}
+ target="_blank"
+ to="/documentation/analysis/pull-request/"
+ >
+ onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis
+ </Link>,
+ }
+ }
+ />
+ </p>
+</Fragment>
+`;
+
+exports[`should render correctly: project admin 1`] = `
+<Fragment>
+ <hr
+ className="big-spacer-top big-spacer-bottom"
+ />
+ <p>
+ <strong>
+ onboarding.analysis.auto_refresh_after_analysis.done
+ </strong>
+
+ onboarding.analysis.auto_refresh_after_analysis.auto_refresh
+ </p>
+ <p
+ className="big-spacer-top"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.admin"
+ id="onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.admin"
+ values={
+ Object {
+ "link_project_settings": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/settings",
+ "query": Object {
+ "category": "pull_request_decoration_binding",
+ "id": "my-project",
+ },
+ }
+ }
+ >
+ onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.project_settings
+ </Link>,
+ "link_see_tutorials": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/tutorials",
+ "query": Object {
+ "id": "my-project",
+ },
+ }
+ }
+ >
+ onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.see_tutorials
+ </Link>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
+ id="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
+ values={
+ Object {
+ "link_branches": <Link
+ onlyActiveOnIndex={false}
+ rel="noopener noreferrer"
+ style={Object {}}
+ target="_blank"
+ to="/documentation/branches/overview/"
+ >
+ onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches
+ </Link>,
+ "link_pr_analysis": <Link
+ onlyActiveOnIndex={false}
+ rel="noopener noreferrer"
+ style={Object {}}
+ target="_blank"
+ to="/documentation/analysis/pull-request/"
+ >
+ onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis
+ </Link>,
+ }
+ }
+ />
+ </p>
+</Fragment>
+`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/AnalysisCommand.tsx
index e679a08c2fc..1cb28a011d1 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/AnalysisCommand.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/AnalysisCommand.tsx
@@ -40,26 +40,25 @@ export default function AnalysisCommand(props: AnalysisCommandProps) {
}
const host = getHostUrl();
- const projectKey = component.key;
switch (languageConfig.buildTool) {
case BuildTools.Maven:
- return <JavaMaven host={host} projectKey={projectKey} token={token} />;
+ return <JavaMaven host={host} component={component} token={token} />;
case BuildTools.Gradle:
- return <JavaGradle host={host} projectKey={projectKey} token={token} />;
+ return <JavaGradle host={host} component={component} token={token} />;
case BuildTools.DotNet:
- return <DotNet host={host} projectKey={projectKey} token={token} />;
+ return <DotNet host={host} component={component} token={token} />;
case BuildTools.CFamily:
return languageConfig.os !== undefined ? (
- <ClangGCCCustom os={languageConfig.os} host={host} projectKey={projectKey} token={token} />
+ <ClangGCCCustom os={languageConfig.os} host={host} component={component} token={token} />
) : null;
case BuildTools.Other:
return languageConfig.os !== undefined ? (
- <Other host={host} os={languageConfig.os} projectKey={projectKey} token={token} />
+ <Other host={host} os={languageConfig.os} component={component} token={token} />
) : null;
default:
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/ClangGCCCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/ClangGCCCommand.tsx
index 1fc693c4cc0..a49fed27b0d 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/ClangGCCCommand.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/ClangGCCCommand.tsx
@@ -25,21 +25,21 @@ import ExecBuildWrapper from './ExecBuildWrapper';
import ExecScanner from './ExecScanner';
export interface ClangGCCCustomProps {
+ component: T.Component;
host: string;
os: OSs;
- projectKey: string;
token: string;
}
export default function ClangGCCCustom(props: ClangGCCCustomProps) {
- const { os, host, projectKey, token } = props;
+ const { os, host, component, token } = props;
return (
<div>
<DownloadBuildWrapper os={os} />
<DownloadScanner os={os} />
<ExecBuildWrapper os={os} />
- <ExecScanner host={host} projectKey={projectKey} os={os} token={token} cfamily={true} />
+ <ExecScanner host={host} component={component} os={os} token={token} cfamily={true} />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNet.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNet.tsx
index 03956c08f93..1ba53cf6225 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNet.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNet.tsx
@@ -23,8 +23,8 @@ import DotNetCore from './DotNetCore';
import DotNetFramework from './DotNetFramework';
export interface DotNetProps {
+ component: T.Component;
host: string;
- projectKey: string;
token: string;
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetCore.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetCore.tsx
index d667ced97e2..9d74fe62b43 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetCore.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetCore.tsx
@@ -26,10 +26,10 @@ import { DotNetProps } from './DotNet';
import DotNetExecute from './DotNetExecute';
export default function DotNetCore(props: DotNetProps) {
- const { host, projectKey, token } = props;
+ const { host, component, token } = props;
const commands = [
- `dotnet sonarscanner begin /k:"${projectKey}" /d:sonar.host.url="${host}" /d:sonar.login="${token}"`,
+ `dotnet sonarscanner begin /k:"${component.key}" /d:sonar.host.url="${host}" /d:sonar.login="${token}"`,
'dotnet build',
`dotnet sonarscanner end /d:sonar.login="${token}"`
];
@@ -46,7 +46,7 @@ export default function DotNetCore(props: DotNetProps) {
<Alert className="spacer-top" variant="info">
{translate('onboarding.analysis.dotnetcore.global.text.path')}
</Alert>
- <DotNetExecute commands={commands} />
+ <DotNetExecute commands={commands} component={component} />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetExecute.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetExecute.tsx
index ec2e272d8a8..56091251a9a 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetExecute.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetExecute.tsx
@@ -24,12 +24,14 @@ import { Link } from 'react-router';
import { translate } from 'sonar-ui-common/helpers/l10n';
import CodeSnippet from '../../../common/CodeSnippet';
import InstanceMessage from '../../../common/InstanceMessage';
+import DoneNextSteps from '../DoneNextSteps';
export interface DotNetExecuteProps {
commands: string[];
+ component: T.Component;
}
-export default function DotNetExecute({ commands }: DotNetExecuteProps) {
+export default function DotNetExecute({ commands, component }: DotNetExecuteProps) {
return (
<>
<h4 className="huge-spacer-top spacer-bottom">
@@ -55,6 +57,7 @@ export default function DotNetExecute({ commands }: DotNetExecuteProps) {
}}
/>
</p>
+ <DoneNextSteps component={component} />
</>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetFramework.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetFramework.tsx
index 0ead421f64b..2542db69702 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetFramework.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/DotNetFramework.tsx
@@ -24,10 +24,10 @@ import { DotNetProps } from './DotNet';
import DotNetExecute from './DotNetExecute';
export default function DotNetFramework(props: DotNetProps) {
- const { host, projectKey, token } = props;
+ const { host, component, token } = props;
const commands = [
- `SonarScanner.MSBuild.exe begin /k:"${projectKey}" /d:sonar.host.url="${host}" /d:sonar.login="${token}"`,
+ `SonarScanner.MSBuild.exe begin /k:"${component.key}" /d:sonar.host.url="${host}" /d:sonar.login="${token}"`,
'MsBuild.exe /t:Rebuild',
`SonarScanner.MSBuild.exe end /d:sonar.login="${token}"`
];
@@ -57,7 +57,7 @@ export default function DotNetFramework(props: DotNetProps) {
</p>
</div>
- <DotNetExecute commands={commands} />
+ <DotNetExecute commands={commands} component={component} />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/ExecScanner.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/ExecScanner.tsx
index cc595bb0d03..a3c2083ec34 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/ExecScanner.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/ExecScanner.tsx
@@ -25,22 +25,23 @@ import CodeSnippet from '../../../common/CodeSnippet';
import InstanceMessage from '../../../common/InstanceMessage';
import { OSs } from '../../types';
import { quote } from '../../utils';
+import DoneNextSteps from '../DoneNextSteps';
export interface ExecScannerProps {
+ component: T.Component;
host: string;
os: OSs;
- projectKey: string;
token: string;
cfamily?: boolean;
}
export default function ExecScanner(props: ExecScannerProps) {
- const { host, os, projectKey, token, cfamily } = props;
+ const { host, os, component, token, cfamily } = props;
const q = quote(os);
const command = [
os === OSs.Windows ? 'sonar-scanner.bat' : 'sonar-scanner',
- '-D' + q(`sonar.projectKey=${projectKey}`),
+ '-D' + q(`sonar.projectKey=${component.key}`),
'-D' + q('sonar.sources=.'),
cfamily ? '-D' + q('sonar.cfamily.build-wrapper-output=bw-output') : undefined,
'-D' + q(`sonar.host.url=${host}`),
@@ -69,9 +70,7 @@ export default function ExecScanner(props: ExecScannerProps) {
}}
/>
</p>
- <p className="big-spacer-top markdown">
- {translate('onboarding.analysis.auto_refresh_after_analysis')}
- </p>
+ <DoneNextSteps component={component} />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaGradle.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaGradle.tsx
index 16fc994a8f4..773148047c2 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaGradle.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaGradle.tsx
@@ -23,20 +23,21 @@ import { Link } from 'react-router';
import { translate } from 'sonar-ui-common/helpers/l10n';
import CodeSnippet from '../../../common/CodeSnippet';
import InstanceMessage from '../../../common/InstanceMessage';
+import DoneNextSteps from '../DoneNextSteps';
export interface JavaGradleProps {
+ component: T.Component;
host: string;
- projectKey: string;
token: string;
}
export default function JavaGradle(props: JavaGradleProps) {
- const { host, projectKey, token } = props;
+ const { host, component, token } = props;
const config = 'plugins {\n id "org.sonarqube" version "3.3"\n}';
const command = [
'./gradlew sonarqube',
- `-Dsonar.projectKey=${projectKey}`,
+ `-Dsonar.projectKey=${component.key}`,
`-Dsonar.host.url=${host}`,
`-Dsonar.login=${token}`
];
@@ -91,9 +92,7 @@ export default function JavaGradle(props: JavaGradleProps) {
}}
/>
</p>
- <p className="big-spacer-top markdown">
- {translate('onboarding.analysis.auto_refresh_after_analysis')}
- </p>
+ <DoneNextSteps component={component} />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaMaven.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaMaven.tsx
index 7a9b4b6849d..d6e00ac2fbf 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaMaven.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/JavaMaven.tsx
@@ -23,18 +23,19 @@ import { Link } from 'react-router';
import { translate } from 'sonar-ui-common/helpers/l10n';
import CodeSnippet from '../../../common/CodeSnippet';
import InstanceMessage from '../../../common/InstanceMessage';
+import DoneNextSteps from '../DoneNextSteps';
export interface JavaMavenProps {
+ component: T.Component;
host: string;
- projectKey: string;
token: string;
}
export default function JavaMaven(props: JavaMavenProps) {
- const { host, projectKey, token } = props;
+ const { host, component, token } = props;
const command = [
'mvn sonar:sonar',
- `-Dsonar.projectKey=${projectKey}`,
+ `-Dsonar.projectKey=${component.key}`,
`-Dsonar.host.url=${host}`,
`-Dsonar.login=${token}`
];
@@ -59,9 +60,7 @@ export default function JavaMaven(props: JavaMavenProps) {
}}
/>
</p>
- <p className="big-spacer-top markdown">
- {translate('onboarding.analysis.auto_refresh_after_analysis')}
- </p>
+ <DoneNextSteps component={component} />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/Other.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/Other.tsx
index 7db9c3880bb..ac53a410e21 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/Other.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/Other.tsx
@@ -23,19 +23,19 @@ import DownloadScanner from './DownloadScanner';
import ExecScanner from './ExecScanner';
export interface OtherProps {
+ component: T.Component;
host: string;
os: OSs;
- projectKey: string;
token: string;
}
export default function Other(props: OtherProps) {
- const { host, os, projectKey, token } = props;
+ const { host, os, component, token } = props;
return (
<div>
<DownloadScanner os={os} />
- <ExecScanner host={host} os={os} projectKey={projectKey} token={token} />
+ <ExecScanner host={host} os={os} component={component} token={token} />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/CLangGCCCommand-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/CLangGCCCommand-test.tsx
index d35ea6ba31e..574c5fbb785 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/CLangGCCCommand-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/CLangGCCCommand-test.tsx
@@ -19,11 +19,19 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import { OSs } from '../../../types';
import ClangGCCCommand from '../ClangGCCCommand';
-it('Shoud renders correctly', () => {
+it('should render correctly', () => {
expect(
- shallow(<ClangGCCCommand os={OSs.Linux} host="host" projectKey="projectKey" token="token" />)
+ shallow(
+ <ClangGCCCommand
+ os={OSs.Linux}
+ host="host"
+ component={mockComponent({ key: 'projectKey' })}
+ token="token"
+ />
+ )
).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNet-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNet-test.tsx
index dd5408d54eb..86e50f914ba 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNet-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNet-test.tsx
@@ -19,8 +19,11 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import DotNet from '../DotNet';
-it('Should renders correctly', () => {
- expect(shallow(<DotNet host="host" projectKey="projectKey" token="token" />)).toMatchSnapshot();
+it('should render correctly', () => {
+ expect(
+ shallow(<DotNet host="host" component={mockComponent({ key: 'projectKey' })} token="token" />)
+ ).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetExecute-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetExecute-test.tsx
index 5a3693177d5..563cae7b1ab 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetExecute-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetExecute-test.tsx
@@ -19,8 +19,11 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import DotNetExecute from '../DotNetExecute';
-it('Should renders correctly', () => {
- expect(shallow(<DotNetExecute commands={['command1', 'command2']} />)).toMatchSnapshot();
+it('should render correctly', () => {
+ expect(
+ shallow(<DotNetExecute commands={['command1', 'command2']} component={mockComponent()} />)
+ ).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetFramework-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetFramework-test.tsx
index a6c1d5c3dbf..e2cfce486d8 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetFramework-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotNetFramework-test.tsx
@@ -19,10 +19,13 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import DotNetFramework from '../DotNetFramework';
-it('Should renders correctly', () => {
+it('should render correctly', () => {
expect(
- shallow(<DotNetFramework host="host" projectKey="projectKey" token="token" />)
+ shallow(
+ <DotNetFramework host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ )
).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotnetCore-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotnetCore-test.tsx
index 1de261193b9..ecf1c268cee 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotnetCore-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/DotnetCore-test.tsx
@@ -19,10 +19,13 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import DotNetCore from '../DotNetCore';
-it('Should renders correctly', () => {
+it('should render correctly', () => {
expect(
- shallow(<DotNetCore host="host" projectKey="projectKey" token="token" />)
+ shallow(
+ <DotNetCore host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ )
).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/ExecScanner-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/ExecScanner-test.tsx
index 02c3feefe19..9f9ccd1d23b 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/ExecScanner-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/ExecScanner-test.tsx
@@ -19,19 +19,26 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import { OSs } from '../../../types';
import ExecScanner, { ExecScannerProps } from '../ExecScanner';
-it.each([OSs.Linux, OSs.Windows, OSs.MacOS])('Shoud renders for %p correctly', os => {
+it.each([OSs.Linux, OSs.Windows, OSs.MacOS])('should render correctly for %p', os => {
expect(shallowRender({ os })).toMatchSnapshot();
});
-it('Should render for cfamily', () => {
+it('should render correctly for cfamily', () => {
expect(shallowRender({ cfamily: true })).toMatchSnapshot();
});
function shallowRender(props: Partial<ExecScannerProps> = {}) {
return shallow<ExecScannerProps>(
- <ExecScanner host="host" os={OSs.Linux} projectKey="projectKey" token="token" {...props} />
+ <ExecScanner
+ host="host"
+ os={OSs.Linux}
+ component={mockComponent({ key: 'projectKey' })}
+ token="token"
+ {...props}
+ />
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaGradle-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaGradle-test.tsx
index 917f279493b..e9f868da12a 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaGradle-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaGradle-test.tsx
@@ -19,10 +19,13 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import JavaGradle from '../JavaGradle';
it('renders correctly', () => {
expect(
- shallow(<JavaGradle host="host" projectKey="projectKey" token="token" />)
+ shallow(
+ <JavaGradle host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ )
).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaMaven-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaMaven-test.tsx
index eddbb1df1e8..054fa94df61 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaMaven-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/JavaMaven-test.tsx
@@ -19,10 +19,13 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import JavaMaven from '../JavaMaven';
it('renders correctly', () => {
expect(
- shallow(<JavaMaven host="host" projectKey="projectKey" token="token" />)
+ shallow(
+ <JavaMaven host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ )
).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/Other-test.tsx b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/Other-test.tsx
index 751a95f8cd5..db6f85490ed 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/Other-test.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/Other-test.tsx
@@ -19,6 +19,7 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockComponent } from '../../../../../helpers/testMocks';
import { OSs } from '../../../types';
import Other, { OtherProps } from '../Other';
@@ -28,6 +29,12 @@ it('renders correctly', () => {
function shallowRender(props: Partial<OtherProps> = {}) {
return shallow<OtherProps>(
- <Other host="host" os={OSs.Linux} projectKey="projectKey" token="token" {...props} />
+ <Other
+ host="host"
+ os={OSs.Linux}
+ component={mockComponent({ key: 'projectKey' })}
+ token="token"
+ {...props}
+ />
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap
index 2df0e23b2b8..c33c2b7b140 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap
@@ -2,17 +2,59 @@
exports[`renders correctly: .NET 1`] = `
<DotNet
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="HOST"
- projectKey="my-project"
token="myToken"
/>
`;
exports[`renders correctly: CFamily 1`] = `
<ClangGCCCustom
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="HOST"
os="linux"
- projectKey="my-project"
token="myToken"
/>
`;
@@ -21,25 +63,88 @@ exports[`renders correctly: Empty CFamily 1`] = `""`;
exports[`renders correctly: gradle 1`] = `
<JavaGradle
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="HOST"
- projectKey="my-project"
token="myToken"
/>
`;
exports[`renders correctly: maven 1`] = `
<JavaMaven
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="HOST"
- projectKey="my-project"
token="myToken"
/>
`;
exports[`renders correctly: other 1`] = `
<Other
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="HOST"
os="win"
- projectKey="my-project"
token="myToken"
/>
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/CLangGCCCommand-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/CLangGCCCommand-test.tsx.snap
index 7539b8cf22d..b4cb5128d1b 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/CLangGCCCommand-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/CLangGCCCommand-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Shoud renders correctly 1`] = `
+exports[`should render correctly 1`] = `
<div>
<DownloadBuildWrapper
os="linux"
@@ -13,9 +13,30 @@ exports[`Shoud renders correctly 1`] = `
/>
<ExecScanner
cfamily={true}
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="host"
os="linux"
- projectKey="projectKey"
token="token"
/>
</div>
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNet-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNet-test.tsx.snap
index a322725aec2..b88033c45f5 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNet-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNet-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Should renders correctly 1`] = `
+exports[`should render correctly 1`] = `
<Fragment>
<RenderOptions
checked="dotnet_core"
@@ -16,8 +16,29 @@ exports[`Should renders correctly 1`] = `
titleLabelKey="onboarding.build.dotnet.variant"
/>
<DotNetCore
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="host"
- projectKey="projectKey"
token="token"
/>
</Fragment>
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetExecute-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetExecute-test.tsx.snap
index bc623435f01..7ff51cbcb67 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetExecute-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetExecute-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Should renders correctly 1`] = `
+exports[`should render correctly 1`] = `
<Fragment>
<h4
className="huge-spacer-top spacer-bottom"
@@ -40,5 +40,29 @@ exports[`Should renders correctly 1`] = `
}
/>
</p>
+ <DoneNextSteps
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ />
</Fragment>
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetFramework-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetFramework-test.tsx.snap
index 986272b490d..13edb7d7370 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetFramework-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotNetFramework-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Should renders correctly 1`] = `
+exports[`should render correctly 1`] = `
<div>
<div>
<h4
@@ -39,6 +39,28 @@ exports[`Should renders correctly 1`] = `
"SonarScanner.MSBuild.exe end /d:sonar.login=\\"token\\"",
]
}
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
/>
</div>
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotnetCore-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotnetCore-test.tsx.snap
index 5621eab6cad..73c108fd1a2 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotnetCore-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/DotnetCore-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Should renders correctly 1`] = `
+exports[`should render correctly 1`] = `
<div>
<h4
className="huge-spacer-top spacer-bottom"
@@ -29,6 +29,28 @@ exports[`Should renders correctly 1`] = `
"dotnet sonarscanner end /d:sonar.login=\\"token\\"",
]
}
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
/>
</div>
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/ExecScanner-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/ExecScanner-test.tsx.snap
index 140fe68ea6a..b48bd7b66eb 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/ExecScanner-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/ExecScanner-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Shoud renders for "linux" correctly 1`] = `
+exports[`should render correctly for "linux" 1`] = `
<div>
<h4
className="huge-spacer-top spacer-bottom"
@@ -45,15 +45,34 @@ exports[`Shoud renders for "linux" correctly 1`] = `
}
/>
</p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
+ <DoneNextSteps
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ />
</div>
`;
-exports[`Shoud renders for "mac" correctly 1`] = `
+exports[`should render correctly for "mac" 1`] = `
<div>
<h4
className="huge-spacer-top spacer-bottom"
@@ -98,15 +117,34 @@ exports[`Shoud renders for "mac" correctly 1`] = `
}
/>
</p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
+ <DoneNextSteps
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ />
</div>
`;
-exports[`Shoud renders for "win" correctly 1`] = `
+exports[`should render correctly for "win" 1`] = `
<div>
<h4
className="huge-spacer-top spacer-bottom"
@@ -151,15 +189,34 @@ exports[`Shoud renders for "win" correctly 1`] = `
}
/>
</p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
+ <DoneNextSteps
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ />
</div>
`;
-exports[`Should render for cfamily 1`] = `
+exports[`should render correctly for cfamily 1`] = `
<div>
<h4
className="huge-spacer-top spacer-bottom"
@@ -204,10 +261,29 @@ exports[`Should render for cfamily 1`] = `
}
/>
</p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
+ <DoneNextSteps
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ />
</div>
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap
index b93775bcc24..9737f0a58df 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap
@@ -76,10 +76,29 @@ exports[`renders correctly 1`] = `
}
/>
</p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
+ <DoneNextSteps
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ />
</div>
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap
index 2482e1d3457..aafc6e3517e 100644
--- a/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/manual/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap
@@ -44,10 +44,29 @@ exports[`renders correctly 1`] = `
}
/>
</p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
+ <DoneNextSteps
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ />
</div>
`;
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"
/>
<ExecScanner
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "projectKey",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
host="host"
os="linux"
- projectKey="projectKey"
token="token"
/>
</div>
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<string | undefined | number>
+): 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
*/