From 4cf0e15406d620f548d72403984f8541c40c538d Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Sun, 14 Dec 2025 20:55:18 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=E2=AC=86=EF=B8=8F(dependencies)=20bump=20b?= =?UTF-8?q?locknote=20to=200.44.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We bump the blocknote dependencies to version 0.44.2 to incorporate the latest features and bug fixes. It seems to fix an issue with Titap, when the text was selected and the user clicked on the Go Back button of the browser, the application was crashing. "[tiptap error]: The editor view is not available. Cannot access view['dom']. The editor may not be mounted yet." --- CHANGELOG.md | 2 + .../app-impress/doc-comments.spec.ts | 9 +- src/frontend/apps/impress/package.json | 16 +- .../doc-editor/components/BlockNoteEditor.tsx | 43 +++--- .../components/BlockNoteSuggestionMenu.tsx | 3 +- .../BlockNoteToolBar/FileDownloadButton.tsx | 75 +++++---- .../comments/CommentToolbarButton.tsx | 12 +- .../components/comments/DocsThreadStore.tsx | 2 +- .../components/comments/useComments.ts | 31 +++- .../components/custom-blocks/CalloutBlock.tsx | 4 +- .../components/custom-blocks/PdfBlock.tsx | 4 +- .../docs/doc-editor/hook/useHeadings.tsx | 2 +- .../docs/doc-editor/hook/useShortcuts.tsx | 2 +- .../docs/doc-editor/hook/useUploadFile.tsx | 6 +- .../doc-editor/stores/useHeadingStore.tsx | 2 +- .../doc-header/components/DocHeaderInfo.tsx | 7 +- .../hooks/useDocTitleUpdate.tsx | 11 +- .../doc-tree/components/DocSubPageItem.tsx | 2 +- .../components/DocTreeItemActions.tsx | 2 +- src/frontend/servers/y-provider/package.json | 4 +- src/frontend/yarn.lock | 145 +++++++++++------- 21 files changed, 224 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5e701ee64..d74a299a5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ and this project adheres to ### Fixed - 🐛(frontend) paste content with comments from another document #1732 +- 🐛(frontend) Select text + Go back one page crash the app #1733 + ## [4.1.0] - 2025-12-09 diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts index 347233e7fe..930b46d80c 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts @@ -6,7 +6,7 @@ import { getOtherBrowserName, verifyDocName, } from './utils-common'; -import { writeInEditor } from './utils-editor'; +import { getEditor, writeInEditor } from './utils-editor'; import { addNewMember, connectOtherUserToDoc, @@ -48,6 +48,7 @@ test.describe('Doc Comments', () => { await thread.locator('[data-test="save"]').click(); await expect(thread.getByText('This is a comment').first()).toBeHidden(); + await editor.first().click(); await editor.getByText('Hello').click(); await thread.getByText('This is a comment').first().hover(); @@ -135,6 +136,7 @@ test.describe('Doc Comments', () => { 'background-color', 'rgba(237, 180, 0, 0.4)', ); + await editor.first().click(); await editor.getByText('Hello').click(); await thread.getByText('This is a comment').first().hover(); @@ -197,6 +199,7 @@ test.describe('Doc Comments', () => { 'background-color', 'rgba(237, 180, 0, 0.4)', ); + await editor.first().click(); await editor.getByText('Hello').click(); await thread.getByText('This is a new comment').first().hover(); @@ -217,6 +220,8 @@ test.describe('Doc Comments', () => { // We share the doc with another user const otherBrowserName = getOtherBrowserName(browserName); + const editor = await getEditor({ page }); + // Add a new member with editor role await page.getByRole('button', { name: 'Share' }).click(); await addNewMember(page, 0, 'Editor', otherBrowserName); @@ -240,7 +245,7 @@ test.describe('Doc Comments', () => { text: 'Hello, I can edit the document', }); await expect( - otherEditor.getByText('Hello, I can edit the document'), + editor.getByText('Hello, I can edit the document'), ).toBeVisible(); await otherEditor.getByText('Hello').selectText(); await otherPage.getByRole('button', { name: 'Comment' }).click(); diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index 675b71dbbb..f88ff58a99 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -19,14 +19,14 @@ }, "dependencies": { "@ag-media/react-pdf-table": "2.0.3", - "@blocknote/code-block": "0.42.3", - "@blocknote/core": "0.42.3", - "@blocknote/mantine": "0.42.3", - "@blocknote/react": "0.42.3", - "@blocknote/xl-docx-exporter": "0.42.3", - "@blocknote/xl-multi-column": "0.42.3", - "@blocknote/xl-odt-exporter": "0.42.3", - "@blocknote/xl-pdf-exporter": "0.42.3", + "@blocknote/code-block": "0.44.2", + "@blocknote/core": "0.44.2", + "@blocknote/mantine": "0.44.2", + "@blocknote/react": "0.44.2", + "@blocknote/xl-docx-exporter": "0.44.2", + "@blocknote/xl-multi-column": "0.44.2", + "@blocknote/xl-odt-exporter": "0.44.2", + "@blocknote/xl-pdf-exporter": "0.44.2", "@dnd-kit/core": "6.3.1", "@dnd-kit/modifiers": "9.0.0", "@emoji-mart/data": "1.2.1", diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx index 6ec70151cd..ed0dafddfa 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx @@ -6,6 +6,7 @@ import { defaultInlineContentSpecs, withPageBreak, } from '@blocknote/core'; +import { CommentsExtension } from '@blocknote/core/comments'; import '@blocknote/core/fonts/inter.css'; import * as locales from '@blocknote/core/locales'; import { BlockNoteView } from '@blocknote/mantine'; @@ -101,7 +102,11 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { const cursorName = collabName || t('Anonymous'); const showCursorLabels: 'always' | 'activity' | (string & {}) = 'activity'; - const threadStore = useComments(doc.id, canSeeComment, user); + const { resolveUsers, threadStore } = useComments( + doc.id, + canSeeComment, + user, + ); const currentUserAvatarUrl = useMemo(() => { if (canSeeComment) { @@ -156,7 +161,6 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { }, showCursorLabels: showCursorLabels as 'always' | 'activity', }, - comments: { threadStore }, dictionary: { ...locales[lang as keyof typeof locales], multi_column: @@ -182,22 +186,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { return defaultPasteHandler(); }, - resolveUsers: async (userIds) => { - return Promise.resolve( - userIds.map((encodedURIUserId) => { - const fullName = decodeURIComponent(encodedURIUserId); - - return { - id: encodedURIUserId, - username: fullName || t('Anonymous'), - avatarUrl: avatarUrlFromName( - fullName, - themeTokens?.font?.families?.base, - ), - }; - }), - ); - }, + extensions: [CommentsExtension({ threadStore, resolveUsers })], tables: { splitCells: true, cellBackgroundColor: true, @@ -207,7 +196,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { uploadFile, schema: blockNoteSchema, }, - [cursorName, lang, provider, uploadFile, threadStore], + [cursorName, lang, provider, uploadFile, threadStore, resolveUsers], ); useHeadings(editor); @@ -268,7 +257,7 @@ export const BlockNoteReader = ({ }: BlockNoteReaderProps) => { const { user } = useAuth(); const { setEditor } = useEditorStore(); - const threadStore = useComments(docId, false, user); + const { threadStore } = useComments(docId, false, user); const { t } = useTranslation(); const editor = useCreateBlockNote( { @@ -281,12 +270,16 @@ export const BlockNoteReader = ({ provider: undefined, }, schema: blockNoteSchema, - comments: { threadStore }, - resolveUsers: async () => { - return Promise.resolve([]); - }, + extensions: [ + CommentsExtension({ + threadStore, + resolveUsers: async () => { + return Promise.resolve([]); + }, + }), + ], }, - [initialContent], + [initialContent, threadStore], ); useEffect(() => { diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx index badc40dcde..e07d15bc06 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx @@ -1,4 +1,5 @@ -import { combineByGroup, filterSuggestionItems } from '@blocknote/core'; +import { combineByGroup } from '@blocknote/core'; +import { filterSuggestionItems } from '@blocknote/core/extensions'; import { DefaultReactSuggestionItem, SuggestionMenuController, diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolBar/FileDownloadButton.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolBar/FileDownloadButton.tsx index abcc71db23..458a3c8491 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolBar/FileDownloadButton.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolBar/FileDownloadButton.tsx @@ -6,24 +6,25 @@ * https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/FormattingToolbar/DefaultButtons/FileDownloadButton.tsx */ -import { - BlockSchema, - InlineContentSchema, - StyleSchema, - blockHasType, -} from '@blocknote/core'; +import { blockHasType } from '@blocknote/core'; import { useBlockNoteEditor, useComponentsContext, useDictionary, - useSelectedBlocks, + useEditorState, } from '@blocknote/react'; -import { useCallback, useMemo } from 'react'; +import { useCallback } from 'react'; import { RiDownload2Fill } from 'react-icons/ri'; import { downloadFile, exportResolveFileUrl } from '@/docs/doc-export'; import { isSafeUrl } from '@/utils/url'; +import { + DocsBlockSchema, + DocsInlineContentSchema, + DocsStyleSchema, +} from '../../types'; + export const FileDownloadButton = ({ open, }: { @@ -33,36 +34,43 @@ export const FileDownloadButton = ({ const Components = useComponentsContext(); const editor = useBlockNoteEditor< - BlockSchema, - InlineContentSchema, - StyleSchema + DocsBlockSchema, + DocsInlineContentSchema, + DocsStyleSchema >(); - const selectedBlocks = useSelectedBlocks(editor); + const fileBlock = useEditorState({ + editor, + selector: ({ editor }) => { + const selectedBlocks = editor.getSelection()?.blocks || [ + editor.getTextCursorPosition().block, + ]; - const fileBlock = useMemo(() => { - // Checks if only one block is selected. - if (selectedBlocks.length !== 1) { - return undefined; - } + if (selectedBlocks.length !== 1) { + return undefined; + } - const block = selectedBlocks[0]; + const block = selectedBlocks[0]; - if ( - blockHasType(block, editor, block.type, { url: 'string', name: 'string' }) - ) { - return block; - } + if ( + !blockHasType(block, editor, block.type, { + url: 'string', + name: 'string', + }) + ) { + return undefined; + } - return undefined; - }, [editor, selectedBlocks]); + return block; + }, + }); const onClick = useCallback(async () => { if (fileBlock && fileBlock.props.url) { editor.focus(); const url = fileBlock.props.url as string; - const name = fileBlock.props.name as string | undefined; + const name = fileBlock.props.name as string; /** * If not hosted on our domain, means not a file uploaded by the user, @@ -110,19 +118,18 @@ export const FileDownloadButton = ({ return null; } + const blockType = fileBlock.type as string; + const tooltipText = + dict.formatting_toolbar.file_download.tooltip[blockType] || + dict.formatting_toolbar.file_download.tooltip['file']; + return ( <> } onClick={() => void onClick()} /> diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/CommentToolbarButton.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/CommentToolbarButton.tsx index 6fa3f2209d..ac2fd963ed 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/CommentToolbarButton.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/CommentToolbarButton.tsx @@ -3,9 +3,12 @@ * https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/FormattingToolbar/DefaultButtons/AddCommentButton.tsx */ +import { CommentsExtension } from '@blocknote/core/comments'; +import { FormattingToolbarExtension } from '@blocknote/core/extensions'; import { useBlockNoteEditor, useComponentsContext, + useExtension, useSelectedBlocks, } from '@blocknote/react'; import { useMemo } from 'react'; @@ -29,6 +32,10 @@ export const CommentToolbarButton = () => { const { t } = useTranslation(); const { spacingsTokens, colorsTokens } = useCunninghamTheme(); const { isDesktop } = useResponsiveStore(); + const comments = useExtension('comments') as unknown as ReturnType< + ReturnType + >; + const { store } = useExtension(FormattingToolbarExtension); const editor = useBlockNoteEditor< DocsBlockSchema, @@ -53,6 +60,7 @@ export const CommentToolbarButton = () => { }; if ( + !comments || !isDesktop || !show || !editor.isEditable || @@ -67,8 +75,8 @@ export const CommentToolbarButton = () => { { - editor.comments?.startPendingComment(); - editor.formattingToolbar.closeMenu(); + comments.startPendingComment(); + store.setState(false); focusOnInputThread(); }} aria-haspopup="dialog" diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/DocsThreadStore.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/DocsThreadStore.tsx index b9b71bea5c..96a07d8951 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/DocsThreadStore.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/DocsThreadStore.tsx @@ -200,7 +200,7 @@ export class DocsThreadStore extends ThreadStore { const { editor } = useEditorStore.getState(); // Should not happen - if (!editor) { + if (!editor || !editor._tiptapEditor?.view?.dom) { console.warn('Editor to add thread not ready'); return Promise.resolve(); } diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/useComments.ts b/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/useComments.ts index 99be3acfea..33a67a04da 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/useComments.ts +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/useComments.ts @@ -1,6 +1,8 @@ -import { useEffect, useMemo } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; -import { User } from '@/features/auth'; +import { useCunninghamTheme } from '@/cunningham'; +import { User, avatarUrlFromName } from '@/features/auth'; import { Doc, useProviderStore } from '@/features/docs/doc-management'; import { DocsThreadStore } from './DocsThreadStore'; @@ -12,6 +14,9 @@ export function useComments( user: User | null | undefined, ) { const { provider } = useProviderStore(); + const { t } = useTranslation(); + const { themeTokens } = useCunninghamTheme(); + const threadStore = useMemo(() => { return new DocsThreadStore( docId, @@ -29,5 +34,25 @@ export function useComments( }; }, [threadStore]); - return threadStore; + const resolveUsers = useCallback( + async (userIds: string[]) => { + return Promise.resolve( + userIds.map((encodedURIUserId) => { + const fullName = decodeURIComponent(encodedURIUserId); + + return { + id: encodedURIUserId, + username: fullName || t('Anonymous'), + avatarUrl: avatarUrlFromName( + fullName, + themeTokens?.font?.families?.base, + ), + }; + }), + ); + }, + [t, themeTokens?.font?.families?.base], + ); + + return { threadStore, resolveUsers }; } diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx index 72999f3f7c..f5144a266a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx @@ -5,8 +5,8 @@ import { InlineContentSchema, StyleSchema, defaultProps, - insertOrUpdateBlock, } from '@blocknote/core'; +import { insertOrUpdateBlockForSlashMenu } from '@blocknote/core/extensions'; import { BlockTypeSelectItem, createReactBlockSpec } from '@blocknote/react'; import { TFunction } from 'i18next'; import React, { useEffect, useState } from 'react'; @@ -156,7 +156,7 @@ export const getCalloutReactSlashMenuItems = ( key: 'callout', title: t('Callout'), onItemClick: () => { - insertOrUpdateBlock(editor, { + insertOrUpdateBlockForSlashMenu(editor, { type: 'callout', }); }, diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx index ace3e738d7..539eee69ed 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/PdfBlock.tsx @@ -4,8 +4,8 @@ import { BlockNoteEditor, InlineContentSchema, StyleSchema, - insertOrUpdateBlock, } from '@blocknote/core'; +import { insertOrUpdateBlockForSlashMenu } from '@blocknote/core/extensions'; import * as locales from '@blocknote/core/locales'; import { AddFileButton, @@ -139,7 +139,7 @@ export const getPdfReactSlashMenuItems = ( { title: t('PDF'), onItemClick: () => { - insertOrUpdateBlock(editor, { type: 'pdf' }); + insertOrUpdateBlockForSlashMenu(editor, { type: 'pdf' }); }, aliases: [t('pdf'), t('document'), t('embed'), t('file')], group, diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx index 6a0e11f7d3..b7f0172b6a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx @@ -8,7 +8,7 @@ export const useHeadings = (editor: DocsBlockNoteEditor) => { useEffect(() => { // Check if editor and its view are mounted before accessing document - if (!editor || !editor._tiptapEditor?.view?.dom) { + if (!editor) { return; } diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx index 54f95c7ca5..09c8625d72 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx @@ -8,7 +8,7 @@ export const useShortcuts = ( ) => { useEffect(() => { // Check if editor and its view are mounted - if (!editor || !editor._tiptapEditor?.view?.dom || !el) { + if (!editor || !el) { return; } diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx index 4487aa8df4..e2693b41ba 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx @@ -96,11 +96,11 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => { useEffect(() => { // Check if editor and its view are mounted before accessing document - if (!editor || !editor._tiptapEditor?.view?.dom) { + if (!editor?.document) { return; } - const imagesBlocks = editor?.document.filter( + const imagesBlocks = editor.document.filter( (block) => block.type === 'image' && block.props.url.includes(ANALYZE_URL), ); @@ -116,7 +116,7 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => { */ useEffect(() => { // Check if editor and its view are mounted before setting up handlers - if (!editor || !editor._tiptapEditor?.view?.dom) { + if (!editor) { return; } diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx index a403c98425..defab77ec9 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx @@ -29,7 +29,7 @@ export const useHeadingStore = create((set, get) => ({ headings: [], setHeadings: (editor) => { // Check if editor and its view are mounted before accessing document - if (!editor || !editor._tiptapEditor?.view?.dom) { + if (!editor?.document) { return; } diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx index 534f50502b..465d04a383 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx @@ -3,15 +3,14 @@ import React from 'react'; import { Text } from '@/components'; import { useConfig } from '@/core'; -import { useDate } from '@/hook'; -import { useResponsiveStore } from '@/stores'; - import { Doc, Role, useIsCollaborativeEditable, useTrans, -} from '../../doc-management'; +} from '@/docs/doc-management'; +import { useDate } from '@/hook'; +import { useResponsiveStore } from '@/stores'; interface DocHeaderInfoProps { doc: Doc; diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useDocTitleUpdate.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useDocTitleUpdate.tsx index 17c18ae96e..c63a90a2c0 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useDocTitleUpdate.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/hooks/useDocTitleUpdate.tsx @@ -1,15 +1,12 @@ import { useTreeContext } from '@gouvfr-lasuite/ui-kit'; import { useCallback } from 'react'; -import { - Doc, - KEY_DOC, - KEY_LIST_DOC, - getEmojiAndTitle, - useUpdateDoc, -} from '@/docs/doc-management'; import { useBroadcastStore } from '@/stores'; +import { KEY_DOC, KEY_LIST_DOC, useUpdateDoc } from '../api'; +import { Doc } from '../types'; +import { getEmojiAndTitle } from '../utils'; + interface UseDocUpdateOptions { onSuccess?: (updatedDoc: Doc) => void; onError?: (error: Error) => void; diff --git a/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocSubPageItem.tsx b/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocSubPageItem.tsx index 89325c3060..dc47859d5c 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocSubPageItem.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocSubPageItem.tsx @@ -16,7 +16,7 @@ import { DocIcon, getEmojiAndTitle, useTrans, -} from '@/features/docs/doc-management'; +} from '@/docs/doc-management'; import { useLeftPanelStore } from '@/features/left-panel'; import { useResponsiveStore } from '@/stores'; diff --git a/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx b/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx index 4ce70ef6a8..c80051587c 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx @@ -17,8 +17,8 @@ import { useCopyDocLink, useCreateChildDoc, useDocTitleUpdate, - useDuplicateDoc, } from '@/docs/doc-management'; +import { useDuplicateDoc } from '@/docs/doc-management/api'; import { useDetachDoc } from '../api/useDetach'; import MoveDocIcon from '../assets/doc-extract-bold.svg'; diff --git a/src/frontend/servers/y-provider/package.json b/src/frontend/servers/y-provider/package.json index a8e876a8c5..6cf5744613 100644 --- a/src/frontend/servers/y-provider/package.json +++ b/src/frontend/servers/y-provider/package.json @@ -16,7 +16,7 @@ "node": ">=22" }, "dependencies": { - "@blocknote/server-util": "0.42.3", + "@blocknote/server-util": "0.44.2", "@hocuspocus/server": "3.4.0", "@sentry/node": "10.26.0", "@sentry/profiling-node": "10.26.0", @@ -30,7 +30,7 @@ "yjs": "*" }, "devDependencies": { - "@blocknote/core": "0.42.3", + "@blocknote/core": "0.44.2", "@hocuspocus/provider": "3.4.0", "@types/cors": "2.8.19", "@types/express": "5.0.5", diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index 68762c9df0..e91c494da1 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -1135,12 +1135,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@blocknote/code-block@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/code-block/-/code-block-0.42.3.tgz#7b1a3ed0b4f2d75835c422c04f52e824aa0845cf" - integrity sha512-kPdHABXJdH7lxB1Fxqg/bxWmtO/5y3REgRcuppEpCkrfXlwV+RPCChCU2jnMTUBe6CZyFQwum6/D9oUGVJKRqw== +"@blocknote/code-block@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/code-block/-/code-block-0.44.2.tgz#955b34b43ac64259a3defc4c17e31e3a0853ad12" + integrity sha512-46gv3EsUcuzWmdAO/JCNwZvIChtssMGjdGobfiHNg3LIjJvNaK2F+Oib4cA4YTpNerGN8TfUQaTCJIK3fTw3og== dependencies: - "@blocknote/core" "0.42.3" + "@blocknote/core" "0.44.2" "@shikijs/core" "^3.13.0" "@shikijs/engine-javascript" "^3.13.0" "@shikijs/langs" "^3.13.0" @@ -1148,18 +1148,19 @@ "@shikijs/themes" "^3.13.0" "@shikijs/types" "^3.13.0" -"@blocknote/core@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/core/-/core-0.42.3.tgz#2ac1654a04df65d4618440e520ad187d0c070169" - integrity sha512-wtZki6Gok5Ac9Ek6QTQztcDymstEQgVCisJwiUZTWXh8CD4UKfnIxM7C9+6eEnZMmQ8GNTvRf1HXFl+E4N78VA== +"@blocknote/core@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/core/-/core-0.44.2.tgz#7d3844030129f9793937cafebb2b151870bc70f4" + integrity sha512-PG51Ccue99x4kZtp/inkIkovr8XNviHZaOKAxuSaQowxVrLLrL599e+/GHeFar4OcJ1dcFkVBAgSwx3kYk4lJA== dependencies: "@emoji-mart/data" "^1.2.1" + "@handlewithcare/prosemirror-inputrules" "0.1.3" "@shikijs/types" "3.13.0" + "@tanstack/store" "0.7.7" "@tiptap/core" "^3.11.0" "@tiptap/extension-bold" "^3.7.2" "@tiptap/extension-code" "^3.7.2" "@tiptap/extension-gapcursor" "^3.7.2" - "@tiptap/extension-history" "^3.7.2" "@tiptap/extension-horizontal-rule" "^3.7.2" "@tiptap/extension-italic" "^3.7.2" "@tiptap/extension-link" "^3.7.2" @@ -1193,37 +1194,42 @@ y-protocols "^1.0.6" yjs "^13.6.27" -"@blocknote/mantine@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/mantine/-/mantine-0.42.3.tgz#3cd0b13e6ecb40b0b086a4877c2b2361a2fad266" - integrity sha512-xzLweZG1KfFoOp/aSHTXE10IrfEHnhDlP0C2Qt2eNO2IHHa7l8XZJpIGhCoVMsn0yylm91OSynNfTO7JkZZi8w== +"@blocknote/mantine@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/mantine/-/mantine-0.44.2.tgz#0dcbfc779ffe918732ef58acebf376eb1e5c1ef2" + integrity sha512-jH00WtAo+DNJ2YUxo9avHC9SCMq3CKHK/xWIEYpqo+LcMk1NdMfhgx08xypX7zB8GWWXoqyxFmlCEydM878Pzw== dependencies: - "@blocknote/core" "0.42.3" - "@blocknote/react" "0.42.3" + "@blocknote/core" "0.44.2" + "@blocknote/react" "0.44.2" react-icons "^5.5.0" -"@blocknote/react@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/react/-/react-0.42.3.tgz#c2ec737083e7341a18084c59de2021e64ad5f665" - integrity sha512-YnrQ1uyezDbaxYcFstWOJ2r8BMxqwwEc7QAhrEjCMEyBAiOxSCPnrM4/GE2mOgCS0Xa9wIp2LDoPQP2Syv+2EA== +"@blocknote/react@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/react/-/react-0.44.2.tgz#729987c1d3eb5598bdec1cfe602919d9899677f3" + integrity sha512-HRcgP1T8Mlog2IqlmbBnvPJLvrv+aGKax3y8yPLJs/4qRkP5lMpA+FkpYYHXSLy9OTcGZBC8i0xcwlJ9CUasTQ== dependencies: - "@blocknote/core" "0.42.3" + "@blocknote/core" "0.44.2" "@emoji-mart/data" "^1.2.1" "@floating-ui/react" "^0.27.16" + "@floating-ui/utils" "0.2.10" + "@tanstack/react-store" "0.7.7" "@tiptap/core" "^3.11.0" "@tiptap/pm" "^3.11.0" "@tiptap/react" "^3.11.0" + "@types/use-sync-external-store" "1.5.0" emoji-mart "^5.6.0" + fast-deep-equal "^3.1.3" lodash.merge "^4.6.2" react-icons "^5.5.0" + use-sync-external-store "1.6.0" -"@blocknote/server-util@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/server-util/-/server-util-0.42.3.tgz#113fc33cabc4e6a9fa776183182dfee6fef7e6ff" - integrity sha512-M+jtKeC2aHOYBp6GQ0YR19iv0/0f1HElrrnKwlaSPbwR6bw6tg+yb3yQkaJJioLTpd2X2Z/RwcEvxSJGnlZ81w== +"@blocknote/server-util@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/server-util/-/server-util-0.44.2.tgz#26807f6e6b0de50a49058824155afd5f79af8717" + integrity sha512-ndqDXDaFcq4HT3LZSL2KlDs1GO09BJXu2CtYhov5Z/6XrFIy8N7nM6T6cZDbSg/4lksJQnR2St615miURQ6NJQ== dependencies: - "@blocknote/core" "0.42.3" - "@blocknote/react" "0.42.3" + "@blocknote/core" "0.44.2" + "@blocknote/react" "0.44.2" "@tiptap/core" "^3.11.0" "@tiptap/pm" "^3.11.0" jsdom "^25.0.1" @@ -1231,24 +1237,24 @@ y-protocols "^1.0.6" yjs "^13.6.27" -"@blocknote/xl-docx-exporter@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/xl-docx-exporter/-/xl-docx-exporter-0.42.3.tgz#e276b1a22c34a2b5d0837606d7b96cc3acaba92e" - integrity sha512-VpotYcG+fQFzC2gtqTlBJDi0GKQQ6RygzeyzBBDGeMKSH3P72TDKVYVqN4Ert7HxXz41aCLGgtaf6x9zlox26g== +"@blocknote/xl-docx-exporter@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/xl-docx-exporter/-/xl-docx-exporter-0.44.2.tgz#d9ad71cfd696267cd288097324125c40379c3d69" + integrity sha512-g3PgJ5S3n1uz4GuL0kxv7CbCpsq8zwefrtTWbiz4KKDFagX2JUIlaLuQxGG8jCTL8xsd7AigS8ofrfWwZCJoaA== dependencies: - "@blocknote/core" "0.42.3" - "@blocknote/xl-multi-column" "0.42.3" + "@blocknote/core" "0.44.2" + "@blocknote/xl-multi-column" "0.44.2" buffer "^6.0.3" docx "^9.5.1" image-meta "^0.2.2" -"@blocknote/xl-multi-column@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/xl-multi-column/-/xl-multi-column-0.42.3.tgz#39fad4ef51f26c4af15423f44334de8edf06fe3c" - integrity sha512-7ylZYlOOVNMJ3u4C07yiE6qr04kcEYnxY3UfcFBSyV8H+N0LHGLFFJIz6JPKWvji4fu5lvbxXqv0IcGbCQ0/cA== +"@blocknote/xl-multi-column@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/xl-multi-column/-/xl-multi-column-0.44.2.tgz#b848fc3c4e4424141aeb2edd0a4c93d9fd57da1d" + integrity sha512-y68NJb84NFo0zS6s5o09NhAyfySBnea3h+vnVq474DqfQoCkQQnb2B6qielDUkx2VpxObahSdUN9P6bwpnk20g== dependencies: - "@blocknote/core" "0.42.3" - "@blocknote/react" "0.42.3" + "@blocknote/core" "0.44.2" + "@blocknote/react" "0.44.2" "@tiptap/core" "^3.11.0" prosemirror-model "^1.25.4" prosemirror-state "^1.4.4" @@ -1257,25 +1263,25 @@ prosemirror-view "^1.41.3" react-icons "^5.5.0" -"@blocknote/xl-odt-exporter@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/xl-odt-exporter/-/xl-odt-exporter-0.42.3.tgz#fee0f142ca8ae5ce8bb969f9de0f79e2a92e1c6a" - integrity sha512-wW1Zxd3Y14IG5X/mi0OBoGV/EFxeO5Alsd0HVsBo0imk+GLSKx2YCU02plUG5l8IOQOUeWBHamm4OT+7sgj9Ow== +"@blocknote/xl-odt-exporter@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/xl-odt-exporter/-/xl-odt-exporter-0.44.2.tgz#b44524a986668c9e6a1324e15c3a6d6765418f65" + integrity sha512-khsYAhoRMacn3y1FQb3IjUHG7imOJRs6L4QPKeDKn5JB9z85Fa4ARltfAmG+Pd0pvTPtVzLQFc65vuqjgGXE+g== dependencies: - "@blocknote/core" "0.42.3" - "@blocknote/xl-multi-column" "0.42.3" + "@blocknote/core" "0.44.2" + "@blocknote/xl-multi-column" "0.44.2" "@zip.js/zip.js" "^2.8.8" buffer "^6.0.3" image-meta "^0.2.2" -"@blocknote/xl-pdf-exporter@0.42.3": - version "0.42.3" - resolved "https://registry.yarnpkg.com/@blocknote/xl-pdf-exporter/-/xl-pdf-exporter-0.42.3.tgz#667c0c2756e8300f0dc134718e6d2833947b799f" - integrity sha512-ZPGVHovDWhwu++vkVzDEh6KOoHK6q8iLFo9fGLcQ8oKjNCJoBr344Z42AdMMxcoCDddQmC+5yqzUN8J/9xnE1Q== +"@blocknote/xl-pdf-exporter@0.44.2": + version "0.44.2" + resolved "https://registry.yarnpkg.com/@blocknote/xl-pdf-exporter/-/xl-pdf-exporter-0.44.2.tgz#595d2ad64e381d5cadf2a1e47855a691caf98465" + integrity sha512-aNUSELq3e4XIRd48hSBuUoc4BkTXKs9gUUHaLKLpUyBAnjJktPiR4fngT69YC6BzuPBO2jmi8cFQybvB9xNenQ== dependencies: - "@blocknote/core" "0.42.3" - "@blocknote/react" "0.42.3" - "@blocknote/xl-multi-column" "0.42.3" + "@blocknote/core" "0.44.2" + "@blocknote/react" "0.44.2" + "@blocknote/xl-multi-column" "0.44.2" "@react-pdf/renderer" "^4.3.0" buffer "^6.0.3" docx "^9.5.1" @@ -1775,7 +1781,7 @@ "@floating-ui/utils" "^0.2.10" tabbable "^6.0.0" -"@floating-ui/utils@^0.2.10": +"@floating-ui/utils@0.2.10", "@floating-ui/utils@^0.2.10": version "0.2.10" resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.10.tgz#a2a1e3812d14525f725d011a73eceb41fef5bc1c" integrity sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== @@ -1887,6 +1893,14 @@ dependencies: is-negated-glob "^1.0.0" +"@handlewithcare/prosemirror-inputrules@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@handlewithcare/prosemirror-inputrules/-/prosemirror-inputrules-0.1.3.tgz#77364764d9dfae115dbf2cbbfe684a3b87652ac7" + integrity sha512-LjGitwgSFHICeU6Mfbt+0Bp4BuWyvHfDYJIf7rq1qdNO88tFcWV3CSqw75o/YbsnUObDgp5Dn+gXIQLRwiyCbg== + dependencies: + prosemirror-history "^1.4.1" + prosemirror-transform "^1.0.0" + "@hocuspocus/common@^3.4.0": version "3.4.0" resolved "https://registry.yarnpkg.com/@hocuspocus/common/-/common-3.4.0.tgz#1e01ca39e23fb9335fae2057db9a0a44613abfa0" @@ -5641,6 +5655,14 @@ dependencies: "@tanstack/query-core" "5.90.10" +"@tanstack/react-store@0.7.7": + version "0.7.7" + resolved "https://registry.yarnpkg.com/@tanstack/react-store/-/react-store-0.7.7.tgz#6c51761956a1b3713ae0a8dbc008ea181f82df1f" + integrity sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg== + dependencies: + "@tanstack/store" "0.7.7" + use-sync-external-store "^1.5.0" + "@tanstack/react-table@8.21.3": version "8.21.3" resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.21.3.tgz#2c38c747a5731c1a07174fda764b9c2b1fb5e91b" @@ -5648,6 +5670,11 @@ dependencies: "@tanstack/table-core" "8.21.3" +"@tanstack/store@0.7.7": + version "0.7.7" + resolved "https://registry.yarnpkg.com/@tanstack/store/-/store-0.7.7.tgz#2c8b1d8c094f3614ae4e0483253239abd0e14488" + integrity sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ== + "@tanstack/table-core@8.21.3": version "8.21.3" resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.21.3.tgz#2977727d8fc8dfa079112d9f4d4c019110f1732c" @@ -5723,11 +5750,6 @@ resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-3.10.2.tgz#d9b66196cae2ebfe7e1747a67b21713463832697" integrity sha512-sBCu8enXm3W3BjnvvGBrzAiSuQSVZyhbQAgaFKjHJKBQRbek55EEbRA0ETUmHcSQbYf0D8hmDt2++HAyEASEsQ== -"@tiptap/extension-history@^3.7.2": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-3.10.2.tgz#f19073e57f4bb8c2e5578c8ac0d7e71ae59d79be" - integrity sha512-1u65sQt0vAyXDOyA2YRgyMcPv6pEt60JEU3IOlt1flVYbIcTFy9X8FILmXlq5MC+bRyJXWn7SfjnJWhWbVv7zA== - "@tiptap/extension-horizontal-rule@^3.7.2": version "3.10.2" resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.10.2.tgz#4250f704bb5da0e9c05f0930cd3adc63571a7066" @@ -6273,6 +6295,11 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== +"@types/use-sync-external-store@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz#222c28a98eb8f4f8a72c1a7e9fe6d8946eca6383" + integrity sha512-5dyB8nLC/qogMrlCizZnYWQTA4lnb/v+It+sqNl5YnSRAPMlIqY/X0Xn+gZw8vOL+TgTTr28VEbn3uf8fUtAkw== + "@types/use-sync-external-store@^0.0.6": version "0.0.6" resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz#60be8d21baab8c305132eb9cb912ed497852aadc" @@ -15333,7 +15360,7 @@ use-sidecar@^1.1.3: detect-node-es "^1.1.0" tslib "^2.0.0" -use-sync-external-store@^1.2.0, use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0, use-sync-external-store@^1.6.0: +use-sync-external-store@1.6.0, use-sync-external-store@^1.2.0, use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0, use-sync-external-store@^1.5.0, use-sync-external-store@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== From bbf834fb6e97fe1b23160498c49cd247945209c0 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Sun, 14 Dec 2025 21:33:13 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20isConnected?= =?UTF-8?q?=20when=20authenticated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WebSocketStatus.Connected does not mean we are totally connected because authentication can still be in progress and failed. So we will use the event onAuthenticated to assert that we are fully connected. --- .../docs/doc-editor/components/DocEditor.tsx | 2 +- .../stores/useProviderStore.tsx | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx index d8070664e7..ad49ebfa3c 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx @@ -90,7 +90,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => { } }, [isProviderReady, setIsSkeletonVisible]); - if (!isProviderReady) { + if (!isProviderReady || provider?.configuration.name !== doc.id) { return ; } diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/stores/useProviderStore.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/stores/useProviderStore.tsx index 33eb3d6ab1..f1c8d51184 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/stores/useProviderStore.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/stores/useProviderStore.tsx @@ -52,13 +52,29 @@ export const useProviderStore = create((set, get) => ({ } }, onAuthenticationFailed() { - set({ isReady: true }); + set({ isReady: true, isConnected: false }); + }, + onAuthenticated() { + set({ isReady: true, isConnected: true }); }, onStatus: ({ status }) => { set((state) => { const nextConnected = status === WebSocketStatus.Connected; + + /** + * status === WebSocketStatus.Connected does not mean we are totally connected + * because authentication can still be in progress and failed + * So we only update isConnected when we loose the connection + */ + const connected = + status !== WebSocketStatus.Connected + ? { + isConnected: false, + } + : undefined; + return { - isConnected: nextConnected, + ...connected, isReady: state.isReady || status === WebSocketStatus.Disconnected, hasLostConnection: state.isConnected && !nextConnected From 2f612dbc2f3b9b8b40ae6877201862f324ed4497 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Mon, 15 Dec 2025 12:38:08 +0100 Subject: [PATCH 3/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20improve=20ac?= =?UTF-8?q?cessibility=20CalloutBlock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent update of Blocknote brokes a test because a element was not easily accessible anymore. We improved the CalloutBlock to be able to be closed when "escape" is pressed, we improve the positionning of the EmojiPicker too. --- .../__tests__/app-impress/doc-editor.spec.ts | 2 + .../components/custom-blocks/CalloutBlock.tsx | 55 +++++++++++-------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index cc981f73f4..4c355861aa 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -802,6 +802,8 @@ test.describe('Doc Editor', () => { await page.getByText('Symbols').scrollIntoViewIfNeeded(); await expect(page.getByRole('button', { name: '🛃' })).toBeVisible(); + await page.keyboard.press('Escape'); + await page.locator('.bn-side-menu > button').last().click(); await page.locator('.mantine-Menu-dropdown > button').last().click(); await page.locator('.bn-color-picker-dropdown > button').last().click(); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx index f5144a266a..4a54ca9616 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/CalloutBlock.tsx @@ -97,34 +97,41 @@ const CalloutComponent = ({ `} > - + { + if (e.key === 'Escape' && openEmojiPicker) { + setOpenEmojiPicker(false); + } + }} + $css={css` + font-size: 1.125rem; + cursor: ${isEditable ? 'pointer' : 'default'}; + ${isEditable && + ` &:hover { background-color: rgba(0, 0, 0, 0.1); } `} - `} - $align="center" - $width="28px" - $radius="4px" - > - {block.props.emoji} - - - {openEmojiPicker && ( - - )} + `} + $align="center" + $width="28px" + $radius="4px" + > + {block.props.emoji} + + + {openEmojiPicker && ( + + )} + );