From 801b38235fa3b7e4d1e9fb5152e9b10aaab43414 Mon Sep 17 00:00:00 2001 From: Devin Villarosa Date: Fri, 3 Jan 2025 10:59:26 -0800 Subject: [PATCH] [UI v2] feat: Adds AutomationsTriggerTemplateSelect component --- .../automations-create-header.stories.tsx | 2 +- .../automations-create-header.tsx | 0 ...ations-trigger-template-select.stories.tsx | 28 ++++++++++ ...tomations-trigger-template-select.test.tsx | 47 ++++++++++++++++ .../automations-trigger-template-select.tsx | 53 +++++++++++++++++++ .../index.ts | 4 ++ 6 files changed, 133 insertions(+), 1 deletion(-) rename ui-v2/src/components/automations/{automations-create => }/automations-create-header/automations-create-header.stories.tsx (86%) rename ui-v2/src/components/automations/{automations-create => }/automations-create-header/automations-create-header.tsx (100%) create mode 100644 ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.stories.tsx create mode 100644 ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.test.tsx create mode 100644 ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.tsx create mode 100644 ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/index.ts diff --git a/ui-v2/src/components/automations/automations-create/automations-create-header/automations-create-header.stories.tsx b/ui-v2/src/components/automations/automations-create-header/automations-create-header.stories.tsx similarity index 86% rename from ui-v2/src/components/automations/automations-create/automations-create-header/automations-create-header.stories.tsx rename to ui-v2/src/components/automations/automations-create-header/automations-create-header.stories.tsx index 4440dea8ff09f..91d6a9258af4d 100644 --- a/ui-v2/src/components/automations/automations-create/automations-create-header/automations-create-header.stories.tsx +++ b/ui-v2/src/components/automations/automations-create-header/automations-create-header.stories.tsx @@ -4,7 +4,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { AutomationsCreateHeader } from "./automations-create-header"; const meta = { - title: "Components/Automations/Create/AutomationsCreateHeader", + title: "Components/Automations/AutomationsCreateHeader", component: AutomationsCreateHeader, decorators: [routerDecorator], } satisfies Meta; diff --git a/ui-v2/src/components/automations/automations-create/automations-create-header/automations-create-header.tsx b/ui-v2/src/components/automations/automations-create-header/automations-create-header.tsx similarity index 100% rename from ui-v2/src/components/automations/automations-create/automations-create-header/automations-create-header.tsx rename to ui-v2/src/components/automations/automations-create-header/automations-create-header.tsx diff --git a/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.stories.tsx b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.stories.tsx new file mode 100644 index 0000000000000..bc8aaf2ecd773 --- /dev/null +++ b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.stories.tsx @@ -0,0 +1,28 @@ +import { reactQueryDecorator } from "@/storybook/utils"; +import type { Meta, StoryObj } from "@storybook/react"; +import { fn } from "@storybook/test"; +import { useState } from "react"; +import { + AutomationsTriggerTemplateSelect, + type TemplateTriggers, +} from "./automations-trigger-template-select"; + +const meta = { + title: "Components/Automations/Wizard/AutomationsTriggerTemplateSelect", + component: AutomationsTriggerTemplateSelect, + decorators: [reactQueryDecorator], + args: { onValueChange: fn() }, + render: function ComponentExmaple() { + const [template, setTemplate] = useState(); + return ( + + ); + }, +} satisfies Meta; + +export default meta; + +export const story: StoryObj = { name: "AutomationsTriggerTemplateSelect" }; diff --git a/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.test.tsx b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.test.tsx new file mode 100644 index 0000000000000..f768ed85902e2 --- /dev/null +++ b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.test.tsx @@ -0,0 +1,47 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { expect, test, vi } from "vitest"; + +import { AutomationsTriggerTemplateSelect } from "./automations-trigger-template-select"; + +test("AutomationsTriggerTemplateSelect can select an option", async () => { + /** + * JSDOM doesn't implement PointerEvent so we need to mock our own implementation + * Default to mouse left click interaction + * https://github.com/radix-ui/primitives/issues/1822 + * https://github.com/jsdom/jsdom/pull/2666 + */ + class MockPointerEvent extends Event { + button: number; + ctrlKey: boolean; + pointerType: string; + + constructor(type: string, props: PointerEventInit) { + super(type, props); + this.button = props.button || 0; + this.ctrlKey = props.ctrlKey || false; + this.pointerType = props.pointerType || "mouse"; + } + } + window.PointerEvent = MockPointerEvent as never; + window.HTMLElement.prototype.scrollIntoView = vi.fn(); + window.HTMLElement.prototype.releasePointerCapture = vi.fn(); + window.HTMLElement.prototype.hasPointerCapture = vi.fn(); + + const user = userEvent.setup(); + + // ------------ Setup + const mockOnValueChangeFn = vi.fn(); + + render( + , + ); + + // ------------ Act + await user.click(screen.getByLabelText("Trigger Template")); + await user.click(screen.getByRole("option", { name: "Deployment status" })); + + // ------------ Assert + expect(screen.getByText("Deployment status")).toBeVisible(); + expect(mockOnValueChangeFn).toBeCalledWith("deployment-status"); +}); diff --git a/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.tsx b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.tsx new file mode 100644 index 0000000000000..53518e3b9a761 --- /dev/null +++ b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/automations-trigger-template-select.tsx @@ -0,0 +1,53 @@ +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; + +const TEMPLATE_TRIGGERS = { + "deployment-status": "Deployment status", + "flow-run-state": "Flow run state", + "work-pool-status": "Work pool status", + "work-queue-status": "Work queue status", + custom: "Custom", +} as const; + +export type TemplateTriggers = keyof typeof TEMPLATE_TRIGGERS; + +type AutomationsTriggerTemplateSelectProps = { + onValueChange: (value: TemplateTriggers) => void; + value?: TemplateTriggers; +}; + +export const AutomationsTriggerTemplateSelect = ({ + onValueChange, + value, +}: AutomationsTriggerTemplateSelectProps) => { + return ( +
+ + +
+ ); +}; diff --git a/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/index.ts b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/index.ts new file mode 100644 index 0000000000000..d83a1f7511c3f --- /dev/null +++ b/ui-v2/src/components/automations/automations-wizard/automations-trigger-template-select/index.ts @@ -0,0 +1,4 @@ +export { + AutomationsTriggerTemplateSelect, + type TemplateTriggers, +} from "./automations-trigger-template-select";