From 9da311c68fc34fceddd41e832856923a3f7268c1 Mon Sep 17 00:00:00 2001 From: Arpit Date: Wed, 25 May 2022 17:05:32 +0530 Subject: [PATCH] [Improvement] Filepicker widget : The file picker should reject files with existing file names. (#3046) * fixes: multiple files with same file name can be uploaded * removes unwanted logs * compare file paths for validating existing selected files * disable picker if max count is reched * fixes loading spinner postions * max file count for single selection * disables the dropzone on max count only when multiple is true * show max count msg for dnd file to the dropzone * clean up * check already selectedFile count with max file count on adding new files * reverts accepted file data for singly selected files * Remove validation for existing files on filepicker Co-authored-by: Sherfin Shamsudeen --- frontend/src/Editor/Components/FilePicker.jsx | 64 +++++++++++++++---- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/frontend/src/Editor/Components/FilePicker.jsx b/frontend/src/Editor/Components/FilePicker.jsx index 6c09e259f5..dcdffb956d 100644 --- a/frontend/src/Editor/Components/FilePicker.jsx +++ b/frontend/src/Editor/Components/FilePicker.jsx @@ -77,17 +77,21 @@ export const FilePicker = ({ borderColor: '#ff1744', }; + const [disablePicker, setDisablePicker] = React.useState(false); + const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject, acceptedFiles, fileRejections } = useDropzone({ accept: parsedFileType, - noClick: !parsedEnablePicker, - noDrag: !parsedEnableDropzone, + noClick: !parsedEnablePicker || disablePicker, + noDrag: !parsedEnableDropzone || disablePicker, noKeyboard: true, maxFiles: parsedMaxFileCount, minSize: parsedMinSize, maxSize: parsedMaxSize, multiple: parsedEnableMultiple, - disabled: parsedDisabledState, + disabled: disablePicker, + validator: validateFileExists, + onDropRejected: () => (selectedFiles.length > 0 ? setShowSelectedFiles(true) : setShowSelectedFiles(false)), onFileDialogCancel: () => (selectedFiles.length > 0 ? setShowSelectedFiles(true) : setShowSelectedFiles(false)), }); @@ -106,6 +110,30 @@ export const FilePicker = ({ const [showSelectedFiles, setShowSelectedFiles] = React.useState(false); const [selectedFiles, setSelectedFiles] = React.useState([]); + //* custom validator + function validateFileExists(_file) { + const selectedFilesCount = selectedFiles.length; + + if (selectedFilesCount === parsedMaxFileCount) { + return { + code: 'max_file_count_reached', + message: `Max file count reached`, + }; + } + + return null; + } + + useEffect(() => { + if (parsedDisabledState) setDisablePicker(true); + + if (selectedFiles.length === parsedMaxFileCount && parsedEnableMultiple) { + setDisablePicker(true); + } else { + setDisablePicker(false); + } + }, [selectedFiles.length, parsedDisabledState, parsedMaxFileCount, parsedEnableMultiple]); + /** * *getFileData() * @param {*} file @@ -152,6 +180,7 @@ export const FilePicker = ({ dataURL: readFileAsDataURL, // TODO: Fix dataURL to have correct format base64Data: readFileAsDataURL, parsedData: shouldProcessFileParsing ? await processFileContent(file.type, readFileAsText) : null, + filePath: file.path, }; }; @@ -202,7 +231,9 @@ export const FilePicker = ({ acceptedFiles.map((acceptedFile) => { const acceptedFileData = fileReader(acceptedFile); acceptedFileData.then((data) => { - fileData.push(data); + if (fileData.length < parsedMaxFileCount) { + fileData.push(data); + } }); }); setSelectedFiles(fileData); @@ -226,8 +257,10 @@ export const FilePicker = ({ } return () => { + if (selectedFiles.length === 0) { + setShowSelectedFiles(false); + } setAccepted(false); - setShowSelectedFiles(false); }; // eslint-disable-next-line react-hooks/exhaustive-deps @@ -255,8 +288,8 @@ export const FilePicker = ({ - {showSelectedFiles ? ( - + {showSelectedFiles && !accepted ? ( + {selectedFiles.map((acceptedFile, index) => ( <>
@@ -288,7 +321,16 @@ export const FilePicker = ({ /> )} - + +
@@ -298,13 +340,13 @@ export const FilePicker = ({ FilePicker.Signifiers = ({ signifier, feedback, cls }) => { if (signifier) { - return <>{feedback === null ?
:

{feedback}

}; + return <>{feedback === null ?
:

{feedback}

}; } return null; }; -FilePicker.AcceptedFiles = ({ children, width, height, showFilezone }) => { +FilePicker.AcceptedFiles = ({ children, width, height }) => { const styles = { color: '#bdbdbd', outline: 'none', @@ -316,7 +358,7 @@ FilePicker.AcceptedFiles = ({ children, width, height, showFilezone }) => { height, }; return ( -