diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ab5bedaee..6308d40c7 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -77,4 +77,4 @@ jobs: -e CI=true \ -e HOME=/tmp \ mcr.microsoft.com/playwright:v1.61.0-noble@sha256:57b65fdc9ceabe0ef613124c7bbe2babcf9362c4d85e382fe3b03604e84b428a \ - bash e2e/run-devguard-tests.sh + bash e2e/run-devguard-tests.sh \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index a1bc980c6..f35c4ac3c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,6 @@ "licenser.useSPDXLicenseFormat": true, "cSpell.words": [ "devguard" - ] + ], + "eslint.useFlatConfig": true } \ No newline at end of file diff --git a/e2e/src/pom/devguard.ts b/e2e/src/pom/devguard.ts index 5e5c9b0be..20798b00b 100644 --- a/e2e/src/pom/devguard.ts +++ b/e2e/src/pom/devguard.ts @@ -113,7 +113,6 @@ export class DevGuardPOM { async setupSbomUpload() { const inputFile = path.join(__dirname, "../../assets/", "sbom.json"); await this.setup().setupOwnRiskScanning(); - await this.setup().selectManualUpload(); await this.setup().uploadSbomFile(inputFile); } diff --git a/e2e/src/pom/flows/setup.ts b/e2e/src/pom/flows/setup.ts index c9db89bda..3c0369dd1 100644 --- a/e2e/src/pom/flows/setup.ts +++ b/e2e/src/pom/flows/setup.ts @@ -4,18 +4,9 @@ export class SetupFlow { constructor(private page: Page) {} async setupOwnRiskScanning() { - await this.page.getByTestId("setup-risk-scanning-button").click(); - await this.page.waitForTimeout(500); - await this.page.getByTestId("own-setup-card").click(); - await this.page.getByTestId("scanner-selection-continue").click(); - } - - async selectManualUpload() { - await this.page.waitForTimeout(500); await this.page.getByTestId("manual-upload-card").click(); - await this.page - .getByTestId("integration-method-selection-continue") - .click(); + await this.page.waitForTimeout(500); + await this.page.getByTestId("upload-manually").click(); } async uploadSbomFile(inputFile: string) { @@ -28,10 +19,8 @@ export class SetupFlow { } async setupAutoRiskScanning() { - await this.page.getByTestId("setup-risk-scanning-button").click(); await this.page.waitForTimeout(500); - await this.page.getByTestId("auto-setup-gitlab").click(); - await this.page.getByTestId("setup-method-continue").click(); + await this.page.getByTestId("gitlab-connect-repository").click(); } async createGitLabIntegration(name: string, url: string, token: string) { diff --git a/eslint.config.mjs b/eslint.config.mjs index 09d035dd1..ff5f661a6 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -13,7 +13,6 @@ export default defineConfig([ plugins: { prettier, }, - rules: { "@next/next/no-img-element": "off", "prettier/prettier": "error", diff --git a/nix/npm-packages.nix b/nix/npm-packages.nix index c22b4d9cd..3092845a1 100644 --- a/nix/npm-packages.nix +++ b/nix/npm-packages.nix @@ -10,7 +10,7 @@ ../package-lock.json ]; }; - hash = "sha256-FW3K7F/5kRiBNxNLweCtrVNJ9XpztyeLxS15IFfJ1ig="; + hash = "sha256-3DGG5Ta+DmEFO3Lb0mAu7amQbyug4qYBbo4jp20T7OQ="; }; node_modules = pkgs.runCommand "node-modules" { diff --git a/package-lock.json b/package-lock.json index affe189c7..c342efa6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,7 +94,7 @@ "zod": "^4.3.6" }, "devDependencies": { - "@eslint/eslintrc": "^3.3.5", + "@eslint/eslintrc": "3.3.5", "@eslint/js": "^9.39.4", "@playwright/test": "^1.61.0", "@tailwindcss/postcss": "^4.2.4", diff --git a/package.json b/package.json index 58fba70a3..f60e953ee 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "react-hook-form": "7.56.4" }, "devDependencies": { - "@eslint/eslintrc": "^3.3.5", + "@eslint/eslintrc": "3.3.5", "@eslint/js": "^9.39.4", "@playwright/test": "^1.61.0", "@tailwindcss/postcss": "^4.2.4", diff --git a/src/app/(loading-group)/[organizationSlug]/help-center/page.tsx b/src/app/(loading-group)/[organizationSlug]/help-center/page.tsx index fca76b287..0f1f2f048 100644 --- a/src/app/(loading-group)/[organizationSlug]/help-center/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/help-center/page.tsx @@ -149,7 +149,7 @@ export default function HelpCenterPage() { }, [firstProject?.slug, resources]); const depRiskTourHref = depRiskTarget - ? `/${activeOrg.slug}/projects/${depRiskTarget.projectSlug}/assets/${depRiskTarget.assetSlug}/refs/${depRiskTarget.refSlug}/dependency-risks/${depRiskTarget.vulnId}?startTour=4` + ? `/${activeOrg.slug}/projects/${depRiskTarget.projectSlug}/assets/${depRiskTarget.assetSlug}/refs/${depRiskTarget.refSlug}/dependency-risks/${depRiskTarget.vulnId}?startTour=dependency-risk` : undefined; const depRiskTourDisabledReason = @@ -164,7 +164,7 @@ export default function HelpCenterPage() { : undefined; const repoTourHref = repoTourTarget - ? `/${activeOrg.slug}/projects/${repoTourTarget.projectSlug}/assets/${repoTourTarget.assetSlug}?startTour=3` + ? `/${activeOrg.slug}/projects/${repoTourTarget.projectSlug}/assets/${repoTourTarget.assetSlug}?startTour=repo-home` : undefined; const repoTourDisabledReason = @@ -215,7 +215,7 @@ export default function HelpCenterPage() { Description="Get a guided overview of the organization dashboard." Button={ { const orgMenu = useOrganizationMenu(); const [mode, setMode] = useViewMode("devguard-org-view-mode"); - const { startTour } = usePageTour(orgOverviewTourSteps); + useAutoTour("org-overview", orgOverviewTourSteps); const { data: orgStatistics, diff --git a/src/app/(loading-group)/[organizationSlug]/page.tsx b/src/app/(loading-group)/[organizationSlug]/page.tsx index de8a02d72..2c277cd71 100644 --- a/src/app/(loading-group)/[organizationSlug]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/page.tsx @@ -274,7 +274,7 @@ const OrganizationHomePage: FunctionComponent = () => { const { showModal, handleStartTour, handleSkip } = useWelcomeTour(); useEffect(() => { - if (searchParams?.get("startTour") === "1") { + if (searchParams?.get("startTour") === "org-home") { startTour(); } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/page.tsx index dac6cddb9..f8c9acf79 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/page.tsx @@ -5,20 +5,24 @@ import WebhookSetupTicketIntegrationDialog from "@/components/guides/WebhookSetu import Page from "@/components/Page"; import { useAssetMenu } from "@/hooks/useAssetMenu"; import "@xyflow/react/dist/style.css"; -import Image from "next/image"; import { useRouter, useSearchParams } from "next/navigation"; import { useState, useEffect } from "react"; import type { FunctionComponent } from "react"; import Autosetup from "../../../../../../../components/Autosetup"; -import ListItem from "../../../../../../../components/common/ListItem"; import RiskScannerDialog from "../../../../../../../components/RiskScannerDialog"; -import { Button } from "../../../../../../../components/ui/button"; import { useAsset } from "../../../../../../../context/AssetContext"; import { useConfig } from "../../../../../../../context/ConfigContext"; import { useAutosetup } from "../../../../../../../hooks/useAutosetup"; import useDecodedParams from "../../../../../../../hooks/useDecodedParams"; import { externalProviderIdToIntegrationName } from "../../../../../../../utils/externalProvider"; import { isLoggedIn, useCurrentUserRole } from "@/hooks/useUserRole"; +import usePersonalAccessToken from "@/hooks/usePersonalAccessToken"; +import { SearchCode, Code, Blocks, Upload, Link2 } from "lucide-react"; +import { Badge } from "@/components/ui/badge"; +import useScannerImage from "../../../../../../../hooks/useScannerImage"; +import { Button } from "@/components/ui/button"; +import { InputWithButton } from "@/components/ui/input-with-button"; +import { Card, CardContent } from "@/components/ui/card"; import { Collapsible, CollapsibleContent, @@ -26,13 +30,15 @@ import { } from "@/components/ui/collapsible"; import { ChevronDownIcon } from "lucide-react"; import { EssentialProjectConfigContent } from "@/components/common/EssentialProjectConfigDrawer"; -import useScannerImage from "../../../../../../../hooks/useScannerImage"; +import { useActiveOrg } from "../../../../../../../hooks/useActiveOrg"; const Index: FunctionComponent = () => { const assetMenu = useAssetMenu(); - const role = useCurrentUserRole(); const [riskScanningIsOpen, setRiskScanningOpen] = useState(false); + const [riskScanningInitialSlide, setRiskScanningInitialSlide] = useState< + number | undefined + >(undefined); const [webhookIsOpen, setWebhookIsOpen] = useState(false); const config = useConfig(); const latestScannerImage = useScannerImage(); @@ -48,6 +54,7 @@ const Index: FunctionComponent = () => { projectSlug: string; assetSlug: string; }; + const activeOrg = useActiveOrg(); // check if we can redirect to the first ref const asset = useAsset(); @@ -93,101 +100,196 @@ const Index: FunctionComponent = () => { Title={} > {isLoggedIn(role) ? ( -
+
{((asset?.externalEntityProviderId && externalProviderIdToIntegrationName( asset.externalEntityProviderId, ) === "gitlab") || - (asset?.repositoryProvider === "gitlab" && - asset?.repositoryId)) && ( + asset?.repositoryProvider === "gitlab") && ( <>
-
- -
+ {asset?.externalEntityId || asset?.repositoryId ? ( + // Asset is connected to an actual repository — autosetup is usable + activeOrg.gitLabIntegrations.length > 0 ? ( + + ) : ( +
+
+ + GitLab Integration required for Auto Setup + + + To use the Auto Setup feature, you need to configure a + GitLab integration for your organization first. + +
+ +
+ ) + ) : ( + // No repository connected yet — guide the user to connect one +
+
+ + Connect a GitLab repository for Auto Setup + + + Link this asset to a GitLab repository to use the Auto + Setup feature. + +
+ +
+ )}

)} -
- - -
- } - /> - -
- - Connect your Issue Tracker to DevGuard{" "} - GitLab Logo - GitLab Logo - GitLab Logo + +
+
+ +
+
+ + Check your Code for Risks - } - Description={ - "You can connect your Issue Tracker to DevGuard to automatically create issues for identified risks. You can handle findings directly from your issue tracker via slash commands. This way, you can easily track and mitigate vulnerabilities, bad-practices, license issues and more." - } - Button={ -
- +
+ Scan your code, dependencies, and infrastructure for + vulnerabilities, leaked secrets, bad practices, and license + issues.
Connect your CI/CD pipeline to scan on every + push.
- } - /> -
- - + {(() => { + const isGitLab = + (asset?.externalEntityProviderId && + externalProviderIdToIntegrationName( + asset.externalEntityProviderId, + ) === "gitlab") || + asset?.repositoryProvider === "gitlab"; + + // Slide indices in RiskScannerDialog carousel: + // 7 = ScannerOptionsSelectionSlide (CI/CD tools) + // 16 = DevGuardCliSlide + // 11 = IntegrationMethodSelectionSlide (manual upload) + // 15 = SetupInformationSourceSlide (supplier URL) + const allCards = [ + { + icon: , + name: "DevGuard CI/CD Integration", + sub: "From our curated list of scans and scanners, select the ones you want to use.", + recommended: true, + githubOnly: false, + slide: 7, + testId: "own-setup-card", + }, + { + icon: , + name: "DevGuard CLI", + sub: "Use the DevGuard CLI to run scans and upload the results to DevGuard.", + recommended: false, + githubOnly: false, + slide: 16, + testId: "devguard-cli-card", + }, + { + icon: , + name: "Manually Upload", + sub: "You already have a SARIF/ SBOM file and want to scan for known vulnerabilities or manage your findings.", + recommended: false, + githubOnly: false, + slide: 11, + testId: "manual-upload-card", + }, + { + icon: , + name: "Supplier provided URL", + sub: "Provide SBOM URLs to setup DevGuard based on external data sources. This data will be periodically fetched and updated.", + recommended: false, + githubOnly: false, + slide: 15, + testId: "supplier-url-card", + }, + ]; + + const cards = allCards.filter((c) => + isGitLab ? !c.githubOnly : true, + ); + + return ( +
+ {cards.map( + ({ icon, name, sub, recommended, slide, testId }) => ( + + ), + )} +
+ ); + })()} +
+
+
+ +

- Essential Project Config + Project Config

These values are required to connect your CI/CD pipeline or @@ -225,6 +327,7 @@ const Index: FunctionComponent = () => { frontendUrl={config.frontendUrl} devguardCIComponentBase={config.devguardCIComponentBase} devguardWebLatestScannerImage={latestScannerImage} + initialSlide={riskScanningInitialSlide} /> = { @@ -331,7 +331,7 @@ const columnsDef: ColumnDef< const Index: FunctionComponent = () => { const assetMenu = useAssetMenu(); - const { startTour } = usePageTour(dependencyInsightsTourSteps); + useAutoTour("dependency-insights", dependencyInsightsTourSteps); const [showSBOMModal, setShowSBOMModal] = useState(false); const [showVexModal, setShowVexModal] = useState(false); diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/dependency-risks/[vulnId]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/dependency-risks/[vulnId]/page.tsx index f50d4a3bd..86b8cdabc 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/dependency-risks/[vulnId]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/dependency-risks/[vulnId]/page.tsx @@ -82,6 +82,8 @@ import { fetcher } from "../../../../../../../../../../../data-fetcher/fetcher"; import { useActiveAssetVersion } from "../../../../../../../../../../../hooks/useActiveAssetVersion"; import useDecodedParams from "../../../../../../../../../../../hooks/useDecodedParams"; import type { ViewDependencyTreeNode } from "../../../../../../../../../../../utils/dependencyGraphHelpers"; +import { useTourSeen } from "@/hooks/useTourSeen"; +import { DocDrawer } from "@/components/common/DocDrawer"; import { convertPathsToTree } from "../../../../../../../../../../../utils/dependencyGraphHelpers"; const MarkdownEditor = dynamic( @@ -319,6 +321,8 @@ const Index: FunctionComponent = () => { const searchParams = useSearchParams(); const { startTour, registerSteps } = usePageTour(dependencyRiskTourSteps); + const { showModal: shouldStartTour, markSeen } = + useTourSeen("dependency-risk"); const [ acceptVexRuleRecommendationDialogOpen, setAcceptVexRuleRecommendationDialogOpen, @@ -377,20 +381,27 @@ const Index: FunctionComponent = () => { ); const handleGraphReady = useCallback(() => { - if (searchParams?.get("startTour") !== "4") return; + if ( + searchParams?.get("startTour") !== "dependency-risk" && + !shouldStartTour + ) + return; + markSeen(); registerSteps(dependencyRiskTourSteps); startTour(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchParams]); + }, [searchParams, shouldStartTour]); // Path explosion: no graph is rendered so onReady never fires — start tour directly useEffect(() => { if ( - searchParams?.get("startTour") !== "4" || + (searchParams?.get("startTour") !== "dependency-risk" && + !shouldStartTour) || graphLoading || (vuln?.vulnerabilityPath.length || 0) !== 0 ) return; + markSeen(); registerSteps([ { ...dependencyRiskTourSteps[0], @@ -401,7 +412,7 @@ const Index: FunctionComponent = () => { ]); startTour(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [graphLoading]); + }, [graphLoading, shouldStartTour]); const graphData = useMemo(() => { if (!vuln || vuln.vulnerabilityPath.length === 0) { diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/page.tsx index fec0f9fa4..fa527965f 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/page.tsx @@ -10,11 +10,11 @@ import { useActiveOrg } from "@/hooks/useActiveOrg"; import { useActiveProject } from "@/hooks/useActiveProject"; import { useAssetMenu } from "@/hooks/useAssetMenu"; import { useViewMode } from "@/hooks/useViewMode"; -import { usePageTour } from "@/hooks/usePageTour"; +import { useAutoTour } from "@/hooks/useAutoTour"; import { repoHomeTourSteps } from "@/components/common/tours/repo-home-tour"; import "@xyflow/react/dist/style.css"; import { usePathname, useSearchParams } from "next/navigation"; -import { useEffect, useMemo } from "react"; +import { useMemo } from "react"; import type { FunctionComponent } from "react"; import { Card, @@ -140,13 +140,7 @@ const Index: FunctionComponent = () => { const searchParams = useSearchParams(); const artifactName = searchParams?.get("artifact") ?? ""; - const { startTour } = usePageTour(repoHomeTourSteps); - useEffect(() => { - if (searchParams?.get("startTour") === "3") { - startTour(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useAutoTour("repo-home", repoHomeTourSteps); const pathname = usePathname(); diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/settings/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/settings/page.tsx index f3fd69f9b..866b35793 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/settings/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/settings/page.tsx @@ -40,7 +40,7 @@ import DateString from "../../../../../../../../components/common/DateString"; import Section from "@/components/common/Section"; import { Card } from "@/components/ui/card"; import Link from "next/link"; -import { usePageTour } from "@/hooks/usePageTour"; +import { useAutoTour } from "@/hooks/useAutoTour"; import { repoSettingsTourSteps } from "@/components/common/tours/repo-settings-tour"; const firstOrUndefined = (el?: number[]): number | undefined => { @@ -313,7 +313,7 @@ const Index: FunctionComponent = () => { const { parentRepositoryId, parentRepositoryName } = getParentRepositoryIdAndName(project); - usePageTour(repoSettingsTourSteps); + useAutoTour("repo-settings", repoSettingsTourSteps); return ( ( @@ -133,14 +133,7 @@ export default function RepositoriesPage() { () => groupHomeTourSteps(isAdmin(currentUserRole)), [currentUserRole], ); - const { startTour } = usePageTour(tourSteps); - - useEffect(() => { - if (searchParams?.get("startTour") === "2") { - startTour(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useAutoTour("group-home", tourSteps); const debouncedHandleSearch = useCallback( debounce((e: React.ChangeEvent) => { @@ -205,6 +198,8 @@ export default function RepositoriesPage() { const res: AssetDTO & { env: Array; } = await resp.json(); + setShowModal(false); + form.reset(); // navigate to the new application router.push( `/${activeOrg.slug}/projects/${project.slug}/assets/${res.slug}`, diff --git a/src/app/(loading-group)/[organizationSlug]/settings/page.tsx b/src/app/(loading-group)/[organizationSlug]/settings/page.tsx index 5d50ce7f7..0f8bd6529 100644 --- a/src/app/(loading-group)/[organizationSlug]/settings/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/settings/page.tsx @@ -14,7 +14,7 @@ // along with this program. If not, see . "use client"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import Page from "../../../../components/Page"; import GithubAppInstallationAlert from "@/components/common/GithubAppInstallationAlert"; @@ -59,7 +59,7 @@ import { useUpdateOrganization, } from "../../../../context/OrganizationContext"; import Alert from "../../../../components/common/Alert"; -import { usePageTour } from "@/hooks/usePageTour"; +import { useAutoTour } from "@/hooks/useAutoTour"; import { orgSettingsTourSteps } from "@/components/common/tours/org-settings-tour"; const Home = () => { @@ -278,7 +278,7 @@ const Home = () => { } }; - const { startTour } = usePageTour(orgSettingsTourSteps); + useAutoTour("org-settings", orgSettingsTourSteps); const config = useConfig(); diff --git a/src/components/RiskScannerDialog.tsx b/src/components/RiskScannerDialog.tsx index b47b31bce..c1381b159 100644 --- a/src/components/RiskScannerDialog.tsx +++ b/src/components/RiskScannerDialog.tsx @@ -55,6 +55,7 @@ interface RiskScannerDialogProps { assetVersion?: AssetVersionDTO; artifacts?: Array; devguardWebLatestScannerImage: string; + initialSlide?: number; } const RiskScannerDialog: FunctionComponent = ({ @@ -66,6 +67,7 @@ const RiskScannerDialog: FunctionComponent = ({ assetVersion, artifacts, devguardWebLatestScannerImage, + initialSlide, }) => { const [api, setApi] = React.useState<{ reInit: () => void; @@ -459,6 +461,9 @@ const RiskScannerDialog: FunctionComponent = ({ if (!asset.externalEntityId && !asset.repositoryProvider) { return 0; // start with the update repository provider slide } + if (initialSlide !== undefined) { + return initialSlide; + } if (asset.repositoryProvider === "github") { // we can skip setup method selection slide - and the whole autosetup slides return 6; @@ -480,10 +485,16 @@ const RiskScannerDialog: FunctionComponent = ({ return activeOrg.gitLabIntegrations.length > 0 ? 3 : 2; }; - // save the slide history to make the back button implementation easier const [slideHistory, setSlideHistory] = useState([getStartIndex()]); - const prevIndex = slideHistory[slideHistory.length - 2] || 0; + useEffect(() => { + if (open) { + setSlideHistory([getStartIndex()]); + } + }, [open, initialSlide]); // eslint-disable-line react-hooks/exhaustive-deps + + const prevIndex = + slideHistory[slideHistory.length - 2] ?? slideHistory[0] ?? 0; const setProxyApi = useCallback((emblaApi: CarouselApi) => { return setApi({ @@ -635,10 +646,8 @@ const RiskScannerDialog: FunctionComponent = ({ prevIndex={prevIndex} /> diff --git a/src/components/guides/risk-scanner-carousel-slides/AutomatedIntegrationSlide.tsx b/src/components/guides/risk-scanner-carousel-slides/AutomatedIntegrationSlide.tsx index c5e775ffa..73a7c99bd 100644 --- a/src/components/guides/risk-scanner-carousel-slides/AutomatedIntegrationSlide.tsx +++ b/src/components/guides/risk-scanner-carousel-slides/AutomatedIntegrationSlide.tsx @@ -120,13 +120,6 @@ const AutomatedIntegrationSlide: FunctionComponent< />

- diff --git a/src/components/guides/risk-scanner-carousel-slides/DevGuardCliSlide.tsx b/src/components/guides/risk-scanner-carousel-slides/DevGuardCliSlide.tsx index 5e6ee57d0..6fdcf1885 100644 --- a/src/components/guides/risk-scanner-carousel-slides/DevGuardCliSlide.tsx +++ b/src/components/guides/risk-scanner-carousel-slides/DevGuardCliSlide.tsx @@ -137,15 +137,6 @@ ${generateDockerSnippet(scannerImage, "sast", org.slug, project.slug, asset.slug
- diff --git a/src/components/guides/risk-scanner-carousel-slides/IntegrationMethodSelectionSlide.tsx b/src/components/guides/risk-scanner-carousel-slides/IntegrationMethodSelectionSlide.tsx index b195fd7b5..33b12b35b 100644 --- a/src/components/guides/risk-scanner-carousel-slides/IntegrationMethodSelectionSlide.tsx +++ b/src/components/guides/risk-scanner-carousel-slides/IntegrationMethodSelectionSlide.tsx @@ -17,9 +17,7 @@ import { DocumentArrowUpIcon, } from "@heroicons/react/24/outline"; import type { FunctionComponent } from "react"; -import { classNames } from "../../../utils/common"; import { Badge } from "../../ui/badge"; -import { Button } from "../../ui/button"; import { Card, CardDescription, CardHeader, CardTitle } from "../../ui/card"; import { CarouselItem } from "../../ui/carousel"; import { DialogHeader, DialogTitle } from "../../ui/dialog"; @@ -28,8 +26,6 @@ interface IntegrationMethodSelectionSlideProps { api?: { scrollTo: (index: number) => void; }; - variant: "manual" | "auto"; - prevIndex: number; setVariant: (variant: "manual" | "auto") => void; cliSlideIndex: number; fileUploadSlideIndex: number; @@ -37,14 +33,7 @@ interface IntegrationMethodSelectionSlideProps { const IntegrationMethodSelectionSlide: FunctionComponent< IntegrationMethodSelectionSlideProps -> = ({ - api, - variant, - setVariant, - prevIndex, - cliSlideIndex, - fileUploadSlideIndex, -}) => { +> = ({ api, setVariant, cliSlideIndex, fileUploadSlideIndex }) => { return (
@@ -53,11 +42,11 @@ const IntegrationMethodSelectionSlide: FunctionComponent<
setVariant("auto")} + className="cursor-pointer" + onClick={() => { + setVariant("auto"); + api?.scrollTo(cliSlideIndex); + }} > @@ -74,13 +63,14 @@ const IntegrationMethodSelectionSlide: FunctionComponent< setVariant("manual")} + className="cursor-pointer mt-2" + data-testid="upload-manually" + onClick={() => { + setVariant("manual"); + api?.scrollTo(fileUploadSlideIndex); + }} > - + Upload manually @@ -95,25 +85,6 @@ const IntegrationMethodSelectionSlide: FunctionComponent<
-
- - -
); diff --git a/src/components/guides/risk-scanner-carousel-slides/ScannerOptionsSelectionSlide.tsx b/src/components/guides/risk-scanner-carousel-slides/ScannerOptionsSelectionSlide.tsx index 67c753584..de765f11f 100644 --- a/src/components/guides/risk-scanner-carousel-slides/ScannerOptionsSelectionSlide.tsx +++ b/src/components/guides/risk-scanner-carousel-slides/ScannerOptionsSelectionSlide.tsx @@ -510,13 +510,6 @@ const ScannerOptionsSelectionSlide: FunctionComponent<
-