From a5cce0710b6e5251993d36c1535657e147d71d3a Mon Sep 17 00:00:00 2001 From: RachelElysia Date: Tue, 11 Feb 2025 15:49:34 -0500 Subject: [PATCH 1/4] Fleet UI: Info banner component, uses Card as base component, add more tests --- frontend/components/Card/Card.tsx | 6 ++-- frontend/components/Card/_styles.scss | 2 +- .../FileProgressModal/FileProgressModal.tsx | 2 +- .../components/FileUploader/FileUploader.tsx | 2 +- .../InfoBanner/InfoBanner.stories.tsx | 9 +++++ .../InfoBanner/InfoBanner.tests.tsx | 30 ++++++++++++++-- frontend/components/InfoBanner/InfoBanner.tsx | 32 +++++------------ frontend/components/InfoBanner/_styles.scss | 34 ++----------------- .../components/MainContent/MainContent.tsx | 2 +- .../AddProfileCard/AddProfileCard.tsx | 2 +- .../AddProfileModal/AddProfileModal.tsx | 2 +- .../InstallSoftwarePreview.tsx | 2 +- .../SetupAssistantPreview.tsx | 2 +- .../SetupExperienceScriptPreview.tsx | 2 +- .../FleetMaintainedAppDetailsPage.tsx | 2 +- .../SoftwareInstallerCard.tsx | 2 +- .../components/SectionCard/SectionCard.tsx | 2 +- .../hosts/ManageHostsPage/ManageHostsPage.tsx | 15 ++++++++ .../ExampleTicket/ExampleTicket.tsx | 2 +- .../DiscardDataOption/DiscardDataOption.tsx | 16 +++++---- 20 files changed, 90 insertions(+), 78 deletions(-) diff --git a/frontend/components/Card/Card.tsx b/frontend/components/Card/Card.tsx index 93e671493ffb..d1f5233f02f8 100644 --- a/frontend/components/Card/Card.tsx +++ b/frontend/components/Card/Card.tsx @@ -1,3 +1,5 @@ +// Base component to reusable , , , etc +// and countless single use components import React from "react"; import classnames from "classnames"; @@ -6,13 +8,13 @@ import { Link } from "react-router"; const baseClass = "card"; type BorderRadiusSize = "small" | "medium" | "large" | "xlarge" | "xxlarge"; -type CardColor = "white" | "gray" | "purple" | "yellow"; +type CardColor = "white" | "grey" | "purple" | "yellow"; interface ICardProps { children?: React.ReactNode; /** The size of the border radius. Defaults to `small`. * - * These correspond to the boarder radius in the design system. Look at + * These correspond to the border radius in the design system. Look at * `var/_global.scss` for values */ borderRadiusSize?: BorderRadiusSize; /** Includes the card shadows. Defaults to `false` */ diff --git a/frontend/components/Card/_styles.scss b/frontend/components/Card/_styles.scss index dcfa49ca2827..dd0f1a3dffd0 100644 --- a/frontend/components/Card/_styles.scss +++ b/frontend/components/Card/_styles.scss @@ -67,7 +67,7 @@ background-color: $core-white; } - &__gray { + &__grey { background-color: $ui-off-white; } diff --git a/frontend/components/FileProgressModal/FileProgressModal.tsx b/frontend/components/FileProgressModal/FileProgressModal.tsx index b7f74822a3fb..a64ab5a6233f 100644 --- a/frontend/components/FileProgressModal/FileProgressModal.tsx +++ b/frontend/components/FileProgressModal/FileProgressModal.tsx @@ -26,7 +26,7 @@ const FileProgressModal = ({ onExit={noop} disableClosingModal > - + + {isFileSelected && fileDetails ? ( ; export const Default: Story = { args: { children:
This is an Info Banner.
, + cta: ( + + ), }, }; diff --git a/frontend/components/InfoBanner/InfoBanner.tests.tsx b/frontend/components/InfoBanner/InfoBanner.tests.tsx index f73a01c77399..eadece8ec461 100644 --- a/frontend/components/InfoBanner/InfoBanner.tests.tsx +++ b/frontend/components/InfoBanner/InfoBanner.tests.tsx @@ -1,15 +1,41 @@ import React from "react"; -import { render, screen } from "@testing-library/react"; +import { render, screen, fireEvent } from "@testing-library/react"; import InfoBanner from "./InfoBanner"; describe("InfoBanner - component", () => { - it("info banner renders text", () => { + it("renders children content", () => { render(Info banner testing text); const title = screen.getByText("Info banner testing text"); expect(title).toBeInTheDocument(); }); + + it("renders as page-level banner", () => { + const { container } = render(); + expect(container.firstChild).toHaveClass("info-banner__page-banner"); + }); + + it("renders CTA element", () => { + const cta = ; + render(); + expect(screen.getByText("Click me")).toBeInTheDocument(); + }); + + it("renders closable button and hides banner on click", () => { + render(Test message); + + const closeButton = screen.getByRole("button"); + expect(closeButton).toBeInTheDocument(); + + fireEvent.click(closeButton); + expect(screen.queryByText("Test message")).not.toBeInTheDocument(); + }); + + it("renders with icon class when icon prop is provided", () => { + const { container } = render(); + expect(container.firstChild).toHaveClass("info-banner__icon"); + }); }); diff --git a/frontend/components/InfoBanner/InfoBanner.tsx b/frontend/components/InfoBanner/InfoBanner.tsx index bd49e3d20645..5ce2db62b954 100644 --- a/frontend/components/InfoBanner/InfoBanner.tsx +++ b/frontend/components/InfoBanner/InfoBanner.tsx @@ -4,6 +4,7 @@ import classNames from "classnames"; import Icon from "components/Icon"; import Button from "components/buttons/Button"; import { IconNames } from "components/icons"; +import Card from "components/Card"; const baseClass = "info-banner"; @@ -11,16 +12,14 @@ export interface IInfoBannerProps { children?: React.ReactNode; className?: string; /** default light purple */ - color?: "purple" | "purple-bold-border" | "yellow" | "grey"; + color?: "purple" | "yellow" | "grey"; /** default 4px */ - borderRadius?: "large" | "xlarge"; + borderRadius?: "medium" | "xlarge"; pageLevel?: boolean; /** Add this element to the end of the banner message. Mutually exclusive with `link`. */ cta?: JSX.Element; /** closable and link are mutually exclusive */ closable?: boolean; - /** Makes the entire banner clickable */ - link?: string; icon?: IconNames; } @@ -32,15 +31,11 @@ const InfoBanner = ({ pageLevel, cta, closable, - link, icon, }: IInfoBannerProps) => { const wrapperClasses = classNames( baseClass, - `${baseClass}__${color}`, { - [`${baseClass}__${color}`]: !!color, - [`${baseClass}__border-radius-${borderRadius}`]: !!borderRadius, [`${baseClass}__page-banner`]: !!pageLevel, [`${baseClass}__icon`]: !!icon, }, @@ -75,23 +70,14 @@ const InfoBanner = ({ return <>; } - if (link) { - return ( - - {content} - - ); - } - return ( -
+ {content} -
+
); }; diff --git a/frontend/components/InfoBanner/_styles.scss b/frontend/components/InfoBanner/_styles.scss index 7055aa499719..386acaed4bc4 100644 --- a/frontend/components/InfoBanner/_styles.scss +++ b/frontend/components/InfoBanner/_styles.scss @@ -2,45 +2,16 @@ display: flex; justify-content: space-between; padding: $pad-medium; - border-radius: $border-radius; - border: 1px solid $ui-vibrant-blue-50; font-size: $x-small; font-weight: $regular; color: $core-fleet-black; - &__purple { - background-color: $ui-vibrant-blue-10; - } - - &__purple-bold-border { - background-color: $ui-vibrant-blue-10; - border-color: $core-vibrant-blue; - } - - &__yellow { - background-color: $ui-yellow-banner; - border-color: $ui-yellow-banner-outline; - } - - &__grey { - background-color: $ui-off-white; - border-color: $ui-fleet-black-50; - } - &__page-banner { padding: $pad-large $pad-xlarge; margin-bottom: $pad-large; width: auto; } - &__border-radius-large { - border-radius: $border-radius-medium; - } - - &__border-radius-xlarge { - border-radius: $border-radius-xlarge; - } - &__info { p { margin: $pad-small 0 0 0; @@ -62,9 +33,8 @@ } &__close { - margin-left: $pad-small; - padding: $xx-small; - padding-right: 0; + padding: $pad-small; + margin: -$pad-small; // Offset clickable padding from making banner taller &:hover { cursor: pointer; diff --git a/frontend/components/MainContent/MainContent.tsx b/frontend/components/MainContent/MainContent.tsx index cc9157cb6d66..f39fe2df8cf5 100644 --- a/frontend/components/MainContent/MainContent.tsx +++ b/frontend/components/MainContent/MainContent.tsx @@ -57,7 +57,7 @@ const MainContent = ({ banner = ; } else if (isVppExpired || willVppExpire) { banner = ; - } else if (isFleetLicenseExpired) { + } else if (!isFleetLicenseExpired) { banner = ; } } diff --git a/frontend/pages/ManageControlsPage/OSSettings/cards/CustomSettings/components/ProfileUploader/components/AddProfileCard/AddProfileCard.tsx b/frontend/pages/ManageControlsPage/OSSettings/cards/CustomSettings/components/ProfileUploader/components/AddProfileCard/AddProfileCard.tsx index d9d09f081fa0..9229db34a8d9 100644 --- a/frontend/pages/ManageControlsPage/OSSettings/cards/CustomSettings/components/ProfileUploader/components/AddProfileCard/AddProfileCard.tsx +++ b/frontend/pages/ManageControlsPage/OSSettings/cards/CustomSettings/components/ProfileUploader/components/AddProfileCard/AddProfileCard.tsx @@ -11,7 +11,7 @@ interface IAddProfileCardProps { } const AddProfileCard = ({ setShowModal }: IAddProfileCardProps) => ( - +