From 0b5bdf1c93d024b444914e5c60a74a7a4a3bf5ba Mon Sep 17 00:00:00 2001 From: vishwas babar <116264015+vishwas-babar@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:19:47 +0530 Subject: [PATCH] feat: support multiple file upload in Attachments component (#13283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #13277 ## What I Did - Enabled `multiple` attribute in the file input - Updated the `handleFileChange` handler to loop through files - Confirmed that each file is sent via `uploadAttachmentFile` ## Why This change allows users to upload multiple files at once instead of doing it one by one. ## Screenshot / Video (Optional) [Screencast From 2025-07-18 23-58-36.webm](https://github.com/user-attachments/assets/ea191f25-1904-4643-afe2-7029785eebcb) --- Let me know if you'd like any changes! 💪 --------- Co-authored-by: Félix Malfait --- .../files/components/AttachmentList.tsx | 8 ++++++- .../files/components/Attachments.tsx | 22 ++++++++++++++----- .../activities/files/components/DropZone.tsx | 14 ++++++------ .../ai-agent-action/components/AIChatTab.tsx | 2 +- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/packages/twenty-front/src/modules/activities/files/components/AttachmentList.tsx b/packages/twenty-front/src/modules/activities/files/components/AttachmentList.tsx index 7e5aa44ba..af8cd7d80 100644 --- a/packages/twenty-front/src/modules/activities/files/components/AttachmentList.tsx +++ b/packages/twenty-front/src/modules/activities/files/components/AttachmentList.tsx @@ -137,6 +137,12 @@ export const AttachmentList = ({ await uploadAttachmentFile(file, targetableObject); }; + const onUploadFiles = async (files: File[]) => { + for (const file of files) { + await onUploadFile(file); + } + }; + const handlePreview = (attachment: Attachment) => { if (!isAttachmentPreviewEnabled) return; setPreviewedAttachment(attachment); @@ -167,7 +173,7 @@ export const AttachmentList = ({ {isDraggingFile ? ( ) : ( diff --git a/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx b/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx index 78c305ee3..67776ae26 100644 --- a/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx +++ b/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx @@ -48,18 +48,26 @@ export const Attachments = ({ const [isDraggingFile, setIsDraggingFile] = useState(false); + const onUploadFile = async (file: File) => { + await uploadAttachmentFile(file, targetableObject); + }; + + const onUploadFiles = async (files: File[]) => { + for (const file of files) { + await onUploadFile(file); + } + }; + const handleFileChange = (e: ChangeEvent) => { - if (isDefined(e.target.files)) onUploadFile?.(e.target.files[0]); + if (isDefined(e.target.files)) { + onUploadFiles(Array.from(e.target.files)); + } }; const handleUploadFileClick = () => { inputFileRef?.current?.click?.(); }; - const onUploadFile = async (file: File) => { - await uploadAttachmentFile(file, targetableObject); - }; - const isAttachmentsEmpty = !attachments || attachments.length === 0; const { objectMetadataItem } = useObjectMetadataItem({ @@ -82,7 +90,7 @@ export const Attachments = ({ {isDraggingFile ? ( ) : ( {hasObjectUpdatePermissions && (