courrier preview
This commit is contained in:
parent
c4958d7e4c
commit
7f87e4f00a
@ -74,6 +74,9 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
// Add any custom toolbar handlers here
|
||||
}
|
||||
},
|
||||
clipboard: {
|
||||
matchVisual: false // Disable clipboard matching for better HTML handling
|
||||
},
|
||||
// Don't initialize better-table yet - we'll do it after content is loaded
|
||||
'better-table': false,
|
||||
},
|
||||
@ -93,68 +96,54 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
direction
|
||||
});
|
||||
|
||||
// Make sure content is properly sanitized before injecting it
|
||||
const cleanContent = sanitizeHtml(processedContent || initialContent);
|
||||
// Simplify complex email content to something Quill can handle better
|
||||
const sanitizedContent = sanitizeHtml(processedContent || initialContent);
|
||||
|
||||
// First, directly set the content
|
||||
if (editorRef.current) {
|
||||
editorRef.current.innerHTML = cleanContent;
|
||||
// Use direct innerHTML setting for the initial content
|
||||
quillRef.current.root.innerHTML = sanitizedContent;
|
||||
|
||||
// Set the direction for the content
|
||||
quillRef.current.format('direction', direction);
|
||||
if (direction === 'rtl') {
|
||||
quillRef.current.format('align', 'right');
|
||||
}
|
||||
|
||||
// Then let Quill parse and format it correctly
|
||||
setTimeout(() => {
|
||||
// Only proceed if editor ref is still available
|
||||
if (!editorRef.current) return;
|
||||
// Set cursor at the beginning
|
||||
quillRef.current.setSelection(0, 0);
|
||||
|
||||
// Ensure the cursor and scroll position is at the top of the editor
|
||||
if (editorRef.current) {
|
||||
editorRef.current.scrollTop = 0;
|
||||
|
||||
// Get the content from the editor element
|
||||
const content = editorRef.current.innerHTML;
|
||||
// Find and scroll parent containers that might have scroll
|
||||
const scrollable = [
|
||||
editorRef.current.closest('.ql-container'),
|
||||
editorRef.current.closest('.rich-email-editor-container'),
|
||||
editorRef.current.closest('.overflow-y-auto'),
|
||||
document.querySelector('.overflow-y-auto')
|
||||
];
|
||||
|
||||
// Clear the editor
|
||||
quillRef.current.setText('');
|
||||
|
||||
// Insert clean content
|
||||
quillRef.current.clipboard.dangerouslyPasteHTML(0, content);
|
||||
|
||||
// Set the direction for the content
|
||||
quillRef.current.format('direction', direction);
|
||||
if (direction === 'rtl') {
|
||||
quillRef.current.format('align', 'right');
|
||||
}
|
||||
|
||||
// Set cursor at the beginning (before the quoted content)
|
||||
quillRef.current.setSelection(0, 0);
|
||||
|
||||
// Ensure the cursor and scroll position is at the top of the editor
|
||||
if (editorRef.current) {
|
||||
editorRef.current.scrollTop = 0;
|
||||
|
||||
// Find and scroll parent containers that might have scroll
|
||||
const scrollable = [
|
||||
editorRef.current.closest('.ql-container'),
|
||||
editorRef.current.closest('.rich-email-editor-container'),
|
||||
editorRef.current.closest('.overflow-y-auto'),
|
||||
document.querySelector('.overflow-y-auto')
|
||||
];
|
||||
|
||||
scrollable.forEach(el => {
|
||||
if (el instanceof HTMLElement) {
|
||||
el.scrollTop = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
scrollable.forEach(el => {
|
||||
if (el instanceof HTMLElement) {
|
||||
el.scrollTop = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error setting initial content:', err);
|
||||
// Fallback: just set text
|
||||
quillRef.current.setText('');
|
||||
|
||||
// Try simplest approach
|
||||
// Extract text as a last resort
|
||||
try {
|
||||
quillRef.current.clipboard.dangerouslyPasteHTML(initialContent);
|
||||
// Create a temporary div to extract text from HTML
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = initialContent;
|
||||
const textContent = tempDiv.textContent || tempDiv.innerText || '';
|
||||
quillRef.current.setText(textContent);
|
||||
} catch (e) {
|
||||
console.error('Fallback failed too:', e);
|
||||
// Last resort: strip all HTML
|
||||
quillRef.current.setText(initialContent.replace(/<[^>]*>/g, ''));
|
||||
quillRef.current.setText('');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,24 +176,22 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Update content from props if changed externally
|
||||
// Update content from props if changed externally - using a simpler approach
|
||||
useEffect(() => {
|
||||
if (quillRef.current && isReady) {
|
||||
if (quillRef.current && isReady && initialContent) {
|
||||
const currentContent = quillRef.current.root.innerHTML;
|
||||
|
||||
// Only update if content changed to avoid editor position reset
|
||||
if (initialContent !== currentContent) {
|
||||
try {
|
||||
// Preserve cursor position if possible
|
||||
const selection = quillRef.current.getSelection();
|
||||
|
||||
// Process content to ensure correct direction
|
||||
const { direction, html: processedContent } = processContentWithDirection(initialContent);
|
||||
|
||||
// First clear the content
|
||||
quillRef.current.root.innerHTML = '';
|
||||
// Sanitize the HTML
|
||||
const sanitizedContent = sanitizeHtml(processedContent || initialContent);
|
||||
|
||||
// Then insert the new content at position 0
|
||||
quillRef.current.clipboard.dangerouslyPasteHTML(0, sanitizeHtml(processedContent || initialContent));
|
||||
// SIMPLIFIED: Set content directly to the root element rather than using clipboard
|
||||
quillRef.current.root.innerHTML = sanitizedContent;
|
||||
|
||||
// Set the direction for the content
|
||||
quillRef.current.format('direction', direction);
|
||||
@ -215,14 +202,20 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
// Force update
|
||||
quillRef.current.update();
|
||||
|
||||
// Restore selection if possible
|
||||
if (selection) {
|
||||
setTimeout(() => quillRef.current.setSelection(selection), 10);
|
||||
}
|
||||
// Set selection to beginning
|
||||
quillRef.current.setSelection(0, 0);
|
||||
} catch (err) {
|
||||
console.error('Error updating content:', err);
|
||||
// Fallback update method
|
||||
quillRef.current.clipboard.dangerouslyPasteHTML(sanitizeHtml(initialContent));
|
||||
// Safer fallback that avoids clipboard API
|
||||
try {
|
||||
// Extract basic text if everything else fails
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = initialContent;
|
||||
const textContent = tempDiv.textContent || tempDiv.innerText || '';
|
||||
quillRef.current.setText(textContent);
|
||||
} catch (e) {
|
||||
console.error('All fallbacks failed:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -399,36 +392,13 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
/* Status styles for email displays */
|
||||
:global(.ql-editor td[class*="status"]),
|
||||
:global(.ql-editor td[class*="Status"]) {
|
||||
background-color: #f8f9fa !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
/* Amount styles */
|
||||
:global(.ql-editor td[class*="amount"]),
|
||||
:global(.ql-editor td[class*="Amount"]),
|
||||
:global(.ql-editor td[class*="price"]),
|
||||
:global(.ql-editor td[class*="Price"]) {
|
||||
text-align: right !important;
|
||||
font-family: monospace !important;
|
||||
}
|
||||
|
||||
/* Header row styles */
|
||||
:global(.ql-editor tr:first-child td),
|
||||
:global(.ql-editor th) {
|
||||
background-color: #f8f9fa !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
/* Improve table cells with specific content */
|
||||
:global(.ql-editor td:has(div[class*="number"])),
|
||||
:global(.ql-editor td:has(div[class*="Number"])),
|
||||
:global(.ql-editor td:has(div[class*="invoice"])),
|
||||
:global(.ql-editor td:has(div[class*="Invoice"])) {
|
||||
font-family: monospace !important;
|
||||
letter-spacing: 0.5px !important;
|
||||
/* Email quote styling */
|
||||
:global(.email-original-content) {
|
||||
margin-top: 20px !important;
|
||||
padding-top: 10px !important;
|
||||
border-top: 1px solid #ddd !important;
|
||||
color: #555 !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
/* Fix quoted paragraphs */
|
||||
|
||||
@ -279,14 +279,15 @@ export function formatReplyEmail(originalEmail: EmailMessage | LegacyEmailMessag
|
||||
// Extract content using centralized utility
|
||||
const { text: originalTextContent, html: originalHtmlContent } = extractEmailContent(originalEmail);
|
||||
|
||||
// Create content with appropriate quote formatting
|
||||
// Create a simpler HTML structure that's easier for Quill to handle
|
||||
const replyBody = `
|
||||
<br/>
|
||||
<br/>
|
||||
<blockquote style="border-left: 2px solid #ddd; padding-left: 10px; margin: 10px 0; color: #505050;">
|
||||
<p>On ${dateStr}, ${fromStr} wrote:</p>
|
||||
${originalHtmlContent || originalTextContent.replace(/\n/g, '<br>')}
|
||||
</blockquote>
|
||||
<div class="email-original-content">
|
||||
<div>On ${dateStr}, ${fromStr} wrote:</div>
|
||||
<blockquote style="margin: 10px 0; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
||||
${originalTextContent.replace(/\n/g, '<br>')}
|
||||
</blockquote>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Process the content with proper direction
|
||||
@ -334,20 +335,19 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe
|
||||
// Extract content using centralized utility
|
||||
const { text: originalTextContent, html: originalHtmlContent } = extractEmailContent(originalEmail);
|
||||
|
||||
// Create forwarded content with header information
|
||||
// Create a simpler forwarded content structure for better Quill compatibility
|
||||
const forwardBody = `
|
||||
<br/>
|
||||
<br/>
|
||||
<div class="email-forwarded-content">
|
||||
<p>---------- Forwarded message ---------</p>
|
||||
<p><strong>From:</strong> ${fromStr}</p>
|
||||
<p><strong>Date:</strong> ${dateStr}</p>
|
||||
<p><strong>Subject:</strong> ${subject || ''}</p>
|
||||
<p><strong>To:</strong> ${toStr}</p>
|
||||
${ccStr ? `<p><strong>Cc:</strong> ${ccStr}</p>` : ''}
|
||||
<div style="margin-top: 15px; border-top: 1px solid #eee; padding-top: 15px;">
|
||||
${originalHtmlContent || originalTextContent.replace(/\n/g, '<br>')}
|
||||
</div>
|
||||
<div class="email-original-content">
|
||||
<div>---------- Forwarded message ---------</div>
|
||||
<div><strong>From:</strong> ${fromStr}</div>
|
||||
<div><strong>Date:</strong> ${dateStr}</div>
|
||||
<div><strong>Subject:</strong> ${subject || ''}</div>
|
||||
<div><strong>To:</strong> ${toStr}</div>
|
||||
${ccStr ? `<div><strong>Cc:</strong> ${ccStr}</div>` : ''}
|
||||
<blockquote style="margin-top: 10px; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
||||
${originalTextContent.replace(/\n/g, '<br>')}
|
||||
</blockquote>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user