import type { ILivechatDepartment, Serialized } from '@rocket.chat/core-typings'; import { Field, FieldGroup, Button, TextInput, Modal, Box, CheckBox, Divider, EmailInput, FieldLabel, FieldRow, FieldError, ModalHeader, ModalIcon, ModalTitle, ModalClose, ModalFooter, ModalFooterControllers, ModalContent, } from '@rocket.chat/fuselage'; import { GenericModal } from '@rocket.chat/ui-client'; import { usePermission, useSetting, useUserPreference, useToastMessageDispatch } from '@rocket.chat/ui-contexts'; import { useCallback, useState, useEffect, useMemo } from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { useHasLicenseModule } from '../../../hooks/useHasLicenseModule'; import Tags from '../components/Tags'; type CloseChatModalFormData = { comment: string; tags: string[]; transcriptPDF: boolean; transcriptEmail: boolean; subject: string; }; export type CloseChatModalProps = { department?: Serialized; visitorEmail?: string; onCancel: () => void; onConfirm: ( comment?: string, tags?: string[], preferences?: { omnichannelTranscriptPDF: boolean; omnichannelTranscriptEmail: boolean }, requestData?: { email: string; subject: string }, ) => Promise; }; const CloseChatModal = ({ department, visitorEmail, onCancel, onConfirm }: CloseChatModalProps) => { const { t } = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); const { formState: { errors }, handleSubmit, register, setError, setFocus, setValue, watch, } = useForm(); const commentRequired = useSetting('Livechat_request_comment_when_closing_conversation', true); const alwaysSendTranscript = useSetting('Livechat_transcript_send_always', false); const customSubject = useSetting('Livechat_transcript_email_subject', ''); const [tagRequired, setTagRequired] = useState(false); const tags = watch('tags'); const comment = watch('comment'); const transcriptEmail = watch('transcriptEmail'); const subject = watch('subject'); const userTranscriptEmail = useUserPreference('omnichannelTranscriptEmail') ?? false; const userTranscriptPDF = useUserPreference('omnichannelTranscriptPDF') ?? false; const { data: hasLicense = false } = useHasLicenseModule('livechat-enterprise'); const transcriptPDFPermission = usePermission('request-pdf-transcript'); const transcriptEmailPermission = usePermission('send-omnichannel-chat-transcript'); const canSendTranscriptEmail = transcriptEmailPermission && visitorEmail && !alwaysSendTranscript; const canSendTranscriptPDF = transcriptPDFPermission && hasLicense; const canSendTranscript = canSendTranscriptEmail || canSendTranscriptPDF; const handleTags = (value: string[]): void => { setValue('tags', value); }; const onSubmit = useCallback( ({ comment, tags, transcriptPDF, transcriptEmail, subject }: CloseChatModalFormData) => { const preferences = { omnichannelTranscriptPDF: !!transcriptPDF, omnichannelTranscriptEmail: alwaysSendTranscript ? true : !!transcriptEmail, }; const requestData = transcriptEmail && visitorEmail ? { email: visitorEmail, subject } : undefined; if (!comment?.trim() && commentRequired) { setError('comment', { type: 'custom', message: t('Required_field', { field: t('Comment') }) }); } if (transcriptEmail && !subject) { setError('subject', { type: 'custom', message: t('Required_field', { field: t('Subject') }) }); } if (!tags?.length && tagRequired) { setError('tags', { type: 'custom', message: t('error-tags-must-be-assigned-before-closing-chat') }); } if (!errors.comment || errors.tags) { onConfirm(comment, tags, preferences, requestData); } }, [commentRequired, tagRequired, visitorEmail, errors, setError, t, onConfirm, alwaysSendTranscript], ); const cannotSubmit = useMemo(() => { const cannotSendTag = (tagRequired && !tags?.length) || errors.tags; const cannotSendComment = (commentRequired && !comment?.trim()) || errors.comment; const cannotSendTranscriptEmail = transcriptEmail && (!visitorEmail || !subject); return Boolean(cannotSendTag || cannotSendComment || cannotSendTranscriptEmail); }, [comment, commentRequired, errors, tagRequired, tags, transcriptEmail, visitorEmail, subject]); useEffect(() => { if (department?.requestTagBeforeClosingChat) { setTagRequired(true); } }, [department]); useEffect(() => { if (commentRequired) { setFocus('comment'); } }, [commentRequired, setFocus]); useEffect(() => { if (tagRequired) { register('tags'); } }, [register, tagRequired]); useEffect(() => { if (transcriptEmail) { if (!visitorEmail) { dispatchToastMessage({ type: 'error', message: t('Customer_without_registered_email') }); return; } setValue('subject', subject || customSubject || t('Transcript_of_your_livechat_conversation')); } }, [transcriptEmail, setValue, visitorEmail, subject, t, customSubject, dispatchToastMessage]); if (commentRequired || tagRequired || canSendTranscript) { return ( // TODO: Replace Modal with GenericModal } > {t('Wrap_up_conversation')} {t('Close_room_description')} {t('Comment')} {errors.comment?.message} {errors.tags?.message} {canSendTranscript && ( <> {t('Chat_transcript')} {canSendTranscriptPDF && ( {t('Omnichannel_transcript_pdf')} )} {canSendTranscriptEmail && ( <> {t('Omnichannel_transcript_email')} {transcriptEmail && ( <> {t('Contact_email')} {t('Subject')} {errors.subject?.message} )} )} {canSendTranscriptPDF && canSendTranscriptEmail ? t('These_options_affect_this_conversation_only_To_set_default_selections_go_to_My_Account_Omnichannel') : t('This_option_affect_this_conversation_only_To_set_default_selection_go_to_My_Account_Omnichannel')} )} ); } return ( => onConfirm()} onCancel={onCancel} onClose={onCancel} confirmText={t('Confirm')} /> ); }; export default CloseChatModal;