From 85e6cc87918f79ca3f315ea4cdaf89e9b68edc52 Mon Sep 17 00:00:00 2001 From: jbpenrath Date: Wed, 14 May 2025 09:28:57 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20allow=20to=20save=20draft?= =?UTF-8?q?=20without=20recipient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the `to` field optional to save draft then check if at least of recipient (to, cc or bcc) has been defined. --- .../forms/components/message-form/index.tsx | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/frontend/src/features/forms/components/message-form/index.tsx b/src/frontend/src/features/forms/components/message-form/index.tsx index d590ac80..d2b94bed 100644 --- a/src/frontend/src/features/forms/components/message-form/index.tsx +++ b/src/frontend/src/features/forms/components/message-form/index.tsx @@ -36,18 +36,17 @@ const emailArraySchema = z.array(z.string().trim().email("message_form.error.inv const messageFormSchema = z.object({ from: z.string().nonempty("message_form.error.mailbox_required"), to: z.string() - .min(1, "message_form.error.min_recipient") + .optional() .transform(toEmailArray) .pipe(emailArraySchema), cc: z.string() - .trim() .optional() .transform(toEmailArray) - .pipe(emailArraySchema), + .pipe(emailArraySchema), bcc: z.string() .optional() .transform(toEmailArray) - .pipe(emailArraySchema.optional()), + .pipe(emailArraySchema), subject: z.string() .trim() .nonempty("message_form.error.subject_required"), @@ -89,13 +88,27 @@ export const MessageForm = ({ if (draft) return draft.to.map(contact => contact.email); if (!parentMessage) return []; if (replyAll) { - return [ + return [...new Set([ {email: parentMessage.sender.email}, ...parentMessage.to, ...parentMessage.cc - ] + ] .filter(contact => contact.email !== selectedMailbox!.email) .map(contact => contact.email) + )] + } + // If the sender is replying to himself, we can consider that it prefers + // to reply to the message recipient from onw of its message. + if (parentMessage.sender.email === selectedMailbox?.email) { + if (parentMessage.to.length > 0) { + return parentMessage.to.map(contact => contact.email); + } + if (parentMessage.cc.length > 0) { + return parentMessage.cc.map(contact => contact.email); + } + if (parentMessage.bcc.length > 0) { + return parentMessage.bcc.map(contact => contact.email); + } } return [parentMessage.sender.email]; }, [parentMessage, replyAll, selectedMailbox]); @@ -128,9 +141,8 @@ export const MessageForm = ({ }, onSuccess: async (response) => { const taskId = (response as sendCreateResponse200).data.task_id; - addQueuedMessage(taskId); + addQueuedMessage(taskId); invalidateThreadMessages(); - invalidateThreadsStats(); onSuccess?.(); onClose?.(); } @@ -172,6 +184,7 @@ export const MessageForm = ({ {t("message_form.success.draft_deleted")} ); + onClose?.(); }, } }); @@ -226,7 +239,15 @@ export const MessageForm = ({ const handleSubmit = async (data: MessageFormFields) => { setPendingSubmit(true); - // Ensure the draft is up to date before sending the message + // recipients are optional to save the draft but required to send the message + // so we have to manually check that at least one recipient is present. + const hasNoRecipients = data.to.length === 0 && data.cc.length === 0 && data.bcc.length === 0; + if (hasNoRecipients) { + setPendingSubmit(false); + form.setError("to", { message: t("message_form.error.min_recipient") }); + return; + } + const draft = await saveDraft(data); if (!draft) { @@ -287,12 +308,11 @@ export const MessageForm = ({
group} fullWidth text={form.formState.errors.to && !Array.isArray(form.formState.errors.to) ? t(form.formState.errors.to.message as string) : t("message_form.helper_text.recipients")} - textItems={Array.isArray(form.formState.errors.to) ? form.formState.errors.to?.map((error, index) => t(error!.message as string, { email: form.getValues(`to`).split(',')[index] })) : undefined} + textItems={Array.isArray(form.formState.errors.to) ? form.formState.errors.to?.map((error, index) => t(error!.message as string, { email: form.getValues(`to`)!.split(',')[index] })) : undefined} /> @@ -351,7 +371,7 @@ export const MessageForm = ({ > {t("actions.send")} - {onClose && ( + {!draft && onClose && (