diff --git a/components/email/RichEmailEditor.tsx b/components/email/RichEmailEditor.tsx index 1e3d7d62..2c3eeff0 100644 --- a/components/email/RichEmailEditor.tsx +++ b/components/email/RichEmailEditor.tsx @@ -34,21 +34,6 @@ const RichEmailEditor: React.FC = ({ const Quill = (await import('quill')).default; - // Import quill-better-table - try { - const QuillBetterTable = await import('quill-better-table'); - - // Register the table module if available - if (QuillBetterTable && QuillBetterTable.default) { - Quill.register({ - 'modules/better-table': QuillBetterTable.default - }, true); - console.log('Better Table module registered successfully'); - } - } catch (err) { - console.warn('Table module not available:', err); - } - // Define custom formats/modules with table support const emailToolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], @@ -70,15 +55,6 @@ const RichEmailEditor: React.FC = ({ // Add any custom toolbar handlers here } }, - 'better-table': preserveFormatting ? { - operationMenu: { - items: { - unmergeCells: { - text: 'Unmerge cells' - } - } - } - } : false, }, placeholder: placeholder, theme: 'snow', @@ -95,41 +71,34 @@ const RichEmailEditor: React.FC = ({ // If we're specifically trying to preserve complex HTML like tables if (preserveFormatting) { - // For tables and complex formatting, we may need to manually preserve some elements - // Get all table elements from the original content + // For tables and complex formatting, use direct HTML setting const tempDiv = document.createElement('div'); tempDiv.innerHTML = preservedContent; - // Force better table rendering in Quill + if (tempDiv.querySelectorAll('table').length > 0) { + // This handles tables better than the Quill Delta format + quillRef.current.root.innerHTML = preservedContent; + } + + // Force refresh after a delay setTimeout(() => { - // This ensures tables are properly rendered by forcing a refresh quillRef.current.update(); - // Additional step: directly set HTML if tables aren't rendering properly - if (tempDiv.querySelectorAll('table').length > 0 && - !quillRef.current.root.querySelectorAll('table').length) { - console.log('Using HTML fallback for tables'); - quillRef.current.root.innerHTML = preservedContent; - } - // Ensure the cursor and scroll position is at the top of the editor quillRef.current.setSelection(0, 0); // Also scroll the container to the top if (editorRef.current) { editorRef.current.scrollTop = 0; - - // Also find and scroll parent containers that might have scroll - const scrollContainer = editorRef.current.closest('.ql-container'); - if (scrollContainer) { - scrollContainer.scrollTop = 0; - } - - // One more check for nested scroll containers (like overflow divs) - const parentScrollContainer = editorRef.current.closest('.rich-email-editor-container'); - if (parentScrollContainer) { - parentScrollContainer.scrollTop = 0; - } + const containers = [ + editorRef.current.closest('.ql-container'), + editorRef.current.closest('.rich-email-editor-container') + ]; + containers.forEach(container => { + if (container) { + (container as HTMLElement).scrollTop = 0; + } + }); } }, 50); } else { @@ -145,10 +114,16 @@ const RichEmailEditor: React.FC = ({ } } - // Add change listener + // Add change listener (with debounce to prevent infinite updates) + let debounceTimeout: NodeJS.Timeout; quillRef.current.on('text-change', () => { - const html = quillRef.current.root.innerHTML; - onChange(html); + clearTimeout(debounceTimeout); + debounceTimeout = setTimeout(() => { + const html = quillRef.current?.root.innerHTML; + if (html !== initialContent) { + onChange(html); + } + }, 300); }); // Improve editor layout @@ -203,7 +178,7 @@ const RichEmailEditor: React.FC = ({ } } } - }, [initialContent, isReady]); + }, [initialContent, isReady, preserveFormatting]); return (