Merge branch 'main' of github.com:hainatravel/global-sales

2.0/email-builder
Jimmy Liow 10 months ago
commit 4a4ceb7375

@ -14,23 +14,17 @@
"@lexical/react": "^0.20.0",
"@vonage/client-sdk": "^1.7.2",
"antd": "^5.22.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"dingtalk-jsapi": "^3.0.41",
"emoji-picker-react": "^4.12.0",
"lexical": "^0.20.0",
"re-resizable": "^6.10.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.28.0",
"zustand": "^4.5.5",
"react-chat-elements": "^12.0.17",
"react-draggable": "^4.4.6",
"react-quill": "^2.0.0",
"react-rnd": "^10.4.13",
"rxjs": "^7.8.1",
"uuid": "^9.0.1",
"vite-plugin-pwa": "^0.21.0"
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/react": "^18.3.12",
@ -46,6 +40,7 @@
"tailwindcss": "^3.4.15",
"vite": "^4.5.1",
"vite-plugin-css-modules": "^0.0.1",
"vite-plugin-pwa": "^0.21.0",
"vite-plugin-svgr": "^4.3.0",
"vite-plugin-windicss": "^1.9.3",
"windicss": "^3.5.6"

@ -37,6 +37,7 @@ export const fetchConversationsList = async (params) => {
intour: '',
session_enable: 1,
lastactivetime: '',
top_state: '',
}
const combinedFilterStr = Object.values(pick(params, ['keyword', 'tags', 'olabel', 'intour', 'ostate'])).join('')
if (isNotEmpty(combinedFilterStr) || params.session_enable === 0) {

@ -599,6 +599,7 @@ export const parseRenderMessageItem = (msg) => {
...(typeof whatsappMsgTypeMapped[thisMsgType].type === 'function' ? whatsappMsgTypeMapped[thisMsgType].type(msg) : { type: whatsappMsgTypeMapped[thisMsgType].type || 'text' }),
// type: whatsappMsgTypeMapped?.[thisMsgType]?.type || 'text',
localDate: (msg?.sendTime || msg?.createTime || '').replace('T', ' '),
dateString: dayjs(msg?.sendTime || msg.createTime).format('MM-DD HH:mm'),
from: msg.from,
sender: msg.from,
senderName: msg?.customerProfile?.name || msg?.fromName || msg?.from || 'me', // msg.from,
@ -670,6 +671,7 @@ export const parseRenderMessageList = (messages) => {
...(typeof whatsappMsgTypeMapped[msgType].type === 'function' ? whatsappMsgTypeMapped[msgType].type(msg) : { type: whatsappMsgTypeMapped[msgType].type || 'text' }),
date: msgContent?.sendTime || msg.msgtime || '',
dateText: dayjs(msgContent?.sendTime || msg.msgtime).format('MM-DD HH:mm'),
dateString: dayjs(msgContent?.sendTime || msg.msgtime).format('MM-DD HH:mm'),
localDate: (msg.msgtime || '').replace('T', ' '),
from: msgContent.from,
sender: msgContent.from,

@ -74,6 +74,7 @@ const tagsSlice = (set) => ({
// 会话筛选
const filterObj = {
pagesize: '',
search: '',
otype: '',
tags: [],
@ -268,8 +269,11 @@ const conversationSlice = (set, get) => ({
const targetId = conversation.sn;
const targetIndex = conversationsList.findIndex((ele) => String(ele.sn) === String(targetId));
conversationsList.splice(targetIndex, 1);
const mergedListMapped = groupBy(conversationsList, 'top_state');
return set({
topList: mergedListMapped['1'] || [],
pageList: mergedListMapped['0'] || [],
conversationsList: [...conversationsList],
activeConversations: { ...activeConversations, [`${targetId}`]: [] },
currentConversation: {},
@ -287,11 +291,14 @@ const conversationSlice = (set, get) => ({
unread_msg_count: 0,
})
: null;
const mergedListMapped = groupBy(conversationsList, 'top_state');
return set((state) => ({
totalNotify: state.totalNotify - (conversation.unread_msg_count || 0),
currentConversation: Object.assign({}, conversation, targetItemFromList),
referenceMsg: {},
topList: mergedListMapped['1'] || [],
pageList: mergedListMapped['0'] || [],
conversationsList: [...conversationsList],
}));
},
@ -306,7 +313,13 @@ const conversationSlice = (set, get) => ({
...conversation,
})
: null;
return set({ conversationsList: [...conversationsList] });
const mergedListMapped = groupBy(conversationsList, 'top_state');
return set({
topList: mergedListMapped['1'] || [],
pageList: mergedListMapped['0'] || [],
conversationsList: [...conversationsList]
});
},
});
@ -379,10 +392,14 @@ const messageSlice = (set, get) => ({
},
}];
}
const mergedList = [...newConversations, ...conversationsList]
const mergedListMapped = groupBy(mergedList, 'top_state');
return set({
topList: mergedListMapped['1'] || [],
pageList: mergedListMapped['0'] || [],
conversationsList: mergedList,
activeConversations: { ...activeConversations, [String(targetId)]: targetMsgs },
conversationsList: [...newConversations, ...conversationsList],
});
},
sentOrReceivedNewMessage: (targetId, message) => {
@ -425,6 +442,8 @@ const messageSlice = (set, get) => ({
// console.log('find in list, i:', targetIndex);
// console.log('find in list, chat updated and Top: \n', JSON.stringify(newConversation, null, 2));
// console.log('list updated : \n', JSON.stringify(conversationsList, null, 2));
const mergedListMapped = groupBy(conversationsList, 'top_state');
const isCurrent = Number(targetId) === Number(currentConversation.sn);
const updatedCurrent = isCurrent
? {
@ -436,6 +455,8 @@ const messageSlice = (set, get) => ({
: {...currentConversation, last_message: message,};
return set({
currentConversation: updatedCurrent,
topList: mergedListMapped['1'] || [],
pageList: mergedListMapped['0'] || [],
conversationsList: [...conversationsList],
totalNotify: totalNotify + (message.sender === 'me' ? 0 : 1),
activeConversations: { ...activeConversations, [String(targetId)]: [...targetMsgs, message] },

@ -11,12 +11,13 @@ const BubbleEmail = ({ onOpenEditor, onOpenEmail, ...message }) => {
const RenderText = memo(function renderText({ className, email, sender }) {
return (
<div onClick={() => handlePreview(message)} className={`text-sm leading-5 emoji-text whitespace-pre-wrap cursor-pointer ${className}`} key={'msg-text'}>
{sender === 'me' && <div><b>From: </b>{email.from}</div>}
<div><b>To: </b>{email.to}</div>
{/* {sender === 'me' && <div><b>From: </b>{email.from}</div>} */}
{/* <div><b>To: </b>{email.to}</div> */}
<div ><b>Subject: </b>{email.subject}</div>
<hr className='border-0 border-solid border-b border-neutral-400'/>
<div className='line-clamp-2 text-neutral-600'>{email.abstract}</div>
</div>
<div className=' text-neutral-500 text-xs italic'>{email.coli_id ? `订单: ${email.coli_id}` : '未绑定订单'}</div>
</div>
);
});
const handlePreview = (message) => {
@ -47,15 +48,19 @@ const BubbleEmail = ({ onOpenEditor, onOpenEmail, ...message }) => {
{...message}
key={`${message.from}.${message.id}`}
type='text'
title={ message.sender !== 'me' &&
title={
<>
<MailOutlined className='text-indigo-600' />
<span className={`pl-2 ${message.sender === 'me' ? '' : 'text-indigo-600'}`}>
{message.sender !== 'me' ?
<>
<b>From: </b>
<span>
{/* {message?.emailOrigin?.fromName}&nbsp;&lt;{message?.emailOrigin.fromEmail}&gt; */}
{message.msgOrigin?.from}
</span>
</> : <><b>To: </b>{message.msgOrigin?.to}</>
}
</span>
</>
}

@ -6,6 +6,7 @@ import { groupBy, isEmpty } from '@/utils/commons';
import useConversationStore from '@/stores/ConversationStore';
import { useShallow } from 'zustand/react/shallow';
import { WABIcon } from '@/components/Icons';
import ChannelLogo from './ChannelLogo';
const BubbleIM = ({ handlePreview, handleContactClick, setNewChatModalVisible, setNewChatFormValues, scrollToMessage, focusMsg, ...message }) => {
const { message: appMessage } = App.useApp();
@ -112,9 +113,12 @@ const BubbleIM = ({ handlePreview, handleContactClick, setNewChatModalVisible, s
// styles: { backgroundColor: '#ccd4ae' },
notchStyle: { fill: '#ccd4ae' }, // todo: channel[WhatsApp] color '#d9fdd3'
replyButton: ['text', 'document', 'image'].includes(message.whatsapp_msg_type) && message.status !== 'failed' ? true : false,
// title: <><WABIcon/>&nbsp;Global Highlights</>, // test: 0
title: <><ChannelLogo channel={message.msg_source} />&nbsp;Global Highlights</>,
}
: {})}
// notch={false}
: {
title: <><ChannelLogo channel={message.msg_source} />{message.title}</>,
})}
className={[
'whitespace-pre-wrap',
message.whatsapp_msg_type === 'sticker' ? 'bg-transparent' : '',

@ -7,7 +7,8 @@ const ChannelLogo = ({channel}) => {
if (Array.isArray(channel)) {
channel = channel[channel.length - 1];
}
switch (channel) {
const _channel = channel.toLowerCase();
switch (_channel) {
case 'waba':
return <WABIcon key={channel} className='text-whatsapp' />;
case 'wa':

@ -169,6 +169,9 @@ export default defineConfig({
output: {
entryFileNames: '[name]/build.[hash].js',
manualChunks(id) {
if (id.toLowerCase().includes('lexical')) {
return 'lexical';
}
if (id.includes('node_modules')) {
return 'vendor';
// return id.toString().split('node_modules/')[1].split('/')[0].toString();

Loading…
Cancel
Save