Change editor
This commit is contained in:
parent
50b67ffee9
commit
36bc444f90
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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<number | undefined>(
|
||||
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<string> => {
|
||||
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<any>(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({
|
|||
)}
|
||||
<Paper p='xs' shadow='sm' withBorder>
|
||||
{hasNotes ? (
|
||||
<Stack gap='xs'>
|
||||
<BlockNoteView
|
||||
editor={editor}
|
||||
editable={canEdit}
|
||||
theme={colorScheme === 'dark' ? 'dark' : 'light'}
|
||||
style={{ minHeight: '400px' }}
|
||||
/>
|
||||
</Stack>
|
||||
<RichTextEditor editor={editor} style={{ minHeight: '400px' }}>
|
||||
{canEdit && (
|
||||
<RichTextEditor.Toolbar sticky>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Bold />
|
||||
<RichTextEditor.Italic />
|
||||
<RichTextEditor.Underline />
|
||||
<RichTextEditor.Strikethrough />
|
||||
<RichTextEditor.ClearFormatting />
|
||||
<RichTextEditor.Code />
|
||||
<RichTextEditor.CodeBlock />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.H1 />
|
||||
<RichTextEditor.H2 />
|
||||
<RichTextEditor.H3 />
|
||||
<RichTextEditor.H4 />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Blockquote />
|
||||
<RichTextEditor.Hr />
|
||||
<RichTextEditor.BulletList />
|
||||
<RichTextEditor.OrderedList />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Link />
|
||||
<RichTextEditor.Unlink />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Undo />
|
||||
<RichTextEditor.Redo />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<FileButton
|
||||
onChange={handleImageUpload}
|
||||
accept='image/*'
|
||||
>
|
||||
{(props) => (
|
||||
<Tooltip label={t`Upload Image`}>
|
||||
<ActionIcon
|
||||
variant='default'
|
||||
size='sm'
|
||||
{...props}
|
||||
>
|
||||
<IconPhoto size='0.9rem' />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
</FileButton>
|
||||
</RichTextEditor.ControlsGroup>
|
||||
</RichTextEditor.Toolbar>
|
||||
)}
|
||||
<RichTextEditor.Content />
|
||||
</RichTextEditor>
|
||||
) : (
|
||||
<Alert title={t`Notes`} icon={<IconInfoCircle />}>
|
||||
{t`There are no notes yet for this item.`}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue