From bdd0f192af53d963fc92952b3f61f71a9f8e8718 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 17 Jul 2023 13:50:21 +0200 Subject: [PATCH] SONAR-19909 New UI for azure pipelines tutorial --- .../src/components/UnorderedList.tsx | 4 +- .../design-system/src/components/index.ts | 2 + .../AzurePipelinesTutorial.tsx | 129 +++++--------- .../BranchAnalysisStepContent.tsx | 7 +- .../ExtensionInstallationStepContent.tsx | 7 +- .../azure-pipelines/JavaToolInstallation.tsx | 25 +-- .../ServiceEndpointStepContent.tsx | 49 +++--- .../__tests__/AzurePipelinesTutorial-it.tsx | 81 ++------- .../AzurePipelinesTutorial-it.tsx.snap | 22 +-- .../commands/AlertClassicEditor.tsx | 34 ++-- .../commands/AnalysisCommand.tsx | 6 +- .../azure-pipelines/commands/ClangGCC.tsx | 70 +++++--- .../azure-pipelines/commands/DotNet.tsx | 13 +- .../azure-pipelines/commands/JavaGradle.tsx | 21 +-- .../azure-pipelines/commands/JavaMaven.tsx | 21 +-- .../azure-pipelines/commands/Other.tsx | 13 +- .../commands/PrepareAnalysisCommand.tsx | 166 ++++++++++-------- .../azure-pipelines/commands/PublishSteps.tsx | 53 +++--- .../GithubCFamilyExampleRepositories.css | 22 --- .../GithubCFamilyExampleRepositories.tsx | 3 +- .../components/SentenceWithHighlights.tsx | 6 +- 21 files changed, 351 insertions(+), 403 deletions(-) delete mode 100644 server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.css diff --git a/server/sonar-web/design-system/src/components/UnorderedList.tsx b/server/sonar-web/design-system/src/components/UnorderedList.tsx index b63f1e322b1..dda24e0f046 100644 --- a/server/sonar-web/design-system/src/components/UnorderedList.tsx +++ b/server/sonar-web/design-system/src/components/UnorderedList.tsx @@ -21,8 +21,8 @@ import styled from '@emotion/styled'; import tw from 'twin.macro'; -export const UnorderedList = styled.ul` - list-style: none; +export const UnorderedList = styled.ul<{ ticks?: boolean }>` + list-style: ${({ ticks }) => (ticks ? 'disc' : 'none')}; ${tw`sw-mt-4`} ${tw`sw-pl-0`} diff --git a/server/sonar-web/design-system/src/components/index.ts b/server/sonar-web/design-system/src/components/index.ts index b633b712bc8..fa3353d59e0 100644 --- a/server/sonar-web/design-system/src/components/index.ts +++ b/server/sonar-web/design-system/src/components/index.ts @@ -80,6 +80,8 @@ export * from './TreeMap'; export * from './TreeMapRect'; export * from './TutorialStep'; export * from './TutorialStepList'; +export * from './UnorderedList'; +export * from './UnorderedListItem'; export * from './buttons'; export { ClipboardIconButton } from './clipboard'; export * from './code-line/LineCoverage'; diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx index 992ebb8b300..e6a84833a20 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx @@ -17,15 +17,13 @@ * 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, TutorialStep, TutorialStepList } from 'design-system'; import * as React from 'react'; -import { Button } from '../../../components/controls/buttons'; import { translate } from '../../../helpers/l10n'; import { AlmKeys } from '../../../types/alm-settings'; import { Component } from '../../../types/types'; import { LoggedInUser } from '../../../types/users'; -import AllSetStep from '../components/AllSetStep'; -import FinishButton from '../components/FinishButton'; -import Step from '../components/Step'; +import AllSet from '../components/AllSet'; import BranchAnalysisStepContent from './BranchAnalysisStepContent'; import ExtensionInstallationStepContent from './ExtensionInstallationStepContent'; import ServiceEndpointStepContent from './ServiceEndpointStepContent'; @@ -39,97 +37,58 @@ export interface AzurePipelinesTutorialProps { } export enum Steps { - ExtensionInstallation, - ServiceEndpoint, - BranchAnalysis, - AllSet, -} - -interface Step { - step: Steps; - content: JSX.Element; - checkValidity?: boolean; + ExtensionInstallation = 'ExtensionInstallation', + ServiceEndpoint = 'ServiceEndpoint', + BranchAnalysis = 'BranchAnalysis', } export default function AzurePipelinesTutorial(props: AzurePipelinesTutorialProps) { const { alm, baseUrl, component, currentUser, willRefreshAutomatically } = props; - - const [currentStep, setCurrentStep] = React.useState(Steps.ExtensionInstallation); - const [isCurrentStepValid, setIsCurrentStepValid] = React.useState(false); - - const steps: Array = [ - { step: Steps.ExtensionInstallation, content: }, - { - step: Steps.ServiceEndpoint, - content: ( - - ), - }, - { - step: Steps.BranchAnalysis, - content: ( - setIsCurrentStepValid(isValid)} - /> - ), - checkValidity: true, - }, - ]; - - const switchCurrentStep = (step: Steps) => { - setCurrentStep(step); - setIsCurrentStepValid(false); - }; - - const canContinue = (step: Step) => !step.checkValidity || isCurrentStepValid; + const [done, setDone] = React.useState(false); return ( <> -
-

- {translate('onboarding.tutorial.with.azure_pipelines.title')} -

-
+ {translate('onboarding.tutorial.with.azure_pipelines.title')} - {steps.map((step, i) => ( - + switchCurrentStep(step.step)} - renderForm={() => ( -
-
{step.content}
- {canContinue(step) && - (step.step === Steps.BranchAnalysis ? ( - switchCurrentStep(step.step + 1)} /> - ) : ( - - ))} -
+ > + +
+ + - ))} - + > + + + + + + + + {done && ( + <> + + + + )} + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx index 8b74202c41e..94d9200ad38 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx @@ -29,8 +29,7 @@ import AnalysisCommand from './commands/AnalysisCommand'; export interface BranchesAnalysisStepProps { languages: Languages; component: Component; - - onStepValidationChange: (isValid: boolean) => void; + onDone: (done: boolean) => void; } const BUILD_TOOLS_ORDERED: Array = [ @@ -42,7 +41,7 @@ const BUILD_TOOLS_ORDERED: Array = [ ]; export function BranchAnalysisStepContent(props: BranchesAnalysisStepProps) { - const { component, onStepValidationChange, languages } = props; + const { component, languages } = props; const [buildTechnology, setBuildTechnology] = React.useState(); const buildToolsList = languages['c'] @@ -59,7 +58,7 @@ export function BranchAnalysisStepContent(props: BranchesAnalysisStepProps) { options={buildToolsList} /> + {translate( 'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence.link' )} diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/JavaToolInstallation.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/JavaToolInstallation.tsx index 162866379f8..13f335f4720 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/JavaToolInstallation.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/JavaToolInstallation.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 { NumberedListItem, UnorderedList, UnorderedListItem } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { translate } from '../../../helpers/l10n'; @@ -33,8 +34,8 @@ function renderSentenceWithFieldAndValue(props: { 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java_installer.sentence' )} values={{ - field: {field}, - value: {value}, + field: {field}, + value: {value}, }} /> ); @@ -42,10 +43,10 @@ function renderSentenceWithFieldAndValue(props: { export default function JavaToolInstallation() { return ( -
  • + {translate('onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java_installer.title')} -
      -
    • + + {renderSentenceWithFieldAndValue({ field: translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java_installer.java_version' @@ -56,16 +57,16 @@ export default function JavaToolInstallation() { {translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java_installer.or_higher' )} -
    • -
    • + + {renderSentenceWithFieldAndValue({ field: translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java_installer.java_architecture' ), value: 'x64', })} -
    • -
    • + + {renderSentenceWithFieldAndValue({ field: translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java_installer.java_source' @@ -74,8 +75,8 @@ export default function JavaToolInstallation() { 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java_installer.pre-installed' ), })} -
    • -
    -
  • + + + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/ServiceEndpointStepContent.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/ServiceEndpointStepContent.tsx index 72fbc966a82..af583bf3a0c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/ServiceEndpointStepContent.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/ServiceEndpointStepContent.tsx @@ -17,15 +17,20 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { + ButtonSecondary, + ClipboardIconButton, + NumberedList, + NumberedListItem, +} from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { Button } from '../../../components/controls/buttons'; -import { ClipboardIconButton } from '../../../components/controls/clipboard'; import { translate } from '../../../helpers/l10n'; import { TokenType } from '../../../types/token'; import { Component } from '../../../types/types'; import { LoggedInUser } from '../../../types/users'; import EditTokenModal from '../components/EditTokenModal'; +import { InlineSnippet } from '../components/InlineSnippet'; import SentenceWithHighlights from '../components/SentenceWithHighlights'; export interface ServiceEndpointStepProps { @@ -41,46 +46,50 @@ export default function ServiceEndpointStepContent(props: ServiceEndpointStepPro return ( <> -
      -
    1. + + -
    2. -
    3. + + -
    4. -
    5. + + {baseUrl}, - button: , + url: ( + + + + ), + button: , }} /> -
    6. -
    7. + + {translate('onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step4.sentence')}: - -
    8. -
    9. + + + {translate('onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step5.sentence')} -
    10. -
    11. + + {translate('onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step6.sentence')} -
    12. -
    + + {isModalVisible && ( { tokenMock.reset(); }); -it('should render correctly and allow navigating between the different steps', async () => { +it('should render correctly and allow token generation', async () => { renderAzurePipelinesTutorial(); const user = userEvent.setup(); @@ -58,9 +58,6 @@ it('should render correctly and allow navigating between the different steps', a //// Default step. assertDefaultStepIsCorrectlyRendered(); - // Continue. - await goToNextStep(user); - //// Token step. assertServiceEndpointStepIsCorrectlyRendered(); @@ -78,9 +75,6 @@ it('should render correctly and allow navigating between the different steps', a ).toBeInTheDocument(); await clickButton(user, 'continue', modal); - // Continue. - await goToNextStep(user); - //// Analysis step: .NET await user.click(getTutorialBuildButtons().dotnetBuildButton.get()); assertDotNetStepIsCorrectlyRendered(); @@ -111,55 +105,11 @@ it('should render correctly and allow navigating between the different steps', a assertOtherStepIsCorrectlyRendered(); //// Finish tutorial - await clickButton(user, 'tutorials.finish'); assertFinishStepIsCorrectlyRendered(); }); -it('allows to navigate back to a previous step', async () => { - renderAzurePipelinesTutorial(); - const user = userEvent.setup(); - - // No clickable steps. - expect( - screen.queryByRole('button', { - name: 'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title', - }) - ).not.toBeInTheDocument(); - - // Go to the next steps. - await goToNextStep(user); - await goToNextStep(user); - - // The first 2 steps become clickable. - expect( - screen.getByRole('button', { - name: 'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title', - }) - ).toBeInTheDocument(); - expect( - screen.getByRole('button', { - name: 'onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.title', - }) - ).toBeInTheDocument(); - - // Navigate back to the first step. - await clickButton(user, 'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title'); - - // No more clickable steps. - expect( - screen.queryByRole('button', { - name: 'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title', - }) - ).not.toBeInTheDocument(); -}); - -it('should not offer CFamily analysis if the language is not available', async () => { +it('should not offer CFamily analysis if the language is not available', () => { renderAzurePipelinesTutorial(undefined, { languages: {} }); - const user = userEvent.setup(); - - // Go to the analysis step. - await goToNextStep(user); - await goToNextStep(user); expect(getTutorialBuildButtons().dotnetBuildButton.get()).toBeInTheDocument(); expect(getTutorialBuildButtons().cFamilyBuildButton.query()).not.toBeInTheDocument(); @@ -179,7 +129,7 @@ function assertServiceEndpointStepIsCorrectlyRendered() { name: 'onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.title', }) ).toBeInTheDocument(); - expect(getCopyToClipboardValue()).toBe('https://sonarqube.example.com/'); + expect(getCopyToClipboardValue(0, 'Copy to clipboard')).toBe('https://sonarqube.example.com/'); expect( screen.getByRole('button', { name: 'onboarding.token.generate.long' }) ).toBeInTheDocument(); @@ -191,26 +141,31 @@ function assertDotNetStepIsCorrectlyRendered() { name: 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.title', }) ).toBeInTheDocument(); - expect(getCopyToClipboardValue()).toBe('foo'); + + expect(getCopyToClipboardValue(1, 'Copy to clipboard')).toBe('foo'); } function assertMavenStepIsCorrectlyRendered() { - expect(getCopyToClipboardValue()).toMatchSnapshot('maven, copy additional properties'); + expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('maven, copy additional properties'); } function assertGradleStepIsCorrectlyRendered() { - expect(getCopyToClipboardValue()).toMatchSnapshot('gradle, copy additional properties'); + expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('gradle, copy additional properties'); } function assertCFamilyStepIsCorrectlyRendered(os: string) { - expect(getCopyToClipboardValue(0)).toMatchSnapshot(`cfamily ${os}, copy shell script`); - expect(getCopyToClipboardValue(1)).toBe('foo'); - expect(getCopyToClipboardValue(2)).toMatchSnapshot(`cfamily ${os}, copy additional properties`); - expect(getCopyToClipboardValue(3)).toMatchSnapshot(`cfamily ${os}, copy build-wrapper command`); + expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(`cfamily ${os}, copy shell script`); + expect(getCopyToClipboardValue(1, 'Copy to clipboard')).toBe('foo'); + expect(getCopyToClipboardValue(2, 'Copy to clipboard')).toMatchSnapshot( + `cfamily ${os}, copy additional properties` + ); + expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot( + `cfamily ${os}, copy build-wrapper command` + ); } function assertOtherStepIsCorrectlyRendered() { - expect(getCopyToClipboardValue()).toBe('foo'); + expect(getCopyToClipboardValue(1, 'Copy to clipboard')).toBe('foo'); } function assertFinishStepIsCorrectlyRendered() { @@ -245,7 +200,3 @@ async function clickButton(user: UserEvent, name: string, context?: HTMLElement) await user.click(screen.getByRole('button', { name })); } } - -async function goToNextStep(user: UserEvent) { - await clickButton(user, 'continue'); -} diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap index cba7e2bcd12..2b4eb427b73 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap @@ -1,33 +1,33 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render correctly and allow navigating between the different steps: cfamily linux, copy additional properties 1`] = `"sonar.cfamily.build-wrapper-output=bw-output"`; +exports[`should render correctly and allow token generation: cfamily linux, copy additional properties 1`] = `"sonar.cfamily.build-wrapper-output=bw-output"`; -exports[`should render correctly and allow navigating between the different steps: cfamily linux, copy build-wrapper command 1`] = `"./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output "`; +exports[`should render correctly and allow token generation: cfamily linux, copy build-wrapper command 1`] = `"./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output "`; -exports[`should render correctly and allow navigating between the different steps: cfamily linux, copy shell script 1`] = ` +exports[`should render correctly and allow token generation: cfamily linux, copy shell script 1`] = ` "curl 'http://localhost/static/cpp/build-wrapper-linux-x86.zip' --output build-wrapper.zip unzip build-wrapper.zip" `; -exports[`should render correctly and allow navigating between the different steps: cfamily mac, copy additional properties 1`] = `"sonar.cfamily.build-wrapper-output=bw-output"`; +exports[`should render correctly and allow token generation: cfamily mac, copy additional properties 1`] = `"sonar.cfamily.build-wrapper-output=bw-output"`; -exports[`should render correctly and allow navigating between the different steps: cfamily mac, copy build-wrapper command 1`] = `"./build-wrapper-macos-x86/build-wrapper-macos-x86 --out-dir bw-output "`; +exports[`should render correctly and allow token generation: cfamily mac, copy build-wrapper command 1`] = `"./build-wrapper-macos-x86/build-wrapper-macos-x86 --out-dir bw-output "`; -exports[`should render correctly and allow navigating between the different steps: cfamily mac, copy shell script 1`] = ` +exports[`should render correctly and allow token generation: cfamily mac, copy shell script 1`] = ` "curl 'http://localhost/static/cpp/build-wrapper-macosx-x86.zip' --output build-wrapper.zip unzip build-wrapper.zip" `; -exports[`should render correctly and allow navigating between the different steps: cfamily win, copy additional properties 1`] = `"sonar.cfamily.build-wrapper-output=bw-output"`; +exports[`should render correctly and allow token generation: cfamily win, copy additional properties 1`] = `"sonar.cfamily.build-wrapper-output=bw-output"`; -exports[`should render correctly and allow navigating between the different steps: cfamily win, copy build-wrapper command 1`] = `"build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir bw-output "`; +exports[`should render correctly and allow token generation: cfamily win, copy build-wrapper command 1`] = `"build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir bw-output "`; -exports[`should render correctly and allow navigating between the different steps: cfamily win, copy shell script 1`] = ` +exports[`should render correctly and allow token generation: cfamily win, copy shell script 1`] = ` "Invoke-WebRequest -Uri 'http://localhost/static/cpp/build-wrapper-win-x86.zip' -OutFile 'build-wrapper.zip' Expand-Archive -Path 'build-wrapper.zip' -DestinationPath '.'" `; -exports[`should render correctly and allow navigating between the different steps: gradle, copy additional properties 1`] = ` +exports[`should render correctly and allow token generation: gradle, copy additional properties 1`] = ` "# Additional properties that will be passed to the scanner, # Put one key=value per line, example: # sonar.exclusions=**/*.bin @@ -36,7 +36,7 @@ sonar.projectName=MyProject " `; -exports[`should render correctly and allow navigating between the different steps: maven, copy additional properties 1`] = ` +exports[`should render correctly and allow token generation: maven, copy additional properties 1`] = ` "# Additional properties that will be passed to the scanner, # Put one key=value per line, example: # sonar.exclusions=**/*.bin diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx index eff9fcb8264..3e618d4190d 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AlertClassicEditor.tsx @@ -17,28 +17,32 @@ * 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 } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { Alert } from '../../../../components/ui/Alert'; import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { AlmKeys } from '../../../../types/alm-settings'; -import DocLink from '../../../common/DocLink'; export default function AlertClassicEditor() { + const docUrl = useDocUrl(); + return ( - - - {translate('onboarding.tutorial.with.azure_pipelines.BranchAnalysis.info.doc_link')} - - ), - }} - /> - + + + + {translate('onboarding.tutorial.with.azure_pipelines.BranchAnalysis.info.doc_link')} + + ), + }} + /> + + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx index 9b2078e5941..bc2dbe26694 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx @@ -33,13 +33,13 @@ export interface AnalysisCommandProps { } export default function AnalysisCommand(props: AnalysisCommandProps) { - const { buildTool, projectKey, projectName } = props; + const { buildTool, onStepValidationChange, projectKey, projectName } = props; React.useEffect(() => { if (buildTool && buildTool !== BuildTools.CFamily) { - props.onStepValidationChange(true); + onStepValidationChange(true); } - }, [buildTool, props.onStepValidationChange]); + }, [buildTool, onStepValidationChange]); if (!buildTool) { return null; diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx index 2796120d285..2b84388ef07 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx @@ -17,10 +17,16 @@ * 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, + NumberedList, + NumberedListItem, + UnorderedList, + UnorderedListItem, +} from 'design-system'; import * as React from 'react'; import { translate } from '../../../../helpers/l10n'; import { getHostUrl } from '../../../../helpers/urls'; -import CodeSnippet from '../../../common/CodeSnippet'; import { CompilationInfo } from '../../components/CompilationInfo'; import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories'; import RenderOptions from '../../components/RenderOptions'; @@ -44,7 +50,7 @@ type OsConstant = { }; export default function ClangGCC(props: ClangGCCProps) { - const { projectKey } = props; + const { projectKey, onStepValidationChange } = props; const [os, setOs] = React.useState(); const host = getHostUrl(); @@ -77,11 +83,11 @@ unzip build-wrapper.zip`, React.useEffect(() => { if (os) { - props.onStepValidationChange(true); + onStepValidationChange(true); } else { - props.onStepValidationChange(false); + onStepValidationChange(false); } - }, [os, props.onStepValidationChange]); + }, [os, onStepValidationChange]); const handlOsChange = (value: OSs) => { setOs(value); @@ -89,9 +95,7 @@ unzip build-wrapper.zip`, return ( <> - - {translate('onboarding.tutorial.with.azure_pipelines.os')} - +
    {translate('onboarding.tutorial.with.azure_pipelines.os')}
    -
      -
    1. + + -
        -
      • + + - -
      • -
      -
    2. + + + + -
    3. + -
    4. + -
    5. + -
        -
      • + + - + -
      • -
      -
    6. + + + -
    7. + -
    8. + + -
    + )} diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/DotNet.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/DotNet.tsx index 0b66059a3cf..f169fac87e2 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/DotNet.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/DotNet.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 { NumberedList, NumberedListItem } from 'design-system'; import * as React from 'react'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; import { BuildTools } from '../../types'; @@ -33,8 +34,8 @@ export default function DotNet(props: DotNetProps): JSX.Element { return ( <> -
      -
    1. + + -
    2. -
    3. + + -
    4. + -
    + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaGradle.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaGradle.tsx index 5e098e2a243..d13c33863b1 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaGradle.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaGradle.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 { NumberedList, NumberedListItem, UnorderedList, UnorderedListItem } from 'design-system'; import * as React from 'react'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; @@ -37,8 +38,8 @@ export default function JavaGradle(props: JavaGradleProps) { return ( <> -
      -
    1. + + -
    2. + -
    3. + {translateWithParameters( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java', translate('onboarding.build', BuildTools.Gradle) )} -
        -
      • + + -
      • -
      -
    4. + + + -
    + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaMaven.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaMaven.tsx index a7e7f9941bf..d7a5878228e 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaMaven.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/JavaMaven.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 { NumberedList, NumberedListItem, UnorderedList, UnorderedListItem } from 'design-system'; import * as React from 'react'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; @@ -36,8 +37,8 @@ export default function JavaMaven(props: JavaMavenProps) { return ( <> -
      -
    1. + + -
    2. + -
    3. + {translateWithParameters( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java', translate('onboarding.build', BuildTools.Maven) )} -
        -
      • + + -
      • -
      -
    4. + + + -
    + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/Other.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/Other.tsx index e1612a94be3..a04fd2fbe49 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/Other.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/Other.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 { NumberedList, NumberedListItem } from 'design-system'; import * as React from 'react'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; import { BuildTools } from '../../types'; @@ -33,8 +34,8 @@ export default function Other(props: OtherProps) { return ( <> -
      -
    1. + + -
    2. + -
    3. + -
    4. + -
    + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx index dc6e5975f2f..5a92bb6ef0b 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.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 { ClipboardIconButton, CodeSnippet, UnorderedList, UnorderedListItem } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { ClipboardIconButton } from '../../../../components/controls/clipboard'; import { translate } from '../../../../helpers/l10n'; -import CodeSnippet from '../../../common/CodeSnippet'; +import { InlineSnippet } from '../../components/InlineSnippet'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; import { BuildTools } from '../../types'; @@ -51,14 +51,14 @@ sonar.projectName=${projectName} `; return ( -
      -
    • + + -
    • -
    • + + + {translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.section' )} - + ), run_analysis_value: ( - + {translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values', buildTool )} - + ), }} /> -
    • + {kind === PrepareType.StandAlone && ( <> -
    • + -
    • + -
    • - - {translate( - 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence.project_key' - )} - - ), - key: {projectKey}, - button: , - }} - /> -
    • - {buildTool === BuildTools.CFamily && ( -
    • + + + project_key: ( + {translate( - 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp.advanced' + 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence.project_key' )} ), - additional: ( - - {translate( - 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp.additional' - )} - + key: ( + + + ), - property: {ADDITIONAL_PROPERTY}, - button: , + button: , }} /> -
    • + + + {buildTool === BuildTools.CFamily && ( + + + + {translate( + 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp.advanced' + )} + + ), + additional: ( + + {translate( + 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp.additional' + )} + + ), + property: ( + + + + ), + button: ( + + ), + }} + /> + + )} )} {kind === PrepareType.JavaMavenGradle && ( -
    • + : - -
    • + + )} {kind === PrepareType.MSBuild && ( -
    • - - {translate( - 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence.project_key' - )} - - ), - key: {projectKey}, - button: , - }} - /> -
    • + + + + {translate( + 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence.project_key' + )} + + ), + key: ( + + + + ), + button: , + }} + /> + + )} -
    + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx index 7366050a733..98088edb4d3 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx @@ -17,37 +17,40 @@ * 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, FlagMessage, Link, NumberedListItem } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import withAvailableFeatures, { WithAvailableFeaturesProps, } from '../../../../app/components/available-features/withAvailableFeatures'; -import { Alert } from '../../../../components/ui/Alert'; import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; +import { useDocUrl } from '../../../../helpers/docs'; import { translate } from '../../../../helpers/l10n'; import { AlmKeys } from '../../../../types/alm-settings'; import { Feature } from '../../../../types/features'; -import DocLink from '../../../common/DocLink'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; export interface PublishStepsProps extends WithAvailableFeaturesProps {} + export function PublishSteps(props: PublishStepsProps) { const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); + const docUrl = useDocUrl(); + return ( <> -
  • + - + {translate( 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.info.sentence1' )} - -
  • -
  • + + + -
  • + {branchSupportEnabled && ( <> -
    - - {translate( - 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link' - )} - - ), - }} - /> + +
    + + {translate( + 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link' + )} + + ), + }} + /> +
    )} diff --git a/server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.css b/server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.css deleted file mode 100644 index ac6236b0881..00000000000 --- a/server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.css +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2023 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. - */ -.github-cfamily-example-repositories-box { - box-sizing: border-box; -} diff --git a/server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.tsx b/server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.tsx index 332ba0ff603..59c2ca6e6e9 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/GithubCFamilyExampleRepositories.tsx @@ -23,7 +23,6 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; import { getBaseUrl } from '../../../helpers/system'; import { OSs, TutorialModes } from '../types'; -import './GithubCFamilyExampleRepositories.css'; export interface GithubCFamilyExampleRepositoriesProps { className?: string; @@ -61,7 +60,7 @@ export default function GithubCFamilyExampleRepositories(
    diff --git a/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithHighlights.tsx b/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithHighlights.tsx index 47dae010bf2..2f99635caed 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithHighlights.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/SentenceWithHighlights.tsx @@ -37,7 +37,11 @@ export default function SentenceWithHighlights({ const transhighlightPrefixKeys = highlightPrefixKeys || translationKey; highlightKeys.forEach((key) => { - values[key] = {translate(transhighlightPrefixKeys, 'sentence', key)}; + values[key] = ( + + {translate(transhighlightPrefixKeys, 'sentence', key)} + + ); }); return (