mirror of
https://github.com/suitenumerique/docs.git
synced 2026-10-21 07:21:45 +02:00
🥅(frontend) change ui when catch unexpected upload error
We updated the UI to provide a clearer indication when an unexpected upload error occurs. Before the error was displayed on the top of the editor, making it less noticeable to the user, now we display the error directly within the upload block, making it more visible to the user and more user-friendly.
This commit is contained in:
@@ -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 }) => {
|
||||
|
||||
+10
-11
@@ -23,6 +23,10 @@ import {
|
||||
import {
|
||||
FloatingComposerController,
|
||||
FloatingThreadController,
|
||||
ReactAudioBlock,
|
||||
ReactFileBlock,
|
||||
ReactImageBlock,
|
||||
ReactVideoBlock,
|
||||
ThreadsSidebar,
|
||||
useCreateBlockNote,
|
||||
} from '@blocknote/react';
|
||||
@@ -33,7 +37,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 {
|
||||
@@ -83,6 +87,10 @@ const baseBlockNoteSchema = withPageBreak(
|
||||
BlockNoteSchema.create({
|
||||
blockSpecs: {
|
||||
...defaultBlockSpecs,
|
||||
audio: ReactAudioBlock(),
|
||||
file: ReactFileBlock(),
|
||||
image: ReactImageBlock(),
|
||||
video: ReactVideoBlock(),
|
||||
callout: CalloutBlock(),
|
||||
codeBlock: createSafeCodeBlockSpec(),
|
||||
diagram: createReactDiagramBlockSpec(),
|
||||
@@ -133,7 +141,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 +354,6 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
|
||||
currentUserAvatarUrl={currentUserAvatarUrl}
|
||||
/>
|
||||
<DocsFindReplaceStyle />
|
||||
{errorAttachment && (
|
||||
<Box $margin={{ bottom: 'big', top: 'none', horizontal: 'large' }}>
|
||||
<TextErrors
|
||||
causes={errorAttachment.cause}
|
||||
canClose
|
||||
$textAlign="left"
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
<BlockNoteView
|
||||
className="--docs--main-editor"
|
||||
editor={editor}
|
||||
|
||||
+20
@@ -71,6 +71,26 @@ describe('useUploadFile', () => {
|
||||
'error',
|
||||
);
|
||||
});
|
||||
|
||||
it('toasts the causes of the API and rethrows when the upload fails', async () => {
|
||||
fetchMock.hardReset();
|
||||
fetchMock.mockGlobal();
|
||||
fetchMock.post(uploadUrl, {
|
||||
status: 400,
|
||||
body: { file: ['File type not allowed.'] },
|
||||
});
|
||||
|
||||
const result = renderUseUploadFile();
|
||||
|
||||
await expect(
|
||||
result.current.uploadFile(createFile(MAX_FILE_SIZE)),
|
||||
).rejects.toThrow('Failed to upload on the doc');
|
||||
|
||||
expect(mockToast).toHaveBeenCalledWith(
|
||||
'A problem occurred while uploading the file, cause: File type not allowed.',
|
||||
'error',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useUploadStatus', () => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { captureException } from '@sentry/nextjs';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { backendUrl } from '@/api';
|
||||
import { APIError, backendUrl } from '@/api';
|
||||
import { useConfig } from '@/core';
|
||||
import { useToast } from '@/hooks';
|
||||
import { formatFileSize } from '@/utils';
|
||||
@@ -44,11 +44,7 @@ export const useUploadFile = (docId: string) => {
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const { data: config } = useConfig();
|
||||
const {
|
||||
mutateAsync: createDocAttachment,
|
||||
isError: isErrorAttachment,
|
||||
error: errorAttachment,
|
||||
} = useCreateDocAttachment();
|
||||
const { mutateAsync: createDocAttachment } = useCreateDocAttachment();
|
||||
|
||||
const maxFileSize = config?.DOCUMENT_IMAGE_MAX_SIZE ?? DEFAULT_MAX_FILE_SIZE;
|
||||
|
||||
@@ -75,21 +71,32 @@ export const useUploadFile = (docId: string) => {
|
||||
const body = new FormData();
|
||||
body.append('file', file);
|
||||
|
||||
const ret = await createDocAttachment({
|
||||
docId,
|
||||
body,
|
||||
});
|
||||
try {
|
||||
const ret = await createDocAttachment({
|
||||
docId,
|
||||
body,
|
||||
});
|
||||
|
||||
return `${backendUrl()}${ret.file}`;
|
||||
return `${backendUrl()}${ret.file}`;
|
||||
} catch (error) {
|
||||
const causes = error instanceof APIError ? error.cause : undefined;
|
||||
|
||||
toast(
|
||||
causes?.length
|
||||
? `${t('A problem occurred while uploading the file, cause:')} ${causes.join(' ')}`
|
||||
: t(
|
||||
'A problem occurred while uploading the file, please try again.',
|
||||
),
|
||||
VariantType.ERROR,
|
||||
);
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[createDocAttachment, docId, maxFileSize, t, toast],
|
||||
);
|
||||
|
||||
return {
|
||||
uploadFile,
|
||||
isErrorAttachment,
|
||||
errorAttachment,
|
||||
};
|
||||
return { uploadFile };
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -132,7 +139,7 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => {
|
||||
{
|
||||
type: 'uploadLoader',
|
||||
props: {
|
||||
information: t('Analyzing file...'),
|
||||
information: t('Analyzing the file'),
|
||||
type: 'loading',
|
||||
blockUploadName,
|
||||
blockUploadType,
|
||||
|
||||
Reference in New Issue
Block a user