diff --git a/ui/src/components/IssueFiltersPopover.test.tsx b/ui/src/components/IssueFiltersPopover.test.tsx new file mode 100644 index 00000000000..d09c48c9406 --- /dev/null +++ b/ui/src/components/IssueFiltersPopover.test.tsx @@ -0,0 +1,83 @@ +// @vitest-environment jsdom + +import { act } from "react"; +import type { ReactNode } from "react"; +import { createRoot } from "react-dom/client"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { IssueFiltersPopover } from "./IssueFiltersPopover"; +import { defaultIssueFilterState } from "../lib/issue-filters"; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true; + +vi.mock("@/components/ui/popover", () => ({ + Popover: ({ children }: { children: ReactNode }) =>
{children}
, + PopoverTrigger: ({ children }: { children: ReactNode }) => <>{children}, + PopoverContent: ({ children, className }: { children: ReactNode; className?: string }) => ( +
+ {children} +
+ ), +})); + +vi.mock("@/components/ui/button", () => ({ + Button: ({ children, ...props }: React.ButtonHTMLAttributes) => ( + + ), +})); + +vi.mock("@/components/ui/checkbox", () => ({ + Checkbox: ({ checked }: { checked?: boolean }) => , +})); + +vi.mock("./StatusIcon", () => ({ + StatusIcon: ({ status }: { status: string }) => {status}, +})); + +vi.mock("./PriorityIcon", () => ({ + PriorityIcon: ({ priority }: { priority: string }) => {priority}, +})); + +describe("IssueFiltersPopover", () => { + let container: HTMLDivElement; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + afterEach(() => { + document.body.innerHTML = ""; + }); + + it("uses a scrollable popover and a three-column desktop grid", () => { + const root = createRoot(container); + + act(() => { + root.render( + , + ); + }); + + const popoverContent = container.querySelector("[data-testid='popover-content']"); + expect(popoverContent).not.toBeNull(); + expect(popoverContent?.className).toContain("overflow-y-auto"); + expect(popoverContent?.className).toContain("max-h-[min(80vh,42rem)]"); + + const layoutGrid = Array.from(popoverContent?.querySelectorAll("div") ?? []).find((element) => + element.className.includes("md:grid-cols-3"), + ); + expect(layoutGrid?.className).toContain("grid-cols-1"); + }); +}); diff --git a/ui/src/components/IssueFiltersPopover.tsx b/ui/src/components/IssueFiltersPopover.tsx index 02f63acf9c8..2d21d49a2bd 100644 --- a/ui/src/components/IssueFiltersPopover.tsx +++ b/ui/src/components/IssueFiltersPopover.tsx @@ -80,7 +80,10 @@ export function IssueFiltersPopover({ ) : null} - +
Filters @@ -120,24 +123,24 @@ export function IssueFiltersPopover({
-
-
- Status -
- {issueStatusOrder.map((status) => ( - - ))} +
+
+
+ Status +
+ {issueStatusOrder.map((status) => ( + + ))} +
-
-
Priority
@@ -153,7 +156,9 @@ export function IssueFiltersPopover({ ))}
+
+
Assignee
@@ -186,6 +191,25 @@ export function IssueFiltersPopover({
+ {projects && projects.length > 0 ? ( +
+ Project +
+ {projects.map((project) => ( + + ))} +
+
+ ) : null} +
+ +
{labels && labels.length > 0 ? (
Labels @@ -204,23 +228,6 @@ export function IssueFiltersPopover({
) : null} - {projects && projects.length > 0 ? ( -
- Project -
- {projects.map((project) => ( - - ))} -
-
- ) : null} - {workspaces && workspaces.length > 0 ? (
Workspace