|
|
|
@ -1,11 +1,11 @@
|
|
|
|
|
import { useEffect, useState, useRef, useCallback } from 'react'
|
|
|
|
|
import { useParams, useNavigate, useLocation } from 'react-router-dom';
|
|
|
|
|
import { App, ConfigProvider, Button, Form, Input, Flex, Checkbox, Popconfirm, Select, Space, Upload, Divider, Modal, Tabs } from 'antd'
|
|
|
|
|
import { UploadOutlined, LoadingOutlined } from '@ant-design/icons'
|
|
|
|
|
import { App, ConfigProvider, Button, Form, Input, Flex, Checkbox, Popconfirm, Select, Space, Upload, Divider, Modal, Tabs, Radio } from 'antd'
|
|
|
|
|
import { UploadOutlined, LoadingOutlined, SaveOutlined, SendOutlined, CheckCircleOutlined } from '@ant-design/icons'
|
|
|
|
|
import '@dckj/react-better-modal/dist/index.css'
|
|
|
|
|
import DnDModal from '@/components/DnDModal'
|
|
|
|
|
import useStyleStore from '@/stores/StyleStore'
|
|
|
|
|
import useConversationStore from '@/stores/ConversationStore'
|
|
|
|
|
// import useConversationStore from '@/stores/ConversationStore'
|
|
|
|
|
import useAuthStore from '@/stores/AuthStore'
|
|
|
|
|
|
|
|
|
|
import LexicalEditor from '@/components/LexicalEditor'
|
|
|
|
@ -17,8 +17,11 @@ import { postSendEmail } from '@/actions/EmailActions'
|
|
|
|
|
import { sentMsgTypeMapped } from '@/channel/bubbleMsgUtils'
|
|
|
|
|
import { EmailBuilder, useEmailDetail, useEmailSignature } from '@/hooks/useEmail'
|
|
|
|
|
import useSnippetStore from '@/stores/SnippetStore'
|
|
|
|
|
import { useOrderStore } from '@/stores/OrderStore'
|
|
|
|
|
// import { useOrderStore } from '@/stores/OrderStore'
|
|
|
|
|
import PaymentlinkBtn from '@/views/Conversations/Online/Input/PaymentlinkBtn'
|
|
|
|
|
import { TextIcon } from '@/components/Icons';
|
|
|
|
|
import GenerateAutoDocDrawer from './Conversations/Online/Components/GenerateAutoDocDrawer';
|
|
|
|
|
import { POPUP_FEATURES } from '@/config';
|
|
|
|
|
|
|
|
|
|
// 禁止上传的附件类型
|
|
|
|
|
// .application, .exe, .app
|
|
|
|
@ -73,7 +76,7 @@ const generateMailContent = (mailData) => `<br><br><p>${mailData.content}</p>`
|
|
|
|
|
*/
|
|
|
|
|
const NewEmail = ({ ...props }) => {
|
|
|
|
|
const pageParam = useParams();
|
|
|
|
|
const editorKey = `${pageParam.action}-${pageParam.quoteid}`
|
|
|
|
|
const editorKey = pageParam.action==='new' ? `new-${Date.now().toString(32)}` : `${pageParam.action}-${pageParam.quoteid}`
|
|
|
|
|
|
|
|
|
|
const { notification, message } = App.useApp()
|
|
|
|
|
const [form] = Form.useForm()
|
|
|
|
@ -85,53 +88,32 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
const emailListMatMapped = emailListOption?.reduce((r, v) => ({ ...r, [v.mat_sn]: v }), {})
|
|
|
|
|
// console.log('emailListMapped', emailListOption, emailListAddrMapped);
|
|
|
|
|
|
|
|
|
|
const emailEdiorProps = useConversationStore((state) => state.emailEdiorProps)
|
|
|
|
|
const [open, setOpen, closeEditor1, currentEditKey, setCurrentEditKey] = useConversationStore((state) => [
|
|
|
|
|
state.editorOpen,
|
|
|
|
|
state.setEditorOpen,
|
|
|
|
|
state.closeEditor1,
|
|
|
|
|
state.currentEditKey,
|
|
|
|
|
state.setCurrentEditKey,
|
|
|
|
|
])
|
|
|
|
|
// const emailEdiorProps = useConversationStore((state) => state.emailEdiorProps)
|
|
|
|
|
// const [open, setOpen, closeEditor1, currentEditKey, setCurrentEditKey] = useConversationStore((state) => [
|
|
|
|
|
// state.editorOpen,
|
|
|
|
|
// state.setEditorOpen,
|
|
|
|
|
// state.closeEditor1,
|
|
|
|
|
// state.currentEditKey,
|
|
|
|
|
// state.setCurrentEditKey,
|
|
|
|
|
// ])
|
|
|
|
|
|
|
|
|
|
const propsKeysArr = Array.from(emailEdiorProps.keys())
|
|
|
|
|
const propsArr = Array.from(emailEdiorProps.values())
|
|
|
|
|
// const propsKeysArr = Array.from(emailEdiorProps.keys())
|
|
|
|
|
// const propsArr = Array.from(emailEdiorProps.values())
|
|
|
|
|
|
|
|
|
|
const [activeEdit, setActiveEdit] = useState(emailEdiorProps.get(editorKey) || {})
|
|
|
|
|
// const [activeEdit, setActiveEdit] = useState(emailEdiorProps.get(editorKey) || {})
|
|
|
|
|
// const { fromEmail, fromUser, fromOrder, oid, toEmail, conversationid, quoteid, initial = {}, mailData: _mailData, action = 'reply', draft = {}, receiverName, ...props } = emailEdiorProps.get(currentEditKey) || {};
|
|
|
|
|
|
|
|
|
|
const onChangeActiveEditor = (key) => {
|
|
|
|
|
setCurrentEditKey(key)
|
|
|
|
|
const _find = emailEdiorProps.get(key) || {}
|
|
|
|
|
setActiveEdit(_find)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onEditTab = (targetKey, action) => {
|
|
|
|
|
if (action === 'add') {
|
|
|
|
|
//
|
|
|
|
|
} else {
|
|
|
|
|
if (propsKeysArr.length === 1) {
|
|
|
|
|
setOpen(false)
|
|
|
|
|
}
|
|
|
|
|
closeEditor1(targetKey)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mai_sn = pageParam.quoteid // activeEdit.quoteid
|
|
|
|
|
const { loading: getLoading, mailData } = useEmailDetail(mai_sn, activeEdit.mailData)
|
|
|
|
|
|
|
|
|
|
const [stickToProps, setStickToProps] = useState({})
|
|
|
|
|
const [propsSerialize, setPropsSerialize] = useState('')
|
|
|
|
|
const { loading: getLoading, mailData, orderDetail } = useEmailDetail(mai_sn)
|
|
|
|
|
|
|
|
|
|
const [newFromEmail, setNewFromEmail] = useState('')
|
|
|
|
|
const [newToEmail, setNewToEmail] = useState('')
|
|
|
|
|
const [emailOPI, setEmailOPI] = useState('')
|
|
|
|
|
const [emailOrder, setEmailOrder] = useState('')
|
|
|
|
|
const [emailOrderSN, setEmailOrderSN] = useState('')
|
|
|
|
|
const [emailMat, setEmailMat] = useState('')
|
|
|
|
|
|
|
|
|
|
const stateReset = () => {
|
|
|
|
|
setStickToProps({})
|
|
|
|
|
setStickToCid('')
|
|
|
|
|
setEmailOrder('')
|
|
|
|
|
setEmailOPI('')
|
|
|
|
|
setNewFromEmail('')
|
|
|
|
@ -140,60 +122,15 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
|
|
|
|
|
const [contentPrefix, setContentPrefix] = useState('')
|
|
|
|
|
|
|
|
|
|
// 存储: 会话ID,
|
|
|
|
|
// 这个窗口没有模态, 即使不是focus, 还是需要保持会话ID
|
|
|
|
|
// 否则, 会话列表切换之后, 会话ID更新, 导致消息关联错误
|
|
|
|
|
const [stickToCid, setStickToCid] = useState(activeEdit.conversationid)
|
|
|
|
|
// const [stickToCid, setStickToCid] = useState(pageParam.conversationid)
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
console.log('useeffect', mailData.info);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
document.title = mailData.info?.MAI_Subject || 'New Email-'
|
|
|
|
|
}, 1500);
|
|
|
|
|
const propsObj = { ...activeEdit, mai: activeEdit.mailData?.info?.MAI_MAT_SN }
|
|
|
|
|
|
|
|
|
|
setContentPrefix(activeEdit.oid ? `<p>Dear Mr./Ms. ${activeEdit.receiverName || ''}</p><p>Reference Number: ${activeEdit.oid}</p>` : '')
|
|
|
|
|
|
|
|
|
|
// 没有引用邮件
|
|
|
|
|
if (isEmpty(activeEdit.quoteid)) {
|
|
|
|
|
setStickToProps(propsObj)
|
|
|
|
|
setPropsSerialize(JSON.stringify(propsObj))
|
|
|
|
|
|
|
|
|
|
setStickToCid(activeEdit.conversationid)
|
|
|
|
|
setEmailOrder(activeEdit.fromOrder)
|
|
|
|
|
setEmailOPI(activeEdit.fromUser)
|
|
|
|
|
setNewFromEmail(activeEdit.fromEmail)
|
|
|
|
|
setNewToEmail(activeEdit.toEmail)
|
|
|
|
|
|
|
|
|
|
const _findMat = emailListAddrMapped?.[activeEdit.fromEmail]?.mat_sn
|
|
|
|
|
setEmailMat(_findMat)
|
|
|
|
|
|
|
|
|
|
// if (open !== true) {
|
|
|
|
|
// form.resetFields()
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
// 转发/回复时, 使用详情的账户信息
|
|
|
|
|
if (mailData.info?.MAI_MAT_SN) {
|
|
|
|
|
const reEmailO = mailData.info?.MAI_COLI_SN
|
|
|
|
|
const reEmailUser = mailData.info?.MAI_OPI_SN
|
|
|
|
|
const reEmailUserMat = mailData.info?.MAI_MAT_SN
|
|
|
|
|
|
|
|
|
|
setEmailOrder((prev) => reEmailO || prev || activeEdit.fromOrder)
|
|
|
|
|
setEmailOPI((prev) => reEmailUser || prev)
|
|
|
|
|
setEmailMat((prev) => reEmailUserMat || prev)
|
|
|
|
|
console.log('useeffect\n', orderDetail.order_no);
|
|
|
|
|
// const propsObj = { ...activeEdit, mai: activeEdit.mailData?.info?.MAI_MAT_SN }
|
|
|
|
|
|
|
|
|
|
const _findMatOld = emailListMatMapped?.[reEmailUserMat]
|
|
|
|
|
if (_findMatOld) {
|
|
|
|
|
setNewFromEmail(_findMatOld.email)
|
|
|
|
|
setEmailOPI(_findMatOld.opi_sn)
|
|
|
|
|
setEmailMat(_findMatOld.mat_sn)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setShowQuoteContent(false)
|
|
|
|
|
setMergeQuote(true)
|
|
|
|
|
setQuoteContent('')
|
|
|
|
|
setContentPrefix(orderDetail.order_no ? `<p>Dear Mr./Ms. ${orderDetail.contact?.[0]?.name || ''}</p><p>Reference Number: ${orderDetail.order_no}</p>` : '')
|
|
|
|
|
|
|
|
|
|
return () => {}
|
|
|
|
|
}, [open, mailData])
|
|
|
|
|
}, [orderDetail.order_no])
|
|
|
|
|
|
|
|
|
|
const handleSwitchEmail = (labelValue) => {
|
|
|
|
|
const { value } = labelValue
|
|
|
|
@ -225,8 +162,8 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
setHtmlContent(htmlContent)
|
|
|
|
|
setTextContent(textContent)
|
|
|
|
|
form.setFieldValue('content', htmlContent)
|
|
|
|
|
form.setFieldValue('abstract', getAbstract(textContent))
|
|
|
|
|
debouncedSave({ htmlContent })
|
|
|
|
|
// form.setFieldValue('abstract', getAbstract(textContent))
|
|
|
|
|
debouncedSave({ htmlContent, ...form.getFieldsValue() })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [initialForm, setInitialForm] = useState({})
|
|
|
|
@ -235,8 +172,49 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
const [mergeQuote, setMergeQuote] = useState(true)
|
|
|
|
|
const [quoteContent, setQuoteContent] = useState('')
|
|
|
|
|
|
|
|
|
|
const setPreFillInProperty = () => { };
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
// console.log('quoteid', quoteid, isEmpty(quoteid), isEmpty(mailData.info));
|
|
|
|
|
console.log('useEffect 2---- \nform.setFieldsValue ');
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
document.title = mailData.info?.MAI_Subject || 'New Email-'
|
|
|
|
|
}, 1500);
|
|
|
|
|
// 没有引用邮件
|
|
|
|
|
if (isEmpty(pageParam.quoteid)) {
|
|
|
|
|
|
|
|
|
|
// setEmailOrder(orderDetail.order_no)
|
|
|
|
|
// setEmailOPI(orderDetail.opi_sn)
|
|
|
|
|
// setNewFromEmail(activeEdit.fromEmail)
|
|
|
|
|
// setNewToEmail(activeEdit.toEmail)
|
|
|
|
|
|
|
|
|
|
// const _findMat = emailListAddrMapped?.[activeEdit.fromEmail]?.mat_sn
|
|
|
|
|
// setEmailMat(_findMat)
|
|
|
|
|
|
|
|
|
|
// if (open !== true) {
|
|
|
|
|
// form.resetFields()
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
// 转发/回复时, 使用详情的账户信息
|
|
|
|
|
if (mailData.info?.MAI_MAT_SN) {
|
|
|
|
|
const reEmailO = mailData.info?.MAI_COLI_SN
|
|
|
|
|
const reEmailUser = mailData.info?.MAI_OPI_SN
|
|
|
|
|
const reEmailUserMat = mailData.info?.MAI_MAT_SN
|
|
|
|
|
|
|
|
|
|
setEmailOrder((prev) => reEmailO || prev ) // activeEdit.fromOrder
|
|
|
|
|
setEmailOPI((prev) => reEmailUser || prev)
|
|
|
|
|
setEmailMat((prev) => reEmailUserMat || prev)
|
|
|
|
|
|
|
|
|
|
const _findMatOld = emailListMatMapped?.[reEmailUserMat]
|
|
|
|
|
if (_findMatOld) {
|
|
|
|
|
setNewFromEmail(_findMatOld.email)
|
|
|
|
|
setEmailOPI(_findMatOld.opi_sn)
|
|
|
|
|
setEmailMat(_findMatOld.mat_sn)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setShowQuoteContent(false)
|
|
|
|
|
setMergeQuote(true)
|
|
|
|
|
setQuoteContent('')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isEmpty(pageParam.quoteid) && pageParam.action !== 'new') {
|
|
|
|
|
return () => {}
|
|
|
|
@ -254,18 +232,26 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
setInitialContent(contentPrefix + signatureBody)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const forwardValues = { from: newFromEmail, subject: `Fw: ${info.MAI_Subject || ''}` }
|
|
|
|
|
if (pageParam.action === 'reply') {
|
|
|
|
|
const _formValues = {
|
|
|
|
|
to: info?.replyTo || newFromEmail,
|
|
|
|
|
cc: info?.MAI_CS || '',
|
|
|
|
|
// bcc: quote.bcc || '',
|
|
|
|
|
subject: `Re: ${info.MAI_Subject || ''}`,
|
|
|
|
|
}
|
|
|
|
|
form.setFieldsValue(_formValues)
|
|
|
|
|
setInitialForm(_formValues)
|
|
|
|
|
} else if (pageParam.action === 'replyall') {
|
|
|
|
|
const _formValues = {
|
|
|
|
|
to: info?.replyToAll || newFromEmail,
|
|
|
|
|
cc: info?.MAI_CS || '',
|
|
|
|
|
// bcc: quote.bcc || '',
|
|
|
|
|
subject: `Re: ${info.MAI_Subject || ''}`,
|
|
|
|
|
}
|
|
|
|
|
const forwardValues = { from: newFromEmail, subject: `Fw: ${info.MAI_Subject || ''}` }
|
|
|
|
|
if (pageParam.action === 'reply') {
|
|
|
|
|
form.setFieldsValue(_formValues)
|
|
|
|
|
setInitialForm(_formValues)
|
|
|
|
|
} else if (pageParam.action === 'forward') {
|
|
|
|
|
setStickToCid('0')
|
|
|
|
|
form.setFieldsValue(forwardValues)
|
|
|
|
|
setInitialForm(forwardValues)
|
|
|
|
|
} else if (pageParam.action === 'edit') {
|
|
|
|
@ -288,12 +274,12 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return () => {}
|
|
|
|
|
}, [propsSerialize, mailData.info, signature, newToEmail, newFromEmail])
|
|
|
|
|
}, [ mailData.info, signature, newToEmail])
|
|
|
|
|
|
|
|
|
|
const [openPlainTextConfirm, setOpenPlainTextConfirm] = useState(false)
|
|
|
|
|
const handlePlainTextOpenChange = ({ target }) => {
|
|
|
|
|
const { checked: newChecked } = target
|
|
|
|
|
if (!newChecked) {
|
|
|
|
|
const { value: newChecked } = target
|
|
|
|
|
if (newChecked === true) {
|
|
|
|
|
setIsRichText(true)
|
|
|
|
|
setOpenPlainTextConfirm(false)
|
|
|
|
|
return
|
|
|
|
@ -366,7 +352,7 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
resolve(e.target.result)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var win = window.open('', file.uid, 'width=1000,height=800,left=20,top=20')
|
|
|
|
|
var win = window.open('', file.uid, POPUP_FEATURES)
|
|
|
|
|
win.document.body.style.margin = '0'
|
|
|
|
|
if (file.type.startsWith('image/')) {
|
|
|
|
|
win.document.write("<img src='" + e.target.result + '\' style="max-width: 100%;" />')
|
|
|
|
@ -407,7 +393,7 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
* 保存成功, 推一个气泡
|
|
|
|
|
* 再从异步通知更新消息发送状态
|
|
|
|
|
*/
|
|
|
|
|
const sentOrReceivedNewMessage = useConversationStore((state) => state.sentOrReceivedNewMessage)
|
|
|
|
|
// const sentOrReceivedNewMessage = useConversationStore((state) => state.sentOrReceivedNewMessage)
|
|
|
|
|
const invokeEmailMessage = (msgObj) => {
|
|
|
|
|
const msgObjMerge = {
|
|
|
|
|
sender: 'me',
|
|
|
|
@ -418,13 +404,13 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
...msgObj,
|
|
|
|
|
// id: `${currentConversation.sn}.${msgObj.id}`,
|
|
|
|
|
// id: `${stickToCid}.${msgObj.id}`,
|
|
|
|
|
conversationid: stickToCid,
|
|
|
|
|
// conversationid: stickToCid,
|
|
|
|
|
msg_source: 'email',
|
|
|
|
|
}
|
|
|
|
|
// olog('invoke upload', msgObjMerge)
|
|
|
|
|
const contentToRender = sentMsgTypeMapped[msgObjMerge.type].contentToRender(msgObjMerge)
|
|
|
|
|
// console.log(contentToRender, 'contentToRender sendMessage------------------');
|
|
|
|
|
sentOrReceivedNewMessage(contentToRender.conversationid, contentToRender)
|
|
|
|
|
// sentOrReceivedNewMessage(contentToRender.conversationid, contentToRender)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [sendLoading, setSendLoading] = useState(false)
|
|
|
|
@ -440,7 +426,7 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
body.coli_sn = emailOrder || ''
|
|
|
|
|
// console.log('body', body, '\n', emailOrder);
|
|
|
|
|
const values = await form.validateFields()
|
|
|
|
|
const preQuoteBody = activeEdit.quoteid ? (quoteContent ? quoteContent : generateQuoteContent(mailData, isRichText)) : ''
|
|
|
|
|
const preQuoteBody = pageParam.quoteid ? (quoteContent ? quoteContent : generateQuoteContent(mailData, isRichText)) : ''
|
|
|
|
|
body.mailcontent = isRichText ? EmailBuilder({ subject: values.subject, content: htmlContent + preQuoteBody }) : textContent + preQuoteBody
|
|
|
|
|
body.cc = values.cc || ''
|
|
|
|
|
body.bcc = values.bcc || ''
|
|
|
|
@ -457,15 +443,15 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
subject: values.subject,
|
|
|
|
|
content: body.mailcontent,
|
|
|
|
|
},
|
|
|
|
|
coli_id: stickToProps.oid || (emailOrder ? `{${emailOrder}}` : ''),
|
|
|
|
|
coli_id: orderDetail.order_no || (emailOrder ? `{${emailOrder}}` : ''),
|
|
|
|
|
}
|
|
|
|
|
setSendLoading(true)
|
|
|
|
|
body.externalID = stickToCid
|
|
|
|
|
body.actionID = `${stickToCid}.${msgObj.id}`
|
|
|
|
|
// body.externalID = stickToCid
|
|
|
|
|
// body.actionID = `${stickToCid}.${msgObj.id}`
|
|
|
|
|
body.contenttype = isRichText ? 'text/html' : 'text/plain'
|
|
|
|
|
try {
|
|
|
|
|
const bubbleMsg = cloneDeep(msgObj)
|
|
|
|
|
bubbleMsg.id = `${stickToCid}.${msgObj.id}`
|
|
|
|
|
// bubbleMsg.id = `${stickToCid}.${msgObj.id}`
|
|
|
|
|
// bubbleMsg.email.mai_sn = '';
|
|
|
|
|
bubbleMsg.content = undefined
|
|
|
|
|
// invokeEmailMessage(bubbleMsg);
|
|
|
|
@ -481,7 +467,7 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
|
|
|
|
|
// setSendLoading(false);
|
|
|
|
|
|
|
|
|
|
setOpen(false)
|
|
|
|
|
// setOpen(false)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
notification.error({
|
|
|
|
|
message: '邮件保存失败',
|
|
|
|
@ -495,7 +481,7 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [openDrawerSnippet] = useSnippetStore((state) => [state.openDrawer])
|
|
|
|
|
const [openPaymentDrawer] = useOrderStore((state) => [state.openDrawer])
|
|
|
|
|
// const [openPaymentDrawer] = useOrderStore((state) => [state.openDrawer])
|
|
|
|
|
|
|
|
|
|
const [bakData, setBakData] = useState({})
|
|
|
|
|
const idleCallbackId = useRef(null)
|
|
|
|
@ -503,7 +489,7 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
debounce((data) => {
|
|
|
|
|
idleCallbackId.current = window.requestIdleCallback(() => {
|
|
|
|
|
console.log('Saving data (idle, debounced):', data)
|
|
|
|
|
writeIndexDB({ ...data, key: currentEditKey }, 'draft', 'EmailEditor')
|
|
|
|
|
writeIndexDB({ ...data, key: editorKey }, 'draft', 'EmailEditor')
|
|
|
|
|
})
|
|
|
|
|
}, 1500), // 1.5s
|
|
|
|
|
[],
|
|
|
|
@ -526,6 +512,25 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<ConfigProvider theme={{ token: { colorPrimary: '#6366f1' } }}>
|
|
|
|
|
<div className='w-full flex gap-4 justify-start items-center text-indigo-600 pb-1 mb-2 border-x-0 border-t-0 border-b border-solid border-neutral-200'>
|
|
|
|
|
<Button type='primary' onClick={onHandleSend} loading={sendLoading} icon={<SendOutlined />}>
|
|
|
|
|
发送
|
|
|
|
|
</Button>
|
|
|
|
|
<Select labelInValue options={emailListOption} value={{ key: newFromEmail, value: newFromEmail, label: newFromEmail }} onChange={handleSwitchEmail} labelRender={item => `发件人: ${item.label || '选择'}`} variant={'borderless'} className='[&_.ant-select-selection-item]:font-bold' />
|
|
|
|
|
<div className='ml-auto'></div>
|
|
|
|
|
<Popconfirm trigger1={['hover', 'click']}
|
|
|
|
|
description='切换内容为纯文本格式将丢失信件和签名的格式, 确定使用纯文本?'
|
|
|
|
|
onConfirm={confirmPlainText}
|
|
|
|
|
open={openPlainTextConfirm}
|
|
|
|
|
onCancel={() => setOpenPlainTextConfirm(false)}>
|
|
|
|
|
{/* <Checkbox checked={!isRichText} onChange={handlePlainTextOpenChange}>
|
|
|
|
|
纯文本
|
|
|
|
|
</Checkbox> */}
|
|
|
|
|
{/* <Button type='link' size='small' icon={<TextIcon />} className=' ' >纯文本</Button> */}
|
|
|
|
|
<Radio.Group options={[{label: '纯文本', value: false}, {label: '富文本', value: true}]} optionType="button" buttonStyle="solid" onChange={handlePlainTextOpenChange} value={isRichText} size='small' />
|
|
|
|
|
</Popconfirm>
|
|
|
|
|
<Button type='dashed' icon={<SaveOutlined />} size='small' className='' >存草稿</Button>
|
|
|
|
|
</div>
|
|
|
|
|
<Form
|
|
|
|
|
form={form}
|
|
|
|
|
onValuesChange={onEditChange}
|
|
|
|
@ -548,32 +553,16 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
<Flex gap={4}>
|
|
|
|
|
{!showCc && (
|
|
|
|
|
<Button type='text' onClick={handleShowCc}>
|
|
|
|
|
Cc
|
|
|
|
|
抄送
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
{!showBcc && (
|
|
|
|
|
<Button type='text' hidden={showBcc} onClick={handleShowBcc}>
|
|
|
|
|
Bcc
|
|
|
|
|
密送
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</Flex>
|
|
|
|
|
</Space.Compact>
|
|
|
|
|
{/* <Input
|
|
|
|
|
addonAfter={
|
|
|
|
|
<Flex gap={4}>
|
|
|
|
|
{!showCc && (
|
|
|
|
|
<Button type='text' onClick={handleShowCc}>
|
|
|
|
|
Cc
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
{!showBcc && (
|
|
|
|
|
<Button type='text' hidden={showBcc} onClick={handleShowBcc}>
|
|
|
|
|
Bcc
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</Flex>
|
|
|
|
|
}
|
|
|
|
|
/> */}
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item label='抄 送' name={'cc'} hidden={!showCc} className='w-full pt-1'>
|
|
|
|
|
<Input />
|
|
|
|
@ -615,10 +604,10 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
<LexicalEditor {...{ isRichText }} onChange={handleEditorChange} defaultValue={initialContent} />
|
|
|
|
|
{activeEdit.quoteid && !showQuoteContent && (
|
|
|
|
|
{pageParam.quoteid && !showQuoteContent && (
|
|
|
|
|
<div className='flex justify-start items-center ml-2'>
|
|
|
|
|
<Button className='flex gap-2 ' type='link' onClick={() => setShowQuoteContent(!showQuoteContent)}>
|
|
|
|
|
显示引用内容 ↓
|
|
|
|
|
显示引用内容 ↓ {/*(不可更改)*/}
|
|
|
|
|
</Button>
|
|
|
|
|
{/* <Button className='flex gap-2 ' type='link' danger onClick={() => {setMergeQuote(false);setShowQuoteContent(false)}}>
|
|
|
|
|
删除引用内容
|
|
|
|
@ -627,8 +616,8 @@ const NewEmail = ({ ...props }) => {
|
|
|
|
|
)}
|
|
|
|
|
{showQuoteContent && (
|
|
|
|
|
<blockquote
|
|
|
|
|
contentEditable
|
|
|
|
|
className='border-0 outline-none'
|
|
|
|
|
// contentEditable
|
|
|
|
|
className='border-0 outline-none cursor-text'
|
|
|
|
|
onBlur={(e) => setQuoteContent(`<blockquote>${e.target.innerHTML}</blockquote>`)}
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: generateQuoteContent(mailData) }}></blockquote>
|
|
|
|
|
)}
|
|
|
|
|