fix: progress bar display for uploads (#1135)

This commit is contained in:
Kristin Aoki
2024-07-01 12:52:08 -04:00
committed by GitHub
parent cdc9af2ed4
commit efd73f9c0b
6 changed files with 76 additions and 33 deletions

View File

@@ -243,14 +243,16 @@ const FileTable = ({
fileType={fileType}
/>
<ApiStatusToast
actionType={intl.formatMessage(messages.apiStatusAddingAction)}
selectedRowCount={selectedRows.length}
isOpen={isAddOpen}
setClose={setAddClose}
setSelectedRows={setSelectedRows}
fileType={fileType}
/>
{fileType === 'files' && (
<ApiStatusToast
actionType={intl.formatMessage(messages.apiStatusAddingAction)}
selectedRowCount={selectedRows.length}
isOpen={isAddOpen}
setClose={setAddClose}
setSelectedRows={setSelectedRows}
fileType={fileType}
/>
)}
<ApiStatusToast
actionType={intl.formatMessage(messages.apiStatusDownloadingAction)}

View File

@@ -92,10 +92,19 @@ const VideosPage = ({
}
return undefined;
};
if (addVideoStatus === RequestStatus.IN_PROGRESS) {
openUploadTracker();
} else {
closeUploadTracker();
switch (addVideoStatus) {
case RequestStatus.IN_PROGRESS:
openUploadTracker();
break;
case RequestStatus.SUCCESSFUL:
setTimeout(() => closeUploadTracker(), 500);
break;
case RequestStatus.FAILED:
setTimeout(() => closeUploadTracker(), 500);
break;
default:
closeUploadTracker();
break;
}
}, [addVideoStatus]);
@@ -298,6 +307,7 @@ const VideosPage = ({
isUploadTrackerOpen,
currentUploadingIdsRef: uploadingIdsRef.current,
handleUploadCancel,
addVideoStatus,
}}
/>
</Container>

View File

@@ -685,7 +685,6 @@ describe('Videos page', () => {
expect(screen.queryByText('Delete mOckID1.mp4')).toBeNull();
});
await executeThunk(deleteVideoFile(courseId, 'mOckID1', 5), store.dispatch);
await waitFor(() => {
const deleteStatus = store.getState().videos.deletingStatus;
expect(deleteStatus).toEqual(RequestStatus.FAILED);

View File

@@ -224,6 +224,7 @@ const uploadToBucket = async ({
const currentController = new AbortController();
controllers.push(currentController);
const currentVideoData = uploadingIdsRef.current.uploadData[edxVideoId];
try {
const putToServerResponse = await uploadVideo(
uploadUrl,
@@ -279,6 +280,24 @@ const uploadToBucket = async ({
}
};
const newUploadData = ({
status,
edxVideoId,
currentData,
key,
originalValue,
}) => {
const newData = currentData;
if (edxVideoId && edxVideoId !== key) {
newData[edxVideoId] = { ...originalValue, status };
delete newData[key];
return newData;
}
newData[key] = { ...originalValue, status };
return newData;
};
export function addVideoFile(
courseId,
files,
@@ -292,31 +311,38 @@ export function addVideoFile(
let hasFailure = false;
await Promise.all(files.map(async (file, idx) => {
const name = file?.name || `Video ${idx + 1}`;
const progress = 0;
uploadingIdsRef.current.uploadData = newUploadData({
status: RequestStatus.PENDING,
currentData: uploadingIdsRef.current.uploadData,
originalValue: { name, progress },
key: `video_${idx}`,
});
const { edxVideoId, uploadUrl } = await addVideoToEdxVal(courseId, file, dispatch);
if (uploadUrl && edxVideoId) {
uploadingIdsRef.current.uploadData = {
...uploadingIdsRef.current.uploadData,
[edxVideoId]: {
name,
status: RequestStatus.PENDING,
progress: 0,
},
};
uploadingIdsRef.current.uploadData = newUploadData({
status: RequestStatus.PENDING,
currentData: uploadingIdsRef.current.uploadData,
originalValue: { name, progress },
key: `video_${idx}`,
edxVideoId,
});
hasFailure = await uploadToBucket({
courseId, uploadUrl, file, uploadingIdsRef, edxVideoId, dispatch,
});
} else {
hasFailure = true;
uploadingIdsRef.current.uploadData = {
...uploadingIdsRef.current.uploadData,
[idx]: {
name,
status: RequestStatus.FAILED,
progress: 0,
},
uploadingIdsRef.current.uploadData[idx] = {
status: RequestStatus.FAILED,
name,
progress,
};
}
}));
try {
const { videos } = await fetchVideoList(courseId);
const newVideos = videos.filter(
@@ -337,11 +363,13 @@ export function addVideoFile(
updateErrors({ error: 'add', message: 'Failed to load videos' }),
);
}
if (hasFailure) {
dispatch(updateEditStatus({ editType: 'add', status: RequestStatus.FAILED }));
} else {
dispatch(updateEditStatus({ editType: 'add', status: RequestStatus.SUCCESSFUL }));
}
uploadingIdsRef.current = {
uploadData: {},
uploadCount: 0,

View File

@@ -7,8 +7,8 @@ describe('addVideoFile', () => {
const courseId = 'course-123';
const mockFile = {
name: 'mockName',
};
const uploadingIdsRef = { current: { uploadData: {} } };
beforeEach(() => {
jest.clearAllMocks();
@@ -18,7 +18,7 @@ describe('addVideoFile', () => {
status: 404,
});
await addVideoFile(courseId, [mockFile], undefined, { current: [] })(dispatch, getState);
await addVideoFile(courseId, [mockFile], undefined, uploadingIdsRef)(dispatch, getState);
expect(dispatch).toHaveBeenCalledWith({
payload: {
@@ -43,7 +43,7 @@ describe('addVideoFile', () => {
jest.spyOn(api, 'uploadVideo').mockResolvedValue({
status: 404,
});
await addVideoFile(courseId, [mockFile], undefined, { current: [] })(dispatch, getState);
await addVideoFile(courseId, [mockFile], undefined, uploadingIdsRef)(dispatch, getState);
expect(videoStatusMock).toHaveBeenCalledWith(courseId, mockEdxVideoId, 'Upload failed', 'upload_failed');
expect(dispatch).toHaveBeenCalledWith({
payload: {
@@ -70,7 +70,7 @@ describe('addVideoFile', () => {
jest.spyOn(api, 'uploadVideo').mockResolvedValue({
status: 200,
});
await addVideoFile(courseId, [mockFile], undefined, { current: [] })(dispatch, getState);
await addVideoFile(courseId, [mockFile], undefined, uploadingIdsRef)(dispatch, getState);
expect(videoStatusMock).toHaveBeenCalledWith(courseId, mockEdxVideoId, 'Upload completed', 'upload_completed');
});
});

View File

@@ -12,15 +12,18 @@ import {
import { WarningFilled } from '@openedx/paragon/icons';
import messages from '../messages';
import UploadProgressList from './UploadProgressList';
import { RequestStatus } from '../../../data/constants';
const UploadModal = ({
isUploadTrackerOpen,
handleUploadCancel,
currentUploadingIdsRef,
addVideoStatus,
}) => {
const intl = useIntl();
const videosPagePath = '';
const { uploadData, uploadCount } = currentUploadingIdsRef;
const cancelIsDisabled = addVideoStatus === RequestStatus.FAILED || addVideoStatus === RequestStatus.SUCCESSFUL;
return (
<ModalDialog
@@ -69,7 +72,7 @@ const UploadModal = ({
</Scrollable>
<ModalDialog.Footer>
<ActionRow>
<Button onClick={handleUploadCancel}>
<Button onClick={handleUploadCancel} disabled={cancelIsDisabled}>
{intl.formatMessage(messages.videoUploadTrackerAlertCancelLabel)}
</Button>
</ActionRow>
@@ -89,6 +92,7 @@ UploadModal.propTypes = {
}).isRequired,
uploadCount: PropTypes.number.isRequired,
}).isRequired,
addVideoStatus: PropTypes.string.isRequired,
};
export default UploadModal;