Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fleet UI: Update Dropdown to use react-select 5.4 and other cleanup #24164

Merged
merged 7 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/components/TeamsDropdown/TeamsDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {

import Icon from "components/Icon";

interface INumberDropdownOption extends Omit<IDropdownOption, "value"> {
export interface INumberDropdownOption extends Omit<IDropdownOption, "value"> {
value: number; // Redefine the value property to be just number
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Used with old react-select dropdown and
// New react-select-5 ActionsDropdown.tsx
// New react-select-5: ActionsDropdown.tsx, DropdownWrapper.tsx
.Select > .Select-menu-outer,
.actions-dropdown {
.actions-dropdown,
.react-select__option {
.is-disabled * {
color: $ui-fleet-black-50;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// stories/DropdownWrapper.stories.tsx

import React from "react";
import { Meta, Story } from "@storybook/react";
import DropdownWrapper, {
IDropdownWrapper,
CustomOptionType,
} from "./DropdownWrapper";

// Define metadata for the story
export default {
title: "Components/DropdownWrapper",
component: DropdownWrapper,
argTypes: {
onChange: { action: "changed" },
},
} as Meta;

// Define a template for the stories
const Template: Story<IDropdownWrapper> = (args) => (
<DropdownWrapper {...args} />
);

// Sample options to be used in the dropdown
const sampleOptions: CustomOptionType[] = [
{ label: "Option 1", value: "option1", helpText: "Help text for option 1" },
{
label: "Option 2",
value: "option2",
tooltipContent: "Tooltip for option 2",
},
{ label: "Option 3", value: "option3", isDisabled: true },
];

// Default story
export const Default = Template.bind({});
Default.args = {
options: sampleOptions,
name: "dropdown-example",
label: "Select an option",
};

// Disabled story
export const Disabled = Template.bind({});
Disabled.args = {
...Default.args,
isDisabled: true,
};

// With Help Text story
export const WithHelpText = Template.bind({});
WithHelpText.args = {
...Default.args,
helpText: "This is some help text for the dropdown",
};

// With Error story
export const WithError = Template.bind({});
WithError.args = {
...Default.args,
error: "This is an error message",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import DropdownWrapper, { CustomOptionType } from "./DropdownWrapper";

const sampleOptions: CustomOptionType[] = [
{
label: "Option 1",
value: "option1",
tooltipContent: "Tooltip 1",
helpText: "Help text 1",
},
{
label: "Option 2",
value: "option2",
tooltipContent: "Tooltip 2",
helpText: "Help text 2",
},
];

describe("DropdownWrapper Component", () => {
const mockOnChange = jest.fn();

beforeEach(() => {
jest.clearAllMocks();
});

test("renders with help text", () => {
render(
<DropdownWrapper
options={sampleOptions}
value="option1"
onChange={mockOnChange}
name="test-dropdown"
label="Test Dropdown"
helpText="This is a help text."
/>
);

expect(screen.getByText(/test dropdown/i)).toBeInTheDocument();
expect(screen.getByText(/this is a help text/i)).toBeInTheDocument();
});

test("calls onChange when an option is selected", async () => {
render(
<DropdownWrapper
options={sampleOptions}
value="option1"
onChange={mockOnChange}
name="test-dropdown"
label="Test Dropdown"
placeholder="Choose option"
/>
);

// Open the dropdown
await userEvent.click(screen.getByText(/option 1/i));

// Select Option 2
await userEvent.click(screen.getByText(/option 2/i));

expect(mockOnChange).toHaveBeenCalledWith({
helpText: "Help text 2",
label: "Option 2",
tooltipContent: "Tooltip 2",
value: "option2",
});
});

test("renders error message when provided", () => {
render(
<DropdownWrapper
options={sampleOptions}
value="option1"
onChange={mockOnChange}
name="test-dropdown"
label="Test Dropdown"
error="This is an error message."
/>
);

expect(screen.getByText(/this is an error message/i)).toBeInTheDocument();
});

test("displays no options message when no options are available", async () => {
render(
<DropdownWrapper
options={[]}
value=""
onChange={mockOnChange}
name="test-dropdown"
label="Test Dropdown"
placeholder="Choose option"
/>
);

// Open dropdown
await userEvent.click(screen.getByText(/choose option/i));

expect(screen.getByText(/no results found/i)).toBeInTheDocument();
});
});
Loading
Loading