diff --git a/CHANGELOG.md b/CHANGELOG.md index a778c12..a076ec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,48 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. Thils file also consider all dropzone-ui [releases](https://github.com/dropzone-ui/dropzone-ui-react/releases). +## [1.2.0](https://github.com/files-ui/files-ui-react/releases/tag/v1.1.0) (2024-01-21) + +## ๐Ÿงช ๐Ÿš€ Allow uploading files with different URLs + +- Enhanced components to perform the upload operation with a different urls for each [ExtFile](https://www.files-ui.com/types#extfile). + - [ExtFile](https://www.files-ui.com/types#extfile): Added a new property in ExtFile type: `uploadUrl`. + - [\](https://www.files-ui.com/components/dropzone) & [\](https://www.files-ui.com/components/fileinputbutton): There is a new sub-prop `uploadConfig.customUrl()` that is a fucntion that given an extFile object, obtains a custom url. +- The order of priority is as follows: + - 1) ExtFile.uploadUrl + - 2) DropzoneProps.UploadConfig.customUrl + - 3) DropzoneProps.UploadConfig.url + +- The setup can be as follows: + +```jsx + ... + return( + + "https://urlfromserver/" + extFile.name + } + /> + "https://urlfromserver/" + extFile.name + } + /> + + {files.map((file) => ( + + ))} + + + + + ) +``` + ## [1.1.0](https://github.com/files-ui/files-ui-react/releases/tag/v1.1.0) (2023-12-17) ## ๐Ÿงช New features and ๐Ÿ› :hammer: Improvements @@ -35,7 +77,7 @@ Thils file also consider all dropzone-ui [releases](https://github.com/dropzone- - [\](https://www.files-ui.com/components/filecard): This new component is an alternative version of FileMosaic. It displays the file info in a card. Receives the same props as FileMosaic plus `elevation`. -- [\](https://www.files-ui.com/components/dropzone): This component replaces the old "InputButton" component. The features are the same as the dropzone except the header and footer related features. That means that this component now can trigger the upload progress. +- [\](https://www.files-ui.com/components/fileinputbutton): This component replaces the old "InputButton" component. The features are the same as the dropzone except the header and footer related features. That means that this component now can trigger the upload progress. Validation is optional, so non valid files can be uploaded. - [\](https://www.files-ui.com/components/avatar): This new component is designed tohandle the selection of images for changing the avatar. Can recieve as source an string url or even a File. diff --git a/package-lock.json b/package-lock.json index baa627f..e836a74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@files-ui/react", - "version": "1.0.8", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@files-ui/react", - "version": "1.0.8", + "version": "1.2.0", "license": "MIT", "dependencies": { "@dynamicss/dynamicss": "^2.2.8", - "@files-ui/core": "latest" + "@files-ui/core": "^2.0.4" }, "devDependencies": { "@rollup/plugin-commonjs": "^24.0.1", @@ -646,9 +646,9 @@ "hasInstallScript": true }, "node_modules/@files-ui/core": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@files-ui/core/-/core-1.0.4.tgz", - "integrity": "sha512-CaSyHSwjeWEkctfALoK4MwAxq3Zr7+Ozyk5AMoB3s1UBIVgh2618wvNuUIHSVhWFKeB28bOoYxCzM2PEXO4QgA==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@files-ui/core/-/core-2.0.4.tgz", + "integrity": "sha512-zlUfkOYpLGw/EEe2ZO+OPDXstygEaaWYIPQtibhV6oR1KTXewMvvbyC8QU/Y9Jy77/8Ps6N/Rl1yjH0PUqdmXg==" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -6801,9 +6801,9 @@ "integrity": "sha512-e6hrGUydr8f+c9E/9fHFSG5LoSLdq/MdZXXfbzEDWIVuzKF2hcdxZE7nHNqUNF2htw1mZ17Pyoshu3A6kFEeFA==" }, "@files-ui/core": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@files-ui/core/-/core-1.0.4.tgz", - "integrity": "sha512-CaSyHSwjeWEkctfALoK4MwAxq3Zr7+Ozyk5AMoB3s1UBIVgh2618wvNuUIHSVhWFKeB28bOoYxCzM2PEXO4QgA==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@files-ui/core/-/core-2.0.4.tgz", + "integrity": "sha512-zlUfkOYpLGw/EEe2ZO+OPDXstygEaaWYIPQtibhV6oR1KTXewMvvbyC8QU/Y9Jy77/8Ps6N/Rl1yjH0PUqdmXg==" }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", diff --git a/package.json b/package.json index f8a623b..1d78054 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@files-ui/react", - "version": "1.1.0", + "version": "1.2.0", "description": "UI components for file uploads with React js", "main": "./build/index.js", "module": "./build/index.es.js", @@ -68,7 +68,7 @@ }, "dependencies": { "@dynamicss/dynamicss": "^2.2.8", - "@files-ui/core": "latest" + "@files-ui/core": "^2.0.4" }, "publishConfig": { "access": "public" diff --git a/src/Dropzone/components/dropzone/Dropzone.tsx b/src/Dropzone/components/dropzone/Dropzone.tsx index ccff70c..a130948 100644 --- a/src/Dropzone/components/dropzone/Dropzone.tsx +++ b/src/Dropzone/components/dropzone/Dropzone.tsx @@ -28,8 +28,10 @@ import { unexpectedErrorUploadResult, getRandomInt, addClassName, - Localization,completeAsureColor, FileIdGenerator, -} from "@files-ui/core" + Localization, + completeAsureColor, + FileIdGenerator, +} from "@files-ui/core"; import { mergeProps } from "../../../overridable"; import InputHidden from "../../../InputHidden/InputHidden"; import { @@ -59,7 +61,12 @@ import { } from "../../../utils"; import { FilesUiContext } from "../../../FilesUiProvider/FilesUiContext"; import DropLayer from "../../../DropLayer/components/DropLayer"; -import { useDropzoneFileListUpdater, useDropLayerClassName, useDropzoneClassName } from "../../../hooks"; +import { + useDropzoneFileListUpdater, + useDropLayerClassName, + useDropzoneClassName, +} from "../../../hooks"; +import { isThereValidUrl } from "../../../utils/url.utils"; //import { print_manager } from "../../../../../utils"; @@ -146,6 +153,7 @@ const Dropzone: React.FC = (props: DropzoneProps) => { cleanOnUpload = true, preparingTime = 1500, autoUpload = false, + urlFromExtFile, } = uploadConfig as UploadConfig; const { @@ -197,8 +205,11 @@ const Dropzone: React.FC = (props: DropzoneProps) => { const [localMessage, setLocalMessage] = React.useState(""); //Id for uploding through FuiFileManager //const dropzoneId: string | number = useDropzoneFileListID(); - // const dropzoneId: string | number = React.useId(); - const dropzoneId: string = React.useMemo(() => FileIdGenerator.getNextId() + "",[]); + // const dropzoneId: string | number = React.useId(); + const dropzoneId: string = React.useMemo( + () => FileIdGenerator.getNextId() + "", + [] + ); //React.useId(); //Flag that determines whether to validate or not const validateFilesFlag: boolean = isValidateActive( @@ -224,6 +235,10 @@ const Dropzone: React.FC = (props: DropzoneProps) => { localization, validateFilesFlag ); + /** + * Flag that determines if component should perform upload given url + */ + const shouldUpload: boolean = isThereValidUrl(url, urlFromExtFile, localFiles); /** * Uploads each file in the array of ExtFiles * First, sets all the files in preparing status and awaits `preparingTime` miliseconds. @@ -247,7 +262,6 @@ const Dropzone: React.FC = (props: DropzoneProps) => { * @returns nothing */ const uploadfiles = async (localFiles: ExtFile[]): Promise => { - //set uploading flag to true setIsUploading(true); @@ -271,12 +285,11 @@ const Dropzone: React.FC = (props: DropzoneProps) => { let arrOfExtFilesInstances: ExtFileInstance[] = []; const totalNumber: number = localFiles.length; - + const missingUpload: number = localFiles.filter((extFile: ExtFile) => isUploadAbleExtFile(extFile, validateFilesFlag) ).length; - let totalRejected: number = 0; let currentCountUpload: number = 0; @@ -285,7 +298,6 @@ const Dropzone: React.FC = (props: DropzoneProps) => { //no missing to upload if (!(missingUpload > 0)) { - setTimeout(() => { if (noMissingFilesLabel) setLocalMessage(DropzoneLocalizer.noFilesMessage as string); @@ -300,7 +312,7 @@ const Dropzone: React.FC = (props: DropzoneProps) => { setLocalMessage(uploadingMessenger(`${missingUpload}/${totalNumber}`)); // setIsUploading(true); //PREPARING stage - + onUploadStart?.(localFiles); arrOfExtFilesInstances = @@ -315,138 +327,154 @@ const Dropzone: React.FC = (props: DropzoneProps) => { x.toExtFile() ); - //CHANGE (o alejo el isUploading o lo alejo para que tenga m,as tiempo antes de la respuyesta) // setIsUploading(true); handleFilesChange(newExtFileLocal, true); - //AWAIT when preparing time is given //general sleep for all files await sleepPreparing(preparingTime); //return; let serverResponses: Array = []; - - if(groupUpload) { - const unifiedUpload = (method, url, arrOfFiles) : Promise<{ success : boolean, message : string, payload: object }> => { - arrOfExtFilesInstances.forEach((el) => el.uploadStatus = "uploading"); - handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); - const formData = new FormData(); - for (let i=0; i < arrOfFiles.length; i++) { - formData.append('files', arrOfFiles[i].file ) - } - return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest(); - xhr.upload.onprogress = (e) => {arrOfExtFilesInstances.forEach((el) => { el.progress = (e.loaded / e.total) * 100 });handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true)}; - xhr.responseType = 'json' - xhr.onload = () => { - if (xhr.status >= 200 && xhr.status < 300) { - console.log(xhr.response); - console.log(typeof xhr.response); - resolve(xhr.response); - } else { - reject(xhr.response); - } - }; - xhr.onerror = (err) => { - reject(err); - }; - xhr.open(method, url); - xhr.send(formData) - }); - }; - try { - let respo:{ success : boolean, message : string, payload: object} = await unifiedUpload("POST", url, arrOfExtFilesInstances); - arrOfExtFilesInstances.forEach( el => el.uploadStatus = "success"); - arrOfExtFilesInstances.forEach( el => el.uploadMessage = respo.message); - } catch (err) { - arrOfExtFilesInstances.forEach( el => el.uploadStatus = "error"); - arrOfExtFilesInstances.forEach( el => el.uploadMessage = err.message); - console.log(err) + + if (groupUpload) { + const unifiedUpload = ( + method, + url, + arrOfFiles + ): Promise<{ success: boolean; message: string; payload: object }> => { + arrOfExtFilesInstances.forEach((el) => (el.uploadStatus = "uploading")); + handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); + const formData = new FormData(); + for (let i = 0; i < arrOfFiles.length; i++) { + formData.append("files", arrOfFiles[i].file); + } + return new Promise((resolve, reject) => { + let xhr = new XMLHttpRequest(); + xhr.upload.onprogress = (e) => { + arrOfExtFilesInstances.forEach((el) => { + el.progress = (e.loaded / e.total) * 100; + }); + handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); + }; + xhr.responseType = "json"; + xhr.onload = () => { + if (xhr.status >= 200 && xhr.status < 300) { + console.log(xhr.response); + console.log(typeof xhr.response); + resolve(xhr.response); + } else { + reject(xhr.response); + } + }; + xhr.onerror = (err) => { + reject(err); + }; + xhr.open(method, url); + xhr.send(formData); + }); + }; + try { + let respo: { success: boolean; message: string; payload: object } = + await unifiedUpload("POST", url, arrOfExtFilesInstances); + arrOfExtFilesInstances.forEach((el) => (el.uploadStatus = "success")); + arrOfExtFilesInstances.forEach( + (el) => (el.uploadMessage = respo.message) + ); + } catch (err) { + arrOfExtFilesInstances.forEach((el) => (el.uploadStatus = "error")); + arrOfExtFilesInstances.forEach( + (el) => (el.uploadMessage = err.message) + ); + console.log(err); } handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); } else { - //Uplad files one by one - for (let i = 0; i < arrOfExtFilesInstances.length; i++) { - const currentExtFileInstance: ExtFileInstance = arrOfExtFilesInstances[i]; + //Uplad files one by one + for (let i = 0; i < arrOfExtFilesInstances.length; i++) { + const currentExtFileInstance: ExtFileInstance = + arrOfExtFilesInstances[i]; + + if ( + currentExtFileInstance.uploadStatus === "preparing" && + !currentExtFileInstance.extraData?.deleted + ) { + //set stage to "uploading" in one file and notify change + // PREPARING => UPLOADING + await sleepTransition(); - - if ( - currentExtFileInstance.uploadStatus === "preparing" && - !currentExtFileInstance.extraData?.deleted - ) { - //set stage to "uploading" in one file and notify change - // PREPARING => UPLOADING - await sleepTransition(); + instantPreparingToUploadOne(currentExtFileInstance); - instantPreparingToUploadOne(currentExtFileInstance); + //messge in footer + if (uploadProgressMessage) + setLocalMessage( + uploadingMessenger(`${++currentCountUpload}/${missingUpload}`) + ); - //messge in footer - if (uploadProgressMessage) - setLocalMessage( - uploadingMessenger(`${++currentCountUpload}/${missingUpload}`) - ); + //CHANGE FILES + handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); - //CHANGE FILES - handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); + //UPLOADING => UPLOAD() + //upload one file and notify about change + let uploadResponse: ExtFile; - //UPLOADING => UPLOAD() - //upload one file and notify about change - let uploadResponse: ExtFile; - - if (fakeUpload) { - uploadResponse = await fakeFuiUpload( - currentExtFileInstance, - DropzoneLocalizer - ); - - let fakeProgress = 0; - while (fakeProgress < 100) { - fakeProgress += getRandomInt(21, 35); - currentExtFileInstance.progress = - fakeProgress > 100 ? 100 : fakeProgress; - await sleepTransition(1000); - handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); - } - } else { - try { - uploadResponse = await uploadExtFile( + if (fakeUpload) { + uploadResponse = await fakeFuiUpload( currentExtFileInstance, - url, - method, - headers, - uploadLabel - ); - } catch (error) { - uploadResponse = unexpectedErrorUploadResult( - currentExtFileInstance.toExtFile() + DropzoneLocalizer ); + + let fakeProgress = 0; + while (fakeProgress < 100) { + fakeProgress += getRandomInt(21, 35); + currentExtFileInstance.progress = + fakeProgress > 100 ? 100 : fakeProgress; + await sleepTransition(1000); + handleFilesChange( + sanitizeArrExtFile(arrOfExtFilesInstances), + true + ); + } + } else { + try { + uploadResponse = await uploadExtFile( + currentExtFileInstance, + url, + urlFromExtFile, + method, + headers, + uploadLabel + ); + } catch (error) { + uploadResponse = unexpectedErrorUploadResult( + currentExtFileInstance.toExtFile() + ); + } } - } - const uploadedFile = uploadResponse; + const uploadedFile = uploadResponse; - //update instances - currentExtFileInstance.uploadStatus = uploadedFile.uploadStatus; - currentExtFileInstance.uploadMessage = uploadedFile.uploadMessage; + //update instances + currentExtFileInstance.uploadStatus = uploadedFile.uploadStatus; + currentExtFileInstance.uploadMessage = uploadedFile.uploadMessage; - //CHANGE - if (!(currentExtFileInstance.uploadStatus === "aborted")) - await sleepTransition(); + //CHANGE + if (!(currentExtFileInstance.uploadStatus === "aborted")) + await sleepTransition(); - handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); + handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); - if (uploadedFile.uploadStatus === "error") { - totalRejected++; - } + if (uploadedFile.uploadStatus === "error") { + totalRejected++; + } - serverResponses.push(uploadResponse); - } else { - handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); + serverResponses.push(uploadResponse); + } else { + handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true); + } } } - } setLocalFiles(sanitizeArrExtFile(arrOfExtFilesInstances)); // upload group finished :D @@ -466,7 +494,7 @@ const Dropzone: React.FC = (props: DropzoneProps) => { const handleAbortUpload = () => { const listExtFileLocal: ExtFileInstance[] | undefined = ExtFileManager.getExtFileInstanceList(dropzoneId); - + if (!listExtFileLocal) return; listExtFileLocal.forEach((extFileInstance: ExtFileInstance) => { if ( @@ -540,7 +568,6 @@ const Dropzone: React.FC = (props: DropzoneProps) => { extFileList: ExtFile[], isUploading?: boolean ): void => { - let finalExtFileList: ExtFile[] = behaviour === "add" && !isUploading ? [...localFiles, ...extFileList] @@ -551,7 +578,6 @@ const Dropzone: React.FC = (props: DropzoneProps) => { setLocalFiles(finalExtFileList); } if (autoUpload && !isUploading) { - uploadfiles(finalExtFileList); } }; @@ -575,7 +601,8 @@ const Dropzone: React.FC = (props: DropzoneProps) => { } } //init xhr on each ext file - if (url) extFileListOutput = toUploadableExtFileList(extFileListOutput); + if (shouldUpload) + extFileListOutput = toUploadableExtFileList(extFileListOutput); // Clean input element to trigger onChange event on input cleanInput(inputRef.current); @@ -595,8 +622,7 @@ const Dropzone: React.FC = (props: DropzoneProps) => { */ const outerFuiValidation = (fuiFileListToValidate: ExtFile[]): ExtFile[] => { const localValidator: FileValidatorProps = { maxFileSize, accept }; - - + let finalNumberOfValids: number = numberOfValidFiles; if (behaviour === "replace") { //re-start number of valids @@ -611,7 +637,7 @@ const Dropzone: React.FC = (props: DropzoneProps) => { maxFiles, localization ); - + return validatedFuiFileList; }; @@ -693,7 +719,8 @@ const Dropzone: React.FC = (props: DropzoneProps) => { } //init xhr on each ext file - if (url) extFileListOutput = toUploadableExtFileList(extFileListOutput); + if (shouldUpload) + extFileListOutput = toUploadableExtFileList(extFileListOutput); handleFilesChange(extFileListOutput); }; @@ -801,7 +828,7 @@ const Dropzone: React.FC = (props: DropzoneProps) => { maxFiles && validFilesCountHeader ? maxFiles : undefined } localization={localization} - urlPresent={url !== undefined && uploadFilesHeader} + urlPresent={shouldUpload && uploadFilesHeader} onUploadStart={ !autoUpload && !uploadButton ? () => uploadfiles(localFiles) diff --git a/src/Dropzone/components/dropzone/DropzoneProps.ts b/src/Dropzone/components/dropzone/DropzoneProps.ts index a3fc75a..3ff9187 100644 --- a/src/Dropzone/components/dropzone/DropzoneProps.ts +++ b/src/Dropzone/components/dropzone/DropzoneProps.ts @@ -153,8 +153,6 @@ export interface DropzoneFullProps extends OverridableComponentProps { * @default false */ disableRipple?: boolean; - - /** * Method for performing specific tasks on drag enter operations */ diff --git a/src/FileCard/FileCardProps.ts b/src/FileCard/FileCardProps.ts index d0ced8f..f37e660 100644 --- a/src/FileCard/FileCardProps.ts +++ b/src/FileCard/FileCardProps.ts @@ -1,3 +1,4 @@ +import { ExtFile } from "@files-ui/core"; import { FileMosaicPropsMap } from "../FileMosaic/components/file-mosaic/FileMosaicProps"; @@ -7,7 +8,7 @@ export interface FileCardPropsMap extends FileMosaicPropsMap { } -export type FileCardProps = { +export type FileCardProps = ExtFile & { [F in keyof FileCardPropsMap]: FileCardPropsMap[F] } diff --git a/src/FileInputButton/FileInputButton.tsx b/src/FileInputButton/FileInputButton.tsx index dd90b1a..07ddc27 100644 --- a/src/FileInputButton/FileInputButton.tsx +++ b/src/FileInputButton/FileInputButton.tsx @@ -23,7 +23,7 @@ import { toUploadableExtFileList, cleanInput, FileIdGenerator, -} from "@files-ui/core" +} from "@files-ui/core"; import { DropzoneActions } from "../Dropzone/components/dropzone/DropzoneProps"; import DropzoneButtons from "../Dropzone/components/DropzoneButtons/DropzoneButtons"; import { FilesUiContext } from "../FilesUiProvider/FilesUiContext"; @@ -37,6 +37,7 @@ import { defaultFileInputButtonProps, FileInputButtonProps, } from "./InputButtonProps"; +import { isThereValidUrl } from "../utils/url.utils"; const FileInputButton: React.FC = ( props: FileInputButtonProps @@ -114,6 +115,7 @@ const FileInputButton: React.FC = ( cleanOnUpload = true, preparingTime = 1500, autoUpload = false, + urlFromExtFile, } = uploadConfig as UploadConfig; const { @@ -138,7 +140,10 @@ const FileInputButton: React.FC = ( //Id for uploding through FuiFileManager //const inputButtonId: string | number = React.useId(); - const inputButtonId: string = React.useMemo(() => FileIdGenerator.getNextId() + "",[]); + const inputButtonId: string = React.useMemo( + () => FileIdGenerator.getNextId() + "", + [] + ); //Flag that determines whether to validate or not const validateFilesFlag: boolean = isValidateActive( accept, @@ -164,6 +169,14 @@ const FileInputButton: React.FC = ( localization, validateFilesFlag ); + /** + * Flag that determines if component should perform upload given url + */ + const shouldUpload: boolean = isThereValidUrl( + url, + urlFromExtFile, + localFiles + ); /** * Uploads each file in the array of ExtFiles * First, sets all the files in preparing status and awaits `preparingTime` miliseconds. @@ -187,7 +200,6 @@ const FileInputButton: React.FC = ( * @returns nothing */ const uploadfiles = async (localFiles: ExtFile[]): Promise => { - //set uploading flag to true setIsUploading(true); @@ -241,7 +253,6 @@ const FileInputButton: React.FC = ( x.toExtFile() ); - //CHANGE (o alejo el isUploading o lo alejo para que tenga m,as tiempo antes de la respuyesta) // setIsUploading(true); handleFilesChange(newExtFileLocal, true); @@ -259,8 +270,6 @@ const FileInputButton: React.FC = ( for (let i = 0; i < arrOfExtFilesInstances.length; i++) { const currentExtFileInstance: ExtFileInstance = arrOfExtFilesInstances[i]; - - if ( currentExtFileInstance.uploadStatus === "preparing" && !currentExtFileInstance.extraData?.deleted @@ -297,6 +306,7 @@ const FileInputButton: React.FC = ( uploadResponse = await uploadExtFile( currentExtFileInstance, url, + urlFromExtFile, method, headers, uploadLabel @@ -383,7 +393,6 @@ const FileInputButton: React.FC = ( extFileList: ExtFile[], isUploading?: boolean ): void => { - let finalExtFileList: ExtFile[] = behaviour === "add" && !isUploading ? [...localFiles, ...extFileList] @@ -417,8 +426,9 @@ const FileInputButton: React.FC = ( extFileListOutput = extFileListOutput.filter((f) => f.valid); } } - //init xhr on each dui file - if (url) extFileListOutput = toUploadableExtFileList(extFileListOutput); + //init xhr on each ext file + if (shouldUpload) + extFileListOutput = toUploadableExtFileList(extFileListOutput); // Clean input element to trigger onChange event on input cleanInput(inputRef.current); diff --git a/src/FileMosaic/components/file-mosaic/FileMosaicProps.ts b/src/FileMosaic/components/file-mosaic/FileMosaicProps.ts index b5b9948..64817cd 100644 --- a/src/FileMosaic/components/file-mosaic/FileMosaicProps.ts +++ b/src/FileMosaic/components/file-mosaic/FileMosaicProps.ts @@ -1,46 +1,7 @@ -import { Localization, UPLOADSTATUS } from "@files-ui/core" +import { ExtFile, Localization, UPLOADSTATUS } from "@files-ui/core" import { OverridableComponentProps } from "../../../overridable"; export interface FileMosaicPropsMap extends OverridableComponentProps { - /** - * The identifier for the file - */ - id?: string | number; - /** - * The file object obtained from client drop or selection - */ - file?: File; - /** - * The name of the file - */ - name?: string; - /** - * The file mime type - */ - type?: string; - /** - * the size of the file in bytes - */ - size?: number; - /** - * whether to show a valid or rejected message ("ok", "rejected") - * by def. valid is false (if not present, it's false too) - * This value wil affect preview behaviour, - * If not valid, the preview will not be shown, nor the view button - */ - valid?: boolean | null; - /** - * The list of errors according to the validation criteria or custom validation function given. - */ - errors?: string[]; - /** - * The message from server - */ - uploadMessage?: string; - /** - * The current upload status of the file - */ - uploadStatus?: UPLOADSTATUS; /** * if true, and if the file is an image, * makes visible the "view" button that will get the image url @@ -52,19 +13,6 @@ export interface FileMosaicPropsMap extends OverridableComponentProps { * @default false */ info?: boolean; - /** - * A string representation or web url of the image - * that will be set to the "src" prop of an If - * given, the component will use this image source instead of - * reading the image file. - */ - imageUrl?: string; - /** - * A string representation or web url of the video - * that will be set to the "src" prop of an