From 65530e210fd7ec88a3e2a106109c6934b00b2de3 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa Date: Wed, 15 Jan 2025 13:27:12 -0300 Subject: [PATCH] fix: simplify InputFileComponent to use native file picker (#5692) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ (index.tsx): Add useRef hook to manage file input element reference for better control over file selection process 🐛 (index.tsx): Fix handleButtonClick function to handle file selection asynchronously and provide fallback option if file selection fails 🐛 (index.tsx): Fix handleNativeInputChange function to correctly handle file selection from native file input element and reset its value after selection * 📝 (index.tsx): Remove unused createFileUpload function and simplify handleButtonClick function to trigger file input click directly ♻️ (index.tsx): Refactor input element to use Button component for better styling and consistency * 📝 (inputFileComponent/index.tsx): remove unnecessary comment in handleButtonClick function --- .../components/inputFileComponent/index.tsx | 125 ++++++++++-------- 1 file changed, 71 insertions(+), 54 deletions(-) diff --git a/src/frontend/src/components/core/parameterRenderComponent/components/inputFileComponent/index.tsx b/src/frontend/src/components/core/parameterRenderComponent/components/inputFileComponent/index.tsx index 7ec0ab7fc..dd52afb16 100644 --- a/src/frontend/src/components/core/parameterRenderComponent/components/inputFileComponent/index.tsx +++ b/src/frontend/src/components/core/parameterRenderComponent/components/inputFileComponent/index.tsx @@ -1,8 +1,7 @@ import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file"; -import { createFileUpload } from "@/helpers/create-file-upload"; import useFileSizeValidator from "@/shared/hooks/use-file-size-validator"; import { cn } from "@/utils/utils"; -import { useEffect } from "react"; +import { useEffect, useRef } from "react"; import { CONSOLE_ERROR_MSG, INVALID_FILE_ALERT, @@ -24,70 +23,77 @@ export default function InputFileComponent({ const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); const setErrorData = useAlertStore((state) => state.setErrorData); const { validateFileSize } = useFileSizeValidator(setErrorData); + const fileInputRef = useRef(null); // Clear component state useEffect(() => { if (disabled && value !== "") { handleOnNewValue({ value: "", file_path: "" }, { skipSnapshot: true }); } - }, [disabled, handleOnNewValue]); + }, [disabled, handleOnNewValue, value]); function checkFileType(fileName: string): boolean { - if (fileTypes === undefined) return true; - for (let index = 0; index < fileTypes.length; index++) { - if (fileName.endsWith(fileTypes[index])) { - return true; - } - } - return false; + if (!fileTypes?.length) return true; + return fileTypes.some((type) => + fileName.toLowerCase().endsWith(type.toLowerCase()), + ); } const { mutate, isPending } = usePostUploadFile(); - const handleButtonClick = (): void => { - createFileUpload({ multiple: false, accept: fileTypes?.join(",") }).then( - (files) => { - const file = files[0]; - if (file) { - if (!validateFileSize(file)) { - return; - } + const handleFileSelection = (file: File | null) => { + if (!file) { + setErrorData({ + title: "Error selecting file", + list: ["No file was selected"], + }); + return; + } - if (checkFileType(file.name)) { - // Upload the file - mutate( - { file, id: currentFlowId }, - { - onSuccess: (data) => { - // Get the file name from the response - const { file_path } = data; + if (!validateFileSize(file)) { + return; + } - // sets the value that goes to the backend - // Update the state and on with the name of the file - // sets the value to the user - handleOnNewValue({ value: file.name, file_path }); - }, - onError: (error) => { - console.error(CONSOLE_ERROR_MSG); - setErrorData({ - title: "Error uploading file", - list: [error.response?.data?.detail], - }); - }, - }, - ); - } else { - // Show an error if the file type is not allowed - setErrorData({ - title: INVALID_FILE_ALERT, - list: [fileTypes?.join(", ") || ""], - }); - } - } + if (!checkFileType(file.name)) { + setErrorData({ + title: INVALID_FILE_ALERT, + list: [fileTypes?.join(", ") || ""], + }); + return; + } + + mutate( + { file, id: currentFlowId }, + { + onSuccess: (data) => { + const { file_path } = data; + handleOnNewValue({ value: file.name, file_path }); + }, + onError: (error) => { + console.error(CONSOLE_ERROR_MSG); + setErrorData({ + title: "Error uploading file", + list: [error.response?.data?.detail || "Unknown error occurred"], + }); + }, }, ); }; + const handleButtonClick = () => { + fileInputRef.current?.click(); + }; + + const handleNativeInputChange = ( + event: React.ChangeEvent, + ) => { + const file = event.target.files?.[0] || null; + handleFileSelection(file); + if (event.target) { + event.target.value = ""; + } + }; + const isDisabled = disabled || isPending; return ( @@ -96,18 +102,29 @@ export default function InputFileComponent({
- + + {value || "Upload a file..."} + + + e.stopPropagation()} />