From 36bc444f90d3d67133cf832faa896f968f7d63f5 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 26 May 2026 09:57:32 +0000 Subject: [PATCH] Change editor --- src/frontend/package.json | 7 + .../src/components/editors/NotesEditor.tsx | 254 ++++++++++++------ src/frontend/yarn.lock | 204 ++++++++++++++ 3 files changed, 388 insertions(+), 77 deletions(-) diff --git a/src/frontend/package.json b/src/frontend/package.json index 349137c2a7..e13c65ac2f 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -73,12 +73,19 @@ "@mantine/modals": "^9.2.1", "@mantine/notifications": "^9.2.1", "@mantine/spotlight": "^9.2.1", + "@mantine/tiptap": "^9.2.1", "@mantine/utils": "^6.0.22", "@mantine/vanilla-extract": "^9.2.1", "@messageformat/date-skeleton": "^1.1.0", "@sentry/react": "^10.43.0", "@tabler/icons-react": "^3.17.0", "@tanstack/react-query": "^5.56.2", + "@tiptap/core": "^3.23.6", + "@tiptap/extension-image": "^3.23.6", + "@tiptap/extension-link": "^3.23.6", + "@tiptap/pm": "^3.23.6", + "@tiptap/react": "^3.23.6", + "@tiptap/starter-kit": "^3.23.6", "@uiw/codemirror-theme-vscode": "^4.25.8", "@uiw/react-codemirror": "^4.25.8", "@uiw/react-split": "^5.9.4", diff --git a/src/frontend/src/components/editors/NotesEditor.tsx b/src/frontend/src/components/editors/NotesEditor.tsx index d6a4dfabf3..36bc96e089 100644 --- a/src/frontend/src/components/editors/NotesEditor.tsx +++ b/src/frontend/src/components/editors/NotesEditor.tsx @@ -1,9 +1,14 @@ import { t } from '@lingui/core/macro'; +import { RichTextEditor } from '@mantine/tiptap'; +import '@mantine/tiptap/styles.css'; import { useHotkeys } from '@mantine/hooks'; import { notifications } from '@mantine/notifications'; import { useQuery } from '@tanstack/react-query'; +import Image from '@tiptap/extension-image'; +import { useEditor } from '@tiptap/react'; +import StarterKit from '@tiptap/starter-kit'; import DOMPurify from 'dompurify'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; @@ -11,12 +16,6 @@ import type { ModelType } from '@lib/enums/ModelType'; import { apiUrl } from '@lib/functions/Api'; import { useApi } from '../../contexts/ApiContext'; -import '@blocknote/core/fonts/inter.css'; -import { BlockNoteView } from '@blocknote/mantine'; -import '@blocknote/mantine/style.css'; -import * as BlockNoteLocales from '@blocknote/core/locales'; -import { useCreateBlockNote } from '@blocknote/react'; - import { identifierString } from '@lib/functions/Conversion'; import { ActionIcon, @@ -24,6 +23,7 @@ import { Badge, Box, Button, + FileButton, Flex, Group, HoverCard, @@ -31,13 +31,13 @@ import { Stack, Tabs, Text, - Tooltip, - useMantineColorScheme + Tooltip } from '@mantine/core'; import { IconCirclePlus, IconDeviceFloppy, IconInfoCircle, + IconPhoto, IconReload, IconStar } from '@tabler/icons-react'; @@ -97,8 +97,8 @@ function NoteInfoHover({ note }: { note: any }) { export default function NotesEditor({ modelType, modelId, - editable, - setDirtyCallback + editable: _editable, + setDirtyCallback: _setDirtyCallback }: Readonly<{ modelType: ModelType; modelId: number; @@ -107,21 +107,18 @@ export default function NotesEditor({ }>) { const api = useApi(); const user = useUserState(); - const [language] = useLocalState(useShallow((s) => [s.language])); - const { colorScheme } = useMantineColorScheme(); + const [_language] = useLocalState(useShallow((s) => [s.language])); const [searchParams, setSearchParams] = useSearchParams(); const [isDirty, setIsDirty] = useState(false); - // The ID of the selected note const [selectedNoteId, setSelectedNoteId] = useState( undefined ); // Callback to upload an image file against the currently selected note - // Returns the URL of the uploaded image on success, or throws an error on failure const uploadFile = useCallback( - (file: File) => { + async (file: File): Promise => { const formData = new FormData(); formData.append('note', selectedNoteId?.toString() ?? ''); formData.append('image', file); @@ -135,12 +132,61 @@ export default function NotesEditor({ [selectedNoteId] ); - const editor = useCreateBlockNote({ - dictionary: - BlockNoteLocales[language as keyof typeof BlockNoteLocales] || - BlockNoteLocales.en, - uploadFile: async (file: File) => { - return uploadFile(file); + // Ref so editorProps handlers always call the latest uploadFile without stale closure + const uploadFileRef = useRef(uploadFile); + useEffect(() => { + uploadFileRef.current = uploadFile; + }, [uploadFile]); + + const editor = useEditor({ + extensions: [ + StarterKit.configure({ + link: { openOnClick: false } + }), + Image + ], + content: '', + onUpdate: () => setIsDirty(true), + editorProps: { + handleDrop: (view, event) => { + const files = event.dataTransfer?.files; + if (!files?.length) return false; + const imageFiles = Array.from(files).filter((f) => + f.type.startsWith('image/') + ); + if (!imageFiles.length) return false; + + event.preventDefault(); + const coords = view.posAtCoords({ + left: event.clientX, + top: event.clientY + }); + imageFiles.forEach((file) => { + uploadFileRef.current(file).then((url) => { + if (!url || !coords) return; + const node = view.state.schema.nodes.image?.create({ src: url }); + if (node) view.dispatch(view.state.tr.insert(coords.pos, node)); + }); + }); + return true; + }, + handlePaste: (view, event) => { + const files = event.clipboardData?.files; + if (!files?.length) return false; + const imageFiles = Array.from(files).filter((f) => + f.type.startsWith('image/') + ); + if (!imageFiles.length) return false; + + imageFiles.forEach((file) => { + uploadFileRef.current(file).then((url) => { + if (!url) return; + const node = view.state.schema.nodes.image?.create({ src: url }); + if (node) view.dispatch(view.state.tr.replaceSelectionWith(node)); + }); + }); + return true; + } } }); @@ -163,26 +209,19 @@ export default function NotesEditor({ enabled: !!modelId && !!modelType }); - useEffect(() => { - return editor.onChange(() => setIsDirty(true)); - }, [editor]); - const [selectedNote, setSelectedNote] = useState(undefined); const loadNote = useCallback( (noteId: number) => { const note = notesQuery.data?.find((note: any) => note.pk === noteId); - setSelectedNote(note); - if (note) { - const blocks = editor.tryParseHTMLToBlocks(note.content ?? ''); - - if (blocks) { - editor.replaceBlocks(editor.document, blocks); - } else { - editor.replaceBlocks(editor.document, []); - } + if (editor) { + // Pass emitUpdate:false to avoid triggering dirty state when loading content + editor.commands.setContent( + note ? DOMPurify.sanitize(note.content ?? '') : '', + { emitUpdate: false } + ); } setIsDirty(false); @@ -228,6 +267,11 @@ export default function NotesEditor({ [user, modelType, notesQuery] ); + // Sync editor editable state when permissions change + useEffect(() => { + editor?.setEditable(canEdit); + }, [editor, canEdit]); + const hasNotes = useMemo(() => { return notesQuery.data && notesQuery.data.length > 0; }, [notesQuery.data]); @@ -242,7 +286,6 @@ export default function NotesEditor({ successMessage: null, onFormSuccess: (response: any) => { notesQuery.refetch().then(() => { - // Select the newly created note setSelectedNoteId(response.pk); }); } @@ -265,7 +308,6 @@ export default function NotesEditor({ pk: selectedNoteId, onFormSuccess: (response: any) => { notesQuery.refetch().then(() => { - // Select the updated note setSelectedNoteId(response.pk); }); } @@ -280,46 +322,58 @@ export default function NotesEditor({ return; } - const blocks = editor.document; - const html = editor.blocksToHTMLLossy(blocks); - const cleanHtml = DOMPurify.sanitize(html); + const cleanHtml = DOMPurify.sanitize(editor.getHTML()); - // Sanitize the HTML content before sending to the server (or ensure it's sanitized on the back-end) + const url = apiUrl(ApiEndpoints.note_list, selectedNoteId); - if (selectedNoteId) { - const url = apiUrl(ApiEndpoints.note_list, selectedNoteId); + notifications.hide('note-update-status'); - notifications.hide('note-update-status'); - - api - .patch(url, { content: cleanHtml }) - .then(() => { - setIsDirty(false); - notifications.show({ - title: t`Success`, - message: t`Note updated`, - color: 'green', - id: 'note-update-status', - autoClose: 2000 - }); - }) - .catch((error) => { - notifications.show({ - title: t`Error`, - message: t`Failed to update note: ${error.message}`, - color: 'red', - id: 'note-update-status', - autoClose: 2000 - }); - }) - .finally(() => { - notesQuery.refetch(); + api + .patch(url, { content: cleanHtml }) + .then(() => { + setIsDirty(false); + notifications.show({ + title: t`Success`, + message: t`Note updated`, + color: 'green', + id: 'note-update-status', + autoClose: 2000 }); - } + }) + .catch((error) => { + notifications.show({ + title: t`Error`, + message: t`Failed to update note: ${error.message}`, + color: 'red', + id: 'note-update-status', + autoClose: 2000 + }); + }) + .finally(() => { + notesQuery.refetch(); + }); }, [selectedNoteId, editor, setIsDirty]); useHotkeys([['mod+s', saveNote]]); + const handleImageUpload = useCallback( + async (file: File | null) => { + if (!file || !editor) return; + try { + const url = await uploadFile(file); + editor.chain().focus().setImage({ src: url }).run(); + } catch { + notifications.show({ + title: t`Error`, + message: t`Failed to upload image`, + color: 'red', + autoClose: 2000 + }); + } + }, + [editor, uploadFile] + ); + return ( <> {createNote.modal} @@ -392,14 +446,60 @@ export default function NotesEditor({ )} {hasNotes ? ( - - - + + {canEdit && ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {(props) => ( + + + + + + )} + + + + )} + + ) : ( }> {t`There are no notes yet for this item.`} diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index f60eb5155d..50ade990e7 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -1318,6 +1318,11 @@ resolved "https://registry.yarnpkg.com/@mantine/store/-/store-9.2.1.tgz#27a3548c4cc1567baa2613490d7dcb9300b391ba" integrity sha512-sBTHt9ilfSZAeXQlqFkm8nRm22RunhevxuOUtdSwS9HhuMuS8T27dRRgbdKH2oEFUbaccdQSy5bHbmGbEgVO8w== +"@mantine/tiptap@^9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@mantine/tiptap/-/tiptap-9.2.1.tgz#5bd0cbec540452571e1e8e86960fd0e069c634c4" + integrity sha512-UzztgwqIknJheF39cqG2AgPI1qEvXIa7jNFuij8iB6GLd0UMmCjKnW42Px0WAaHuNfMjweml9IyTLBTSvIK0uA== + "@mantine/utils@^6.0.22": version "6.0.22" resolved "https://registry.yarnpkg.com/@mantine/utils/-/utils-6.0.22.tgz#7eace697084e2bc5a831eb0fd7cbbc04cc1b0354" @@ -1944,11 +1949,26 @@ resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-3.23.4.tgz#f0d6427375d41e69127664d50bd48c91909b63d9" integrity sha512-ni2LWE52bVeSt3L2HVBSmbBw+elc32ATej9C68EyKzN/8vR5ILxFn6RCdDTKm4asmwZyq2jys12dKmBdWMr9QA== +"@tiptap/core@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-3.23.6.tgz#3925af02f6119f2610bb5796487bdcc6ec7e363e" + integrity sha512-MRB3pHz4Oxqmcawh0cQ5iOGdY5xtNYp/1CoK7hdTLzw5K0C6/gTC2VvanB1R4INaB6EpBkxG/GiWkVirDRnuXw== + +"@tiptap/extension-blockquote@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-3.23.6.tgz#e15ecc13abd00d9f2b525972c276d9200fd3ac08" + integrity sha512-2RmnqNqTltZ2k1F7IfjoDNs935Uq4rRDR7d98mqkg3OlDktcQIyBpv0t9dTay6H5bkQeZUuS8ogK2S1E8Edjug== + "@tiptap/extension-bold@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-3.23.4.tgz#c39a61a2afb78fcad5302902510fc823844fd668" integrity sha512-3L9tnZ12i+98u5df2nV2zGu/sc3rhI87E3ocn1YYAO8PJUAgZnMwdet8JawCrS1uut5sRKlxo3SXEmdNfRVm/w== +"@tiptap/extension-bold@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-3.23.6.tgz#a08f0bdac029caab4051d369e5c27966d2efe990" + integrity sha512-1LMhjnytdbbhWHSoOwnLxZAOQZWPkKyXVCNmaIk0Mhi4tLPUXptG4qKS5sVYTCveE5H6IBPFrbgBFi5dMI6krA== + "@tiptap/extension-bubble-menu@^3.23.4": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.23.4.tgz#9e2d5d892d6d4917e44c5ebfe87de68e44878ead" @@ -1956,51 +1976,170 @@ dependencies: "@floating-ui/dom" "^1.0.0" +"@tiptap/extension-bubble-menu@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.23.6.tgz#c31f8dcaa821b9ac496b2b5e364ca5a9754b4e7b" + integrity sha512-Mwkyp9LkDHFbqmWRIkp63FinRxFu3ajC4qSb9t4mnHsb4kAdbNLLsGtbFg+le0SWk4CxGwAOwM7SzeJ+6UGqCA== + dependencies: + "@floating-ui/dom" "^1.0.0" + +"@tiptap/extension-bullet-list@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-3.23.6.tgz#a91fcac15ea5a9605c34be61d40969d3af5b20f8" + integrity sha512-RMRgfXZykr/13X8UBOwvpgysVOo9KchwqMoEbvqQSj4YFfU56iIn59C8sbxiQ1sKfeltUf0wH4fPc0I4iwKqAA== + +"@tiptap/extension-code-block@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-3.23.6.tgz#ebb5d57ebe819bd094926a6ba20008af3ae0b4b6" + integrity sha512-4kccgcn5yHThxrzsIhJny3EwfEZYIk+BjUCL4uIuzOyWvExtGhZ6JMHVCZeMhI8D1/bX1LNkkAKN5DXPzH4lXQ== + "@tiptap/extension-code@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-3.23.4.tgz#8afbc0a1dc132d1d05890cc652fc897a8f94d9e0" integrity sha512-C0TeRipMycUEBnV+Mzx6eLp/yZb6Vi/waP3Tkb0lO5/ikg7LWLB7AlmMunjIXEUcR/pJHID/aEh5PfJFpysUDg== +"@tiptap/extension-code@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-3.23.6.tgz#1f7c8e9520c092c318d2842892afa7a1b56bf8cd" + integrity sha512-KG8KXFYyLrtYvT7AZ1WGV61ofx8pDe5g9pH658MERxqQGii+Pyfc6xkz04l7XeBts/7+571UQp/0O7i/z560TA== + +"@tiptap/extension-document@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-3.23.6.tgz#a3b3d20edb0670cf1230d64ebb340541fd89b46e" + integrity sha512-XDAIgG9KcKumFM9KJWUEUhXPbFIhhl47bfy5GknareWTRKke85rcoj/oxKKO9ihLZr8JfpbXjqnS4SCm5yhYPw== + +"@tiptap/extension-dropcursor@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-3.23.6.tgz#2b2ea76ab8bc4b14376f0f9cc4080ff4d2a7926a" + integrity sha512-+XWEoRKf3lXxi7Le1aOM2xU1XHwxICGpXjT3m4QaYqUgIpsq8gQEuso6kVg8DnTD7biKQs6+oIQ0o2b/gTW9WA== + "@tiptap/extension-floating-menu@^3.23.4": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-3.23.4.tgz#ae6dfc00182811decc43402106c29d704179b29b" integrity sha512-eAc72bKM26yIPx0jsU8qdjE71vFNVu5R9jGbdItBMFc0SPLS4qY8g+8RJ+iWoLwbcSEpgooLS9D9sLfdAU+Tvw== +"@tiptap/extension-floating-menu@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-3.23.6.tgz#34a714fc8d58e624916d4bf335ecccab64dd018f" + integrity sha512-2kjuDcEq69lEcECl75xqY5MyzUSh2zcC5aLrpwP1WwhJz5bxsIFHiaps5AP6h9R4A+ZBj5b2haay2Y1wDUU3VA== + +"@tiptap/extension-gapcursor@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-3.23.6.tgz#f382b00f788756c0a519e4b1eb0a9c7b3fa5a35a" + integrity sha512-wbKmxXsszxWacEkrHucRpSQbiKjz4fmOebD6OVyL9AcrmlbxNk8vcM3iyh/8cVeRy09XY+morM165t/u7/z4IQ== + +"@tiptap/extension-hard-break@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-3.23.6.tgz#0aefb994338baaee76cc7877e15d27559c407129" + integrity sha512-KeUm+tkUfIVSX9QM9XOIhaay0Fn36sLKUo5NVYjN3uJaxFvaZXZmTlxdO85OTdgF2P5sqh9LomrIgliaFRGk4w== + +"@tiptap/extension-heading@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-3.23.6.tgz#76c103cfa1ee6645676a8597a282eaadfa03dfe4" + integrity sha512-A/0jPhxnUh9THSZymlu0OGPZe1wdFdwHAXnRCmqvYUCwJjrG7LCC/ahzmcj1tcNzI9hgHyuYPSfev8RXYrNu/w== + "@tiptap/extension-horizontal-rule@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.23.4.tgz#c9a4e9bd2c881f04a0eae037c3f0b1b696fa76e6" integrity sha512-EA4kK8ywZ4dQNOdxeZbplmDDs5T5LjMgHpqxRwukj9wwKiILOK5E3fcKm1fCKh9Q02w96jax6YVccHwmgJP3sQ== +"@tiptap/extension-horizontal-rule@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.23.6.tgz#1997dd36ddea754bfcb3d0bf271a78438099499d" + integrity sha512-hEUlz4H+I64r+TH6LCuNCRgO7JTHncXGmx9+WbU69EOfY8O0ZurcgeJc8HeiAKL+r9YuC1e5YHfFxgCaaC0jlg== + +"@tiptap/extension-image@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-3.23.6.tgz#8f7e46c523b7e5b67ebd20b93389ea95cc58f9b5" + integrity sha512-vvNGxArvD2dW+XvV0KdYovRVUzCy8QVNulc2r5pV7umnG1E6cCmMkiHiif8J2ePJu2KtysAvJQe0iF+UqueGMw== + "@tiptap/extension-italic@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-3.23.4.tgz#70ff0badf85503bf5d5f887fdbf5c03d5802a8d0" integrity sha512-jUAHi+HZlg47BzgVIy6y/UH5vev7vPQ95jddhB5K3hC122kvWFMXlken7UOnqzbxNcHs2+4Oi/ZJirYMpT4P5w== +"@tiptap/extension-italic@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-3.23.6.tgz#03edff818014bdcae3cf7cc7b351192842f27498" + integrity sha512-wol5KdwCPAvpiYhH9PLlvO8ZnJHwZtIboVevrfOGgBcKlXRA3dedR4OAMXHnUtkkzu9KtliLg1+TYzEx4JZG9Q== + +"@tiptap/extension-link@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-3.23.6.tgz#709d1e63abdbf1c81b142d8131f9a1c811dcbf25" + integrity sha512-KNZz7z7P2/qbQsx5bPAbSPjrKDg1VHsedGlLHJCr8U2VRD5VgmDLkMpkouP1CsDg15qgyUKv/nDib5KgPpLNWA== + dependencies: + linkifyjs "^4.3.3" + +"@tiptap/extension-list-item@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-3.23.6.tgz#01a573f5c395d99c5b63cd58d2d84c095bb6a2df" + integrity sha512-3zzyhdkUWcHVpXuvy6KiIwjh29rbH6gEDEqPQqHLrl1XGnO9pnShC7pSHctlCDjmcx3O4n9cd4QMtVBlUerbiA== + +"@tiptap/extension-list-keymap@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-list-keymap/-/extension-list-keymap-3.23.6.tgz#2bbb2427361c0fe191898bab83edd6660442726b" + integrity sha512-x8bPcLViGzg/RAmQM/XtmfqIwQ/Pv9Q8mkd+OgfUiTqjeJqKwVQmiqbLFNa7zw81+H61M+HDU+qGAaQ3vRIMjw== + +"@tiptap/extension-list@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-list/-/extension-list-3.23.6.tgz#65f2573389baed413c8df3bbb5a037651d34c634" + integrity sha512-z6vj9+Qht2sjdQkyyHcUpsC/yCIZqTrQiyHDhs/HGKrfvoANyAZGpqdNeKf1wSyjIso+27tQuIH5NDfk8ygyNw== + +"@tiptap/extension-ordered-list@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-3.23.6.tgz#fb38de6da6262c90d3098640eef1bbb32a5bbdbe" + integrity sha512-1m/wWB/ZtXcmG2vNdiUkCqsOgqv5vBjCv/mVaHhF9OvV+zQS8YDjoWE7zEuT/GgELdT77Xq8lHrn4nCDudB3/A== + "@tiptap/extension-paragraph@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-3.23.4.tgz#f27e6f66e663c9e5f3a660921e04a303b465030d" integrity sha512-KbhXjCFzWphvFn5VU7E4dtmYDm+bssI1i0+CnXPWCXkjdaaX88ck68Xp1fKz8/bbI/CqlgiNDO/3TvqgtZ6woQ== +"@tiptap/extension-paragraph@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-3.23.6.tgz#4a6b3b945e3b0afdf5d8126a026b56aa7a72d3e2" + integrity sha512-+7m58LUSncodjrIyXks4RZ3tLNYrvgT77wRR4l3HnM5OABY3GDsDTqi7c1t1yI29NVOSk/DUacqy6UwYAj1DGg== + "@tiptap/extension-strike@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-3.23.4.tgz#9db6b0982e3f550e90e729e03e898cef23b711a3" integrity sha512-Vnq5vW801zPbu1LtKeA5k4R241jY+hRjXeijYwIPxy15KzIiipY12518HiCf6/8kkRbMxgOfdYg9X4BRV3HV3g== +"@tiptap/extension-strike@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-3.23.6.tgz#b68e8df11c8c24c82d8c292ff94bc962f3cec871" + integrity sha512-oF7FEZ37f15aCe5kPgzGDYf/m+hr7VdQ/Ko/Hds/UM9pX7AG1fdtmRrl6wqkRqDM/incZaC/AQR2/Dpo2VCNGQ== + "@tiptap/extension-text@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-3.23.4.tgz#1ab44d78d34c746f97100ff34cc28e0914231eaa" integrity sha512-q9kxver/MR18p66aWZHSPycnr9hcBFyVGeGj8gf+BQCzn5hpvtSYTfLvk1nq8GFhygdQ9/e3f7B5ovrm/jnpvw== +"@tiptap/extension-text@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-3.23.6.tgz#e6154568e0869c6fcd81c4df84dc41134311b483" + integrity sha512-ipoC2TkIAIOTiF5ByiGgvQB1DqDyfP90wrUB3mohBcgvp7lQnwHszCDGv8dNnmcUek8uXV/uoLu2VXeVQlxjPA== + "@tiptap/extension-underline@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extension-underline/-/extension-underline-3.23.4.tgz#f85d5b047d9f9f167c59099cb8244a1bca360d79" integrity sha512-F1ocPT10LV+seky25R1TMCRdc/Iof99jLcDSYDGr6mNEDY4ct2RvOeSM8aDdYq6CkH+vXt3i3JDeRwV23KzswQ== +"@tiptap/extension-underline@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extension-underline/-/extension-underline-3.23.6.tgz#2d88333cbdb8cf1154377d6014dba8ce768bb715" + integrity sha512-P55wGIZGYTVH92Fq0cgI4/O9AhLCaJC3hhxg15RSERP5/YegM9eJHDK/GQ1EE/DvYA+xpYGOV6agKwAUqfA/Iw== + "@tiptap/extensions@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/extensions/-/extensions-3.23.4.tgz#f57253d162cecbdf3ae835dfcc1422af926ec6ac" integrity sha512-SlGPXauW8iKWG7wwuwC/0y/smLImp0h6GBIGgNnTBgIP/ThXQnjLMSZH0mW/REO87dQxkku01V3ARRywi+juhg== +"@tiptap/extensions@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/extensions/-/extensions-3.23.6.tgz#96fde5cae89459581c6d5356728444bd0299a8f2" + integrity sha512-X09/Db1teB+ifXzDGVVFmOeQRx7wTAayE9/280spxpsHkHZvJ5bHRvWIzUzviMIjbBz+NPDIKYPK7gMfh9iaig== + "@tiptap/pm@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-3.23.4.tgz#91eca287eb5a4e29bc155a702d10bcf9b56a117e" @@ -2019,6 +2158,24 @@ prosemirror-transform "^1.10.2" prosemirror-view "^1.38.1" +"@tiptap/pm@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-3.23.6.tgz#714c7b38e16816591b0adc9e9a2c72161de40daf" + integrity sha512-in5CaMaWlJcH2A1q6GJKFtrodE8WLS3M9tIi/f89jPmIVHJShpodC0KZDNyJkrVBQomYk0DEh86Utm6ASXzQww== + dependencies: + prosemirror-changeset "^2.3.0" + prosemirror-commands "^1.6.2" + prosemirror-dropcursor "^1.8.1" + prosemirror-gapcursor "^1.3.2" + prosemirror-history "^1.4.1" + prosemirror-keymap "^1.2.2" + prosemirror-model "^1.24.1" + prosemirror-schema-list "^1.5.0" + prosemirror-state "^1.4.3" + prosemirror-tables "^1.6.4" + prosemirror-transform "^1.10.2" + prosemirror-view "^1.38.1" + "@tiptap/react@^3.13.0": version "3.23.4" resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-3.23.4.tgz#df7cf9d8a2d42a3b3eb9bc73e5569fb7ddf8fe3d" @@ -2031,6 +2188,48 @@ "@tiptap/extension-bubble-menu" "^3.23.4" "@tiptap/extension-floating-menu" "^3.23.4" +"@tiptap/react@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-3.23.6.tgz#c62ef43af585f557c08cca4b2efd87121be5a986" + integrity sha512-Tw9KZkYqFMk3vaJAEQKqEYIO/iq3cSJe7OUEGBul4k4GaMQeLItLf5EYhUd0GIPXci1WVVPNntKJsHfX25M37w== + dependencies: + "@types/use-sync-external-store" "^0.0.6" + fast-equals "^5.3.3" + use-sync-external-store "^1.4.0" + optionalDependencies: + "@tiptap/extension-bubble-menu" "^3.23.6" + "@tiptap/extension-floating-menu" "^3.23.6" + +"@tiptap/starter-kit@^3.23.6": + version "3.23.6" + resolved "https://registry.yarnpkg.com/@tiptap/starter-kit/-/starter-kit-3.23.6.tgz#0fa0c2d18424ef093a4345657c44b99299af3df6" + integrity sha512-gykwtGWrnWCmtql1hid3opac/KV8zQvOAnu3bTqIqcHrn1FusbUwKmNzavSbfGvcktHM3hFjb35W48JyVLyu/A== + dependencies: + "@tiptap/core" "^3.23.6" + "@tiptap/extension-blockquote" "^3.23.6" + "@tiptap/extension-bold" "^3.23.6" + "@tiptap/extension-bullet-list" "^3.23.6" + "@tiptap/extension-code" "^3.23.6" + "@tiptap/extension-code-block" "^3.23.6" + "@tiptap/extension-document" "^3.23.6" + "@tiptap/extension-dropcursor" "^3.23.6" + "@tiptap/extension-gapcursor" "^3.23.6" + "@tiptap/extension-hard-break" "^3.23.6" + "@tiptap/extension-heading" "^3.23.6" + "@tiptap/extension-horizontal-rule" "^3.23.6" + "@tiptap/extension-italic" "^3.23.6" + "@tiptap/extension-link" "^3.23.6" + "@tiptap/extension-list" "^3.23.6" + "@tiptap/extension-list-item" "^3.23.6" + "@tiptap/extension-list-keymap" "^3.23.6" + "@tiptap/extension-ordered-list" "^3.23.6" + "@tiptap/extension-paragraph" "^3.23.6" + "@tiptap/extension-strike" "^3.23.6" + "@tiptap/extension-text" "^3.23.6" + "@tiptap/extension-underline" "^3.23.6" + "@tiptap/extensions" "^3.23.6" + "@tiptap/pm" "^3.23.6" + "@types/argparse@1.0.38": version "1.0.38" resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" @@ -3901,6 +4100,11 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +linkifyjs@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.3.3.tgz#da08f0eeb4d89a24541d09591fbdcc211eb8fef0" + integrity sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg== + local-pkg@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-1.1.2.tgz#c03d208787126445303f8161619dc701afa4abb5"