From eb4093bd7446ee971df0f10b27dace67c0c6b044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20Bora=20=C4=B0nevi?= Date: Mon, 22 Jun 2026 15:45:10 +0200 Subject: [PATCH] Add initial working saved replies --- .../blocks/helpdesk/message-composer.tsx | 136 ++++++++--- .../components/blocks/helpdesk/message.tsx | 21 +- .../blocks/helpdesk/saved-reply-dialog.tsx | 198 ++++++++++++++++ .../blocks/helpdesk/saved-reply-schema.tsx | 25 ++ .../app/components/blocks/helpdesk/ticket.tsx | 11 + ...upport._ticketviewer.ticket.$ticket_id.tsx | 117 ++++++++-- fdm-helpdesk/src/index.ts | 1 + fdm-helpdesk/src/saved-reply.test.ts | 212 +++++++++++++++++ fdm-helpdesk/src/saved-reply.ts | 219 ++++++++++++++++++ 9 files changed, 886 insertions(+), 54 deletions(-) create mode 100644 fdm-app/app/components/blocks/helpdesk/saved-reply-dialog.tsx create mode 100644 fdm-app/app/components/blocks/helpdesk/saved-reply-schema.tsx create mode 100644 fdm-helpdesk/src/saved-reply.test.ts create mode 100644 fdm-helpdesk/src/saved-reply.ts diff --git a/fdm-app/app/components/blocks/helpdesk/message-composer.tsx b/fdm-app/app/components/blocks/helpdesk/message-composer.tsx index f8709413f..fd8b5c392 100644 --- a/fdm-app/app/components/blocks/helpdesk/message-composer.tsx +++ b/fdm-app/app/components/blocks/helpdesk/message-composer.tsx @@ -1,5 +1,9 @@ import { zodResolver } from "@hookform/resolvers/zod" -import { useId } from "react" +import type { + SavedReplyContext, + SavedReplySummary, +} from "@nmi-agro/fdm-helpdesk" +import { useEffect, useId } from "react" import { Controller, useWatch } from "react-hook-form" import { useFetcher } from "react-router" import { RemixFormProvider, useRemixForm } from "remix-hook-form" @@ -25,7 +29,7 @@ import { Switch } from "~/components/ui/switch" import { Textarea } from "~/components/ui/textarea" import { Message } from "./message" import { MessageSchema } from "./message-schema" -import type { HelpdeskUser } from "./types" +import type { HelpdeskUser } from "./types.d" const formDefaultValues = { body: "", @@ -37,16 +41,21 @@ export function MessageComposer({ intent, principal, showAgentControls, + savedReplies, + savedReplyContext, defaultValues = { ...formDefaultValues }, className, }: { intent: string principal: HelpdeskUser | null showAgentControls?: boolean + savedReplies?: SavedReplySummary[] + savedReplyContext?: SavedReplyContext defaultValues?: z.infer className?: string }) { const fetcher = useFetcher() + const savedReplyFetcher = useFetcher() const form = useRemixForm({ mode: "onTouched", @@ -58,11 +67,28 @@ export function MessageComposer({ ...defaultValues, }, }) + const sender_role = useWatch({ name: "sender_role", control: form.control }) const is_internal = useWatch({ name: "is_internal", control: form.control }) const messageInputId = useId() + useEffect(() => { + if (typeof savedReplyFetcher.data?.body === "string") { + const current = form.getValues("body") + if (current) { + form.setValue( + "body", + `${current}\n\n${savedReplyFetcher.data.body}`, + ) + } else { + form.setValue("body", savedReplyFetcher.data.body) + } + } + }, [form.getValues, form.setValue, savedReplyFetcher.data]) + const isSubmitting = fetcher.state !== "idle" + const isFetchingSavedReply = savedReplyFetcher.state !== "idle" + const isDisabled = isSubmitting || isFetchingSavedReply return ( @@ -77,7 +103,7 @@ export function MessageComposer({ isInternal={is_internal} title={
@@ -118,7 +144,7 @@ export function MessageComposer({ field.onChange } className="mt-1" - disabled={isSubmitting} + disabled={isDisabled} /> } > -
+
+ {savedReplies && savedReplies.length > 0 ? ( + + Gebruik een sjabloon: + + + ) : undefined} ( - - -