From 03b6e8c60bb906fef329eaa8cb112ad45b446ff6 Mon Sep 17 00:00:00 2001 From: "Pablo F.G" Date: Fri, 17 Jul 2026 11:57:07 +0200 Subject: [PATCH] feat(ui): reused custom banner component --- .../providers/no-providers-added.tsx | 59 ++----------------- .../scans/no-providers-connected.tsx | 37 ------------ .../scans-providers-empty-state.test.tsx | 36 ++++------- .../scans/scans-providers-empty-state.tsx | 18 ++++-- 4 files changed, 31 insertions(+), 119 deletions(-) delete mode 100644 ui/components/scans/no-providers-connected.tsx diff --git a/ui/components/providers/no-providers-added.tsx b/ui/components/providers/no-providers-added.tsx index a9cc9d351c..5bfb8836ea 100644 --- a/ui/components/providers/no-providers-added.tsx +++ b/ui/components/providers/no-providers-added.tsx @@ -11,21 +11,10 @@ const NO_PROVIDERS_ADDED_ACTION = { LINK: "link", } as const; -// "page" is the full-screen empty state (Providers page); "hint" is a compact -// horizontal banner that sits above other content (Scans page). -const NO_PROVIDERS_ADDED_VARIANT = { - PAGE: "page", - HINT: "hint", -} as const; - -type NoProvidersAddedVariant = - (typeof NO_PROVIDERS_ADDED_VARIANT)[keyof typeof NO_PROVIDERS_ADDED_VARIANT]; - interface NoProvidersAddedBaseProps { containerClassName?: string; // Tour anchor for the CTA; needed because this empty state replaces the table's AddProviderButton. ctaTourId?: string; - variant?: NoProvidersAddedVariant; } interface NoProvidersAddedButtonProps extends NoProvidersAddedBaseProps { @@ -44,23 +33,14 @@ type NoProvidersAddedProps = | NoProvidersAddedButtonProps | NoProvidersAddedLinkProps; -const renderCta = ( - props: NoProvidersAddedProps, - variant: NoProvidersAddedVariant, -) => { - const isHint = variant === NO_PROVIDERS_ADDED_VARIANT.HINT; - const className = isHint - ? "w-full justify-center md:w-fit" - : "w-full max-w-xs justify-center"; - const size = isHint ? undefined : "lg"; - +const renderCta = (props: NoProvidersAddedProps) => { if (props.action === NO_PROVIDERS_ADDED_ACTION.LINK) { return ( @@ -70,9 +50,9 @@ const renderCta = ( return ( - - - - ); -}; diff --git a/ui/components/scans/scans-providers-empty-state.test.tsx b/ui/components/scans/scans-providers-empty-state.test.tsx index deee8318e3..a0a6c7d438 100644 --- a/ui/components/scans/scans-providers-empty-state.test.tsx +++ b/ui/components/scans/scans-providers-empty-state.test.tsx @@ -1,44 +1,32 @@ import { render, screen } from "@testing-library/react"; -import { describe, expect, it, vi } from "vitest"; +import { describe, expect, it } from "vitest"; import { ADD_PROVIDER_HREF } from "@/lib/providers-navigation"; import { ScansProvidersEmptyState } from "./scans-providers-empty-state"; -vi.mock("./no-providers-connected", () => ({ - NoProvidersConnected: () =>
No Connected Providers
, -})); - describe("ScansProvidersEmptyState", () => { - it("shows the add provider message with a providers page CTA", () => { - // Given/When + it("shows the add-provider hint with a providers page CTA when there are no providers", () => { render(); - // Then expect(screen.getByText("No Providers Configured")).toBeInTheDocument(); - const cta = screen.getByRole("link", { - name: /open add provider modal/i, - }); - + const cta = screen.getByRole("link", { name: /add a provider/i }); expect(cta).toHaveAttribute("href", ADD_PROVIDER_HREF); expect(cta.tagName).toBe("A"); }); - it("does not render the provider wizard in Scans", () => { - // Given/When - render(); - - // Then - expect(screen.getByText("No Providers Configured")).toBeInTheDocument(); - expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); - }); - - it("shows the no connected providers message", () => { - // Given/When + it("shows the no-connected-providers hint with a providers page CTA", () => { render(); - // Then expect(screen.getByText("No Connected Providers")).toBeInTheDocument(); + const cta = screen.getByRole("link", { name: /review providers/i }); + expect(cta).toHaveAttribute("href", "/providers"); + expect(cta.tagName).toBe("A"); + }); + + it("does not render the provider wizard dialog in Scans", () => { + render(); + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); }); }); diff --git a/ui/components/scans/scans-providers-empty-state.tsx b/ui/components/scans/scans-providers-empty-state.tsx index e4f5e4f6e0..7f3afe0559 100644 --- a/ui/components/scans/scans-providers-empty-state.tsx +++ b/ui/components/scans/scans-providers-empty-state.tsx @@ -1,8 +1,6 @@ -import { NoProvidersAdded } from "@/components/providers/no-providers-added"; +import { CustomBanner } from "@/components/shadcn/custom/custom-banner"; import { ADD_PROVIDER_HREF } from "@/lib/providers-navigation"; -import { NoProvidersConnected } from "./no-providers-connected"; - interface ScansProvidersEmptyStateProps { thereIsNoProviders: boolean; } @@ -11,8 +9,18 @@ export function ScansProvidersEmptyState({ thereIsNoProviders, }: ScansProvidersEmptyStateProps) { return thereIsNoProviders ? ( - + ) : ( - + ); }