mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
refactor(ui): render the no-providers scan hint as a compact banner
- Add a "hint" variant to NoProvidersAdded (horizontal banner) so the Scans-page no-providers hint matches the not-connected hint - Providers page keeps the default full-page "page" variant
This commit is contained in:
@@ -11,10 +11,21 @@ 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 {
|
||||
@@ -33,14 +44,23 @@ type NoProvidersAddedProps =
|
||||
| NoProvidersAddedButtonProps
|
||||
| NoProvidersAddedLinkProps;
|
||||
|
||||
const renderCta = (props: NoProvidersAddedProps) => {
|
||||
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";
|
||||
|
||||
if (props.action === NO_PROVIDERS_ADDED_ACTION.LINK) {
|
||||
return (
|
||||
<Button
|
||||
asChild
|
||||
aria-label="Open Add Provider modal"
|
||||
className="w-full max-w-xs justify-center"
|
||||
size="lg"
|
||||
className={className}
|
||||
size={size}
|
||||
>
|
||||
<Link href={props.href}>Add a Provider</Link>
|
||||
</Button>
|
||||
@@ -50,9 +70,9 @@ const renderCta = (props: NoProvidersAddedProps) => {
|
||||
return (
|
||||
<Button
|
||||
aria-label="Open Add Provider modal"
|
||||
className="w-full max-w-xs justify-center"
|
||||
className={className}
|
||||
data-tour-id={props.ctaTourId}
|
||||
size="lg"
|
||||
size={size}
|
||||
onClick={props.onOpenWizard}
|
||||
>
|
||||
Add a Provider
|
||||
@@ -61,6 +81,33 @@ const renderCta = (props: NoProvidersAddedProps) => {
|
||||
};
|
||||
|
||||
export const NoProvidersAdded = (props: NoProvidersAddedProps) => {
|
||||
const variant = props.variant ?? NO_PROVIDERS_ADDED_VARIANT.PAGE;
|
||||
|
||||
// Compact horizontal hint, matching NoProvidersConnected so both provider
|
||||
// hints on the Scans page share one composition.
|
||||
if (variant === NO_PROVIDERS_ADDED_VARIANT.HINT) {
|
||||
return (
|
||||
<Card variant="base">
|
||||
<CardContent className="flex w-full flex-col items-start gap-6 md:flex-row md:items-center md:justify-between md:gap-8">
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center justify-start gap-3">
|
||||
<InfoIcon className="h-6 w-6 text-gray-800 dark:text-white" />
|
||||
<h2 className="text-lg font-bold text-gray-800 dark:text-white">
|
||||
No Providers Configured
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
No providers have been configured. Start by setting up a provider.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full md:w-auto md:shrink-0">
|
||||
{renderCta(props, variant)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="region"
|
||||
@@ -87,7 +134,7 @@ export const NoProvidersAdded = (props: NoProvidersAddedProps) => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{renderCta(props)}
|
||||
{renderCta(props, variant)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@@ -119,10 +119,7 @@ export function ScansPageShell({
|
||||
{/* Signals the navbar that this route's data has loaded (enables the replay icon). */}
|
||||
<PageReady />
|
||||
{showProvidersHint && (
|
||||
<ScansProvidersEmptyState
|
||||
thereIsNoProviders={thereAreNoProviders}
|
||||
containerClassName="min-h-0"
|
||||
/>
|
||||
<ScansProvidersEmptyState thereIsNoProviders={thereAreNoProviders} />
|
||||
)}
|
||||
<div
|
||||
role="group"
|
||||
|
||||
@@ -5,20 +5,13 @@ import { NoProvidersConnected } from "./no-providers-connected";
|
||||
|
||||
interface ScansProvidersEmptyStateProps {
|
||||
thereIsNoProviders: boolean;
|
||||
/** Overrides the NoProvidersAdded container height so it can sit as a compact top hint. */
|
||||
containerClassName?: string;
|
||||
}
|
||||
|
||||
export function ScansProvidersEmptyState({
|
||||
thereIsNoProviders,
|
||||
containerClassName,
|
||||
}: ScansProvidersEmptyStateProps) {
|
||||
return thereIsNoProviders ? (
|
||||
<NoProvidersAdded
|
||||
action="link"
|
||||
href={ADD_PROVIDER_HREF}
|
||||
containerClassName={containerClassName}
|
||||
/>
|
||||
<NoProvidersAdded action="link" href={ADD_PROVIDER_HREF} variant="hint" />
|
||||
) : (
|
||||
<NoProvidersConnected />
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user