]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19922 Cleaning up indentation with some fixes
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>
Thu, 20 Jul 2023 13:43:21 +0000 (15:43 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 21 Jul 2023 20:03:17 +0000 (20:03 +0000)
25 files changed:
server/sonar-web/design-system/src/components/CodeSnippet.tsx
server/sonar-web/design-system/src/components/__tests__/CodeSnippet-test.tsx
server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap
server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/RepositoryVariables.tsx
server/sonar-web/src/main/js/components/tutorials/components/GradleBuild.tsx
server/sonar-web/src/main/js/components/tutorials/gitlabci/EnvironmentVariablesStep.tsx
server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsfileStep.tsx [deleted file]
server/sonar-web/src/main/js/components/tutorials/jenkins/MultiBranchPipelineStep.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepBitbucket.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGitLab.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGithub.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CreateJenkinsfileBulletPoint.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetCore.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetFramework.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsMSBuild.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNetPrereqsScanner.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Gradle.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Maven.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/Other.tsx
server/sonar-web/src/main/js/components/tutorials/other/BuildToolForm.tsx

index bf11a5632bab9aa610606b596fb79c8b9eb6b507..fcb8532c4877ab35e1e6f8c6cbca591bb50d32c3 100644 (file)
@@ -19,6 +19,7 @@
  */
 import styled from '@emotion/styled';
 import classNames from 'classnames';
+import { escape as lodashEscape } from 'lodash';
 import tw from 'twin.macro';
 import { themeBorder, themeColor } from '../helpers/theme';
 import { isDefined } from '../helpers/types';
@@ -53,7 +54,10 @@ export function CodeSnippet(props: Props) {
     <StyledClipboardButton copyValue={finalSnippet} />
   );
 
-  const renderSnippet = render ?? (wrap || isOneLine ? finalSnippet : `<pre>${finalSnippet}</pre>`);
+  const renderSnippet =
+    render ?? (wrap || isOneLine)
+      ? `<code>${lodashEscape(finalSnippet)}</code>`
+      : `<pre>${lodashEscape(finalSnippet)}</pre>`;
 
   return (
     <Wrapper
index 8b0aad26b4c6f912d349e65d4b8bcd72494eeb68..13d0a5bde5792d569356d9345f4b77b638e9d817 100644 (file)
@@ -23,20 +23,25 @@ import { renderWithContext } from '../../helpers/testUtils';
 import { FCProps } from '../../types/misc';
 import { CodeSnippet } from '../CodeSnippet';
 
-it('should show full size when multiline with no editting', () => {
+it('should show full size when multiline with no editing', () => {
   const { container } = setupWithProps();
   const copyButton = screen.getByRole('button', { name: 'Copy' });
   expect(copyButton).toHaveStyle('top: 1.5rem');
   expect(container).toMatchSnapshot();
 });
 
-it('should show reduced size when single line with no editting', () => {
+it('should show reduced size when single line with no editing', () => {
   const { container } = setupWithProps({ isOneLine: true, snippet: 'foobar' });
   const copyButton = screen.getByRole('button', { name: 'Copy' });
   expect(copyButton).toHaveStyle('top: 1rem');
   expect(container).toMatchSnapshot();
 });
 
+it('should highlight code content correctly', () => {
+  const { container } = setupWithProps({ snippet: '<prop>foobar<prop>' });
+  expect(container).toMatchSnapshot();
+});
+
 function setupWithProps(props: Partial<FCProps<typeof CodeSnippet>> = {}) {
   return renderWithContext(
     <HelmetProvider>
index e52ece83539db3bb5950c9c7738095ae156697df..20b9a394505ad74842ccf67ea91577e4f0586691 100644 (file)
@@ -1,6 +1,213 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should show full size when multiline with no editting 1`] = `
+exports[`should highlight code content correctly 1`] = `
+.emotion-0 {
+  background-color: rgb(252,252,253);
+  border: 1px solid rgb(225,230,243);
+  border-radius: 0.5rem;
+  position: relative;
+  margin-top: 0.5rem;
+  margin-bottom: 0.5rem;
+}
+
+.emotion-0.code-snippet-simple-oneline {
+  margin-top: 0;
+  margin-bottom: 0;
+  border-radius: 0.25rem;
+}
+
+.emotion-4 {
+  box-sizing: border-box;
+  -webkit-text-decoration: none;
+  text-decoration: none;
+  outline: none;
+  border: var(--border);
+  color: var(--color);
+  background-color: var(--background);
+  -webkit-transition: background-color 0.2s ease,outline 0.2s ease;
+  transition: background-color 0.2s ease,outline 0.2s ease;
+  display: -webkit-inline-box;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  height: 2.25rem;
+  font-family: Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 600;
+  padding-left: 1rem;
+  padding-right: 1rem;
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+  border-radius: 0.5rem;
+  cursor: pointer;
+  --background: rgb(255,255,255);
+  --backgroundHover: rgb(239,242,249);
+  --color: rgb(62,67,87);
+  --focus: rgba(197,205,223,0.2);
+  --border: 1px solid rgb(197,205,223);
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  font-family: Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+  right: 1.5rem;
+  top: 1.5rem;
+  position: absolute;
+}
+
+.emotion-4:hover,
+.emotion-4:active {
+  color: var(--color);
+  background-color: var(--backgroundHover);
+}
+
+.emotion-4:focus,
+.emotion-4:active {
+  color: var(--color);
+  outline: 4px solid var(--focus);
+}
+
+.emotion-4:disabled,
+.emotion-4:disabled:hover {
+  color: rgb(166,173,194);
+  background-color: rgb(239,242,249);
+  border: 1px solid rgb(197,205,223);
+  cursor: not-allowed;
+}
+
+.emotion-4>svg {
+  margin-right: 0.25rem;
+}
+
+.emotion-4 [disabled] {
+  pointer-events: none;
+}
+
+.emotion-4:hover,
+.emotion-4:active,
+.emotion-4:focus {
+  border-color: rgb(197,205,223);
+}
+
+.code-snippet-highlighted-oneline .emotion-4 {
+  bottom: 0.5rem;
+}
+
+.emotion-6 code {
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.125rem;
+  font-weight: 400;
+  background: rgb(252,252,253);
+  color: rgb(51,53,60);
+}
+
+.emotion-6 code.hljs {
+  padding: unset;
+}
+
+.emotion-6 .hljs-meta,
+.emotion-6 .hljs-variable {
+  color: rgb(51,53,60);
+}
+
+.emotion-6 .hljs-doctag,
+.emotion-6 .hljs-title,
+.emotion-6 .hljs-title.class_,
+.emotion-6 .hljs-title.function_ {
+  color: rgb(34,84,192);
+}
+
+.emotion-6 .hljs-comment {
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.125rem;
+  font-style: italic;
+  color: rgb(109,111,119);
+}
+
+.emotion-6 .hljs-keyword,
+.emotion-6 .hljs-tag,
+.emotion-6 .hljs-type {
+  color: rgb(152,29,150);
+}
+
+.emotion-6 .hljs-literal,
+.emotion-6 .hljs-number {
+  color: rgb(126,83,5);
+}
+
+.emotion-6 .hljs-string {
+  color: rgb(32,105,31);
+}
+
+.emotion-6 .hljs-meta .hljs-keyword {
+  color: rgb(47,103,48);
+}
+
+.emotion-6.code-wrap {
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.emotion-6 mark {
+  font-weight: 400;
+  padding: 0.25rem;
+  border-radius: 0.25rem;
+  background-color: rgb(197,205,223);
+  color: rgb(217,45,32);
+}
+
+<div>
+  <div
+    class="sw-code fs-mask emotion-0 emotion-1"
+  >
+    <button
+      aria-describedby="tooltip-3"
+      class="sw-select-none emotion-2 emotion-3 emotion-4 emotion-5"
+      data-clipboard-text="<prop>foobar<prop>"
+      type="button"
+    >
+      <svg
+        aria-hidden="true"
+        class="octicon octicon-copy"
+        fill="currentColor"
+        focusable="false"
+        height="16"
+        role="img"
+        style="display: inline-block; user-select: none; vertical-align: middle; overflow: visible;"
+        viewBox="0 0 16 16"
+        width="16"
+      >
+        <path
+          d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"
+        />
+        <path
+          d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"
+        />
+      </svg>
+      Copy
+    </button>
+    <span
+      class="hljs sw-overflow-auto sw-pr-24 sw-flex emotion-6 emotion-7"
+    >
+      <pre>
+        &lt;prop&gt;foobar&lt;prop&gt;
+      </pre>
+    </span>
+  </div>
+</div>
+`;
+
+exports[`should show full size when multiline with no editing 1`] = `
 .emotion-0 {
   background-color: rgb(252,252,253);
   border: 1px solid rgb(225,230,243);
@@ -209,7 +416,7 @@ bar
 </div>
 `;
 
-exports[`should show reduced size when single line with no editting 1`] = `
+exports[`should show reduced size when single line with no editing 1`] = `
 .emotion-0 {
   background-color: rgb(252,252,253);
   border: 1px solid rgb(225,230,243);
@@ -410,7 +617,9 @@ exports[`should show reduced size when single line with no editting 1`] = `
     <span
       class="hljs sw-overflow-auto sw-pr-24 sw-flex emotion-6 emotion-7"
     >
-      foobar
+      <code>
+        foobar
+      </code>
     </span>
   </div>
 </div>
index a84a805333535d0b83ceaf3daa1041e05a9fd0d9..cf7b50ab403302d3dc5b9331cb6222c46d45772b 100644 (file)
@@ -112,7 +112,7 @@ export default function RepositoryVariables(props: RepositoryVariablesProps) {
             defaultMessage={translate('onboarding.tutorial.env_variables')}
             id="onboarding.tutorial.env_variables"
             values={{
-              extra: <ClipboardIconButton copyValue={baseUrl} />,
+              extra: <ClipboardIconButton copyValue={baseUrl} className="sw-ml-1" />,
               field: (
                 <span className="sw-body-sm-highlight">
                   {translate('onboarding.tutorial.env_variables.field')}
index 6e1edddb92b7a9aa99b8264e52d504e8c3265221..b71bcc00289b19f2ccc7058e6fa376ea49be0532 100644 (file)
@@ -56,7 +56,7 @@ export default function GradleBuild({ component }: Props) {
       <GradleBuildSelection className="sw-my-4">
         {(build) => (
           <CodeSnippet
-            language="gradle"
+            language={build === GradleBuildDSL.Groovy ? 'groovy' : 'kotlin'}
             className="sw-p-6"
             snippet={buildGradleSnippet(component.key, component.name, build)}
           />
index 843cacaae4f71fdc8a6241ef74349d6d8a995ec8..38a8de03348480f2bb0519db7177b9c61863990e 100644 (file)
@@ -71,7 +71,7 @@ export default function EnvironmentVariablesStep(props: EnvironmentVariablesStep
               defaultMessage={fieldValueTranslation}
               id="onboarding.tutorial.with.gitlab_ci.variables.step1"
               values={{
-                extra: <ClipboardIconButton copyValue="SONAR_TOKEN" />,
+                extra: <ClipboardIconButton copyValue="SONAR_TOKEN" className="sw-ml-1" />,
                 field: (
                   <span className="sw-body-sm-highlight">
                     {translate('onboarding.tutorial.with.gitlab_ci.variables.step1')}
@@ -135,7 +135,7 @@ export default function EnvironmentVariablesStep(props: EnvironmentVariablesStep
               defaultMessage={fieldValueTranslation}
               id="onboarding.tutorial.with.gitlab_ci.variables.step1"
               values={{
-                extra: <ClipboardIconButton copyValue="SONAR_HOST_URL" />,
+                extra: <ClipboardIconButton copyValue="SONAR_HOST_URL" className="sw-ml-1" />,
                 field: (
                   <span className="sw-body-sm-highlight">
                     {translate('onboarding.tutorial.with.gitlab_ci.variables.step1')}
@@ -150,7 +150,7 @@ export default function EnvironmentVariablesStep(props: EnvironmentVariablesStep
               defaultMessage={fieldValueTranslation}
               id="onboarding.tutorial.with.gitlab_ci.variables.step2"
               values={{
-                extra: <ClipboardIconButton copyValue={baseUrl} />,
+                extra: <ClipboardIconButton copyValue={baseUrl} className="sw-ml-1" />,
                 field: (
                   <span className="sw-body-sm-highlight">
                     {translate('onboarding.tutorial.env_variables.field')}
index b06d09d08e8b374772590a903bf95e286cc19037..1f5d6c95f9907afa4fc40dec1d59c0ad71541626 100644 (file)
@@ -100,6 +100,13 @@ const filenameForBuildTool = {
   [BuildTools.Other]: 'sonar-project.properties',
 };
 
+const snippetLanguageForBuildTool = {
+  [BuildTools.CFamily]: undefined,
+  [BuildTools.Gradle]: undefined,
+  [BuildTools.Maven]: 'xml',
+  [BuildTools.Other]: undefined,
+};
+
 export function YmlFileStep(props: YmlFileStepProps) {
   const { component, hasCLanguageFeature } = props;
 
@@ -178,7 +185,7 @@ export function YmlFileStep(props: YmlFileStepProps) {
                 {(build) => (
                   <CodeSnippet
                     className="sw-p-6"
-                    language="yml"
+                    language="gradle"
                     snippet={snippetForBuildTool[buildTool](component.key, component.name, build)}
                   />
                 )}
@@ -186,7 +193,7 @@ export function YmlFileStep(props: YmlFileStepProps) {
             ) : (
               <CodeSnippet
                 className="sw-p-6"
-                language="yml"
+                language={snippetLanguageForBuildTool[buildTool]}
                 snippet={snippetForBuildTool[buildTool](component.key, component.name)}
               />
             )}
diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx
new file mode 100644 (file)
index 0000000..12394ea
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+import { FlagMessage, NumberedList, NumberedListItem, TutorialStep } from 'design-system';
+import * as React from 'react';
+import { translate } from '../../../helpers/l10n';
+import { Component } from '../../../types/types';
+import { withCLanguageFeature } from '../../hoc/withCLanguageFeature';
+import RenderOptions from '../components/RenderOptions';
+import { BuildTools } from '../types';
+import CFamilly from './buildtool-steps/CFamilly';
+import DotNet from './buildtool-steps/DotNet';
+import Gradle from './buildtool-steps/Gradle';
+import Maven from './buildtool-steps/Maven';
+import Other from './buildtool-steps/Other';
+
+const BUILD_TOOLS_WITH_NO_ADDITIONAL_OPTIONS = [
+  BuildTools.Maven,
+  BuildTools.Gradle,
+  BuildTools.Other,
+];
+
+const BUILDTOOL_COMPONENT_MAP: {
+  [x in BuildTools]: React.ComponentType<LanguageProps>;
+} = {
+  [BuildTools.Maven]: Maven,
+  [BuildTools.Gradle]: Gradle,
+  [BuildTools.DotNet]: DotNet,
+  [BuildTools.CFamily]: CFamilly,
+  [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, 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 (
+    <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>
+  );
+}
+
+export default withCLanguageFeature(JenkinsfileStep);
index 03ca049eab28705090c688c54c53799cb90a3608..a97684627988bad14d5f007d39e3f8f046c4647d 100644 (file)
@@ -17,7 +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 { BasicSeparator, Title, TutorialStepList } from 'design-system';
 import * as React from 'react';
 import withAvailableFeatures, {
   WithAvailableFeaturesProps,
@@ -31,7 +31,7 @@ import {
 import { Feature } from '../../../types/features';
 import { Component } from '../../../types/types';
 import AllSet from '../components/AllSet';
-import JenkinsfileStep from './JenkinsfileStep';
+import JenkinsfileStep from './JenkinsStep';
 import MultiBranchPipelineStep from './MultiBranchPipelineStep';
 import PipelineStep from './PipelineStep';
 import PreRequisitesStep from './PreRequisitesStep';
@@ -58,30 +58,30 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) {
       <Title>{translate('onboarding.tutorial.with.jenkins.title')}</Title>
 
       {hasSelectAlmStep && <SelectAlmStep alm={alm} onChange={setAlm} />}
-
       {alm && (
         <>
-          <PreRequisitesStep alm={alm} branchesEnabled={branchSupportEnabled} />
+          <TutorialStepList className="sw-mb-10">
+            <PreRequisitesStep alm={alm} branchesEnabled={branchSupportEnabled} />
+
+            {branchSupportEnabled ? (
+              <MultiBranchPipelineStep
+                alm={alm}
+                almBinding={almBinding}
+                projectBinding={projectBinding}
+              />
+            ) : (
+              <PipelineStep alm={alm} />
+            )}
 
-          {branchSupportEnabled ? (
-            <MultiBranchPipelineStep
+            <WebhookStep
               alm={alm}
               almBinding={almBinding}
+              branchesEnabled={branchSupportEnabled}
               projectBinding={projectBinding}
             />
-          ) : (
-            <PipelineStep alm={alm} />
-          )}
-
-          <WebhookStep
-            alm={alm}
-            almBinding={almBinding}
-            branchesEnabled={branchSupportEnabled}
-            projectBinding={projectBinding}
-          />
-
-          <JenkinsfileStep component={component} baseUrl={baseUrl} onDone={setDone} />
 
+            <JenkinsfileStep component={component} baseUrl={baseUrl} onDone={setDone} />
+          </TutorialStepList>
           {done && (
             <>
               <BasicSeparator className="sw-my-10" />
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
deleted file mode 100644 (file)
index 12394ea..0000000
+++ /dev/null
@@ -1,106 +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.
- */
-import { FlagMessage, NumberedList, NumberedListItem, TutorialStep } from 'design-system';
-import * as React from 'react';
-import { translate } from '../../../helpers/l10n';
-import { Component } from '../../../types/types';
-import { withCLanguageFeature } from '../../hoc/withCLanguageFeature';
-import RenderOptions from '../components/RenderOptions';
-import { BuildTools } from '../types';
-import CFamilly from './buildtool-steps/CFamilly';
-import DotNet from './buildtool-steps/DotNet';
-import Gradle from './buildtool-steps/Gradle';
-import Maven from './buildtool-steps/Maven';
-import Other from './buildtool-steps/Other';
-
-const BUILD_TOOLS_WITH_NO_ADDITIONAL_OPTIONS = [
-  BuildTools.Maven,
-  BuildTools.Gradle,
-  BuildTools.Other,
-];
-
-const BUILDTOOL_COMPONENT_MAP: {
-  [x in BuildTools]: React.ComponentType<LanguageProps>;
-} = {
-  [BuildTools.Maven]: Maven,
-  [BuildTools.Gradle]: Gradle,
-  [BuildTools.DotNet]: DotNet,
-  [BuildTools.CFamily]: CFamilly,
-  [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, 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 (
-    <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>
-  );
-}
-
-export default withCLanguageFeature(JenkinsfileStep);
index 5907b2baf595867d310dc3dd12ccaa46bead4477..17a01755dc3110f578b6e60102be49ad4019c9e1 100644 (file)
@@ -181,7 +181,7 @@ export default function MultiBranchPipelineStep(props: MultiBranchPipelineStepPr
                 )}
                 :
               </strong>
-              <UnorderedList ticks className="sw-ml-4 sw-mt-1 sw-w-abs-600">
+              <UnorderedList ticks className="sw-ml-4 sw-mt-1">
                 <ListItem>
                   <LabelActionPair
                     translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviors.${
index 63ff06f5c7990810b3f773a1b22d35bc630d36a1..43349200275b0554a9cb2fe479be37812cbcee98 100644 (file)
@@ -93,7 +93,7 @@ export default function WebhookStepBitbucket(props: WebhookStepBitbucketProps) {
           <ListItem>
             <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.step1.name" />
           </ListItem>
-          <ListItem className="sw-w-abs-600">
+          <ListItem>
             <p>
               <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url" />
             </p>
index 883d086041cfad054c29fa6b741e2626f19237a3..e1829267589f1ce111d4bd99b4204bda4e4e5855 100644 (file)
@@ -41,7 +41,7 @@ export default function WebhookStepGitLab({ branchesEnabled }: WebhookStepGitLab
         />
         <UnorderedList ticks className="sw-ml-12">
           {branchesEnabled ? (
-            <ListItem className="sw-w-abs-600">
+            <ListItem>
               <p>
                 <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.gitlab.step1.url_with_branches" />
               </p>
index bea0464256e11d99f17d0470989d2914738a6f7f..4046ba3890b71ea09f7d25c1d83d560ac5a7bd7e 100644 (file)
@@ -61,7 +61,7 @@ export default function WebhookStepGithub(props: WebhookStepGithubProps) {
           }}
         />
         <UnorderedList ticks className="sw-ml-12">
-          <ListItem className="sw-w-abs-600">
+          <ListItem>
             <p>
               <LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.github.step1.url" />
             </p>
index a0e21e870132863755a724e7a596824948ffc179..0e42069ef583b85b52cac66f8d664cccc86359ef 100644 (file)
@@ -25,7 +25,7 @@ import DefaultProjectKey from '../../components/DefaultProjectKey';
 import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories';
 import RenderOptions from '../../components/RenderOptions';
 import { OSs, TutorialModes } from '../../types';
-import { LanguageProps } from '../JenkinsfileStep';
+import { LanguageProps } from '../JenkinsStep';
 import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint';
 
 const YAML_MAP: Record<OSs, (baseUrl: string) => string> = {
@@ -104,7 +104,7 @@ const YAML_MAP: Record<OSs, (baseUrl: string) => string> = {
 
 export default function CFamilly(props: LanguageProps) {
   const { baseUrl, component, onDone } = props;
-  const [os, setOs] = React.useState<OSs>();
+  const [os, setOs] = React.useState<OSs>(OSs.Linux);
 
   React.useEffect(() => {
     onDone(os !== undefined);
@@ -113,24 +113,22 @@ export default function CFamilly(props: LanguageProps) {
   return (
     <>
       <DefaultProjectKey component={component} />
-      <NumberedListItem className="sw-max-w-2/3">
+      <NumberedListItem>
         {translate('onboarding.build.other.os')}
-        <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)}
+        <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="sw-my-4 sw-w-abs-600"
+            os={os}
+            ci={TutorialModes.Jenkins}
           />
-          {os && (
-            <GithubCFamilyExampleRepositories
-              className="sw-my-4"
-              os={os}
-              ci={TutorialModes.Jenkins}
-            />
-          )}
-        </div>
+        )}
       </NumberedListItem>
       {os && (
         <CreateJenkinsfileBulletPoint
index ba4930155f9902fb974ca8b70c7c1664962cac53..03aed27f960dc908590091370aee668855a03589 100644 (file)
@@ -33,46 +33,45 @@ export default function CreateJenkinsfileBulletPoint(props: CreateJenkinsfileBul
   const { children, snippet, alertTranslationKeyPart } = props;
 
   return (
-    <NumberedListItem className="sw-max-w-2/3">
+    <NumberedListItem>
       <SentenceWithFilename
         filename="Jenkinsfile"
         translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step"
       />
-      <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>
+      <br />
+      {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}
     </NumberedListItem>
   );
 }
index d39dfed053f8edf319155300d0ef1427118b9b23..4d48a3878d47b5ae5fbe3ae893df1bc6a3de7bd3 100644 (file)
@@ -23,7 +23,7 @@ import { translate } from '../../../../helpers/l10n';
 import { Component } from '../../../../types/types';
 import RenderOptions from '../../components/RenderOptions';
 import { OSs } from '../../types';
-import { LanguageProps } from '../JenkinsfileStep';
+import { LanguageProps } from '../JenkinsStep';
 import DotNetCore from './DotNetCore';
 import DotNetFramework from './DotNetFramework';
 
@@ -43,7 +43,8 @@ const DotOS: { [key in keyof typeof DotNetFlavor]: OSDotNet } = {
 
 export default function DotNet(props: LanguageProps) {
   const { component, onDone } = props;
-  const [flavorComponent, setFlavorComponent] = React.useState<keyof typeof DotNetFlavor>();
+  const [flavorComponent, setFlavorComponent] =
+    React.useState<keyof typeof DotNetFlavor>('win_core');
   const DotNetTutorial = flavorComponent && DotNetFlavor[flavorComponent];
 
   React.useEffect(() => {
@@ -54,15 +55,13 @@ export default function DotNet(props: LanguageProps) {
     <>
       <NumberedListItem>
         {translate('onboarding.tutorial.with.jenkins.jenkinsfile.dotnet.build_agent')}
-        <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>
+        <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)}
+        />
       </NumberedListItem>
       {DotNetTutorial && flavorComponent && (
         <DotNetTutorial component={component} os={DotOS[flavorComponent]} />
index 9987c9863e1fdf136defb14763cccd9459672d05..4a5a62224adec35020f88b885822d2cc50f3fe10 100644 (file)
@@ -48,13 +48,13 @@ export default function DotNetCore({ component, os }: DotNetCoreFrameworkProps)
   return (
     <>
       <DotNetPrereqsScanner />
-      <NumberedListItem className="sw-max-w-2/3">
+      <NumberedListItem>
         <SentenceWithFilename
           filename="Jenkinsfile"
           translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step"
         />
         <CodeSnippet
-          className="sw-ml-8 sw-p-6"
+          className="sw-p-6"
           language="groovy"
           snippet={jenkinsfileSnippet(component.key, os)}
         />
index a7e3eab0918545c6423dbc7dad8f11cfdf71c5bc..4ae7fe8fc154defc027bf7a2475fb096d7b6daae 100644 (file)
@@ -45,7 +45,7 @@ export default function DotNetFramework({ component }: DotNetCoreFrameworkProps)
     <>
       <DotNetPrereqsScanner />
       <DotNetPrereqsMSBuild />
-      <NumberedListItem className="sw-max-w-2/3">
+      <NumberedListItem>
         <SentenceWithFilename
           filename="Jenkinsfile"
           translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step"
index 79796519486bf390c1de9edee8723df2668b1bae..a73c2e813afeeeabccd0fffd55551d823ba2b482 100644 (file)
@@ -31,7 +31,7 @@ import SentenceWithHighlights from '../../components/SentenceWithHighlights';
 
 export default function DotNetPrereqsMSBuild() {
   return (
-    <NumberedListItem className="sw-max-w-2/3">
+    <NumberedListItem>
       <SentenceWithHighlights
         highlightKeys={['default_msbuild']}
         translationKey="onboarding.tutorial.with.jenkins.dotnet.msbuild.prereqs.title"
index 1d2c961dca3d4f844e9da252190f2461b3333191..b47692c26a20d81fe29a752ebbcd19a54e9098b6 100644 (file)
@@ -31,12 +31,13 @@ import SentenceWithHighlights from '../../components/SentenceWithHighlights';
 
 export default function DotNetPrereqsScanner() {
   return (
-    <NumberedListItem className="sw-max-w-2/3">
+    <NumberedListItem>
       <SentenceWithHighlights
         highlightKeys={['default_scanner']}
         translationKey="onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.title"
       />
-      <FlagMessage className="sw-ml-8 sw-mt-2" variant="info">
+      <br />
+      <FlagMessage className="sw-mt-2" variant="info">
         {translate('onboarding.tutorial.with.jenkins.dotnet.scanner.prereqs.info')}
       </FlagMessage>
       <OrderedList tickStyle="ALPHA" className="sw-ml-12">
index 03aa14f18179e59b9c02df4498e1c9c57274340f..662256ee14cdfe41447a37776e1325868bc76ee3 100644 (file)
@@ -25,7 +25,7 @@ import GradleBuildSelection from '../../components/GradleBuildSelection';
 import { InlineSnippet } from '../../components/InlineSnippet';
 import { GradleBuildDSL } from '../../types';
 import { buildGradleSnippet } from '../../utils';
-import { LanguageProps } from '../JenkinsfileStep';
+import { LanguageProps } from '../JenkinsStep';
 import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint';
 
 const JENKINSFILE_SNIPPET = `node {
@@ -44,7 +44,7 @@ export default function Gradle(props: LanguageProps) {
 
   return (
     <>
-      <NumberedListItem className="sw-max-w-2/3">
+      <NumberedListItem>
         <span>
           <FormattedMessage
             defaultMessage={translate(
@@ -58,17 +58,15 @@ export default function Gradle(props: LanguageProps) {
             }}
           />
         </span>
-        <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>
+        <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>
       </NumberedListItem>
       <CreateJenkinsfileBulletPoint snippet={JENKINSFILE_SNIPPET} />
     </>
index 2ac775c1027cf09725fc9b92e48f277fb322f87e..9c8a1e5c5cf320b72a3485f976af4b58a329c3a8 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import { LanguageProps } from '../JenkinsfileStep';
+import { LanguageProps } from '../JenkinsStep';
 import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint';
 
 function jenkinsfileSnippet(projectKey: string, projectName: string) {
index c9c8fcad16e90eb4188b56f9dd45289a9e1ff446..0a12687b635e5c6784cbb841e1aeacca08d0eb3b 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as React from 'react';
 import DefaultProjectKey from '../../components/DefaultProjectKey';
-import { LanguageProps } from '../JenkinsfileStep';
+import { LanguageProps } from '../JenkinsStep';
 import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint';
 
 const JENKINSFILE_SNIPPET = `node {
index 889231e06af68ff35cae1f422478c21263d6846e..e1266dd3543bbe5b3b8979eec9ca87546bb8bda3 100644 (file)
@@ -95,7 +95,7 @@ export class BuildToolForm extends React.PureComponent<Props, State> {
 
         {config.buildTool === BuildTools.CFamily && config.os && (
           <GithubCFamilyExampleRepositories
-            className="sw-mt-4"
+            className="sw-mt-4 sw-w-abs-600"
             os={config.os}
             ci={TutorialModes.Local}
           />