diff --git a/apps/web/app/(app)/automation/RuleForm.tsx b/apps/web/app/(app)/automation/RuleForm.tsx index eebb4dfa..ba70f56b 100644 --- a/apps/web/app/(app)/automation/RuleForm.tsx +++ b/apps/web/app/(app)/automation/RuleForm.tsx @@ -18,7 +18,7 @@ import { toast } from "sonner"; import TextareaAutosize from "react-textarea-autosize"; import { capitalCase } from "capital-case"; import { usePostHog } from "posthog-js/react"; -import { ExternalLinkIcon, PlusIcon } from "lucide-react"; +import { ExternalLinkIcon, PlusIcon, FilterIcon } from "lucide-react"; import { Card } from "@/components/Card"; import { Button } from "@/components/ui/button"; import { ErrorMessage, Input, Label } from "@/components/Input"; @@ -28,7 +28,12 @@ import { SectionDescription, TypographyH3, } from "@/components/Typography"; -import { ActionType, CategoryFilterType, RuleType } from "@prisma/client"; +import { + ActionType, + CategoryFilterType, + LogicalOperator, + RuleType, +} from "@prisma/client"; import { createRuleAction, updateRuleAction } from "@/utils/actions/rule"; import { type CreateRuleBody, @@ -58,6 +63,13 @@ import { hasVariables } from "@/utils/template"; import { getEmptyCondition } from "@/utils/condition"; import { AlertError } from "@/components/Alert"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; export function RuleForm({ rule }: { rule: CreateRuleBody & { id?: string } }) { const { @@ -189,7 +201,36 @@ export function RuleForm({ rule }: { rule: CreateRuleBody & { id?: string } }) { /> - Conditions +
+ Conditions + + + + + + + + setValue("conditionalOperator", value as LogicalOperator) + } + > + + Match all conditions + + + Match any condition + + + + +
{errors.conditions?.root?.message && (
diff --git a/apps/web/utils/actions/rule.ts b/apps/web/utils/actions/rule.ts index ba4b9da1..522346ac 100644 --- a/apps/web/utils/actions/rule.ts +++ b/apps/web/utils/actions/rule.ts @@ -19,6 +19,7 @@ import { getGmailAccessToken, getGmailClient } from "@/utils/gmail/client"; import { aiFindExampleMatches } from "@/utils/ai/example-matches/find-example-matches"; import { withActionInstrumentation } from "@/utils/actions/middleware"; import { flattenConditions } from "@/utils/condition"; +import { LogicalOperator } from "@prisma/client"; export const createRuleAction = withActionInstrumentation( "createRule", @@ -58,6 +59,7 @@ export const createRuleAction = withActionInstrumentation( } : undefined, userId: session.user.id, + conditionalOperator: body.conditionalOperator || LogicalOperator.AND, // conditions instructions: conditions.instructions || null, from: conditions.from || null, @@ -124,6 +126,8 @@ export const updateRuleAction = withActionInstrumentation( automate: body.automate ?? undefined, runOnThreads: body.runOnThreads ?? undefined, name: body.name || undefined, + conditionalOperator: + body.conditionalOperator || LogicalOperator.AND, // conditions instructions: conditions.instructions || null, from: conditions.from || null, diff --git a/apps/web/utils/actions/validation.ts b/apps/web/utils/actions/validation.ts index d72898dd..72745c66 100644 --- a/apps/web/utils/actions/validation.ts +++ b/apps/web/utils/actions/validation.ts @@ -1,5 +1,9 @@ import { z } from "zod"; -import { CategoryFilterType, GroupItemType } from "@prisma/client"; +import { + CategoryFilterType, + GroupItemType, + LogicalOperator, +} from "@prisma/client"; import { ActionType, RuleType } from "@prisma/client"; // groups @@ -134,6 +138,9 @@ export const createRuleBody = z.object({ message: "You can't have two conditions with the same type.", }, ), + conditionalOperator: z + .enum([LogicalOperator.AND, LogicalOperator.OR]) + .default(LogicalOperator.AND), }); export type CreateRuleBody = z.infer;