组件: 可拖拽的弹窗

dev/email
Lei OT 12 months ago
parent 3f36c648f9
commit 1f91520f1b

@ -4,28 +4,34 @@ import Modal from '@dckj/react-better-modal';
import '@dckj/react-better-modal/dist/index.css';
import { isEmpty } from '@/utils/commons';
const DnDModal = ({ children, open, setOpen, onCancel, initial = {}, title, ...props }) => {
const DnDModal = ({ children, open, setOpen, onCancel, onMove, onResize, initial = {}, title, footer=null, ...props }) => {
// const [open, setOpen] = useState(false);
function onHandleMove(e) {
console.log(e, '--->>> onHandleMove');
// console.log(e, '--->>> onHandleMove');
if (typeof onMove === 'function') {
onMove(e);
}
}
function onHandleResize(e) {
console.log(e, '--->>> onHandleResize');
// console.log(e, '--->>> onHandleResize');
if (typeof onResize === 'function') {
onResize(e);
}
}
function onHandleOk() {
console.log('onOk callback');
// console.log('onOk callback');
}
function onHandleCancel() {
console.log('onCancel callback');
// console.log('onCancel callback');
if (typeof onCancel === 'function') {
onCancel();
}
setOpen(false);
}
function onStageChange({ state }) {
console.log(state);
// console.log(state);
}
return (
<Modal
@ -37,14 +43,14 @@ const DnDModal = ({ children, open, setOpen, onCancel, initial = {}, title, ...p
maskClosable={false}
// theme='dark'
// className={'!border !border-solid !border-indigo-500 rounded !p-2' }
className='rounded-t rounded-b-none border border-solid border-indigo-300 shadow-heavy '
titleBarClassName='bg-neutral-100 rounded rounded-b-none border-none p-3 font-bold text-slate-600'
contentClassName='p-2'
footerClassName='p-2'
className='!rounded-t !rounded-b-none !border !border-solid !border-indigo-300 !shadow-heavy '
titleBarClassName='!bg-neutral-100 !rounded !rounded-b-none !border-none !p-3 !font-bold !text-slate-600'
contentClassName='!p-2'
footerClassName='!p-2'
zIndex={2}
initialWidth={initial.width || 680}
initialHeight={initial.height || 600}
initialTop={initial.top}
initialTop={initial.top || 74}
initialLeft={initial.left || window.innerWidth - 700}
title={title}
minimizeButton={<></>}
@ -53,7 +59,7 @@ const DnDModal = ({ children, open, setOpen, onCancel, initial = {}, title, ...p
onCancel={onHandleCancel}
// onOk={onHandleOk}
onStageChange={onStageChange}
footer={null}>
footer={footer}>
<>{children}</>
</Modal>
);

@ -122,7 +122,7 @@ const BubbleIM = ({ handlePreview, handleContactClick, setNewChatModalVisible, s
focusMsg === message.id ? 'message-box-focus' : '',
message.status === 'failed' ? 'failed-msg' : '',
// '*:bg-waba-me'
message.sender === 'me' ? '*:bg-waba-me' : '', // todo: channel color
message.sender === 'me' ? '*:!bg-waba-me' : '', // todo: channel color
].join(' ')}
{...(message.type === 'meetingLink'
? {

@ -1,11 +1,9 @@
import { createContext, useEffect, useState } from 'react';
import { useState } from 'react';
import { Button, Divider, Avatar } from 'antd';
import { DeleteOutlined } from '@ant-design/icons';
import Modal from '@dckj/react-better-modal';
import { Avatar as Avatar1 } from 'react-chat-elements';
import { ReplyIcon, ShareForwardIcon } from '@/components/Icons';
import { isEmpty, olog, stringToColour } from '@/utils/commons';
import { stringToColour } from '@/utils/commons';
import EmailEditorPopup from '../Input/EmailEditorPopup';
import DnDModal from '@/components/DndModal';
const TagColorStyle = (tag) => {
const color = stringToColour(tag);
@ -17,33 +15,14 @@ const EmailDetail = ({ open, setOpen, emailDetail, ...props }) => {
// const [open, setOpen] = useState(false);
const [initialPosition, setInitialPosition] = useState({});
const [initialSize, setInitialSize] = useState({});
const [initialMailTo, setInitialMailTo] = useState({});
function onHandleMove(e) {
// console.log(e, '--->>> onHandleMove');
const { top, left, width, height } = e;
setInitialPosition({ top, left });
console.log('top, left, width, height', '--->>> onHandleMove');
console.log(top, left, width, height, '--->>> onHandleMove');
}
function onHandleResize(e) {
// console.log(e, '--->>> onHandleResize');
const { top, left, width, height } = e;
setInitialPosition({ top, left });
setInitialSize({ width, height });
console.log('top, left, width, height', '--->>> onHandleResize');
console.log(top, left, width, height, '--->>> onHandleResize');
}
function onHandleOk() {
console.log('onOk callback');
}
function onHandleCancel() {
console.log('onCancel callback');
setOpen(false);
}
function onStageChange({ state }) {
console.log(state);
}
const [action, setAction] = useState('');
@ -62,37 +41,7 @@ const EmailDetail = ({ open, setOpen, emailDetail, ...props }) => {
return (
<>
<Modal
visible={open}
keyboard={false}
draggable
resizable
mask={false}
maskClosable={false}
// theme='dark'
// className={'!border !border-solid !border-indigo-500 rounded !p-2' }
className='rounded-t rounded-b-none border border-solid border-indigo-300 shadow-heavy '
titleBarClassName='bg-neutral-100 rounded rounded-b-none border-none p-3 font-bold text-slate-600'
contentClassName='p-2'
footerClassName='p-2'
zIndex={2}
initialWidth={680}
initialHeight={600}
initialTop={74}
initialLeft={window.innerWidth - 700}
// left={initialPosition.left}
// top={initialPosition.top}
// width={initialSize.width}
// height={initialSize.height}
// title={`${reference ? ': ' : ': '} ${fromEmail || ''}`}
title={emailOrigin.subject}
minimizeButton={<></>}
onMove={onHandleMove}
onResize={onHandleResize}
onCancel={onHandleCancel}
// onOk={onHandleOk}
onStageChange={onStageChange}
footer={null}>
<DnDModal open={open} setOpen={setOpen} title={emailOrigin.subject} initial={{ top: 74, width: 680, height: 600 }} onMove={onHandleMove} onResize={onHandleResize}>
{/* email toolbar */}
<div className='email-container flex flex-col gap-2 *:p-2 *:rounded-sm *:border-b *:border-gray-200 *:shadow-1md'>
{/* <div className='flex items-center justify-start '>
@ -150,8 +99,16 @@ const EmailDetail = ({ open, setOpen, emailDetail, ...props }) => {
{/* <div className='mt-2'>{emailOrigin.attachments.map(attachment => <div key={attachment.name}>{attachment.name}</div>)}</div> */}
</div>
</div>
</Modal>
<EmailEditorPopup open={openEmailEditor} setOpen={setOpenEmailEditor} fromEmail={fromEmail} quote={ReferEmailMsg} initial={{...initialPosition, ...initialSize}} action={action} key={`email-editor-inner-${action}-popup_${ReferEmailMsg.id}`}/>
</DnDModal>
<EmailEditorPopup
open={openEmailEditor}
setOpen={setOpenEmailEditor}
fromEmail={fromEmail}
quote={ReferEmailMsg}
initial={{ ...initialPosition, ...initialSize }}
action={action}
key={`email-editor-inner-${action}-popup_${ReferEmailMsg.id}`}
/>
</>
);
};

@ -2,11 +2,12 @@ import { createContext, useEffect, useState } from 'react';
import { Button, Form, Input, Flex, Checkbox, Switch, Mentions, Popover, Popconfirm, Select } from 'antd';
import Modal from '@dckj/react-better-modal';
import '@dckj/react-better-modal/dist/index.css';
import DnDModal from '@/components/DndModal';
import LexicalEditor from '@/components/LexicalEditor';
import { $getRoot, $getSelection, } from 'lexical';
import {$generateHtmlFromNodes, $generateNodesFromDOM} from '@lexical/html';
import { $getRoot, $getSelection } from 'lexical';
import { $generateHtmlFromNodes, $generateNodesFromDOM } from '@lexical/html';
import { isEmpty } from '@/utils/commons';
// import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
@ -35,30 +36,9 @@ const getAbstract = (longtext) => {
return abstract;
};
const EmailEditorPopup = ({ open, setOpen, fromEmail, reference, quote = {}, initial = {}, action='reply', ...props }) => {
const EmailEditorPopup = ({ open, setOpen, fromEmail, reference, quote = {}, initial = {}, action = 'reply', ...props }) => {
const [form] = Form.useForm();
// const [open, setOpen] = useState(false);
function onHandleMove(e) {
console.log(e, '--->>> onHandleMove');
}
function onHandleResize(e) {
console.log(e, '--->>> onHandleResize');
}
function onHandleOk() {
console.log('onOk callback');
}
function onHandleCancel() {
console.log('onCancel callback');
form.resetFields();
setOpen(false);
}
function onStageChange({ state }) {
console.log(state);
}
const [isRichText, setIsRichText] = useState(true);
const [htmlContent, setHtmlContent] = useState('');
const [textContent, setTextContent] = useState('');
@ -88,15 +68,10 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, reference, quote = {}, ini
body.content = isRichText ? htmlContent : textContent;
body.fromEmail = newFromEmail || fromEmail;
console.log('body', body);
form
.validateFields()
.then((values) => {
form.resetFields();
})
// .catch((err) => {})
;
form.validateFields().then((values) => {
form.resetFields();
});
// .catch((err) => {})
// setOpen(false);
};
@ -147,7 +122,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, reference, quote = {}, ini
cc: quote.cc,
subject: `Re: ${subject}`,
};
const forwardValues = {subject: `Fw: ${subject}`,};
const forwardValues = { subject: `Fw: ${subject}` };
if (action === 'reply') {
form.setFieldsValue(_formValues);
setInitialForm(_formValues);
@ -160,8 +135,8 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, reference, quote = {}, ini
}, [quote, open]);
const [openPlainTextConfirm, setOpenPlainTextConfirm] = useState(false);
const handlePlainTextOpenChange = ({target}) => {
const {checked: newChecked} = target;
const handlePlainTextOpenChange = ({ target }) => {
const { checked: newChecked } = target;
if (!newChecked) {
setIsRichText(true);
setOpenPlainTextConfirm(false);
@ -172,51 +147,37 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, reference, quote = {}, ini
const confirmPlainText = () => {
setIsRichText(false);
setOpenPlainTextConfirm(false);
}
};
return (
<>
<Modal
visible={open}
keyboard={false}
draggable
resizable
mask={false}
maskClosable={false}
// theme='dark'
// className={'!border !border-solid !border-indigo-500 rounded !p-2' }
className='rounded-t rounded-b-none border border-solid border-indigo-300 shadow-heavy '
titleBarClassName='bg-neutral-100 rounded rounded-b-none border-none p-3 font-bold text-slate-600'
contentClassName='p-2'
footerClassName='p-2'
zIndex={2}
initialWidth={initial.width || 680}
initialHeight={initial.height || 600}
initialTop={initial.top || (isEmpty(reference) ? 20 : 74)}
initialLeft={initial.left || window.innerWidth - 700}
<DnDModal
open={open}
setOpen={setOpen}
initial={{ top: isEmpty(reference) ? 20 : 74, width: 680, height: 600 }}
onCancel={() => {
form.resetFields();
}}
title={initialForm.subject || `${reference ? '回复: ' : '写邮件: '} ${fromEmail || ''}`}
minimizeButton={<></>}
onMove={onHandleMove}
onResize={onHandleResize}
onCancel={onHandleCancel}
// onOk={onHandleOk}
onStageChange={onStageChange}
footer={
<div className='w-full flex gap-6 justify-start items-center text-indigo-600'>
<Button type='primary' className='bg-indigo-500 shadow shadow-indigo-300 hover:!bg-indigo-400 active:bg-indigo-400 focus:bg-indigo-400' onClick={onHandleSend}>
发送
</Button>
<Popconfirm
description='切换内容为纯文本格式将丢失信件核签名的格式, 确定使用纯文本?'
onConfirm={confirmPlainText}
open={openPlainTextConfirm}
>
<Checkbox checked={!isRichText} onChange={handlePlainTextOpenChange}>纯文本</Checkbox>
<Popconfirm description='切换内容为纯文本格式将丢失信件核签名的格式, 确定使用纯文本?' onConfirm={confirmPlainText} open={openPlainTextConfirm}>
<Checkbox checked={!isRichText} onChange={handlePlainTextOpenChange}>
纯文本
</Checkbox>
</Popconfirm>
<Select options={[
{key: 'lyt@hainatravel.com', value: 'lyt@hainatravel.com', label: 'LYT <lyt@hainatravel.com>' },
{key: 'XXX@chinahighlights.com', value: 'XXX@chinahighlights.com', label: 'XXX <XXX@chinahighlights.com>' },
]} value={newFromEmail || fromEmail} onChange={(val) => setNewFromEmail(val)} variant={'borderless'} />
<Select
options={[
{ key: 'lyt@hainatravel.com', value: 'lyt@hainatravel.com', label: 'LYT <lyt@hainatravel.com>' },
{ key: 'XXX@chinahighlights.com', value: 'XXX@chinahighlights.com', label: 'XXX <XXX@chinahighlights.com>' },
]}
value={newFromEmail || fromEmail}
onChange={(val) => setNewFromEmail(val)}
variant={'borderless'}
/>
</div>
}>
<Form
@ -273,7 +234,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, reference, quote = {}, ini
</Form.Item>
</Form>
<LexicalEditor {...{ isRichText }} onChange={handleEditorChange} initialValue={initialContent} />
</Modal>
</DnDModal>
</>
);
};

Loading…
Cancel
Save