Skip to content

Commit

Permalink
Fleet UI: Info banner component, uses Card as base component, tests (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
RachelElysia authored Feb 19, 2025
1 parent 739ca1e commit 20033a8
Show file tree
Hide file tree
Showing 19 changed files with 70 additions and 76 deletions.
6 changes: 4 additions & 2 deletions frontend/components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Base component to reusable <InfoBanner/>, <HostCountCard/>, <SectionCard/>, etc
// and countless single use components
import React from "react";
import classnames from "classnames";

Expand All @@ -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` */
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/Card/_styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
background-color: $core-white;
}

&__gray {
&__grey {
background-color: $ui-off-white;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const FileProgressModal = ({
onExit={noop}
disableClosingModal
>
<Card color="gray" className={`${baseClass}__card`}>
<Card color="grey" className={`${baseClass}__card`}>
<FileDetails
graphicNames={graphicNames}
fileDetails={fileDetails}
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/FileUploader/FileUploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export const FileUploader = ({
};

return (
<Card color="gray" className={classes}>
<Card color="grey" className={classes}>
{isFileSelected && fileDetails ? (
<FileDetails
graphicNames={graphicNames}
Expand Down
9 changes: 9 additions & 0 deletions frontend/components/InfoBanner/InfoBanner.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import { Meta, StoryObj } from "@storybook/react";
import CustomLink from "components/CustomLink";

import InfoBanner from ".";

Expand All @@ -17,5 +18,13 @@ type Story = StoryObj<typeof InfoBanner>;
export const Default: Story = {
args: {
children: <div>This is an Info Banner.</div>,
cta: (
<CustomLink
url="http://localhost:6006/"
text="Reopen Storybook"
newTab
// TODO: variant="info-banner" after merge
/>
),
},
};
30 changes: 28 additions & 2 deletions frontend/components/InfoBanner/InfoBanner.tests.tsx
Original file line number Diff line number Diff line change
@@ -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(<InfoBanner>Info banner testing text</InfoBanner>);

const title = screen.getByText("Info banner testing text");

expect(title).toBeInTheDocument();
});

it("renders as page-level banner", () => {
const { container } = render(<InfoBanner pageLevel />);
expect(container.firstChild).toHaveClass("info-banner__page-banner");
});

it("renders CTA element", () => {
const cta = <button>Click me</button>;
render(<InfoBanner cta={cta} />);
expect(screen.getByText("Click me")).toBeInTheDocument();
});

it("renders closable button and hides banner on click", () => {
render(<InfoBanner closable>Test message</InfoBanner>);

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(<InfoBanner icon="info" />);
expect(container.firstChild).toHaveClass("info-banner__icon");
});
});
32 changes: 9 additions & 23 deletions frontend/components/InfoBanner/InfoBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@ 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";

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;
}

Expand All @@ -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,
},
Expand Down Expand Up @@ -75,23 +70,14 @@ const InfoBanner = ({
return <></>;
}

if (link) {
return (
<a
href={link}
target="_blank"
rel="noreferrer"
className={wrapperClasses}
>
{content}
</a>
);
}

return (
<div className={wrapperClasses} role="status">
<Card
className={wrapperClasses}
color={color}
borderRadiusSize={borderRadius}
>
{content}
</div>
</Card>
);
};

Expand Down
34 changes: 2 additions & 32 deletions frontend/components/InfoBanner/_styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/MainContent/MainContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const MainContent = ({
banner = <AppleBMTermsMessage />;
} else if (isVppExpired || willVppExpire) {
banner = <VppRenewalMessage expired={isVppExpired} />;
} else if (isFleetLicenseExpired) {
} else if (!isFleetLicenseExpired) {
banner = <LicenseExpirationBanner />;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface IAddProfileCardProps {
}

const AddProfileCard = ({ setShowModal }: IAddProfileCardProps) => (
<Card color="gray" className={baseClass}>
<Card color="grey" className={baseClass}>
<div className={`${baseClass}__card--content-wrap`}>
<ProfileGraphic baseClass={baseClass} showMessage />
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ const AddProfileModal = ({
{isPremiumTier && !isLoadingLabels && isErrorLabels && <DataError />}
{(!isPremiumTier || (!isLoadingLabels && !isErrorLabels)) && (
<div className={`${baseClass}__modal-content-wrap`}>
<Card color="gray" className={`${baseClass}__file`}>
<Card color="grey" className={`${baseClass}__file`}>
{!fileDetails ? (
<FileChooser isLoading={isLoading} onFileOpen={onFileOpen} />
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const baseClass = "install-software-preview";

const InstallSoftwarePreview = () => {
return (
<Card color="gray" paddingSize="xxlarge" className={baseClass}>
<Card color="grey" paddingSize="xxlarge" className={baseClass}>
<h3>End user experience</h3>
<p>
After the <b>Remote Management</b> screen, the end user will see
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const baseClass = "setup-assistant-preview";

const SetupAssistantPreview = () => {
return (
<Card color="gray" paddingSize="xxlarge" className={baseClass}>
<Card color="grey" paddingSize="xxlarge" className={baseClass}>
<h3>End user experience</h3>
<p>
After the end user continues past the <b>Remote Management</b> screen,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const baseClass = "setup-experience-script-preview";

const SetupExperienceScriptPreview = () => {
return (
<Card color="gray" paddingSize="xxlarge" className={baseClass}>
<Card color="grey" paddingSize="xxlarge" className={baseClass}>
<h3>End user experience</h3>
<p>
After software is installed, the end user will see the script being run.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const FleetAppSummary = ({
<Card
className={`${baseClass}__fleet-app-summary`}
borderRadiusSize="medium"
color="gray"
color="grey"
>
<div className={`${baseClass}__fleet-app-summary--left`}>
<SoftwareIcon name={name} size="medium" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ const SoftwareInstallerCard = ({
return (
<Card borderRadiusSize="xxlarge" includeShadow className={baseClass}>
<div className={`${baseClass}__row-1`}>
{/* TODO: main-info could be a seperate component as its reused on a couple
{/* TODO: main-info could be a separate component as its reused on a couple
pages already. Come back and pull this into a component */}
<div className={`${baseClass}__main-info`}>
{renderIcon()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const SectionCard = ({
const cardClasses = classnames(baseClass, className);

return (
<Card className={cardClasses} color="gray">
<Card className={cardClasses} color="grey">
<div className={`${baseClass}__content-wrapper`}>
{iconName && <Icon name={iconName} />}
<div className={`${baseClass}__content`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const ExampleTicket = ({
);

return (
<Card className={baseClass} color="gray">
<Card className={baseClass} color="grey">
{screenshot}
</Card>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Card from "components/Card";
import Checkbox from "components/forms/fields/Checkbox";
import Icon from "components/Icon";
import InfoBanner from "components/InfoBanner";
Expand Down Expand Up @@ -67,12 +68,12 @@ const DiscardDataOption = ({
{["differential", "differential_ignore_removals"].includes(
selectedLoggingType
) && (
<InfoBanner color="purple-bold-border">
<>
<>
<InfoBanner color="purple">
The <b>Discard data</b> setting is ignored when differential logging
is enabled. This query&apos;s results will not be saved in Fleet.
</>
</InfoBanner>
</InfoBanner>
</>
)}
<Checkbox
name="discardData"
Expand Down

0 comments on commit 20033a8

Please sign in to comment.