diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2021-06-15 09:43:43 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2021-06-17 20:03:07 +0000 |
commit | dee4f363b8bdebe59126a5464e1ebc4fc3202932 (patch) | |
tree | fbe1296dd813a2db3f232cf199755bab0980d887 /server | |
parent | cf6800f19682deb0450bcd2269910cf3e1fb2bdb (diff) | |
download | sonarqube-dee4f363b8bdebe59126a5464e1ebc4fc3202932.tar.gz sonarqube-dee4f363b8bdebe59126a5464e1ebc4fc3202932.zip |
SONAR-14934 Improve the manual tutorial
Diffstat (limited to 'server')
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 }}> + … + </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 */ |