From 52b75e0b060cf6720801c4ca61d97d7bd5c6ea16 Mon Sep 17 00:00:00 2001 From: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:36:17 -0500 Subject: [PATCH] fix: uploading progress percentage (#763) --- src/import-page/data/api.js | 9 +++++---- src/import-page/data/api.test.jsx | 2 +- src/import-page/data/thunks.js | 11 ++++++++--- src/import-page/file-section/FileSection.jsx | 2 -- src/import-page/import-stepper/ImportStepper.jsx | 2 +- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/import-page/data/api.js b/src/import-page/data/api.js index dda69970ea..1955dc98d4 100644 --- a/src/import-page/data/api.js +++ b/src/import-page/data/api.js @@ -12,13 +12,12 @@ export const getImportStatusApiUrl = (courseId, fileName) => `${getApiBaseUrl()} * @param {Object} requestConfig * @returns {Promise} */ -export async function startCourseImporting(courseId, fileData, requestConfig) { +export async function startCourseImporting(courseId, fileData, requestConfig, updateProgress) { const chunkSize = 20 * 1000000; // 20 MB const fileSize = fileData.size || 0; const chunkLength = Math.ceil(fileSize / chunkSize); let resp; - - const upload = async (blob, start, stop) => { + const upload = async (blob, start, stop, index) => { const contentRange = `bytes ${start}-${stop}/${fileSize}`; const contentDisposition = `attachment; filename="${fileData.name}"`; const headers = { @@ -33,6 +32,8 @@ export async function startCourseImporting(courseId, fileData, requestConfig) { formData, { headers, ...requestConfig }, ); + const percent = Math.trunc(((1 / chunkLength) * (index + 1)) * 100); + updateProgress(percent); resp = camelCaseObject(data); }; @@ -40,7 +41,7 @@ export async function startCourseImporting(courseId, fileData, requestConfig) { const start = index * chunkSize; const stop = start + chunkSize < fileSize ? start + chunkSize : fileSize; const blob = file.slice(start, stop, file.type); - await upload(blob, start, stop - 1); + await upload(blob, start, stop - 1, index); }; /* eslint-disable no-await-in-loop */ diff --git a/src/import-page/data/api.test.jsx b/src/import-page/data/api.test.jsx index 9aa50dac5f..5f0e7b43b8 100644 --- a/src/import-page/data/api.test.jsx +++ b/src/import-page/data/api.test.jsx @@ -29,7 +29,7 @@ describe('API Functions', () => { const data = { importStatus: 1 }; axiosMock.onPost(postImportCourseApiUrl(courseId)).reply(200, data); - const result = await startCourseImporting(courseId, file); + const result = await startCourseImporting(courseId, file, {}, jest.fn()); expect(axiosMock.history.post[0].url).toEqual(postImportCourseApiUrl(courseId)); expect(result).toEqual(data); }); diff --git a/src/import-page/data/thunks.js b/src/import-page/data/thunks.js index 04415443f1..95acb291ec 100644 --- a/src/import-page/data/thunks.js +++ b/src/import-page/data/thunks.js @@ -6,7 +6,7 @@ import { RequestStatus } from '../../data/constants'; import { setImportCookie } from '../utils'; import { getImportStatus, startCourseImporting } from './api'; import { - reset, updateCurrentStage, updateError, updateFileName, + reset, updateCurrentStage, updateError, updateFileName, updateProgress, updateImportTriggered, updateLoadingStatus, updateSavingStatus, updateSuccessDate, } from './slice'; import { IMPORT_STAGES, LAST_IMPORT_COOKIE_NAME } from './constants'; @@ -44,9 +44,14 @@ export function handleProcessUpload(courseId, fileData, requestConfig, handleErr const file = fileData.get('file'); dispatch(reset()); dispatch(updateSavingStatus(RequestStatus.PENDING)); - dispatch(updateImportTriggered(true)); dispatch(updateFileName(file.name)); - const { importStatus } = await startCourseImporting(courseId, file, requestConfig); + dispatch(updateImportTriggered(true)); + const { importStatus } = await startCourseImporting( + courseId, + file, + requestConfig, + (percent) => dispatch(updateProgress(percent)), + ); dispatch(updateCurrentStage(importStatus)); setImportCookie(moment().valueOf(), importStatus === IMPORT_STAGES.SUCCESS, file.name); dispatch(updateSavingStatus(RequestStatus.SUCCESSFUL)); diff --git a/src/import-page/file-section/FileSection.jsx b/src/import-page/file-section/FileSection.jsx index b601268af2..012023f04f 100644 --- a/src/import-page/file-section/FileSection.jsx +++ b/src/import-page/file-section/FileSection.jsx @@ -11,7 +11,6 @@ import { IMPORT_STAGES } from '../data/constants'; import { getCurrentStage, getError, getFileName, getImportTriggered, } from '../data/selectors'; -import { updateProgress } from '../data/slice'; import messages from './messages'; import { handleProcessUpload } from '../data/thunks'; @@ -42,7 +41,6 @@ const FileSection = ({ intl, courseId }) => { handleError, )) } - onUploadProgress={(percent) => dispatch(updateProgress(percent))} accept={{ 'application/gzip': ['.tar.gz'] }} data-testid="dropzone" /> diff --git a/src/import-page/import-stepper/ImportStepper.jsx b/src/import-page/import-stepper/ImportStepper.jsx index 72755d825f..476187b294 100644 --- a/src/import-page/import-stepper/ImportStepper.jsx +++ b/src/import-page/import-stepper/ImportStepper.jsx @@ -95,7 +95,7 @@ const ImportStepper = ({ intl, courseId }) => {

{intl.formatMessage(messages.stepperHeaderTitle)}