From e9de09a927959f734f461b81ebda2bc3c24f591e Mon Sep 17 00:00:00 2001 From: Ryan Hopper-Lowe Date: Wed, 8 Jan 2025 13:02:42 -0600 Subject: [PATCH] feat: add email receivers to workflow form Signed-off-by: Ryan Hopper-Lowe --- .../components/agent/AgentDropdownActions.tsx | 2 +- .../components/agent/AgentPublishStatus.tsx | 2 +- ui/admin/app/components/composed/CopyText.tsx | 72 ++++++++++++------- .../app/components/composed/typography.tsx | 10 +-- ui/admin/app/components/tools/ToolIcon.tsx | 2 +- .../CreateWorkflowTrigger.tsx | 2 +- .../workflow-triggers/EmailReceiverForm.tsx | 35 +++++---- .../workflow/DeleteWorkflowEmailReceiver.tsx | 63 ++++++++++++++++ .../workflow/DeleteWorkflowWebhook.tsx | 2 +- ui/admin/app/components/workflow/Workflow.tsx | 2 + .../workflow/WorkflowEmailDialog.tsx | 66 +++++++++++++++++ .../workflow/WorkflowEmailPanel.tsx | 69 ++++++++++++++++++ .../workflow/WorkflowWebhookDialog.tsx | 12 +++- ui/admin/app/lib/model/email-receivers.ts | 2 +- ...auth.workflow-triggers.email.$receiver.tsx | 11 ++- 15 files changed, 300 insertions(+), 52 deletions(-) create mode 100644 ui/admin/app/components/workflow/DeleteWorkflowEmailReceiver.tsx create mode 100644 ui/admin/app/components/workflow/WorkflowEmailDialog.tsx create mode 100644 ui/admin/app/components/workflow/WorkflowEmailPanel.tsx diff --git a/ui/admin/app/components/agent/AgentDropdownActions.tsx b/ui/admin/app/components/agent/AgentDropdownActions.tsx index ee7ba8e5c..12fc40813 100644 --- a/ui/admin/app/components/agent/AgentDropdownActions.tsx +++ b/ui/admin/app/components/agent/AgentDropdownActions.tsx @@ -42,7 +42,7 @@ export function AgentDropdownActions({ agent }: { agent: Agent }) { return ( <> - + diff --git a/ui/admin/app/components/agent/AgentPublishStatus.tsx b/ui/admin/app/components/agent/AgentPublishStatus.tsx index 651f9e805..63eefd779 100644 --- a/ui/admin/app/components/agent/AgentPublishStatus.tsx +++ b/ui/admin/app/components/agent/AgentPublishStatus.tsx @@ -104,7 +104,7 @@ export function AgentPublishStatus({ className="h-8 text-muted-foreground text-sm bg-background flex-row-reverse" holdStatusDelay={6000} text={agentUrl} - iconOnly + hideText /> { @@ -38,17 +49,26 @@ export function CopyText({
- {!iconOnly && ( + {!hideText && ( handleCopy(text)} - className="decoration-dotted underline-offset-4 underline text-ellipsis overflow-hidden text-nowrap" + className={cn( + "decoration-dotted underline-offset-4 underline text-ellipsis overflow-hidden text-nowrap", + classNames.textWrapper + )} > -

+

{displayText}

@@ -60,19 +80,21 @@ export function CopyText({
)} - + {!hideIcon && ( + + )}
); diff --git a/ui/admin/app/components/composed/typography.tsx b/ui/admin/app/components/composed/typography.tsx index 19bf18281..4ac2b4178 100644 --- a/ui/admin/app/components/composed/typography.tsx +++ b/ui/admin/app/components/composed/typography.tsx @@ -13,7 +13,7 @@ export function Truncate({ className, asChild, disableTooltip, - tooltipContent =

{children}

, + tooltipContent = children, }: { children: React.ReactNode; className?: string; @@ -23,8 +23,10 @@ export function Truncate({ }) { const Comp = asChild ? Slot : "p"; + const content = {children}; + if (disableTooltip) { - return {children}; + return content; } return ( @@ -32,9 +34,7 @@ export function Truncate({ {tooltipContent} -
- {children} -
+
{content}
); diff --git a/ui/admin/app/components/tools/ToolIcon.tsx b/ui/admin/app/components/tools/ToolIcon.tsx index e27359975..7c6f74081 100644 --- a/ui/admin/app/components/tools/ToolIcon.tsx +++ b/ui/admin/app/components/tools/ToolIcon.tsx @@ -37,7 +37,7 @@ export function ToolIcon(props: ToolIconProps) { } return ( - + {content} diff --git a/ui/admin/app/components/workflow-triggers/CreateWorkflowTrigger.tsx b/ui/admin/app/components/workflow-triggers/CreateWorkflowTrigger.tsx index cda5ebc88..fa223dac1 100644 --- a/ui/admin/app/components/workflow-triggers/CreateWorkflowTrigger.tsx +++ b/ui/admin/app/components/workflow-triggers/CreateWorkflowTrigger.tsx @@ -20,7 +20,7 @@ import { export function CreateWorkflowTrigger() { return ( - + diff --git a/ui/admin/app/components/workflow-triggers/EmailReceiverForm.tsx b/ui/admin/app/components/workflow-triggers/EmailReceiverForm.tsx index 2f6160227..0267edcdb 100644 --- a/ui/admin/app/components/workflow-triggers/EmailReceiverForm.tsx +++ b/ui/admin/app/components/workflow-triggers/EmailReceiverForm.tsx @@ -1,8 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect } from "react"; import { useForm } from "react-hook-form"; -import { useNavigate } from "react-router"; -import { $path } from "safe-routes"; import { toast } from "sonner"; import useSWR, { mutate } from "swr"; import { z } from "zod"; @@ -32,29 +30,34 @@ const formSchema = z.object({ description: z.string(), alias: z.string(), workflow: z.string().min(1, "Workflow is required"), - allowedSenders: z.array(z.string()), + allowedSenders: z.array(z.string()).optional(), }); export type EmailRecieverFormValues = z.infer; type EmailRecieverFormProps = { - emailReceiver?: EmailReceiver; + emailReceiver?: Partial; + onContinue?: () => void; + hideTitle?: boolean; }; -export function EmailReceiverForm({ emailReceiver }: EmailRecieverFormProps) { - const navigate = useNavigate(); +export function EmailReceiverForm({ + emailReceiver, + onContinue, + hideTitle, +}: EmailRecieverFormProps) { const getWorkflows = useSWR(WorkflowService.getWorkflows.key(), () => WorkflowService.getWorkflows() ); const handleSubmitSuccess = () => { - if (emailReceiver) { + if (emailReceiver?.id) { mutate( EmailReceiverApiService.getEmailReceiverById(emailReceiver.id) ); } mutate(EmailReceiverApiService.getEmailReceivers.key()); - navigate($path("/workflow-triggers")); + onContinue?.(); }; const form = useForm({ @@ -69,6 +72,8 @@ export function EmailReceiverForm({ emailReceiver }: EmailRecieverFormProps) { }, }); + const { handleSubmit, reset } = form; + const createEmailReceiver = useAsync( EmailReceiverApiService.createEmailReceiver, { @@ -91,11 +96,11 @@ export function EmailReceiverForm({ emailReceiver }: EmailRecieverFormProps) { useEffect(() => { if (emailReceiver) { - form.reset(emailReceiver); + reset(emailReceiver); } - }, [emailReceiver, form]); + }, [emailReceiver, reset]); - const handleSubmit = form.handleSubmit((values: EmailRecieverFormValues) => + const onSubmit = handleSubmit((values: EmailRecieverFormValues) => emailReceiver?.id ? updateEmailReceiver.execute(emailReceiver.id, values) : createEmailReceiver.execute(values) @@ -111,9 +116,11 @@ export function EmailReceiverForm({ emailReceiver }: EmailRecieverFormProps) {
-

{isEdit ? "Edit" : "Create"} Email Receiver

+ {!hideTitle && ( +

{isEdit ? "Edit" : "Create"} Email Trigger

+ )} - {isEdit ? "Update" : "Create"} Email Receiver + {isEdit ? "Update" : "Create"} Email Trigger diff --git a/ui/admin/app/components/workflow/DeleteWorkflowEmailReceiver.tsx b/ui/admin/app/components/workflow/DeleteWorkflowEmailReceiver.tsx new file mode 100644 index 000000000..82ffee5d9 --- /dev/null +++ b/ui/admin/app/components/workflow/DeleteWorkflowEmailReceiver.tsx @@ -0,0 +1,63 @@ +import { TrashIcon } from "lucide-react"; +import { useState } from "react"; +import { toast } from "sonner"; +import { mutate } from "swr"; + +import { EmailReceiverApiService } from "~/lib/service/api/emailReceiverApiService"; + +import { Button } from "~/components/ui/button"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "~/components/ui/popover"; +import { useAsync } from "~/hooks/useAsync"; + +export function DeleteWorkflowEmailReceiver({ + emailReceiverId, +}: { + emailReceiverId: string; +}) { + const [open, setOpen] = useState(false); + + const deleteEmailReceiver = useAsync( + EmailReceiverApiService.deleteEmailReceiver, + { + onSuccess: () => { + mutate(EmailReceiverApiService.getEmailReceivers.key()); + }, + onError: () => toast.error(`Something went wrong.`), + } + ); + + const handleDelete = async () => { + await deleteEmailReceiver.execute(emailReceiverId); + setOpen(false); + }; + + return ( + + + + + + +

Are you sure you want to delete this email trigger?

+
+ + +
+
+
+ ); +} diff --git a/ui/admin/app/components/workflow/DeleteWorkflowWebhook.tsx b/ui/admin/app/components/workflow/DeleteWorkflowWebhook.tsx index 911fdf642..cf6459f2d 100644 --- a/ui/admin/app/components/workflow/DeleteWorkflowWebhook.tsx +++ b/ui/admin/app/components/workflow/DeleteWorkflowWebhook.tsx @@ -30,7 +30,7 @@ export function DeleteWorkflowWebhook({ webhookId }: { webhookId: string }) { return ( - + diff --git a/ui/admin/app/components/workflow/Workflow.tsx b/ui/admin/app/components/workflow/Workflow.tsx index 08a2b30b7..e985d5115 100644 --- a/ui/admin/app/components/workflow/Workflow.tsx +++ b/ui/admin/app/components/workflow/Workflow.tsx @@ -17,6 +17,7 @@ import { WorkflowProvider, useWorkflow, } from "~/components/workflow/WorkflowContext"; +import { WorkflowEmailPanel } from "~/components/workflow/WorkflowEmailPanel"; import { WorkflowSchedulePanel } from "~/components/workflow/WorkflowSchedulePanel"; import { WorkflowWebhookPanel } from "~/components/workflow/WorkflowWebhookPanel"; import { StepsForm } from "~/components/workflow/steps/StepsForm"; @@ -172,6 +173,7 @@ function WorkflowContent({ className }: WorkflowProps) { +