diff --git a/packages/twenty-front/src/modules/activities/components/RichTextEditor.tsx b/packages/twenty-front/src/modules/activities/components/RichTextEditor.tsx index 21ac7228d3da..26dd4204e631 100644 --- a/packages/twenty-front/src/modules/activities/components/RichTextEditor.tsx +++ b/packages/twenty-front/src/modules/activities/components/RichTextEditor.tsx @@ -1,7 +1,7 @@ import { useApolloClient } from '@apollo/client'; import { useCreateBlockNote } from '@blocknote/react'; import { isArray, isNonEmptyString } from '@sniptt/guards'; -import { ClipboardEvent, useCallback, useMemo } from 'react'; +import { useCallback, useMemo } from 'react'; import { useRecoilCallback, useRecoilState } from 'recoil'; import { Key } from 'ts-key-enum'; import { useDebouncedCallback } from 'use-debounce'; @@ -20,20 +20,16 @@ import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDraw import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritingKey'; -import { FileFolder, useUploadFileMutation } from '~/generated/graphql'; import { isDefined } from '~/utils/isDefined'; -import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; - -import { getFileType } from '../files/utils/getFileType'; import { BLOCK_SCHEMA } from '@/activities/blocks/constants/Schema'; +import { useUploadAttachmentFile } from '@/activities/files/hooks/useUploadAttachmentFile'; import { Note } from '@/activities/types/Note'; import { Task } from '@/activities/types/Task'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import '@blocknote/core/fonts/inter.css'; import '@blocknote/mantine/style.css'; import '@blocknote/react/style.css'; -import { getFileAbsoluteURI } from '~/utils/file/getFileAbsoluteURI'; type RichTextEditorProps = { activityId: string; @@ -121,22 +117,13 @@ export const RichTextEditor = ({ canCreateActivityState, ); - const [uploadFile] = useUploadFileMutation(); + const { uploadAttachmentFile } = useUploadAttachmentFile(); - const handleUploadAttachment = async (file: File): Promise => { - if (isUndefinedOrNull(file)) { - return ''; - } - const result = await uploadFile({ - variables: { - file, - fileFolder: FileFolder.Attachment, - }, + const handleUploadAttachment = async (file: File) => { + return await uploadAttachmentFile(file, { + id: activityId, + targetObjectNameSingular: activityObjectNameSingular, }); - if (!result?.data?.uploadFile) { - throw new Error("Couldn't upload Image"); - } - return getFileAbsoluteURI(result.data.uploadFile); }; const prepareBody = (newStringifiedBody: string) => { @@ -152,8 +139,6 @@ export const RichTextEditor = ({ const imageProps = block.props; const imageUrl = new URL(imageProps.url); - imageUrl.searchParams.delete('token'); - return { ...block, props: { @@ -284,65 +269,19 @@ export const RichTextEditor = ({ } }, [activity, activityBody]); + const handleEditorBuiltInUploadFile = async (file: File) => { + const { attachementAbsoluteURL } = await handleUploadAttachment(file); + + return attachementAbsoluteURL; + }; + const editor = useCreateBlockNote({ initialContent: initialBody, domAttributes: { editor: { class: 'editor' } }, schema: BLOCK_SCHEMA, - uploadFile: handleUploadAttachment, + uploadFile: handleEditorBuiltInUploadFile, }); - const handleImagePaste = async (event: ClipboardEvent) => { - const clipboardItems = event.clipboardData?.items; - - if (isDefined(clipboardItems)) { - for (let i = 0; i < clipboardItems.length; i++) { - if (clipboardItems[i].kind === 'file') { - const isImage = clipboardItems[i].type.match('^image/'); - const pastedFile = clipboardItems[i].getAsFile(); - if (!pastedFile) { - return; - } - - const attachmentUrl = await handleUploadAttachment(pastedFile); - - if (!attachmentUrl) { - return; - } - - if (isDefined(isImage)) { - editor?.insertBlocks( - [ - { - type: 'image', - props: { - url: attachmentUrl, - }, - }, - ], - editor?.getTextCursorPosition().block, - 'after', - ); - } else { - editor?.insertBlocks( - [ - { - type: 'file', - props: { - url: attachmentUrl, - fileType: getFileType(pastedFile.name), - name: pastedFile.name, - }, - }, - ], - editor?.getTextCursorPosition().block, - 'after', - ); - } - } - } - } - }; - useScopedHotkeys( Key.Escape, () => { @@ -427,7 +366,6 @@ export const RichTextEditor = ({ diff --git a/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx b/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx index 301a324668a7..bbd8d6152af4 100644 --- a/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx +++ b/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx @@ -7,7 +7,9 @@ import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getActivi import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; +import { isNonEmptyString } from '@sniptt/guards'; import { FileFolder, useUploadFileMutation } from '~/generated/graphql'; +import { getFileAbsoluteURI } from '~/utils/file/getFileAbsoluteURI'; // Note: This is probably not the right way to do this. export const computePathWithoutToken = (attachmentPath: string): string => { @@ -36,8 +38,8 @@ export const useUploadAttachmentFile = () => { const attachmentPath = result?.data?.uploadFile; - if (!attachmentPath) { - return; + if (!isNonEmptyString(attachmentPath)) { + throw new Error("Couldn't upload the attachment."); } const targetableObjectFieldIdName = getActivityTargetObjectFieldIdName({ @@ -55,6 +57,10 @@ export const useUploadAttachmentFile = () => { } as Partial; await createOneAttachment(attachmentToCreate); + + const attachementAbsoluteURL = getFileAbsoluteURI(attachmentPath); + + return { attachementAbsoluteURL }; }; return { uploadAttachmentFile };