-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[UI v2] feat: Adds flow run data table filter components
- Loading branch information
1 parent
1262485
commit 826eaad
Showing
9 changed files
with
418 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
ui-v2/src/components/flow-runs/data-table/run-name-search.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Icon } from "@/components/ui/icons"; | ||
import { Input, type InputProps } from "@/components/ui/input"; | ||
|
||
export const RunNameSearch = (props: InputProps) => { | ||
return ( | ||
<div className="relative"> | ||
<Input placeholder="Search by run name" className="pl-10" {...props} /> | ||
<Icon | ||
id="Search" | ||
className="absolute left-3 top-2.5 text-muted-foreground" | ||
size={18} | ||
/> | ||
</div> | ||
); | ||
}; |
74 changes: 74 additions & 0 deletions
74
ui-v2/src/components/flow-runs/data-table/sort-filter.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { beforeAll, describe, expect, it, vi } from "vitest"; | ||
|
||
import { mockPointerEvents } from "@tests/utils/browser"; | ||
import { SortFilter } from "./sort-filter"; | ||
|
||
describe("FlowRunsDataTable -- SortFilter", () => { | ||
beforeAll(mockPointerEvents); | ||
|
||
it("returns correct sort filter for Newest to oldest", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
const mockOnSelectFn = vi.fn(); | ||
render(<SortFilter value={undefined} onSelect={mockOnSelectFn} />); | ||
|
||
// Test | ||
await user.click( | ||
screen.getByRole("combobox", { name: /flow run sort order/i }), | ||
); | ||
await user.click(screen.getByRole("option", { name: /newest to oldest/i })); | ||
|
||
// Assert | ||
expect(mockOnSelectFn).toBeCalledWith("START_TIME_ASC"); | ||
}); | ||
|
||
it("returns correct sort filter for Oldest to newest", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
const mockOnSelectFn = vi.fn(); | ||
render(<SortFilter value={undefined} onSelect={mockOnSelectFn} />); | ||
|
||
// Test | ||
await user.click( | ||
screen.getByRole("combobox", { name: /flow run sort order/i }), | ||
); | ||
await user.click(screen.getByRole("option", { name: /oldest to newest/i })); | ||
|
||
// Assert | ||
expect(mockOnSelectFn).toBeCalledWith("START_TIME_DESC"); | ||
}); | ||
|
||
it("returns correct sort filter for A to Z", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
const mockOnSelectFn = vi.fn(); | ||
render(<SortFilter value={undefined} onSelect={mockOnSelectFn} />); | ||
|
||
// Test | ||
await user.click( | ||
screen.getByRole("combobox", { name: /flow run sort order/i }), | ||
); | ||
await user.click(screen.getByRole("option", { name: /a to z/i })); | ||
|
||
// Assert | ||
expect(mockOnSelectFn).toBeCalledWith("NAME_ASC"); | ||
}); | ||
|
||
it("returns correct sort filter for Z to A", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
const mockOnSelectFn = vi.fn(); | ||
render(<SortFilter value={undefined} onSelect={mockOnSelectFn} />); | ||
|
||
// Test | ||
await user.click( | ||
screen.getByRole("combobox", { name: /flow run sort order/i }), | ||
); | ||
await user.click(screen.getByRole("option", { name: /z to a/i })); | ||
|
||
// Assert | ||
expect(mockOnSelectFn).toBeCalledWith("NAME_DESC"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
} from "@/components/ui/select"; | ||
|
||
type SortFilters = | ||
| "START_TIME_ASC" | ||
| "START_TIME_DESC" | ||
| "NAME_ASC" | ||
| "NAME_DESC"; | ||
|
||
type SortFilterProps = { | ||
onSelect: (filter: SortFilters) => void; | ||
value: undefined | SortFilters; | ||
}; | ||
|
||
export const SortFilter = ({ value, onSelect }: SortFilterProps) => { | ||
return ( | ||
<Select value={value} onValueChange={onSelect}> | ||
<SelectTrigger aria-label="Flow run sort order"> | ||
<SelectValue placeholder="Sort by" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectItem value="START_TIME_ASC">Newest to oldest</SelectItem> | ||
<SelectItem value="START_TIME_DESC">Oldest to newest</SelectItem> | ||
<SelectItem value="NAME_ASC">A to Z</SelectItem> | ||
<SelectItem value="NAME_DESC">Z to A</SelectItem> | ||
</SelectContent> | ||
</Select> | ||
); | ||
}; |
17 changes: 17 additions & 0 deletions
17
ui-v2/src/components/flow-runs/data-table/state-filter.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { useState } from "react"; | ||
import { type FlowRunState, StateFilter } from "./state-filter"; | ||
|
||
const meta: Meta<typeof StateFilter> = { | ||
title: "Components/FlowRuns/DataTable/StateFilter", | ||
component: StateFilterStory, | ||
}; | ||
export default meta; | ||
|
||
function StateFilterStory() { | ||
const [filters, setFilters] = useState<Set<FlowRunState>>(); | ||
return <StateFilter selectedFilters={filters} onSelectFilter={setFilters} />; | ||
} | ||
|
||
export const story: StoryObj = { name: "StateFilter" }; |
87 changes: 87 additions & 0 deletions
87
ui-v2/src/components/flow-runs/data-table/state-filter.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { beforeAll, describe, expect, it } from "vitest"; | ||
|
||
import { mockPointerEvents } from "@tests/utils/browser"; | ||
import { useState } from "react"; | ||
import { type FlowRunState, StateFilter } from "./state-filter"; | ||
|
||
describe("FlowRunsDataTable -- StateFilter", () => { | ||
beforeAll(mockPointerEvents); | ||
|
||
const TestStateFilter = () => { | ||
const [filters, setFilters] = useState<Set<FlowRunState>>(); | ||
return ( | ||
<StateFilter selectedFilters={filters} onSelectFilter={setFilters} /> | ||
); | ||
}; | ||
|
||
it("selects All except scheduled option", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
render(<TestStateFilter />); | ||
// Test | ||
await user.click(screen.getByRole("button", { name: /all run states/i })); | ||
await user.click( | ||
screen.getByRole("menuitem", { name: /all except scheduled/i }), | ||
); | ||
await user.keyboard("{Escape}"); | ||
|
||
// Assert | ||
expect( | ||
screen.getByRole("button", { name: /all except scheduled/i }), | ||
).toBeVisible(); | ||
}); | ||
|
||
it("selects All run states option", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
render(<TestStateFilter />); | ||
// Test | ||
await user.click(screen.getByRole("button", { name: /all run states/i })); | ||
await user.click(screen.getByRole("menuitem", { name: /all run states/i })); | ||
await user.keyboard("{Escape}"); | ||
|
||
// Assert | ||
expect( | ||
screen.getByRole("button", { name: /all run states/i }), | ||
).toBeVisible(); | ||
}); | ||
|
||
it("selects a single run state option", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
render(<TestStateFilter />); | ||
// Test | ||
await user.click(screen.getByRole("button", { name: /all run states/i })); | ||
await user.click(screen.getByRole("menuitem", { name: /failed/i })); | ||
|
||
await user.keyboard("{Escape}"); | ||
|
||
// Assert | ||
expect(screen.getByRole("button", { name: /failed/i })).toBeVisible(); | ||
}); | ||
|
||
it("selects multiple run state options", async () => { | ||
// Setup | ||
const user = userEvent.setup(); | ||
render(<TestStateFilter />); | ||
// Test | ||
await user.click(screen.getByRole("button", { name: /all run states/i })); | ||
await user.click(screen.getByRole("menuitem", { name: /timedout/i })); | ||
await user.click(screen.getByRole("menuitem", { name: /crashed/i })); | ||
|
||
await user.click(screen.getByRole("menuitem", { name: /failed/i })); | ||
await user.click(screen.getByRole("menuitem", { name: /running/i })); | ||
await user.click(screen.getByRole("menuitem", { name: /retrying/i })); | ||
|
||
await user.keyboard("{Escape}"); | ||
|
||
// Assert | ||
expect( | ||
screen.getByRole("button", { | ||
name: /timedout crashed failed running \+ 1/i, | ||
}), | ||
).toBeVisible(); | ||
}); | ||
}); |
Oops, something went wrong.