diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectFileStep.tsx b/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectFileStep.tsx index 47d322e1f6..0f6537a5e7 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectFileStep.tsx +++ b/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectFileStep.tsx @@ -154,19 +154,19 @@ const SelectFileStep = (props: SelectFileStepProps) => { const [progress, setProgress] = useState(0); const [isInfiniteProgress, setIsInfiniteProgress] = useState(true); - const [isError, setIsError] = useState(false); + const [isNetworkError, setIsNetworkError] = useState(false); const [isFileError, setIsFileError] = useState(false); const [isBackupEmpty, setIsBackupEmpty] = useState(false); const isAbort = useRef(false); + const [uploadFile, setFile] = useState(); + const [startChunk, setChunk] = useState(0); + const [chunkSize, setChunkSize] = useState(0); + const [failTries, setFailTries] = useState(FAIL_TRIES); const uploadInterval = useRef(); - const onUploadToServer = () => { - console.log("handle internet abortion"); - }; - const poolStatus = useCallback(async () => { try { const res = await getMigrationStatus(); @@ -220,12 +220,16 @@ const SelectFileStep = (props: SelectFileStepProps) => { setIsInfiniteProgress(false); } } catch (error) { - cancelMigration(); - toastr.error(error || t("Common:SomethingWentWrong")); - setIsFileError(true); - setLoadingStatus("none"); - setIsError(true); - clearInterval(uploadInterval.current); + if (error instanceof Error) { + if (error.message === "Network Error") { + setIsNetworkError(true); + } + cancelMigration(); + toastr.error(error || t("Common:SomethingWentWrong")); + setIsFileError(true); + setLoadingStatus("none"); + clearInterval(uploadInterval.current); + } } }, [ cancelMigration, @@ -241,10 +245,24 @@ const SelectFileStep = (props: SelectFileStepProps) => { try { if (file instanceof Array) { setFiles(file.map((item) => item.name)); - await multipleFileUploading(file, setProgress, isAbort); + await multipleFileUploading( + file, + setProgress, + isAbort, + setChunk, + startChunk, + setChunkSize, + ); } else { setFiles([file.name]); - await singleFileUploading(file, setProgress, isAbort); + await singleFileUploading( + file, + setProgress, + isAbort, + setChunk, + startChunk, + setChunkSize, + ); } if (isAbort.current) return; @@ -252,9 +270,15 @@ const SelectFileStep = (props: SelectFileStepProps) => { await initMigrationName(migratorName); setLoadingStatus("proceed"); } catch (error) { - toastr.error(error || t("Common:SomethingWentWrong")); - setIsFileError(true); - setLoadingStatus("none"); + if (error instanceof Error) { + if (error.message === "Network Error") { + setIsNetworkError(true); + } + + toastr.error(error || t("Common:SomethingWentWrong")); + setIsFileError(true); + setLoadingStatus("none"); + } } finally { isAbort.current = false; } @@ -273,10 +297,39 @@ const SelectFileStep = (props: SelectFileStepProps) => { setFailTries(FAIL_TRIES); setIsInfiniteProgress(true); setMigratingWorkspace(migratorName); + setFile(file); + setChunkSize(0); + setChunk(0); + isAbort.current = false; onUploadFile(file); }; + const onUploadToServer = () => { + if (!(uploadFile instanceof File) && !(uploadFile instanceof Array)) return; + + const size = + uploadFile instanceof Array + ? Math.ceil( + uploadFile.reduce((acc, curr) => acc + curr.size, 0) / chunkSize, + ) + : Math.ceil(uploadFile.size / chunkSize); + + if (size > startChunk) { + setProgress(0); + setIsNetworkError(false); + setIsFileError(false); + setIsSaveDisabled(true); + setLoadingStatus("upload"); + setFailTries(FAIL_TRIES); + setIsInfiniteProgress(true); + setMigratingWorkspace(migratorName); + onUploadFile(uploadFile); + } else { + setLoadingStatus("proceed"); + } + }; + const onDownloadArchives = async () => { try { const res = await getMigrationStatus(); @@ -399,7 +452,7 @@ const SelectFileStep = (props: SelectFileStepProps) => { )} - {isError ? ( + {isNetworkError ? ( { saveButtonLabel={t("Settings:UploadToServer")} cancelButtonLabel={t("Common:Back")} displaySettings - saveButtonDisabled={ - migratingWorkspace !== migratorName || isSaveDisabled - } showReminder /> ) : ( diff --git a/packages/client/src/store/ImportAccountsStore.ts b/packages/client/src/store/ImportAccountsStore.ts index bb444e0146..13c3179d47 100644 --- a/packages/client/src/store/ImportAccountsStore.ts +++ b/packages/client/src/store/ImportAccountsStore.ts @@ -332,7 +332,11 @@ class ImportAccountsStore { files: File[], setProgress: (progress: number) => void, isAbort: React.MutableRefObject, + setChunk: React.Dispatch>, + startChunk: number, + setChunkSize: React.Dispatch>, ) => { + let chunk = 0; try { const location = combineUrl( window.location.origin, @@ -341,11 +345,15 @@ class ImportAccountsStore { const requestsDataArray: { formData: FormData; fileName: string }[] = []; const res: { data: { ChunkSize: number } } = await axios.post( - `${location}?Init=true`, + `${location}?Init=${startChunk === 0}`, ); + if (!res.data.ChunkSize) return; + const chunkUploadSize = res.data.ChunkSize; + setChunkSize(chunkUploadSize); + if (isAbort!.current) return; const chunksNumber = files @@ -365,7 +373,7 @@ class ImportAccountsStore { } }); - let chunk = 0; + chunk = startChunk || 0; while ( chunk < chunksNumber && @@ -383,7 +391,7 @@ class ImportAccountsStore { chunk += 1; } } catch (e) { - console.error(e); + setChunk(chunk); } }; @@ -391,19 +399,29 @@ class ImportAccountsStore { file: File, setProgress: (progress: number) => void, isAbort: React.MutableRefObject, + setChunk: React.Dispatch>, + startChunk: number, + setChunkSize: React.Dispatch>, ) => { + let chunk = 0; try { const location = combineUrl( window.location.origin, "migrationFileUpload.ashx", ); - const requestsDataArray = []; - let chunk = 0; const res: { data: { ChunkSize: number } } = await axios.post( - `${location}?Init=true`, + `${location}?Init=${startChunk === 0}`, ); + + if (!res.data.ChunkSize) return; + const chunkUploadSize = res.data.ChunkSize; + + setChunkSize(chunkUploadSize); + + const requestsDataArray = []; + const chunks = Math.ceil(file.size / chunkUploadSize); if (isAbort.current) return; @@ -416,7 +434,7 @@ class ImportAccountsStore { chunk += 1; } - chunk = 0; + chunk = startChunk || 0; while ( chunk < chunks && (this.fileLoadingStatus === "upload" || @@ -433,7 +451,7 @@ class ImportAccountsStore { chunk += 1; } } catch (e) { - console.error(e); + setChunk(chunk); } };