From 2cef43bf41c76d8c2108da21c6bf0c70b1b94313 Mon Sep 17 00:00:00 2001 From: Petr Stefan Date: Sat, 10 Feb 2018 14:42:38 +0100 Subject: [PATCH] Download supplementary & attachments files archive --- .../Exercises/FilesTable/FilesTable.js | 18 +++++++++++++++--- .../AttachmentFilesTableContainer.js | 16 ++++++++++++---- .../SupplementaryFilesTableContainer.js | 12 ++++++++++-- src/redux/modules/attachmentFiles.js | 13 ++++++++++++- src/redux/modules/supplementaryFiles.js | 13 ++++++++++++- 5 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/components/Exercises/FilesTable/FilesTable.js b/src/components/Exercises/FilesTable/FilesTable.js index 2a3214a67..64477676c 100644 --- a/src/components/Exercises/FilesTable/FilesTable.js +++ b/src/components/Exercises/FilesTable/FilesTable.js @@ -7,7 +7,7 @@ import Icon from 'react-fontawesome'; import { Table } from 'react-bootstrap'; import Button from '../../widgets/FlatButton'; import Box from '../../widgets/Box'; -import { SendIcon } from '../../icons'; +import { SendIcon, DownloadIcon } from '../../icons'; import UploadContainer from '../../../containers/UploadContainer'; import ResourceRenderer from '../../helpers/ResourceRenderer'; @@ -31,7 +31,8 @@ const FilesTable = ({ RowComponent, intl, isOpen = true, - viewOnly = false + viewOnly = false, + downloadArchive }) =>
@@ -88,6 +89,16 @@ const FilesTable = ({

}
} + {downloadArchive && +

+ +

}
; @@ -113,7 +124,8 @@ FilesTable.propTypes = { RowComponent: PropTypes.func.isRequired, intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired, isOpen: PropTypes.bool, - viewOnly: PropTypes.bool + viewOnly: PropTypes.bool, + downloadArchive: PropTypes.func }; export default injectIntl(FilesTable); diff --git a/src/containers/AttachmentFilesTableContainer/AttachmentFilesTableContainer.js b/src/containers/AttachmentFilesTableContainer/AttachmentFilesTableContainer.js index 558a40c9c..a6cec0d02 100644 --- a/src/containers/AttachmentFilesTableContainer/AttachmentFilesTableContainer.js +++ b/src/containers/AttachmentFilesTableContainer/AttachmentFilesTableContainer.js @@ -13,7 +13,8 @@ import { import { fetchAttachmentFiles, addAttachmentFiles, - removeAttachmentFile + removeAttachmentFile, + downloadAttachmentArchive } from '../../redux/modules/attachmentFiles'; import { createGetAttachmentFiles } from '../../redux/selectors/attachmentFiles'; @@ -23,7 +24,8 @@ const AttachmentFilesTableContainer = ({ attachmentFiles, loadFiles, addFiles, - removeFile + removeFile, + downloadArchive }) => ; AttachmentFilesTableContainer.propTypes = { @@ -55,7 +58,8 @@ AttachmentFilesTableContainer.propTypes = { attachmentFiles: ImmutablePropTypes.map, loadFiles: PropTypes.func.isRequired, addFiles: PropTypes.func.isRequired, - removeFile: PropTypes.func.isRequired + removeFile: PropTypes.func.isRequired, + downloadArchive: PropTypes.func }; export default connect( @@ -70,6 +74,10 @@ export default connect( (dispatch, { exercise }) => ({ loadFiles: () => dispatch(fetchAttachmentFiles(exercise.id)), addFiles: files => dispatch(addAttachmentFiles(exercise.id, files)), - removeFile: id => dispatch(removeAttachmentFile(exercise.id, id)) + removeFile: id => dispatch(removeAttachmentFile(exercise.id, id)), + downloadArchive: e => { + e.preventDefault(); + dispatch(downloadAttachmentArchive(exercise.id)); + } }) )(AttachmentFilesTableContainer); diff --git a/src/containers/SupplementaryFilesTableContainer/SupplementaryFilesTableContainer.js b/src/containers/SupplementaryFilesTableContainer/SupplementaryFilesTableContainer.js index c88ca3d47..128a980f9 100644 --- a/src/containers/SupplementaryFilesTableContainer/SupplementaryFilesTableContainer.js +++ b/src/containers/SupplementaryFilesTableContainer/SupplementaryFilesTableContainer.js @@ -13,7 +13,8 @@ import { import { fetchSupplementaryFilesForExercise, addSupplementaryFiles, - removeSupplementaryFile + removeSupplementaryFile, + downloadSupplementaryArchive } from '../../redux/modules/supplementaryFiles'; import { downloadSupplementaryFile } from '../../redux/modules/files'; @@ -27,6 +28,7 @@ const SupplementaryFilesTableContainer = ({ removeFile, downloadFile, viewOnly = false, + downloadArchive, ...props }) => ; @@ -64,7 +67,8 @@ SupplementaryFilesTableContainer.propTypes = { addFiles: PropTypes.func.isRequired, removeFile: PropTypes.func.isRequired, downloadFile: PropTypes.func.isRequired, - viewOnly: PropTypes.bool + viewOnly: PropTypes.bool, + downloadArchive: PropTypes.func }; export default connect( @@ -80,6 +84,10 @@ export default connect( downloadFile: (event, id) => { event.preventDefault(); dispatch(downloadSupplementaryFile(id)); + }, + downloadArchive: e => { + e.preventDefault(); + dispatch(downloadSupplementaryArchive(exercise.id)); } }) )(SupplementaryFilesTableContainer); diff --git a/src/redux/modules/attachmentFiles.js b/src/redux/modules/attachmentFiles.js index 3535c2a37..e394c9936 100644 --- a/src/redux/modules/attachmentFiles.js +++ b/src/redux/modules/attachmentFiles.js @@ -5,6 +5,7 @@ import factory, { resourceStatus } from '../helpers/resourceManager'; import { createApiAction } from '../middleware/apiMiddleware'; +import { downloadHelper } from '../helpers/api/download'; const resourceName = 'attachmentFiles'; const { actions, reduceActions } = factory({ resourceName }); @@ -19,7 +20,9 @@ export const actionTypes = { ADD_FILES_FULFILLED: 'recodex/attachmentFiles/ADD_FILES_FULFILLED', ADD_FILES_FAILED: 'recodex/attachmentFiles/ADD_FILES_REJECTED', REMOVE_FILE: 'recodex/attachmentFiles/REMOVE_FILE', - REMOVE_FILE_FULFILLED: 'recodex/attachmentFiles/REMOVE_FILE_FULFILLED' + REMOVE_FILE_FULFILLED: 'recodex/attachmentFiles/REMOVE_FILE_FULFILLED', + DOWNLOAD_ATTACHMENT_ARCHIVE: + 'recodex/attachmentFiles/DOWNLOAD_ATTACHMENT_ARCHIVE' }; export const fetchAttachmentFiles = exerciseId => @@ -53,6 +56,14 @@ export const removeAttachmentFile = (exerciseId, fileId) => meta: { exerciseId, fileId } }); +export const downloadAttachmentArchive = downloadHelper({ + actionType: actionTypes.DOWNLOAD_ATTACHMENT_ARCHIVE, + fetch: null, + endpoint: id => `/exercises/${id}/attachment-files/download-archive`, + fileNameSelector: (id, state) => `${id}.zip`, + contentType: 'application/zip' +}); + /** * Reducer */ diff --git a/src/redux/modules/supplementaryFiles.js b/src/redux/modules/supplementaryFiles.js index 361a4566d..5f8e2298c 100644 --- a/src/redux/modules/supplementaryFiles.js +++ b/src/redux/modules/supplementaryFiles.js @@ -5,6 +5,7 @@ import factory, { resourceStatus } from '../helpers/resourceManager'; import { createApiAction } from '../middleware/apiMiddleware'; +import { downloadHelper } from '../helpers/api/download'; const resourceName = 'supplementaryFiles'; const { actions, reduceActions } = factory({ resourceName }); @@ -19,7 +20,9 @@ export const actionTypes = { ADD_FILES_FULFILLED: 'recodex/supplementaryFiles/ADD_FILES_FULFILLED', ADD_FILES_FAILED: 'recodex/supplementaryFiles/ADD_FILES_REJECTED', REMOVE_FILE: 'recodex/supplementaryFiles/REMOVE_FILE', - REMOVE_FILE_FULFILLED: 'recodex/supplementaryFiles/REMOVE_FILE_FULFILLED' + REMOVE_FILE_FULFILLED: 'recodex/supplementaryFiles/REMOVE_FILE_FULFILLED', + DOWNLOAD_SUPPLEMENTARY_ARCHIVE: + 'recodex/supplementaryFiles/DOWNLOAD_SUPPLEMENTARY_ARCHIVE' }; export const fetchSupplementaryFilesForExercise = exerciseId => @@ -53,6 +56,14 @@ export const removeSupplementaryFile = (exerciseId, fileId) => meta: { exerciseId, fileId } }); +export const downloadSupplementaryArchive = downloadHelper({ + actionType: actionTypes.DOWNLOAD_SUPPLEMENTARY_ARCHIVE, + fetch: null, + endpoint: id => `/exercises/${id}/supplementary-files/download-archive`, + fileNameSelector: (id, state) => `${id}.zip`, + contentType: 'application/zip' +}); + /** * Reducer */