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 7aabc689c..4af5cd8dc 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
@@ -356,20 +356,20 @@ test.describe('Doc Editor', () => {
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, 'assets/test.html'));
- await expect(editor.getByText('Analyzing file...')).toBeVisible();
+ await expect(editor.getByText('Analyzing the file')).toBeVisible();
// To be sure the retry happens even after a page reload
await goToGridDoc(page, {
title: randomDoc,
});
- await expect(editor.getByText('Analyzing file...')).toBeVisible();
+ await expect(editor.getByText('Analyzing the file')).toBeVisible();
// The retry takes a few seconds
await expect(editor.getByText('test.html')).toBeVisible({
timeout: 7000,
});
- await expect(editor.getByText('Analyzing file...')).toBeHidden();
+ await expect(editor.getByText('Analyzing the file')).toBeHidden();
});
test('it checks if callout custom block', async ({ page, browserName }) => {
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 879473f3d..8425caec7 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
@@ -33,7 +33,7 @@ import { useTranslation } from 'react-i18next';
import { WebsocketProvider } from 'y-websocket';
import * as Y from 'yjs';
-import { Box, TextErrors } from '@/components';
+import { Box } from '@/components';
import { useConfig } from '@/core';
import { useCunninghamTheme } from '@/cunningham';
import {
@@ -133,7 +133,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
? DEFAULT_LOCALE
: i18n.resolvedLanguage;
- const { uploadFile, errorAttachment } = useUploadFile(doc.id);
+ const { uploadFile } = useUploadFile(doc.id);
const conf = useConfig().data;
const { isFeatureFlagActivated } = useAnalytics();
const aiBlockNoteAllowed = !!(
@@ -346,15 +346,6 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
currentUserAvatarUrl={currentUserAvatarUrl}
/>
- {errorAttachment && (
-
-
-
- )}
{
isError: isErrorAttachment,
error: errorAttachment,
} = useCreateDocAttachment();
+ const editor = useEditorStore((state) => state.editor);
+ const uploadBlockIdRef = useRef(undefined);
const maxFileSize = config?.DOCUMENT_IMAGE_MAX_SIZE ?? DEFAULT_MAX_FILE_SIZE;
const uploadFile = useCallback(
- async (file: File) => {
+ async (file: File, blockId?: string) => {
+ uploadBlockIdRef.current = blockId;
+
// The server rejects an oversized file, but the proxy in front of it usually cuts the
// request first and answers a bare 413 the editor cannot make sense of. Telling the
// user before sending anything saves them the wait and the cryptic message.
@@ -85,6 +90,38 @@ export const useUploadFile = (docId: string) => {
[createDocAttachment, docId, maxFileSize, t, toast],
);
+ /**
+ * Handle the upload error by replacing the block with an
+ * uploadLoader block displaying a warning message.
+ */
+ useEffect(() => {
+ const blockId = uploadBlockIdRef.current;
+ if (!errorAttachment || !blockId || !editor) {
+ return;
+ }
+
+ try {
+ editor.replaceBlocks(
+ [blockId],
+ [
+ {
+ type: 'uploadLoader',
+ props: {
+ information: t(
+ 'A problem occurred while uploading the file, please try again.',
+ ),
+ type: 'warning',
+ },
+ },
+ ],
+ );
+ } catch {
+ /* The block may be gone already (removed or updated by a collaborator) */
+ }
+
+ uploadBlockIdRef.current = undefined;
+ }, [editor, errorAttachment, t]);
+
return {
uploadFile,
isErrorAttachment,
@@ -132,7 +169,7 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => {
{
type: 'uploadLoader',
props: {
- information: t('Analyzing file...'),
+ information: t('Analyzing the file'),
type: 'loading',
blockUploadName,
blockUploadType,