feat: extract WysiwygEditor into reusable component and add advanced formatting options
Build and Push Multi-Platform Images / build-and-push (push) Successful in 23s
Build and Push Multi-Platform Images / build-and-push (push) Successful in 23s
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
|
||||
import { WysiwygEditor, type WysiwygEditorHandle } from '../components/WysiwygEditor';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Button, Dropdown, Empty, Form, Input, Modal, Popconfirm, Select, Space, Spin, Steps, Tag, Tooltip, Typography, message } from 'antd';
|
||||
import type { MenuProps } from 'antd';
|
||||
@@ -21,9 +22,6 @@ import {
|
||||
ZoomInOutlined,
|
||||
ZoomOutOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { useEditor, EditorContent } from '@tiptap/react';
|
||||
import StarterKit from '@tiptap/starter-kit';
|
||||
import Underline from '@tiptap/extension-underline';
|
||||
import { inboxApi, type InboxBarcode, type InboxFile, type PostprocessActionResult } from '../api/inbox';
|
||||
import { paperlessApi } from '../api/paperless';
|
||||
import { userSettingsApi, type SenderOption } from '../api/userSettings';
|
||||
@@ -637,27 +635,6 @@ function DownloadSegmentsDialog({ open, fileId, fileName, documents, onClose }:
|
||||
);
|
||||
}
|
||||
|
||||
function TiptapToolbar({ editor }: { editor: ReturnType<typeof useEditor> }) {
|
||||
if (!editor) return null;
|
||||
const btnStyle = (active: boolean): React.CSSProperties => ({
|
||||
padding: '2px 8px',
|
||||
border: '1px solid #d9d9d9',
|
||||
borderRadius: 4,
|
||||
cursor: 'pointer',
|
||||
background: active ? '#e6f4ff' : '#fff',
|
||||
fontWeight: active ? 600 : 400,
|
||||
});
|
||||
return (
|
||||
<div style={{ display: 'flex', gap: 4, padding: '4px 0', borderBottom: '1px solid #f0f0f0', marginBottom: 6, flexWrap: 'wrap' }}>
|
||||
<button style={btnStyle(editor.isActive('bold'))} onMouseDown={(e) => { e.preventDefault(); editor.chain().focus().toggleBold().run(); }}>F</button>
|
||||
<button style={{ ...btnStyle(editor.isActive('italic')), fontStyle: 'italic' }} onMouseDown={(e) => { e.preventDefault(); editor.chain().focus().toggleItalic().run(); }}>K</button>
|
||||
<button style={{ ...btnStyle(editor.isActive('underline')), textDecoration: 'underline' }} onMouseDown={(e) => { e.preventDefault(); editor.chain().focus().toggleUnderline().run(); }}>U</button>
|
||||
<button style={btnStyle(editor.isActive('bulletList'))} onMouseDown={(e) => { e.preventDefault(); editor.chain().focus().toggleBulletList().run(); }}>• Liste</button>
|
||||
<button style={btnStyle(editor.isActive('orderedList'))} onMouseDown={(e) => { e.preventDefault(); editor.chain().focus().toggleOrderedList().run(); }}>1. Liste</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface SendEmailDialogProps {
|
||||
open: boolean;
|
||||
fileId: string;
|
||||
@@ -672,11 +649,7 @@ function SendEmailDialog({ open, fileId, fileName, documents, onClose }: SendEma
|
||||
const [filenames, setFilenames] = useState<string[]>([]);
|
||||
const [senders, setSenders] = useState<SenderOption[]>([]);
|
||||
const [selectedSender, setSelectedSender] = useState<string>('default');
|
||||
|
||||
const editor = useEditor({
|
||||
extensions: [StarterKit, Underline],
|
||||
content: '',
|
||||
});
|
||||
const editorRef = useRef<WysiwygEditorHandle>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
@@ -688,15 +661,13 @@ function SendEmailDialog({ open, fileId, fileName, documents, onClose }: SendEma
|
||||
),
|
||||
);
|
||||
userSettingsApi.get().then((settings) => {
|
||||
editor?.commands.setContent(settings.mailSignatureHtml ?? '');
|
||||
}).catch(() => {
|
||||
editor?.commands.clearContent();
|
||||
});
|
||||
editorRef.current?.setContent(settings.mailSignatureHtml ?? '');
|
||||
}).catch(() => {});
|
||||
userSettingsApi.getSenders().then((s) => {
|
||||
setSenders(s);
|
||||
setSelectedSender(s.length > 1 ? 'user' : 'default');
|
||||
}).catch(() => setSenders([]));
|
||||
}, [open, documents, fileName, form, editor]);
|
||||
}, [open, documents, fileName, form]);
|
||||
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
@@ -705,8 +676,8 @@ function SendEmailDialog({ open, fileId, fileName, documents, onClose }: SendEma
|
||||
await inboxApi.sendEmail(fileId, {
|
||||
to: values.to,
|
||||
subject: values.subject,
|
||||
body: editor?.getText() ?? '',
|
||||
html: editor?.getHTML(),
|
||||
body: editorRef.current?.getText() ?? '',
|
||||
html: editorRef.current?.getHTML(),
|
||||
segments: documents.map((doc, i) => ({
|
||||
pages: doc.pages,
|
||||
filename: filenames[i] || fileName,
|
||||
@@ -752,10 +723,7 @@ function SendEmailDialog({ open, fileId, fileName, documents, onClose }: SendEma
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label="Nachricht">
|
||||
<div style={{ border: '1px solid #d9d9d9', borderRadius: 6, padding: '6px 10px', minHeight: 160 }}>
|
||||
<TiptapToolbar editor={editor} />
|
||||
<EditorContent editor={editor} style={{ minHeight: 120, outline: 'none' }} />
|
||||
</div>
|
||||
<WysiwygEditor ref={editorRef} minHeight={180} />
|
||||
</Form.Item>
|
||||
<Form.Item label="Anhänge">
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
||||
|
||||
Reference in New Issue
Block a user