diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2023-07-18 11:16:29 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-07-21 20:03:16 +0000 |
commit | 57e3800540955230c9a7f02df588ac5a1c72f712 (patch) | |
tree | 7b0921485cbf19fd20e91f22daff5fff829ad5af /server/sonar-web/src | |
parent | e95c3702319d1818faabf0aeba569f14f8cc6ccf (diff) | |
download | sonarqube-57e3800540955230c9a7f02df588ac5a1c72f712.tar.gz sonarqube-57e3800540955230c9a7f02df588ac5a1c72f712.zip |
SONAR-19907 New UI for Jenkins tutorial
Diffstat (limited to 'server/sonar-web/src')
25 files changed, 700 insertions, 851 deletions
diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx index 72f92633148..8824df09ed1 100644 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx @@ -124,7 +124,6 @@ it('should correctly fetch the corresponding ALM setting', async () => { .mockResolvedValueOnce([ { key: 'binding', url: 'https://enterprise.github.com', alm: AlmKeys.GitHub }, ]); - const user = userEvent.setup(); renderTutorialSelection( { projectBinding: mockProjectAlmBindingResponse({ alm: AlmKeys.GitHub, key: 'binding' }), @@ -133,7 +132,6 @@ it('should correctly fetch the corresponding ALM setting', async () => { ); await waitOnDataLoaded(); - await startJenkinsTutorial(user); expect(screen.getByText('https://enterprise.github.com', { exact: false })).toBeInTheDocument(); }); @@ -190,12 +188,6 @@ async function startLocalTutorial(user: UserEvent) { await user.click(screen.getByRole('radio', { name: 'onboarding.build.maven' })); } -async function startJenkinsTutorial(user: UserEvent) { - await user.click( - screen.getByRole('button', { name: 'onboarding.tutorial.with.jenkins.prereqs.done' }) - ); -} - function renderTutorialSelection( props: Partial<ComponentPropsType<typeof TutorialSelection>> = {}, navigateTo: string = 'dashboard?id=bar' diff --git a/server/sonar-web/src/main/js/components/tutorials/components/DefaultProjectKey.tsx b/server/sonar-web/src/main/js/components/tutorials/components/DefaultProjectKey.tsx index 6303900989e..b2b8bf75909 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/DefaultProjectKey.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/DefaultProjectKey.tsx @@ -38,7 +38,8 @@ export default function DefaultProjectKey(props: DefaultProjectKeyProps) { /> <CodeSnippet snippet={sonarProjectSnippet(component.key)} - className="sw-p-9 sw-overflow-auto" + isOneLine + className="sw-p-6 sw-overflow-auto" /> </NumberedListItem> ); diff --git a/server/sonar-web/src/main/js/components/tutorials/components/LabelValuePair.tsx b/server/sonar-web/src/main/js/components/tutorials/components/LabelValuePair.tsx index b3bee6e131b..fee3a456865 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/LabelValuePair.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/LabelValuePair.tsx @@ -17,8 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { ClipboardIconButton } from 'design-system'; import * as React from 'react'; -import { ClipboardIconButton } from '../../../components/controls/clipboard'; import { translate } from '../../../helpers/l10n'; export interface LabelValuePairProps { @@ -28,9 +28,9 @@ export interface LabelValuePairProps { export default function LabelValuePair({ translationKey, value }: LabelValuePairProps) { return ( - <div className="display-flex-center"> - <strong className="little-spacer-right">{translate(translationKey, 'label')}:</strong> {value} - <ClipboardIconButton className="little-spacer-left" copyValue={value} /> + <div className="sw-flex sw-items-center"> + <b className="sw-mr-1 sw-font-semibold">{translate(translationKey, 'label')}:</b> {value} + <ClipboardIconButton className="sw-ml-1" copyValue={value} /> </div> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithFilename.tsx b/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithFilename.tsx index 94aa6f25a07..66babe1170c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithFilename.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithFilename.tsx @@ -32,7 +32,7 @@ export default function SentenceWithFilename({ translationKey, }: SentenceWithFilenameProps) { return ( - <span className="markdown"> + <span> <FormattedMessage defaultMessage={translate(translationKey, 'sentence')} id={`${translationKey}.sentence`} diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx index 9b66bd3ca43..03ca049eab2 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx @@ -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 { BasicSeparator, Title } from 'design-system'; import * as React from 'react'; import withAvailableFeatures, { WithAvailableFeaturesProps, @@ -29,7 +30,7 @@ import { } from '../../../types/alm-settings'; import { Feature } from '../../../types/features'; import { Component } from '../../../types/types'; -import AllSetStep from '../components/AllSetStep'; +import AllSet from '../components/AllSet'; import JenkinsfileStep from './JenkinsfileStep'; import MultiBranchPipelineStep from './MultiBranchPipelineStep'; import PipelineStep from './PipelineStep'; @@ -45,97 +46,48 @@ export interface JenkinsTutorialProps extends WithAvailableFeaturesProps { willRefreshAutomatically?: boolean; } -enum Steps { - SelectAlm = 0, - PreRequisites = 1, - MultiBranchPipeline = 2, - Webhook = 3, - Jenkinsfile = 4, - AllSet = 5, -} - export function JenkinsTutorial(props: JenkinsTutorialProps) { const { almBinding, baseUrl, component, projectBinding, willRefreshAutomatically } = props; const hasSelectAlmStep = projectBinding?.alm === undefined; const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); const [alm, setAlm] = React.useState<AlmKeys | undefined>(projectBinding?.alm); - const [step, setStep] = React.useState(alm ? Steps.PreRequisites : Steps.SelectAlm); + const [done, setDone] = React.useState(false); return ( <> - <div className="page-header big-spacer-bottom"> - <h2 className="page-title">{translate('onboarding.tutorial.with.jenkins.title')}</h2> - </div> + <Title>{translate('onboarding.tutorial.with.jenkins.title')}</Title> - {hasSelectAlmStep && ( - <SelectAlmStep - alm={alm} - open={step === Steps.SelectAlm} - onCheck={(value) => { - setAlm(value); - setStep(Steps.PreRequisites); - }} - onOpen={() => setStep(Steps.SelectAlm)} - /> - )} + {hasSelectAlmStep && <SelectAlmStep alm={alm} onChange={setAlm} />} {alm && ( <> - <PreRequisitesStep - alm={alm} - branchesEnabled={branchSupportEnabled} - finished={step > Steps.PreRequisites} - onDone={() => setStep(Steps.MultiBranchPipeline)} - onOpen={() => setStep(Steps.PreRequisites)} - open={step === Steps.PreRequisites} - /> + <PreRequisitesStep alm={alm} branchesEnabled={branchSupportEnabled} /> {branchSupportEnabled ? ( <MultiBranchPipelineStep alm={alm} almBinding={almBinding} - finished={step > Steps.MultiBranchPipeline} - onDone={() => setStep(Steps.Webhook)} - onOpen={() => setStep(Steps.MultiBranchPipeline)} - open={step === Steps.MultiBranchPipeline} projectBinding={projectBinding} /> ) : ( - <PipelineStep - alm={alm} - finished={step > Steps.MultiBranchPipeline} - onDone={() => setStep(Steps.Webhook)} - onOpen={() => setStep(Steps.MultiBranchPipeline)} - open={step === Steps.MultiBranchPipeline} - /> + <PipelineStep alm={alm} /> )} <WebhookStep alm={alm} almBinding={almBinding} branchesEnabled={branchSupportEnabled} - finished={step > Steps.Webhook} - onDone={() => setStep(Steps.Jenkinsfile)} - onOpen={() => setStep(Steps.Webhook)} - open={step === Steps.Webhook} projectBinding={projectBinding} /> - <JenkinsfileStep - component={component} - baseUrl={baseUrl} - finished={step > Steps.Jenkinsfile} - onDone={() => setStep(Steps.AllSet)} - onOpen={() => setStep(Steps.Jenkinsfile)} - open={step === Steps.Jenkinsfile} - /> + <JenkinsfileStep component={component} baseUrl={baseUrl} onDone={setDone} /> - <AllSetStep - alm={alm} - open={step === Steps.AllSet} - stepNumber={4} - willRefreshAutomatically={willRefreshAutomatically} - /> + {done && ( + <> + <BasicSeparator className="sw-my-10" /> + <AllSet alm={alm} willRefreshAutomatically={willRefreshAutomatically} /> + </> + )} </> )} </> diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsfileStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsfileStep.tsx index 9ecb92389bb..12394ea8705 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsfileStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsfileStep.tsx @@ -17,13 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { FlagMessage, NumberedList, NumberedListItem, TutorialStep } from 'design-system'; import * as React from 'react'; -import { Alert } from '../../../components/ui/Alert'; import { translate } from '../../../helpers/l10n'; import { Component } from '../../../types/types'; import { withCLanguageFeature } from '../../hoc/withCLanguageFeature'; import RenderOptions from '../components/RenderOptions'; -import Step from '../components/Step'; import { BuildTools } from '../types'; import CFamilly from './buildtool-steps/CFamilly'; import DotNet from './buildtool-steps/DotNet'; @@ -31,21 +30,11 @@ import Gradle from './buildtool-steps/Gradle'; import Maven from './buildtool-steps/Maven'; import Other from './buildtool-steps/Other'; -export interface JenkinsfileStepProps { - baseUrl: string; - component: Component; - hasCLanguageFeature: boolean; - finished: boolean; - onDone: () => void; - onOpen: () => void; - open: boolean; -} - -export interface LanguageProps { - onDone: () => void; - component: Component; - baseUrl: string; -} +const BUILD_TOOLS_WITH_NO_ADDITIONAL_OPTIONS = [ + BuildTools.Maven, + BuildTools.Gradle, + BuildTools.Other, +]; const BUILDTOOL_COMPONENT_MAP: { [x in BuildTools]: React.ComponentType<LanguageProps>; @@ -57,48 +46,60 @@ const BUILDTOOL_COMPONENT_MAP: { [BuildTools.Other]: Other, }; +export interface JenkinsfileStepProps { + baseUrl: string; + component: Component; + hasCLanguageFeature: boolean; + onDone: (done: boolean) => void; +} + +export interface LanguageProps { + onDone: (done: boolean) => void; + component: Component; + baseUrl: string; +} + export function JenkinsfileStep(props: JenkinsfileStepProps) { - const { component, hasCLanguageFeature, baseUrl, finished, open } = props; + const { component, hasCLanguageFeature, baseUrl, onDone } = props; + const [buildTool, setBuildTool] = React.useState<BuildTools>(); + const buildToolOrder = Object.keys(BUILDTOOL_COMPONENT_MAP); if (!hasCLanguageFeature) { buildToolOrder.splice(buildToolOrder.indexOf(BuildTools.CFamily), 1); } + + const BuildToolComponent = buildTool ? BUILDTOOL_COMPONENT_MAP[buildTool] : undefined; + + React.useEffect(() => { + if (buildTool && BUILD_TOOLS_WITH_NO_ADDITIONAL_OPTIONS.includes(buildTool)) { + onDone(true); + } + }, [buildTool, onDone]); + return ( - <Step - finished={finished} - onOpen={props.onOpen} - open={open} - renderForm={() => ( - <div className="boxed-group-inner"> - <ol className="list-styled"> - <li> - {translate('onboarding.build')} - <RenderOptions - label={translate('onboarding.build')} - checked={buildTool} - onCheck={(value) => setBuildTool(value as BuildTools)} - optionLabelKey="onboarding.build" - options={buildToolOrder} - /> - {buildTool === BuildTools.CFamily && ( - <Alert variant="info" className="spacer-top abs-width-600"> - {translate('onboarding.tutorial.with.jenkins.jenkinsfile.cfamilly.agent_setup')} - </Alert> - )} - </li> - {buildTool !== undefined && - React.createElement(BUILDTOOL_COMPONENT_MAP[buildTool], { - component, - baseUrl, - onDone: props.onDone, - })} - </ol> - </div> - )} - stepNumber={3} - stepTitle={translate('onboarding.tutorial.with.jenkins.jenkinsfile.title')} - /> + <TutorialStep title={translate('onboarding.tutorial.with.jenkins.jenkinsfile.title')}> + <NumberedList> + <NumberedListItem> + {translate('onboarding.build')} + <RenderOptions + label={translate('onboarding.build')} + checked={buildTool} + onCheck={(value) => setBuildTool(value as BuildTools)} + optionLabelKey="onboarding.build" + options={buildToolOrder} + /> + {buildTool === BuildTools.CFamily && ( + <FlagMessage variant="info" className="sw-mt-2 sw-w-abs-600"> + {translate('onboarding.tutorial.with.jenkins.jenkinsfile.cfamilly.agent_setup')} + </FlagMessage> + )} + </NumberedListItem> + {BuildToolComponent !== undefined && ( + <BuildToolComponent component={component} baseUrl={baseUrl} onDone={props.onDone} /> + )} + </NumberedList> + </TutorialStep> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/MultiBranchPipelineStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/MultiBranchPipelineStep.tsx index bab33765bd7..5907b2baf59 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/MultiBranchPipelineStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/MultiBranchPipelineStep.tsx @@ -17,46 +17,46 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { + CodeSnippet, + ListItem, + NumberedList, + NumberedListItem, + TutorialStep, + UnorderedList, +} from 'design-system'; import * as React from 'react'; -import { rawSizes } from '../../../app/theme'; -import { Button } from '../../../components/controls/buttons'; -import ChevronRightIcon from '../../../components/icons/ChevronRightIcon'; import { translate } from '../../../helpers/l10n'; import { AlmKeys, AlmSettingsInstance, ProjectAlmBindingResponse, } from '../../../types/alm-settings'; -import CodeSnippet from '../../common/CodeSnippet'; import LabelActionPair from '../components/LabelActionPair'; import LabelValuePair from '../components/LabelValuePair'; import SentenceWithHighlights from '../components/SentenceWithHighlights'; -import Step from '../components/Step'; import { buildGithubLink } from '../utils'; export interface MultiBranchPipelineStepProps { alm: AlmKeys; almBinding?: AlmSettingsInstance; - finished: boolean; - onDone: () => void; - onOpen: () => void; - open: boolean; + projectBinding?: ProjectAlmBindingResponse; } /* Capture [workspaceID] from this pattern: https://bitbucket.org/[workspaceId]/ */ -const bitbucketcloudUrlRegex = new RegExp('https:\\/\\/bitbucket.org\\/(.+)\\/'); +const bitbucketcloudUrlRegex = /https:\/\/bitbucket.org\/(.+)\//; function extractBitbucketCloudWorkspaceId(almBinding?: AlmSettingsInstance): string | undefined { if (almBinding?.url) { - const result = almBinding.url.match(bitbucketcloudUrlRegex); + const result = bitbucketcloudUrlRegex.exec(almBinding.url); return result ? result[1] : undefined; } } export default function MultiBranchPipelineStep(props: MultiBranchPipelineStepProps) { - const { alm, almBinding, finished, open, projectBinding } = props; + const { alm, almBinding, projectBinding } = props; const workspaceId = extractBitbucketCloudWorkspaceId(almBinding); const isGitLab = alm === AlmKeys.GitLab; @@ -64,221 +64,197 @@ export default function MultiBranchPipelineStep(props: MultiBranchPipelineStepPr const isBitbucketCloud = alm === AlmKeys.BitbucketCloud; const isGitHub = alm === AlmKeys.GitHub; - const renderForm = React.useCallback( - () => ( - <div className="boxed-group-inner"> - <p className="big-spacer-bottom"> - {translate('onboarding.tutorial.with.jenkins.multi_branch_pipeline.intro')} - </p> - <ol className="list-styled"> - <li> - <SentenceWithHighlights - highlightKeys={['new_item', 'type']} - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1" - /> - </li> - <li> - <SentenceWithHighlights - highlightKeys={['tab', 'source']} - translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.${alm}`} - /> - <ul className="list-styled list-alpha"> - {isBitbucketServer && ( - <> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.server" /> - </li> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.creds" /> - </li> - <li> - {projectBinding?.repository ? ( - <LabelValuePair - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner" - value={projectBinding.repository} - /> - ) : ( - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner" /> - )} - </li> - <li> - {projectBinding?.slug ? ( - <LabelValuePair - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo" - value={projectBinding.slug} - /> - ) : ( - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo" /> + return ( + <TutorialStep title={translate('onboarding.tutorial.with.jenkins.multi_branch_pipeline.title')}> + <p className="sw-mb-4"> + {translate('onboarding.tutorial.with.jenkins.multi_branch_pipeline.intro')} + </p> + <NumberedList> + <NumberedListItem> + <SentenceWithHighlights + highlightKeys={['new_item', 'type']} + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1" + /> + </NumberedListItem> + <NumberedListItem> + <SentenceWithHighlights + highlightKeys={['tab', 'source']} + translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.${alm}`} + /> + <UnorderedList ticks className="sw-ml-12"> + {isBitbucketServer && ( + <> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.server" /> + </ListItem> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.creds" /> + </ListItem> + <ListItem> + {projectBinding?.repository ? ( + <LabelValuePair + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner" + value={projectBinding.repository} + /> + ) : ( + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner" /> + )} + </ListItem> + <ListItem> + {projectBinding?.slug ? ( + <LabelValuePair + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo" + value={projectBinding.slug} + /> + ) : ( + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo" /> + )} + </ListItem> + </> + )} + {isBitbucketCloud && ( + <> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.server" /> + </ListItem> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.creds" /> + </ListItem> + <ListItem> + {workspaceId ? ( + <LabelValuePair + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.owner" + value={workspaceId} + /> + ) : ( + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.owner" /> + )} + </ListItem> + <ListItem> + {projectBinding?.repository ? ( + <LabelValuePair + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.repo" + value={projectBinding.repository} + /> + ) : ( + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.repo" /> + )} + </ListItem> + </> + )} + {isGitHub && ( + <> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.creds" /> + </ListItem> + <ListItem> + {almBinding !== undefined && + projectBinding !== undefined && + buildGithubLink(almBinding, projectBinding) !== null ? ( + <LabelValuePair + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url" + value={buildGithubLink(almBinding, projectBinding) as string} + /> + ) : ( + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url" /> + )} + </ListItem> + </> + )} + {isGitLab && ( + <> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.gitlab.creds" /> + </ListItem> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.gitlab.owner" /> + </ListItem> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.gitlab.repo" /> + </ListItem> + </> + )} + <ListItem> + <strong> + {translate( + 'onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.label' + )} + : + </strong> + <UnorderedList ticks className="sw-ml-4 sw-mt-1 sw-w-abs-600"> + <ListItem> + <LabelActionPair + translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.${ + isGitLab ? 'branches_mrs' : 'branches_prs' + }`} + /> + </ListItem> + <ListItem> + <LabelActionPair + translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.${ + isGitLab ? 'discover_mrs' : 'discover_prs' + }`} + /> + </ListItem> + <ListItem> + <strong> + {translate( + 'onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.ref_specs.label' )} - </li> - </> - )} - {isBitbucketCloud && ( - <> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.server" /> - </li> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.creds" /> - </li> - <li> - {workspaceId ? ( - <LabelValuePair - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.owner" - value={workspaceId} + : + </strong> + <UnorderedList className="sw-ml-4 sw-mt-1"> + <ListItem> + <SentenceWithHighlights + highlightKeys={['add', 'ref_spec']} + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.ref_specs.add_behaviour" /> - ) : ( - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.owner" /> - )} - </li> - <li> - {projectBinding?.repository ? ( - <LabelValuePair - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.repo" - value={projectBinding.repository} + </ListItem> + <ListItem> + <SentenceWithHighlights + highlightKeys={['ref_spec']} + translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.ref_specs.${ + isGitLab ? 'set_mr_ref_specs' : 'set_pr_ref_specs' + }`} /> - ) : ( - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucketcloud.repo" /> - )} - </li> - </> - )} - {isGitHub && ( - <> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.creds" /> - </li> - <li> - {almBinding !== undefined && - projectBinding !== undefined && - buildGithubLink(almBinding, projectBinding) !== null ? ( - <LabelValuePair - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url" - value={buildGithubLink(almBinding, projectBinding) as string} + <CodeSnippet + className="sw-p-4" + isOneLine + snippet="+refs/heads/*:refs/remotes/@{remote}/*" /> - ) : ( - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url" /> - )} - </li> - </> - )} - {isGitLab && ( - <> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.gitlab.creds" /> - </li> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.gitlab.owner" /> - </li> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.gitlab.repo" /> - </li> - </> - )} - <li> - <strong> - {translate( - 'onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.label' - )} - : - </strong> - <ol className="list-styled list-roman little-spacer-top abs-width-600"> - <li> - <LabelActionPair - translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.${ - isGitLab ? 'branches_mrs' : 'branches_prs' - }`} - /> - </li> - <li> - <LabelActionPair - translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.${ - isGitLab ? 'discover_mrs' : 'discover_prs' - }`} - /> - </li> - <li> - <strong> - {translate( - 'onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.ref_specs.label' - )} - : - </strong> - <ul className="list-styled little-spacer-top"> - <li> - <SentenceWithHighlights - highlightKeys={['add', 'ref_spec']} - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.ref_specs.add_behaviour" - /> - </li> - <li> - <SentenceWithHighlights - highlightKeys={['ref_spec']} - translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.ref_specs.${ - isGitLab ? 'set_mr_ref_specs' : 'set_pr_ref_specs' - }`} - /> - <CodeSnippet isOneLine snippet="+refs/heads/*:refs/remotes/@{remote}/*" /> - </li> - </ul> - </li> - </ol> - </li> - </ul> - <p className="big-spacer-left padder-left"> - {translate( - 'onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.leave_defaults' - )} - </p> - </li> - <li> - <SentenceWithHighlights - highlightKeys={['tab']} - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3" - /> - <ul className="list-styled list-alpha"> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode" /> - </li> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path" /> - </li> - </ul> - </li> - <li> - <SentenceWithHighlights - highlightKeys={['save']} - translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4" - /> - </li> - </ol> - <Button className="big-spacer-top" onClick={props.onDone}> - {translate('continue')} - <ChevronRightIcon size={rawSizes.baseFontSizeRaw} /> - </Button> - </div> - ), - [ - isBitbucketCloud, - isBitbucketServer, - isGitHub, - isGitLab, - workspaceId, - alm, - projectBinding, - almBinding, - props.onDone, - ] - ); - - return ( - <Step - finished={finished} - onOpen={props.onOpen} - open={open} - renderForm={renderForm} - stepNumber={1} - stepTitle={translate('onboarding.tutorial.with.jenkins.multi_branch_pipeline.title')} - /> + </ListItem> + </UnorderedList> + </ListItem> + </UnorderedList> + </ListItem> + </UnorderedList> + <p className="sw-ml-12"> + {translate( + 'onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.leave_defaults' + )} + </p> + </NumberedListItem> + <NumberedListItem> + <SentenceWithHighlights + highlightKeys={['tab']} + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3" + /> + <UnorderedList ticks className="sw-ml-12"> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode" /> + </ListItem> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path" /> + </ListItem> + </UnorderedList> + </NumberedListItem> + <NumberedListItem> + <SentenceWithHighlights + highlightKeys={['save']} + translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4" + /> + </NumberedListItem> + </NumberedList> + </TutorialStep> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/PipelineStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/PipelineStep.tsx index 03989c36c66..6bf868cbc44 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/PipelineStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/PipelineStep.tsx @@ -17,113 +17,97 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { + ListItem, + NumberedList, + NumberedListItem, + TutorialStep, + UnorderedList, +} from 'design-system'; import * as React from 'react'; -import { rawSizes } from '../../../app/theme'; -import { Button } from '../../../components/controls/buttons'; -import ChevronRightIcon from '../../../components/icons/ChevronRightIcon'; import { translate } from '../../../helpers/l10n'; import { AlmKeys } from '../../../types/alm-settings'; import LabelActionPair from '../components/LabelActionPair'; import SentenceWithHighlights from '../components/SentenceWithHighlights'; -import Step from '../components/Step'; export interface PipelineStepProps { alm: AlmKeys; - finished: boolean; - onDone: () => void; - onOpen: () => void; - open: boolean; } export default function PipelineStep(props: PipelineStepProps) { - const { alm, finished, open } = props; + const { alm } = props; return ( - <Step - finished={finished} - onOpen={props.onOpen} - open={open} - renderForm={() => ( - <div className="boxed-group-inner"> - <p className="big-spacer-bottom"> - {translate('onboarding.tutorial.with.jenkins.pipeline.intro')} - </p> - <ol className="list-styled"> - <li> + <TutorialStep title={translate('onboarding.tutorial.with.jenkins.pipeline.title')}> + <p className="sw-mb-4">{translate('onboarding.tutorial.with.jenkins.pipeline.intro')}</p> + <NumberedList> + <NumberedListItem> + <SentenceWithHighlights + highlightKeys={['new_item', 'type']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.step1" + /> + </NumberedListItem> + <NumberedListItem> + {alm === AlmKeys.GitLab ? ( + <> <SentenceWithHighlights - highlightKeys={['new_item', 'type']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.step1" + highlightKeys={['tab', 'option']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.trigger" /> - </li> - <li> - {alm === AlmKeys.GitLab ? ( - <> + <UnorderedList className="sw-ml-12"> + <ListItem> <SentenceWithHighlights - highlightKeys={['tab', 'option']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.trigger" + highlightKeys={['triggers', 'push_events']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.pick_triggers" /> - <ul className="list-styled"> - <li> - <SentenceWithHighlights - highlightKeys={['triggers', 'push_events']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.pick_triggers" - /> - </li> - <li> - <SentenceWithHighlights - highlightKeys={['advanced']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.click_advanced" - /> - </li> - <li> - <SentenceWithHighlights - highlightKeys={['secret_token', 'generate']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.secret_token" - /> - </li> - </ul> - </> - ) : ( - <SentenceWithHighlights - highlightKeys={['tab', 'option']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.step2" - /> - )} - </li> - <li> - <SentenceWithHighlights - highlightKeys={['tab']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.step3" - /> - <ul className="list-styled"> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.pipeline.step3.definition" /> - </li> - <li> + </ListItem> + <ListItem> + <SentenceWithHighlights + highlightKeys={['advanced']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.click_advanced" + /> + </ListItem> + <ListItem> <SentenceWithHighlights - highlightKeys={['label', 'branches_to_build']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.step3.scm" + highlightKeys={['secret_token', 'generate']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.gitlab.step2.secret_token" /> - </li> - <li> - <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.pipeline.step3.script_path" /> - </li> - </ul> - </li> - <li> + </ListItem> + </UnorderedList> + </> + ) : ( + <SentenceWithHighlights + highlightKeys={['tab', 'option']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.step2" + /> + )} + </NumberedListItem> + <NumberedListItem> + <SentenceWithHighlights + highlightKeys={['tab']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.step3" + /> + <UnorderedList className="sw-ml-12"> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.pipeline.step3.definition" /> + </ListItem> + <ListItem> <SentenceWithHighlights - highlightKeys={['save']} - translationKey="onboarding.tutorial.with.jenkins.pipeline.step4" + highlightKeys={['label', 'branches_to_build']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.step3.scm" /> - </li> - </ol> - <Button className="big-spacer-top" onClick={props.onDone}> - {translate('continue')} - <ChevronRightIcon size={rawSizes.baseFontSizeRaw} /> - </Button> - </div> - )} - stepNumber={1} - stepTitle={translate('onboarding.tutorial.with.jenkins.pipeline.title')} - /> + </ListItem> + <ListItem> + <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.pipeline.step3.script_path" /> + </ListItem> + </UnorderedList> + </NumberedListItem> + <NumberedListItem> + <SentenceWithHighlights + highlightKeys={['save']} + translationKey="onboarding.tutorial.with.jenkins.pipeline.step4" + /> + </NumberedListItem> + </NumberedList> + </TutorialStep> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx index 66b40aeee7d..bbce2f6f1f8 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx @@ -17,78 +17,65 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { FlagMessage, Link, ListItem, TutorialStep, UnorderedList } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { rawSizes } from '../../../app/theme'; -import { Button } from '../../../components/controls/buttons'; -import ChevronRightIcon from '../../../components/icons/ChevronRightIcon'; -import { Alert } from '../../../components/ui/Alert'; +import { useDocUrl } from '../../../helpers/docs'; import { translate } from '../../../helpers/l10n'; import { AlmKeys } from '../../../types/alm-settings'; -import DocLink from '../../common/DocLink'; import SentenceWithHighlights from '../components/SentenceWithHighlights'; -import Step from '../components/Step'; export interface PreRequisitesStepProps { alm: AlmKeys; branchesEnabled: boolean; - finished: boolean; - onDone: () => void; - onOpen: () => void; - open: boolean; } export default function PreRequisitesStep(props: PreRequisitesStepProps) { - const { alm, branchesEnabled, finished, open } = props; + const { alm, branchesEnabled } = props; + + const docUrl = useDocUrl(); + return ( - <Step - finished={finished} - onOpen={props.onOpen} - open={open} - renderForm={() => ( - <div className="boxed-group-inner"> - <Alert className="big-spacer-bottom" variant="warning"> - <SentenceWithHighlights - highlightKeys={['installed', 'configured']} - translationKey="onboarding.tutorial.with.jenkins.prereqs.intro" - /> - </Alert> - <ul className="list-styled big-spacer-bottom"> - {branchesEnabled && ( - <li> - {translate('onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source', alm)} - </li> - )} - {!branchesEnabled && alm === AlmKeys.GitLab && ( - <li>{translate('onboarding.tutorial.with.jenkins.prereqs.plugins.gitlab_plugin')}</li> - )} - <li>{translate('onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner')}</li> - </ul> - <p className="big-spacer-bottom"> - <FormattedMessage - defaultMessage={translate( - 'onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide' - )} - id="onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide" - values={{ - link: ( - <DocLink to="/analyzing-source-code/ci-integration/jenkins-integration/"> - {translate('onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide.link')} - </DocLink> - ), - }} - /> - </p> - <p className="big-spacer-bottom"> - {translate('onboarding.tutorial.with.jenkins.prereqs.following_are_recommendations')} - </p> - <Button className="big-spacer-top" onClick={props.onDone}> - {translate('onboarding.tutorial.with.jenkins.prereqs.done')} - <ChevronRightIcon size={rawSizes.baseFontSizeRaw} /> - </Button> - </div> - )} - stepTitle={translate('onboarding.tutorial.with.jenkins.prereqs.title')} - /> + <TutorialStep title={translate('onboarding.tutorial.with.jenkins.prereqs.title')}> + <FlagMessage className="sw-mb-4" variant="warning"> + <span> + <SentenceWithHighlights + highlightKeys={['installed', 'configured']} + translationKey="onboarding.tutorial.with.jenkins.prereqs.intro" + /> + </span> + </FlagMessage> + <UnorderedList ticks className="sw-ml-8 sw-mb-4"> + {branchesEnabled && ( + <ListItem> + {translate('onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source', alm)} + </ListItem> + )} + {!branchesEnabled && alm === AlmKeys.GitLab && ( + <ListItem> + {translate('onboarding.tutorial.with.jenkins.prereqs.plugins.gitlab_plugin')} + </ListItem> + )} + <ListItem> + {translate('onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner')} + </ListItem> + </UnorderedList> + <p className="sw-mb-4"> + <FormattedMessage + defaultMessage={translate('onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide')} + id="onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide" + values={{ + link: ( + <Link to={docUrl('/analyzing-source-code/ci-integration/jenkins-integration/')}> + {translate('onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide.link')} + </Link> + ), + }} + /> + </p> + <p className="sw-mb-4"> + {translate('onboarding.tutorial.with.jenkins.prereqs.following_are_recommendations')} + </p> + </TutorialStep> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/SelectAlmStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/SelectAlmStep.tsx index 7be3688d5bf..40dd9773602 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/SelectAlmStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/SelectAlmStep.tsx @@ -17,18 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { ToggleButton, TutorialStep } from 'design-system'; import * as React from 'react'; -import AlertSuccessIcon from '../../../components/icons/AlertSuccessIcon'; import { hasMessage, translate } from '../../../helpers/l10n'; import { AlmKeys } from '../../../types/alm-settings'; -import ButtonToggle from '../../controls/ButtonToggle'; -import Step from '../components/Step'; export interface SelectAlmStepProps { alm?: AlmKeys; - open: boolean; - onCheck: (value: AlmKeys) => void; - onOpen: () => void; + onChange: (value: AlmKeys) => void; } function getAlmLongName(alm: AlmKeys) { @@ -36,39 +32,23 @@ function getAlmLongName(alm: AlmKeys) { } export default function SelectAlmStep(props: SelectAlmStepProps) { - const { alm, open } = props; + const { alm } = props; return ( - <Step - finished - open={open} - onOpen={props.onOpen} - renderForm={() => ( - <div className="boxed-group-inner"> - <ButtonToggle - label={translate('onboarding.tutorial.with.jenkins.alm_selection.title')} - onCheck={props.onCheck} - options={[ - AlmKeys.BitbucketCloud, - AlmKeys.BitbucketServer, - AlmKeys.GitHub, - AlmKeys.GitLab, - ].map((almKey) => ({ - label: getAlmLongName(almKey), - value: almKey, - }))} - value={alm} - /> - </div> - )} - renderResult={() => - alm && ( - <div className="boxed-group-actions display-flex-center"> - <AlertSuccessIcon className="spacer-right" /> - {getAlmLongName(alm)} - </div> - ) - } - stepTitle={translate('onboarding.tutorial.with.jenkins.alm_selection.title')} - /> + <TutorialStep title={translate('onboarding.tutorial.with.jenkins.alm_selection.title')}> + <ToggleButton + label={translate('onboarding.tutorial.with.jenkins.alm_selection.title')} + onChange={props.onChange} + options={[ + AlmKeys.BitbucketCloud, + AlmKeys.BitbucketServer, + AlmKeys.GitHub, + AlmKeys.GitLab, + ].map((almKey) => ({ + label: getAlmLongName(almKey), + value: almKey, + }))} + value={alm} + /> + </TutorialStep> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStep.tsx index 1d7f6874d7f..5dd15fe8374 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStep.tsx @@ -19,30 +19,22 @@ */ /* eslint-disable react/no-unused-prop-types */ +import { NumberedList, TutorialStep } from 'design-system'; import * as React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { rawSizes } from '../../../app/theme'; -import { Button, ButtonLink } from '../../../components/controls/buttons'; -import ChevronRightIcon from '../../../components/icons/ChevronRightIcon'; import { translate } from '../../../helpers/l10n'; import { AlmKeys, AlmSettingsInstance, ProjectAlmBindingResponse, } from '../../../types/alm-settings'; -import Step from '../components/Step'; import WebhookStepBitbucket from './WebhookStepBitbucket'; -import WebhookStepGithub from './WebhookStepGithub'; import WebhookStepGitLab from './WebhookStepGitLab'; +import WebhookStepGithub from './WebhookStepGithub'; export interface WebhookStepProps { alm: AlmKeys; almBinding?: AlmSettingsInstance; branchesEnabled: boolean; - finished: boolean; - onDone: () => void; - onOpen: () => void; - open: boolean; projectBinding?: ProjectAlmBindingResponse; } @@ -79,37 +71,14 @@ function renderAlmSpecificInstructions(props: WebhookStepProps) { } export default function WebhookStep(props: WebhookStepProps) { - const { alm, finished, open } = props; + const { alm } = props; return ( - <Step - finished={finished} - onOpen={props.onOpen} - open={open} - renderForm={() => ( - <div className="boxed-group-inner"> - <p className="big-spacer-bottom"> - <FormattedMessage - defaultMessage={translate('onboarding.tutorial.with.jenkins.webhook.intro.sentence')} - id="onboarding.tutorial.with.jenkins.webhook.intro.sentence" - values={{ - link: ( - <ButtonLink onClick={props.onDone}> - {translate('onboarding.tutorial.with.jenkins.webhook.intro.link')} - </ButtonLink> - ), - }} - /> - </p> - <ol className="list-styled">{renderAlmSpecificInstructions(props)}</ol> - <Button className="big-spacer-top" onClick={props.onDone}> - {translate('continue')} - <ChevronRightIcon size={rawSizes.baseFontSizeRaw} /> - </Button> - </div> - )} - stepNumber={2} - stepTitle={translate('onboarding.tutorial.with.jenkins.webhook', alm, 'title')} - /> + <TutorialStep title={translate('onboarding.tutorial.with.jenkins.webhook', alm, 'title')}> + <p className="sw-mb-4"> + {translate('onboarding.tutorial.with.jenkins.webhook.intro.sentence')} + </p> + <NumberedList>{renderAlmSpecificInstructions(props)}</NumberedList> + </TutorialStep> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepBitbucket.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepBitbucket.tsx index 069451b99ee..63ff06f5c79 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepBitbucket.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepBitbucket.tsx @@ -17,9 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { CodeSnippet, FlagMessage, ListItem, NumberedListItem, UnorderedList } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { Alert } from '../../../components/ui/Alert'; import { translate } from '../../../helpers/l10n'; import { stripTrailingSlash } from '../../../helpers/urls'; import { @@ -27,7 +27,6 @@ import { AlmSettingsInstance, ProjectAlmBindingResponse, } from '../../../types/alm-settings'; -import CodeSnippet from '../../common/CodeSnippet'; import Link from '../../common/Link'; import LabelActionPair from '../components/LabelActionPair'; import SentenceWithHighlights from '../components/SentenceWithHighlights'; @@ -74,7 +73,7 @@ export default function WebhookStepBitbucket(props: WebhookStepBitbucketProps) { return ( <> - <li> + <NumberedListItem> <FormattedMessage defaultMessage={translate('onboarding.tutorial.with.jenkins.webhook.step1.sentence')} id="onboarding.tutorial.with.jenkins.webhook.step1.sentence" @@ -90,66 +89,63 @@ export default function WebhookStepBitbucket(props: WebhookStepBitbucketProps) { ), }} /> - <ul className="list-styled list-alpha"> - <li> + <UnorderedList ticks className="sw-ml-12"> + <ListItem> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.step1.name" /> - </li> - <li className="abs-width-600"> + </ListItem> + <ListItem className="sw-w-abs-600"> <p> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url" /> </p> <CodeSnippet + className="sw-p-4" isOneLine - snippet={buildUrlSnippet( - branchesEnabled, - isBitbucketCloud, - almBinding && almBinding.url - )} + snippet={buildUrlSnippet(branchesEnabled, isBitbucketCloud, almBinding?.url)} /> {branchesEnabled && !isBitbucketCloud && ( - <Alert variant="info"> + <FlagMessage variant="info"> {translate('onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url.warning')} - </Alert> + </FlagMessage> )} - </li> - </ul> - </li> + </ListItem> + </UnorderedList> + </NumberedListItem> {isBitbucketCloud ? ( - <li> + <NumberedListItem> <SentenceWithHighlights highlightKeys={['triggers', 'option']} translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucketcloud.step2" /> - <ul className="list-styled list-alpha"> - <li> + <UnorderedList ticks className="sw-ml-12"> + <ListItem> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucketcloud.step2.repo" /> - </li> + </ListItem> {branchesEnabled && ( - <li> + <ListItem> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucketcloud.step2.pr" /> - </li> + </ListItem> )} - </ul> - </li> + </UnorderedList> + </NumberedListItem> ) : ( - <li> + <NumberedListItem> <SentenceWithHighlights highlightKeys={['events']} translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2" /> - <ul className="list-styled list-alpha"> - <li> + <UnorderedList ticks className="sw-ml-12"> + <ListItem> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.repo" /> - </li> + </ListItem> {branchesEnabled && ( - <li> + <ListItem> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.pr" /> - </li> + </ListItem> )} - </ul> - </li> + </UnorderedList> + </NumberedListItem> )} - <li> + <NumberedListItem> {isBitbucketCloud ? ( <SentenceWithHighlights highlightKeys={['save']} @@ -161,7 +157,7 @@ export default function WebhookStepBitbucket(props: WebhookStepBitbucketProps) { translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step3" /> )} - </li> + </NumberedListItem> </> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGitLab.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGitLab.tsx index 5bc211ab7be..883d086041c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGitLab.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGitLab.tsx @@ -17,10 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { CodeSnippet, ListItem, NumberedListItem, UnorderedList } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { translate } from '../../../helpers/l10n'; -import CodeSnippet from '../../common/CodeSnippet'; import LabelActionPair from '../components/LabelActionPair'; import SentenceWithHighlights from '../components/SentenceWithHighlights'; @@ -31,7 +31,7 @@ export interface WebhookStepGitLabProps { export default function WebhookStepGitLab({ branchesEnabled }: WebhookStepGitLabProps) { return ( <> - <li> + <NumberedListItem> <FormattedMessage defaultMessage={translate('onboarding.tutorial.with.jenkins.webhook.step1.sentence')} id="onboarding.tutorial.with.jenkins.webhook.step1.sentence" @@ -39,52 +39,56 @@ export default function WebhookStepGitLab({ branchesEnabled }: WebhookStepGitLab link: translate('onboarding.tutorial.with.jenkins.webhook.gitlab.step1.link'), }} /> - <ul className="list-styled"> + <UnorderedList ticks className="sw-ml-12"> {branchesEnabled ? ( - <li className="abs-width-600"> + <ListItem className="sw-w-abs-600"> <p> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.gitlab.step1.url_with_branches" /> </p> - <CodeSnippet isOneLine snippet="***JENKINS_SERVER_URL***/gitlab-webhook/post" /> - </li> + <CodeSnippet + className="sw-p-4" + isOneLine + snippet="***JENKINS_SERVER_URL***/gitlab-webhook/post" + /> + </ListItem> ) : ( <> - <li> + <ListItem> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.gitlab.step1.url_no_branches" /> - </li> - <li> + </ListItem> + <ListItem> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.gitlab.step1.secret_token" /> - </li> + </ListItem> </> )} - </ul> - </li> - <li> + </UnorderedList> + </NumberedListItem> + <NumberedListItem> <SentenceWithHighlights highlightKeys={['trigger']} translationKey="onboarding.tutorial.with.jenkins.webhook.gitlab.step2" /> - <ul className="list-styled"> - <li> - <strong> + <UnorderedList ticks className="sw-ml-12"> + <ListItem> + <strong className="sw-font-semibold"> {translate('onboarding.tutorial.with.jenkins.webhook.gitlab.step2.repo')} </strong> - </li> + </ListItem> {branchesEnabled && ( - <li> - <strong> + <ListItem> + <strong className="sw-font-semibold"> {translate('onboarding.tutorial.with.jenkins.webhook.gitlab.step2.mr')} </strong> - </li> + </ListItem> )} - </ul> - </li> - <li> + </UnorderedList> + </NumberedListItem> + <NumberedListItem> <SentenceWithHighlights highlightKeys={['add_webhook']} translationKey="onboarding.tutorial.with.jenkins.webhook.gitlab.step3" /> - </li> + </NumberedListItem> </> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGithub.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGithub.tsx index 624e6336aef..bea0464256e 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGithub.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGithub.tsx @@ -17,12 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { CodeSnippet, Link, ListItem, NumberedListItem, UnorderedList } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { translate } from '../../../helpers/l10n'; import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../../types/alm-settings'; -import CodeSnippet from '../../common/CodeSnippet'; -import Link from '../../common/Link'; import LabelActionPair from '../components/LabelActionPair'; import SentenceWithHighlights from '../components/SentenceWithHighlights'; import { buildGithubLink } from '../utils'; @@ -45,57 +44,57 @@ export default function WebhookStepGithub(props: WebhookStepGithubProps) { return ( <> - <li> + <NumberedListItem> <FormattedMessage defaultMessage={translate('onboarding.tutorial.with.jenkins.webhook.step1.sentence')} id="onboarding.tutorial.with.jenkins.webhook.step1.sentence" values={{ link: linkUrl ? ( - <Link to={linkUrl} target="_blank"> + <Link to={linkUrl}> {translate('onboarding.tutorial.with.jenkins.webhook.github.step1.link')} </Link> ) : ( - <strong> + <strong className="sw-font-semibold"> {translate('onboarding.tutorial.with.jenkins.webhook.github.step1.link')} </strong> ), }} /> - <ul className="list-styled"> - <li className="abs-width-600"> + <UnorderedList ticks className="sw-ml-12"> + <ListItem className="sw-w-abs-600"> <p> <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.github.step1.url" /> </p> - <CodeSnippet isOneLine snippet={webhookUrl} /> - </li> - </ul> - </li> - <li> + <CodeSnippet className="sw-p-4" isOneLine snippet={webhookUrl} /> + </ListItem> + </UnorderedList> + </NumberedListItem> + <NumberedListItem> <SentenceWithHighlights highlightKeys={['events', 'option']} translationKey="onboarding.tutorial.with.jenkins.webhook.github.step2" /> - <ul className="list-styled"> - <li> - <strong> + <UnorderedList ticks className="sw-ml-12"> + <ListItem> + <strong className="sw-font-semibold"> {translate('onboarding.tutorial.with.jenkins.webhook.github.step2.repo')} </strong> - </li> + </ListItem> {branchesEnabled && ( - <li> - <strong> + <ListItem> + <strong className="sw-font-semibold"> {translate('onboarding.tutorial.with.jenkins.webhook.github.step2.pr')} </strong> - </li> + </ListItem> )} - </ul> - </li> - <li> + </UnorderedList> + </NumberedListItem> + <NumberedListItem> <SentenceWithHighlights highlightKeys={['add_webhook']} translationKey="onboarding.tutorial.with.jenkins.webhook.github.step3" /> - </li> + </NumberedListItem> </> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx index fd1378270cf..d68683744d3 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx @@ -50,13 +50,10 @@ const ui = { devopsPlatformTitle: byRole('heading', { name: 'onboarding.tutorial.with.jenkins.alm_selection.title', }), - devopsPlatformButton: (alm: AlmKeys) => byRole('button', { name: `alm.${alm}.long` }), + devopsPlatformButton: (alm: AlmKeys) => byRole('radio', { name: `alm.${alm}.long` }), prerequisitesTitle: byRole('heading', { name: 'onboarding.tutorial.with.jenkins.prereqs.title' }), branchSourcePluginBulletPoint: (alm: AlmKeys) => byText(`onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source.${alm}`), - configureAnalysisButton: byRole('button', { - name: 'onboarding.tutorial.with.jenkins.prereqs.done', - }), multiBranchStepTitle: byRole('heading', { name: 'onboarding.tutorial.with.jenkins.multi_branch_pipeline.title', }), @@ -98,65 +95,60 @@ it.each([AlmKeys.BitbucketCloud, AlmKeys.BitbucketServer, AlmKeys.GitHub, AlmKey // 2. Prerequisites expect(ui.branchSourcePluginBulletPoint(alm).get()).toBeInTheDocument(); - await user.click(ui.configureAnalysisButton.get()); - // 3. Multibranch Pipeline Job expect(ui.multiBranchPipelineSecondListItem(alm).get()).toBeInTheDocument(); - expect(getCopyToClipboardValue()).toMatchSnapshot(`ref spec`); - - await user.click(ui.continueButton.get()); + expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(`ref spec`); // 4. Create DevOps platform webhook expect(ui.webhookStepTitle(alm).get()).toBeInTheDocument(); - expect(getCopyToClipboardValue()).toMatchSnapshot(`jenkins url`); - - await user.click(ui.continueButton.get()); + expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(`jenkins url`); // 5. Create jenkinsfile // Maven await user.click(ui.mavenBuildButton.get()); - expect(getCopyToClipboardValue()).toMatchSnapshot(`maven jenkinsfile`); + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`maven jenkinsfile`); // Gradle (Groovy) await user.click(ui.gradleBuildButton.get()); - expect(getCopyToClipboardValue()).toMatchSnapshot(`Groovy: build.gradle file`); + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`Groovy: build.gradle file`); // Gradle(Kotlin) await user.click(ui.gradleDSLButton(GradleBuildDSL.Kotlin).get()); - expect(getCopyToClipboardValue()).toMatchSnapshot(`Kotlin: build.gradle.kts file`); - expect(getCopyToClipboardValue(1)).toMatchSnapshot(`gradle jenkinsfile`); + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`Kotlin: build.gradle.kts file`); + expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`gradle jenkinsfile`); // .NET await user.click(ui.dotnetBuildButton.get()); await user.click(ui.windowsDotnetCoreButton.get()); - expect(getCopyToClipboardValue(1)).toMatchSnapshot(`windows dotnet core jenkinsfile`); + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`windows dotnet core jenkinsfile`); await user.click(ui.windowsDotnetFrameworkButton.get()); - expect(getCopyToClipboardValue(2)).toMatchSnapshot(`windows dotnet framework jenkinsfile`); + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot( + `windows dotnet framework jenkinsfile` + ); await user.click(ui.linuxDotnetCoreButton.get()); - expect(getCopyToClipboardValue(1)).toMatchSnapshot(`linux dotnet core jenkinsfile`); + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`linux dotnet core jenkinsfile`); // CFamilly await user.click(ui.cFamilyBuildButton.get()); - expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(`sonar-project.properties code`); + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`sonar-project.properties code`); await user.click(ui.linuxButton.get()); - expect(getCopyToClipboardValue()).toMatchSnapshot(`cfamily linux jenkinsfile`); + expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`cfamily linux jenkinsfile`); await user.click(ui.windowsButton.get()); - expect(getCopyToClipboardValue()).toMatchSnapshot(`cfamily windows jenkinsfile`); + expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`cfamily windows jenkinsfile`); await user.click(ui.macosButton.get()); - expect(getCopyToClipboardValue()).toMatchSnapshot(`cfamily macos jenkinsfile`); + expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`cfamily macos jenkinsfile`); // Other await user.click(ui.otherBuildButton.get()); - expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot( + expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot( `other build tools sonar-project.properties code` ); - expect(getCopyToClipboardValue()).toMatchSnapshot(`other build tools jenkinsfile`); + expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`other build tools jenkinsfile`); - await user.click(ui.finishTutorialButton.get()); expect(ui.allSetSentence.get()).toBeInTheDocument(); } ); @@ -169,13 +161,7 @@ it.each([AlmKeys.GitHub, AlmKeys.GitLab, AlmKeys.BitbucketCloud])( expect(await ui.devopsPlatformTitle.find()).toBeInTheDocument(); await user.click(ui.devopsPlatformButton(alm).get()); - await user.click(ui.configureAnalysisButton.get()); expect(ui.pipelineIntroText.get()).toBeInTheDocument(); - await user.click(ui.continueButton.get()); - // navigate back and forth - await user.click(ui.pipelineStepTitle.get()); - await user.click(ui.continueButton.get()); - expect(ui.webhookStepIntroSentence.get()).toBeInTheDocument(); } ); @@ -199,14 +185,8 @@ it.each([AlmKeys.GitHub, AlmKeys.BitbucketCloud])( expect(ui.devopsPlatformTitle.query()).not.toBeInTheDocument(); - await user.click(ui.configureAnalysisButton.get()); - await user.click(ui.continueButton.get()); - expect(ui.webhookAlmLink(alm).get()).toBeInTheDocument(); - - await user.click(ui.continueButton.get()); await user.click(ui.mavenBuildButton.get()); - await user.click(ui.finishTutorialButton.get()); expect(ui.allSetSentence.get()).toBeInTheDocument(); } ); @@ -216,11 +196,7 @@ it('navigates between steps', async () => { renderJenkinsTutorial(); await user.click(ui.devopsPlatformButton(AlmKeys.GitHub).get()); - await user.click(ui.configureAnalysisButton.get()); - await user.click(ui.continueButton.get()); - await user.click(ui.continueButton.get()); await user.click(ui.mavenBuildButton.get()); - await user.click(ui.finishTutorialButton.get()); expect(ui.allSetSentence.get()).toBeInTheDocument(); // Navigate back @@ -234,7 +210,6 @@ it('navigates between steps', async () => { expect(ui.multiBranchPipelineSecondListItem(AlmKeys.GitHub).get()).toBeInTheDocument(); await user.click(ui.prerequisitesTitle.get()); - expect(ui.configureAnalysisButton.get()).toBeInTheDocument(); await user.click(ui.devopsPlatformTitle.get()); expect(ui.devopsPlatformButton(AlmKeys.BitbucketCloud).get()).toBeInTheDocument(); diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx index 8bbd6f71141..ca17d2de1fd 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { NumberedListItem } from 'design-system/lib'; import * as React from 'react'; import { translate } from '../../../../helpers/l10n'; import { CompilationInfo } from '../../components/CompilationInfo'; import DefaultProjectKey from '../../components/DefaultProjectKey'; -import FinishButton from '../../components/FinishButton'; import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories'; import RenderOptions from '../../components/RenderOptions'; import { OSs, TutorialModes } from '../../types'; @@ -103,38 +103,42 @@ const YAML_MAP: Record<OSs, (baseUrl: string) => string> = { }; export default function CFamilly(props: LanguageProps) { - const { baseUrl, component } = props; + const { baseUrl, component, onDone } = props; const [os, setOs] = React.useState<OSs>(); + + React.useEffect(() => { + onDone(os !== undefined); + }, [os, onDone]); + return ( <> <DefaultProjectKey component={component} /> - <li className="abs-width-600"> + <NumberedListItem className="sw-max-w-2/3"> {translate('onboarding.build.other.os')} - <RenderOptions - label={translate('onboarding.build.other.os')} - checked={os} - optionLabelKey="onboarding.build.other.os" - onCheck={(value) => setOs(value as OSs)} - options={Object.values(OSs)} - /> - {os && ( - <GithubCFamilyExampleRepositories - className="big-spacer-top big-spacer-bottom" - os={os} - ci={TutorialModes.Jenkins} + <div className="sw-ml-8"> + <RenderOptions + label={translate('onboarding.build.other.os')} + checked={os} + optionLabelKey="onboarding.build.other.os" + onCheck={(value) => setOs(value as OSs)} + options={Object.values(OSs)} /> - )} - </li> + {os && ( + <GithubCFamilyExampleRepositories + className="sw-my-4 sw-bg-inherit" + os={os} + ci={TutorialModes.Jenkins} + /> + )} + </div> + </NumberedListItem> {os && ( - <> - <CreateJenkinsfileBulletPoint - alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" - snippet={YAML_MAP[os](baseUrl)} - > - <CompilationInfo /> - </CreateJenkinsfileBulletPoint> - <FinishButton onClick={props.onDone} /> - </> + <CreateJenkinsfileBulletPoint + alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" + snippet={YAML_MAP[os](baseUrl)} + > + <CompilationInfo /> + </CreateJenkinsfileBulletPoint> )} </> ); diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CreateJenkinsfileBulletPoint.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CreateJenkinsfileBulletPoint.tsx index f1df6ad3070..ba4930155f9 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CreateJenkinsfileBulletPoint.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CreateJenkinsfileBulletPoint.tsx @@ -17,61 +17,62 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { CodeSnippet, FlagMessage, HelperHintIcon, NumberedListItem } from 'design-system'; import * as React from 'react'; import HelpTooltip from '../../../../components/controls/HelpTooltip'; -import { Alert } from '../../../../components/ui/Alert'; -import CodeSnippet from '../../../common/CodeSnippet'; import SentenceWithFilename from '../../components/SentenceWithFilename'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; export interface CreateJenkinsfileBulletPointProps { alertTranslationKeyPart?: string; children?: React.ReactNode; - otherAlert?: JSX.Element; snippet: string; } export default function CreateJenkinsfileBulletPoint(props: CreateJenkinsfileBulletPointProps) { - const { children, snippet, alertTranslationKeyPart, otherAlert } = props; + const { children, snippet, alertTranslationKeyPart } = props; return ( - <li className="abs-width-600"> + <NumberedListItem className="sw-max-w-2/3"> <SentenceWithFilename filename="Jenkinsfile" translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" /> - {alertTranslationKeyPart && ( - <Alert className="spacer-top" variant="info"> - <div className="text-middle"> - <SentenceWithHighlights - highlightKeys={['default', 'in_jenkins']} - translationKey={`${alertTranslationKeyPart}.replace`} - /> - <HelpTooltip - className="little-spacer-left" - overlay={ - <> - <p className="spacer-bottom"> - <SentenceWithHighlights - highlightKeys={['path']} - translationKey={`${alertTranslationKeyPart}.help1`} - /> - </p> - <p> - <SentenceWithHighlights - highlightKeys={['path', 'name']} - translationKey={`${alertTranslationKeyPart}.help2`} - /> - </p> - </> - } - /> - {otherAlert} - </div> - </Alert> - )} - <CodeSnippet snippet={snippet} /> - {children} - </li> + <div className="sw-ml-8"> + {alertTranslationKeyPart && ( + <FlagMessage className="sw-mt-2" variant="info"> + <div> + <SentenceWithHighlights + highlightKeys={['default', 'in_jenkins']} + translationKey={`${alertTranslationKeyPart}.replace`} + /> + <HelpTooltip + className="sw-ml-1" + overlay={ + <> + <p className="sw-mb-2"> + <SentenceWithHighlights + highlightKeys={['path']} + translationKey={`${alertTranslationKeyPart}.help1`} + /> + </p> + <p> + <SentenceWithHighlights + highlightKeys={['path', 'name']} + translationKey={`${alertTranslationKeyPart}.help2`} + /> + </p> + </> + } + > + <HelperHintIcon /> + </HelpTooltip> + </div> + </FlagMessage> + )} + <CodeSnippet className="sw-p-6" language="groovy" snippet={snippet} /> + {children} + </div> + </NumberedListItem> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx index a38208f9f3f..d39dfed053f 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx @@ -17,10 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { NumberedListItem } from 'design-system/lib'; import * as React from 'react'; import { translate } from '../../../../helpers/l10n'; import { Component } from '../../../../types/types'; -import FinishButton from '../../components/FinishButton'; import RenderOptions from '../../components/RenderOptions'; import { OSs } from '../../types'; import { LanguageProps } from '../JenkinsfileStep'; @@ -42,26 +42,30 @@ const DotOS: { [key in keyof typeof DotNetFlavor]: OSDotNet } = { }; export default function DotNet(props: LanguageProps) { - const { component } = props; - const [flavorComponent, setFlavorComponet] = React.useState<keyof typeof DotNetFlavor>(); + const { component, onDone } = props; + const [flavorComponent, setFlavorComponent] = React.useState<keyof typeof DotNetFlavor>(); const DotNetTutorial = flavorComponent && DotNetFlavor[flavorComponent]; + + React.useEffect(() => { + onDone(flavorComponent !== undefined); + }, [flavorComponent, onDone]); + return ( <> - <li> + <NumberedListItem> {translate('onboarding.tutorial.with.jenkins.jenkinsfile.dotnet.build_agent')} - <RenderOptions - label={translate('onboarding.tutorial.with.jenkins.jenkinsfile.dotnet.build_agent')} - checked={flavorComponent} - optionLabelKey="onboarding.build.dotnet" - onCheck={(value) => setFlavorComponet(value as keyof typeof DotNetFlavor)} - options={Object.keys(DotNetFlavor)} - /> - </li> + <div className="sw-ml-8"> + <RenderOptions + label={translate('onboarding.tutorial.with.jenkins.jenkinsfile.dotnet.build_agent')} + checked={flavorComponent} + optionLabelKey="onboarding.build.dotnet" + onCheck={(value) => setFlavorComponent(value as keyof typeof DotNetFlavor)} + options={Object.keys(DotNetFlavor)} + /> + </div> + </NumberedListItem> {DotNetTutorial && flavorComponent && ( - <> - <DotNetTutorial component={component} os={DotOS[flavorComponent]} /> - <FinishButton onClick={props.onDone} /> - </> + <DotNetTutorial component={component} os={DotOS[flavorComponent]} /> )} </> ); diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetCore.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetCore.tsx index 76d162038d7..9987c9863e1 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetCore.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetCore.tsx @@ -17,8 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { CodeSnippet, NumberedListItem } from 'design-system'; import * as React from 'react'; -import CodeSnippet from '../../../common/CodeSnippet'; import SentenceWithFilename from '../../components/SentenceWithFilename'; import { OSs } from '../../types'; import { DotNetCoreFrameworkProps, OSDotNet } from './DotNet'; @@ -48,13 +48,17 @@ export default function DotNetCore({ component, os }: DotNetCoreFrameworkProps) return ( <> <DotNetPrereqsScanner /> - <li className="abs-width-600"> + <NumberedListItem className="sw-max-w-2/3"> <SentenceWithFilename filename="Jenkinsfile" translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" /> - <CodeSnippet snippet={jenkinsfileSnippet(component.key, os)} /> - </li> + <CodeSnippet + className="sw-ml-8 sw-p-6" + language="groovy" + snippet={jenkinsfileSnippet(component.key, os)} + /> + </NumberedListItem> </> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetFramework.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetFramework.tsx index 8581a8f3a1a..a7e3eab0918 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetFramework.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetFramework.tsx @@ -17,8 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { CodeSnippet, NumberedListItem } from 'design-system'; import * as React from 'react'; -import CodeSnippet from '../../../common/CodeSnippet'; import SentenceWithFilename from '../../components/SentenceWithFilename'; import { DotNetCoreFrameworkProps } from './DotNet'; import DotNetPrereqsMSBuild from './DotNetPrereqsMSBuild'; @@ -45,13 +45,17 @@ export default function DotNetFramework({ component }: DotNetCoreFrameworkProps) <> <DotNetPrereqsScanner /> <DotNetPrereqsMSBuild /> - <li className="abs-width-600"> + <NumberedListItem className="sw-max-w-2/3"> <SentenceWithFilename filename="Jenkinsfile" translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" /> - <CodeSnippet snippet={jenkinsfileSnippet(component.key)} /> - </li> + <CodeSnippet + className="sw-ml-8 sw-p-6" + language="groovy" + snippet={jenkinsfileSnippet(component.key)} + /> + </NumberedListItem> </> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsMSBuild.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsMSBuild.tsx index bb5a13be596..79796519486 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsMSBuild.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsMSBuild.tsx @@ -17,44 +17,52 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { + ClipboardIconButton, + FlagMessage, + ListItem, + NumberedListItem, + OrderedList, +} from 'design-system'; import * as React from 'react'; -import { ClipboardIconButton } from '../../../../components/controls/clipboard'; -import { Alert } from '../../../../components/ui/Alert'; import { translate } from '../../../../helpers/l10n'; +import { InlineSnippet } from '../../components/InlineSnippet'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; export default function DotNetPrereqsMSBuild() { return ( - <li className="abs-width-600"> + <NumberedListItem className="sw-max-w-2/3"> <SentenceWithHighlights highlightKeys={['default_msbuild']} translationKey="onboarding.tutorial.with.jenkins.dotnet.msbuild.prereqs.title" /> - <Alert className="spacer-top" variant="info"> - {translate('onboarding.tutorial.with.jenkins.dotnet.msbuild.prereqs.info')} - </Alert> - <ol className="list-styled list-roman"> - <li> + <div className="sw-ml-8 sw-mt-2"> + <FlagMessage variant="info"> + {translate('onboarding.tutorial.with.jenkins.dotnet.msbuild.prereqs.info')} + </FlagMessage> + </div> + <OrderedList tickStyle="ALPHA" className="sw-ml-12"> + <ListItem> <SentenceWithHighlights highlightKeys={['msbuild']} translationKey="onboarding.tutorial.with.jenkins.dotnet.msbuild.prereqs.step1" /> - </li> - <li> + </ListItem> + <ListItem> <SentenceWithHighlights highlightKeys={['path']} translationKey="onboarding.tutorial.with.jenkins.dotnet.msbuild.prereqs.step2" /> - </li> - <li> + </ListItem> + <ListItem> <SentenceWithHighlights highlightKeys={['msbuild', 'add_msbuild', 'name', 'msbuild_plugin']} translationKey="onboarding.tutorial.with.jenkins.dotnet.msbuild.prereqs.step3" /> - <code className="rule">Default MSBuild</code> - <ClipboardIconButton copyValue="Default MSBuild" /> - </li> - </ol> - </li> + <InlineSnippet className="sw-ml-1" snippet="Default MSBuild" /> + <ClipboardIconButton className="sw-ml-2 sw-align-sub" copyValue="Default MSBuild" /> + </ListItem> + </OrderedList> + </NumberedListItem> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsScanner.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsScanner.tsx index 2e9780f1e04..1d2c961dca3 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsScanner.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsScanner.tsx @@ -17,50 +17,59 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { + ClipboardIconButton, + FlagMessage, + ListItem, + NumberedListItem, + OrderedList, +} from 'design-system'; import * as React from 'react'; -import { ClipboardIconButton } from '../../../../components/controls/clipboard'; -import { Alert } from '../../../../components/ui/Alert'; import { translate } from '../../../../helpers/l10n'; +import { InlineSnippet } from '../../components/InlineSnippet'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; export default function DotNetPrereqsScanner() { return ( - <li className="abs-width-600"> + <NumberedListItem className="sw-max-w-2/3"> <SentenceWithHighlights highlightKeys={['default_scanner']} translationKey="onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.title" /> - <Alert className="spacer-top" variant="info"> + <FlagMessage className="sw-ml-8 sw-mt-2" variant="info"> {translate('onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.info')} - </Alert> - <ol className="list-styled list-roman"> - <li> + </FlagMessage> + <OrderedList tickStyle="ALPHA" className="sw-ml-12"> + <ListItem> <SentenceWithHighlights highlightKeys={['path']} translationKey="onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.step1" /> - </li> - <li> + </ListItem> + <ListItem> <SentenceWithHighlights highlightKeys={['default_scanner', 'add_scanner_for_msbuild']} translationKey="onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.step2" /> - </li> - <li> + </ListItem> + <ListItem> <SentenceWithHighlights highlightKeys={['name']} translationKey="onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.step3" /> - <code className="rule">SonarScanner for MSBuild</code> - <ClipboardIconButton copyValue="SonarScanner for MSBuild" /> - </li> - <li> + <InlineSnippet className="sw-ml-1" snippet="SonarScanner for MSBuild" /> + <ClipboardIconButton + className="sw-ml-2 sw-align-sub" + copyValue="SonarScanner for MSBuild" + /> + </ListItem> + <ListItem> <SentenceWithHighlights highlightKeys={['install_from']} translationKey="onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.step5" /> - </li> - </ol> - </li> + </ListItem> + </OrderedList> + </NumberedListItem> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Gradle.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Gradle.tsx index 51c24f8c8ef..03aa14f1817 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Gradle.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Gradle.tsx @@ -17,12 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { CodeSnippet, NumberedListItem } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { translate } from '../../../../helpers/l10n'; -import CodeSnippet from '../../../common/CodeSnippet'; -import FinishButton from '../../components/FinishButton'; import GradleBuildSelection from '../../components/GradleBuildSelection'; +import { InlineSnippet } from '../../components/InlineSnippet'; import { GradleBuildDSL } from '../../types'; import { buildGradleSnippet } from '../../utils'; import { LanguageProps } from '../JenkinsfileStep'; @@ -44,8 +44,8 @@ export default function Gradle(props: LanguageProps) { return ( <> - <li className="abs-width-600"> - <span className="markdown"> + <NumberedListItem className="sw-max-w-2/3"> + <span> <FormattedMessage defaultMessage={translate( 'onboarding.tutorial.with.jenkins.jenkinsfile.gradle.step2', @@ -53,19 +53,24 @@ export default function Gradle(props: LanguageProps) { )} id="onboarding.tutorial.with.jenkins.jenkinsfile.gradle.step2.sentence" values={{ - groovy: <code>{GradleBuildDSL.Groovy}</code>, - kotlin: <code>{GradleBuildDSL.Kotlin}</code>, + groovy: <InlineSnippet snippet={GradleBuildDSL.Groovy} />, + kotlin: <InlineSnippet snippet={GradleBuildDSL.Kotlin} />, }} /> </span> - <GradleBuildSelection className="big-spacer-top big-spacer-bottom"> - {(build) => ( - <CodeSnippet snippet={buildGradleSnippet(component.key, component.name, build)} /> - )} - </GradleBuildSelection> - </li> + <div className="sw-ml-8"> + <GradleBuildSelection className="sw-my-4"> + {(build) => ( + <CodeSnippet + className="sw-p-6" + language={build === GradleBuildDSL.Groovy ? 'groovy' : 'kotlin'} + snippet={buildGradleSnippet(component.key, component.name, build)} + /> + )} + </GradleBuildSelection> + </div> + </NumberedListItem> <CreateJenkinsfileBulletPoint snippet={JENKINSFILE_SNIPPET} /> - <FinishButton onClick={props.onDone} /> </> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Maven.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Maven.tsx index b35210eeb2c..2ac775c1027 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Maven.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Maven.tsx @@ -18,7 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import FinishButton from '../../components/FinishButton'; import { LanguageProps } from '../JenkinsfileStep'; import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; @@ -36,14 +35,11 @@ function jenkinsfileSnippet(projectKey: string, projectName: string) { }`; } -export default function Maven({ component, onDone }: LanguageProps) { +export default function Maven({ component }: LanguageProps) { return ( - <> - <CreateJenkinsfileBulletPoint - alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3" - snippet={jenkinsfileSnippet(component.key, component.name)} - /> - <FinishButton onClick={onDone} /> - </> + <CreateJenkinsfileBulletPoint + alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3" + snippet={jenkinsfileSnippet(component.key, component.name)} + /> ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Other.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Other.tsx index cb775a5f807..c9c8fcad16e 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Other.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Other.tsx @@ -19,7 +19,6 @@ */ import * as React from 'react'; import DefaultProjectKey from '../../components/DefaultProjectKey'; -import FinishButton from '../../components/FinishButton'; import { LanguageProps } from '../JenkinsfileStep'; import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; @@ -44,7 +43,6 @@ export default function Other(props: LanguageProps) { alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" snippet={JENKINSFILE_SNIPPET} /> - <FinishButton onClick={props.onDone} /> </> ); } |