Reusing the useUploadAttachment Hook In the implementation of the feature to ensure the attachment table is updated whenever new images are added to a RICH_TEXT field #7617 , it is likely that the useUploadAttachment hook is reused. The useUploadAttachment hook is responsible for handling the upload of attachments, including images, and returning the uploaded file URL. By reusing this hook, you can leverage its existing functionality to handle image uploads within the RICH_TEXT field. In this case, the modified image handling logic would utilize the useUploadAttachment hook to upload new images added to the RICH_TEXT content. The hook would then return the uploaded file URL, which would be used to update the attachment table with the details of the newly added images. By reusing the useUploadAttachment hook, you can avoid duplicating code and ensure consistency in the way attachments are handled throughout the application. Fixes #6565 --------- Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
import { useRecoilValue } from 'recoil';
|
|
|
|
import { Attachment } from '@/activities/files/types/Attachment';
|
|
import { getFileType } from '@/activities/files/utils/getFileType';
|
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
|
import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getActivityTargetObjectFieldIdName';
|
|
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 => {
|
|
return attachmentPath.replace(/\?token=[^&]*$/, '');
|
|
};
|
|
|
|
export const useUploadAttachmentFile = () => {
|
|
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
|
const [uploadFile] = useUploadFileMutation();
|
|
|
|
const { createOneRecord: createOneAttachment } =
|
|
useCreateOneRecord<Attachment>({
|
|
objectNameSingular: CoreObjectNameSingular.Attachment,
|
|
});
|
|
|
|
const uploadAttachmentFile = async (
|
|
file: File,
|
|
targetableObject: ActivityTargetableObject,
|
|
) => {
|
|
const result = await uploadFile({
|
|
variables: {
|
|
file,
|
|
fileFolder: FileFolder.Attachment,
|
|
},
|
|
});
|
|
|
|
const attachmentPath = result?.data?.uploadFile;
|
|
|
|
if (!isNonEmptyString(attachmentPath)) {
|
|
throw new Error("Couldn't upload the attachment.");
|
|
}
|
|
|
|
const targetableObjectFieldIdName = getActivityTargetObjectFieldIdName({
|
|
nameSingular: targetableObject.targetObjectNameSingular,
|
|
});
|
|
|
|
const attachmentToCreate = {
|
|
authorId: currentWorkspaceMember?.id,
|
|
name: file.name,
|
|
fullPath: computePathWithoutToken(attachmentPath),
|
|
type: getFileType(file.name),
|
|
[targetableObjectFieldIdName]: targetableObject.id,
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
} as Partial<Attachment>;
|
|
|
|
await createOneAttachment(attachmentToCreate);
|
|
|
|
const attachementAbsoluteURL = getFileAbsoluteURI(attachmentPath);
|
|
|
|
return { attachementAbsoluteURL };
|
|
};
|
|
|
|
return { uploadAttachmentFile };
|
|
};
|