Files
clinicpro/assets/admin/components/RichTextEditor.tsx
T
hamed 47323daa27 feat: add RichTextEditor component for rich text editing in articles
feat: create SanitizeBlogBodiesCommand to clean existing blog bodies according to current HTML sanitization policies

test: add AppointmentTreatmentSessionLinkTest to ensure appointment booking functionality works correctly with treatment session links
2026-08-08 11:40:17 +03:30

79 lines
2.7 KiB
TypeScript

import React from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import {
ClassicEditor,
Essentials,
Paragraph,
Heading,
Bold,
Italic,
Link,
List,
BlockQuote,
Table,
TableToolbar,
Undo,
} from 'ckeditor5';
import translations from 'ckeditor5/translations/fa.js';
import 'ckeditor5/ckeditor5.css';
/**
* ادیتور متن غنی مقاله‌ها.
*
* تا ۲۰۲۶-۰۸-۰۸ هر دو صفحهٔ مقاله مستقیم `@ckeditor/ckeditor5-build-classic` را
* import می‌کردند. آن پکیج deprecated بود و ۶۲ advisory داشت (یافتهٔ ۴ آدیت
* ۲۰۲۶-۰۸-۰۷). جایگزینش پکیج umbrella `ckeditor5` است که در آن، برخلاف build
* آماده، فهرست پلاگین‌ها صریح است.
*
* پیکربندی اینجا متمرکز شد تا مهاجرت بعدی یک فایل باشد نه دو صفحه — و تا نوار
* ابزارِ دو صفحه از هم واگرا نشود.
*
* فهرست پلاگین‌ها دقیقاً همان دکمه‌های نوار ابزارِ قبلی است، نه بیشتر: هر پلاگین
* اضافه یعنی markup تازه‌ای که `html_sanitizer.yaml` هنوز مجازش نکرده و هنگام
* ذخیره حذف می‌شود.
*/
export default function RichTextEditor({
value,
onChange,
}: {
value: string;
onChange: (html: string) => void;
}) {
return (
<div dir="rtl" className="ck-rtl">
<CKEditor
editor={ClassicEditor}
data={value}
onChange={(_evt, editor) => onChange(editor.getData())}
config={{
licenseKey: 'GPL',
language: 'fa',
translations: [translations],
plugins: [
Essentials,
Paragraph,
Heading,
Bold,
Italic,
Link,
List,
BlockQuote,
Table,
TableToolbar,
Undo,
],
toolbar: [
'heading', '|',
'bold', 'italic', 'link', 'bulletedList', 'numberedList', '|',
'blockQuote', 'insertTable', '|',
'undo', 'redo',
],
table: {
contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells'],
},
}}
/>
</div>
);
}