From bf8710b12b5193ab5ebc74fc017ad746ba0d6b55 Mon Sep 17 00:00:00 2001 From: soupette Date: Tue, 31 Mar 2020 16:28:12 +0200 Subject: [PATCH 01/15] Created input upload Signed-off-by: soupette --- .../src/components/InputUploadURL/Wrapper.js | 13 ++++++ .../src/components/InputUploadURL/index.js | 41 +++++++++++++++++ .../src/components/ModalNavWrapper/index.js | 4 ++ .../admin/src/components/UploadForm/index.js | 33 +++++++++++-- .../src/containers/ModalStepper/index.js | 46 +++++++++++++++---- .../src/containers/ModalStepper/reducer.js | 3 ++ .../admin/src/translations/en.json | 2 + 7 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js create mode 100644 packages/strapi-plugin-upload/admin/src/components/InputUploadURL/index.js diff --git a/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js b/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js new file mode 100644 index 0000000000..a85f70f03c --- /dev/null +++ b/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js @@ -0,0 +1,13 @@ +import styled from 'styled-components'; +import ContainerFluid from '../ContainerFluid'; + +const Wrapper = styled(ContainerFluid)` + margin-bottom: 3px; + padding-top: 23px; + + textarea { + height: 101px; + } +`; + +export default Wrapper; diff --git a/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/index.js b/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/index.js new file mode 100644 index 0000000000..4f92d943ad --- /dev/null +++ b/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/index.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { Inputs } from '@buffetjs/custom'; +import { useGlobalContext } from 'strapi-helper-plugin'; +import PropTypes from 'prop-types'; +import Wrapper from './Wrapper'; +import { getTrad } from '../../utils'; + +const InputUploadURL = ({ onChange, value }) => { + const { formatMessage } = useGlobalContext(); + const label = formatMessage({ id: getTrad('input.url.label') }); + const description = formatMessage({ id: getTrad('input.url.description') }); + + return ( + +
+
+ +
+
+
+ ); +}; + +InputUploadURL.defaultProps = { + onChange: () => {}, + value: [], +}; + +InputUploadURL.propTypes = { + onChange: PropTypes.func, + value: PropTypes.arrayOf(PropTypes.string), +}; + +export default InputUploadURL; diff --git a/packages/strapi-plugin-upload/admin/src/components/ModalNavWrapper/index.js b/packages/strapi-plugin-upload/admin/src/components/ModalNavWrapper/index.js index 5abc1e354b..ac7aa49355 100644 --- a/packages/strapi-plugin-upload/admin/src/components/ModalNavWrapper/index.js +++ b/packages/strapi-plugin-upload/admin/src/components/ModalNavWrapper/index.js @@ -13,6 +13,10 @@ const ModalNavWrapper = ({ children, links, renderRightContent, initialTab }) => const handleGoTo = link => { setTo(link.to); + + if (link.onClick) { + link.onClick(link.to); + } }; return ( diff --git a/packages/strapi-plugin-upload/admin/src/components/UploadForm/index.js b/packages/strapi-plugin-upload/admin/src/components/UploadForm/index.js index daccff9ae5..7661e1a6ad 100644 --- a/packages/strapi-plugin-upload/admin/src/components/UploadForm/index.js +++ b/packages/strapi-plugin-upload/admin/src/components/UploadForm/index.js @@ -1,13 +1,30 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import InputFileModal from '../InputFileModal'; +import InputUploadURL from '../InputUploadURL'; import ModalNavWrapper from '../ModalNavWrapper'; import ModalSection from '../ModalSection'; -const UploadForm = ({ addFilesToUpload }) => { +const UploadForm = ({ + addFilesToUpload, + filesToDownload, + onChange, + setShouldDisplayNextButton, +}) => { + useEffect(() => { + return () => { + setShouldDisplayNextButton(false); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const handleClick = to => { + setShouldDisplayNextButton(to === 'url'); + }; + const links = [ - { to: 'computer', label: 'computer', isDisabled: false }, - { to: 'url', label: 'url', isDisabled: true }, + { to: 'computer', label: 'computer', isDisabled: false, onClick: handleClick }, + { to: 'url', label: 'url', isDisabled: false, onClick: handleClick }, ]; return ( @@ -15,7 +32,7 @@ const UploadForm = ({ addFilesToUpload }) => { {to => ( {to === 'computer' && } - {to === 'url' &&
COMING SOON
} + {to === 'url' && }
)} @@ -24,10 +41,16 @@ const UploadForm = ({ addFilesToUpload }) => { UploadForm.defaultProps = { addFilesToUpload: () => {}, + filesToDownload: [], + onChange: () => {}, + setShouldDisplayNextButton: () => {}, }; UploadForm.propTypes = { addFilesToUpload: PropTypes.func, + filesToDownload: PropTypes.arrayOf(PropTypes.string), + onChange: PropTypes.func, + setShouldDisplayNextButton: PropTypes.func, }; export default UploadForm; diff --git a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js index df3e71c699..865a29cc83 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js @@ -1,6 +1,6 @@ import React, { useEffect, useState, useReducer, useRef } from 'react'; import PropTypes from 'prop-types'; -import { get } from 'lodash'; +import { get, isEmpty } from 'lodash'; import { Modal, ModalFooter, PopUpWarning, useGlobalContext, request } from 'strapi-helper-plugin'; import { Button } from '@buffetjs/core'; import pluginId from '../../pluginId'; @@ -22,8 +22,9 @@ const ModalStepper = ({ const [isWarningDeleteOpen, setIsWarningDeleteOpen] = useState(false); const [shouldDeleteFile, setShouldDeleteFile] = useState(false); const [isFormDisabled, setIsFormDisabled] = useState(false); + const [displayNextButton, setDisplayNextButton] = useState(false); const [reducerState, dispatch] = useReducer(reducer, initialState, init); - const { currentStep, fileToEdit, filesToUpload } = reducerState.toJS(); + const { currentStep, fileToEdit, filesToDownload, filesToUpload } = reducerState.toJS(); const { Component, components, headerBreadcrumbs, next, prev, withBackButton } = stepper[ currentStep ]; @@ -32,10 +33,10 @@ const ModalStepper = ({ const editModalRef = useRef(); useEffect(() => { - if (currentStep === 'upload' && filesToUploadLength === 0) { - // Passing true to the onToggle prop will refetch the data when the modal closes - toggleRef.current(true); - } + // if (currentStep === 'upload' && filesToUploadLength === 0) { + // // Passing true to the onToggle prop will refetch the data when the modal closes + // toggleRef.current(true); + // } }, [filesToUploadLength, currentStep]); useEffect(() => { @@ -86,10 +87,18 @@ const ModalStepper = ({ }; const handleChange = ({ target: { name, value } }) => { + let val = value; + let type = 'ON_CHANGE'; + + if (name === 'url') { + val = value.split('\n'); + type = 'ON_CHANGE_URLS_TO_DOWNLOAD'; + } + dispatch({ - type: 'ON_CHANGE', + type, keys: name, - value, + value: val, }); }; @@ -98,6 +107,12 @@ const ModalStepper = ({ toggleModalWarning(); }; + const handleClickNextButton = () => { + // Navigate to next step + // goNext(); + // validate the form + }; + const handleClickDeleteFile = async () => { toggleModalWarning(); }; @@ -120,6 +135,7 @@ const ModalStepper = ({ const handleClose = () => { onClosed(); setIsFormDisabled(false); + setDisplayNextButton(false); dispatch({ type: 'RESET_PROPS', @@ -307,6 +323,8 @@ const ModalStepper = ({ setIsWarningDeleteOpen(prev => !prev); }; + const shouldDisplayNextButton = currentStep === 'browse' && displayNextButton; + return ( <> @@ -323,6 +341,7 @@ const ModalStepper = ({ onAbortUpload={handleAbortUpload} addFilesToUpload={addFilesToUpload} fileToEdit={fileToEdit} + filesToDownload={filesToDownload} filesToUpload={filesToUpload} components={components} isEditingUploadedFile={currentStep === 'edit'} @@ -341,6 +360,7 @@ const ModalStepper = ({ toggleDisableForm={setIsFormDisabled} ref={currentStep === 'edit' ? editModalRef : null} setCropResult={handleSetCropResult} + setShouldDisplayNextButton={setDisplayNextButton} withBackButton={withBackButton} /> )} @@ -350,6 +370,16 @@ const ModalStepper = ({ + {shouldDisplayNextButton && ( + + )} {currentStep === 'upload' && ( )} {currentStep === 'upload' && ( - {currentStep === 'upload' && ( - )} + {shouldDisplayNextButton && ( + + )} {currentStep === 'edit-new' && ( )} {currentStep === 'edit-new' && ( diff --git a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js index 6b6242be8a..ee369a768b 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js @@ -105,8 +105,6 @@ const InputModalStepperProvider = ({ }; const handleClickNextButton = () => { - // Navigate to next step - // goNext(); dispatch({ type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', nextStep: 'upload', @@ -257,8 +255,10 @@ const InputModalStepperProvider = ({ // Cancel upload if (source) { + // Cancel dowload file upload with axios source.cancel('Operation canceled by the user.'); } else { + // Cancel uplodad file with fetch fileToCancel.abortController.abort(); } diff --git a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js index c899b65192..a907d4ae9a 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js @@ -41,6 +41,7 @@ const ModalStepper = ({ // Passing true to the onToggle prop will refetch the data when the modal closes toggleRef.current(true); } else { + // Download files from url downloadFilesRef.current(); } } @@ -85,6 +86,7 @@ const ModalStepper = ({ headers: new Headers({ Origin: window.location.origin, mode: 'cors' }), responseType: 'blob', cancelToken: source.token, + // Should we add a timeout? }) .then(({ data }) => { const createdFile = new File([data], file.fileURL, { @@ -128,10 +130,12 @@ const ModalStepper = ({ const fileToCancel = filesToUpload.find(file => file.originalIndex === fileOriginalIndex); const { source } = fileToCancel; + // Cancel if (source) { + // Cancel dowload file upload with axios source.cancel('Operation canceled by the user.'); } else { - // Cancel upload + // Cancel upload with fetch fileToCancel.abortController.abort(); } @@ -164,7 +168,6 @@ const ModalStepper = ({ const handleClickNextButton = () => { // Navigate to next step - // goNext(); dispatch({ type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', nextStep: next, @@ -358,8 +361,6 @@ const ModalStepper = ({ goTo(prev); }; - // FIXME: when back button needed - // eslint-disable-next-line no-unused-vars const goNext = () => { if (next === null) { onToggle(); @@ -436,7 +437,7 @@ const ModalStepper = ({ onClick={handleClickNextButton} disabled={isEmpty(filesToDownload)} > - Next + {formatMessage({ id: getTrad('button.next') })} )} {currentStep === 'upload' && ( diff --git a/packages/strapi-plugin-upload/admin/src/translations/en.json b/packages/strapi-plugin-upload/admin/src/translations/en.json index 0877d543d0..af2fbfa6b3 100644 --- a/packages/strapi-plugin-upload/admin/src/translations/en.json +++ b/packages/strapi-plugin-upload/admin/src/translations/en.json @@ -1,4 +1,5 @@ { + "button.next": "Next", "checkControl.crop-original": "Crop the original asset", "checkControl.crop-duplicate": "Duplicate & crop the asset", "control-card.add": "Add", From 913e97221be7c255147e2c9173cd77da4eb7615b Mon Sep 17 00:00:00 2001 From: soupette Date: Wed, 1 Apr 2020 09:40:05 +0200 Subject: [PATCH 12/15] Add tests to modalstepper reducer Signed-off-by: soupette --- .../ModalStepper/tests/reducer.test.js | 438 ++++++++++++++++++ .../utils/createNewFilesToDownloadArray.js | 2 - .../admin/src/utils/getFilesToDownload.js | 2 +- .../createNewFilesToDownloadArray.test.js | 2 +- .../utils/tests/getFilesToDownload.test.js | 36 ++ 5 files changed, 476 insertions(+), 4 deletions(-) create mode 100644 packages/strapi-plugin-upload/admin/src/utils/tests/getFilesToDownload.test.js diff --git a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js index 044866736d..9d37694460 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js @@ -184,6 +184,188 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { }); }); + describe('ADD_URLS_TO_FILES_TO_DOWNLOAD', () => { + it('should add the files to the empty filesToUpload array and update the current step', () => { + const action = { + type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + nextStep: 'test', + }; + const state = fromJS({ + currentStep: 'browse', + filesToUpload: [], + filesToDownload: ['test', 'test1'], + }); + const expected = fromJS({ + currentStep: 'test', + filesToDownload: [], + filesToUpload: [ + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test', + }, + originalIndex: 0, + fileURL: 'test', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 1, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }); + + const received = reducer(state, action); + + expect(received.get('currentStep')).toEqual(expected.get('currentStep')); + expect(received.get('filesToDownload')).toEqual(expected.get('filesToDownload')); + expect(received.get('filesToUpload').toJS()).toEqual( + expect.arrayContaining([ + expect.objectContaining(expected.getIn(['filesToUpload', '0']).toJS()), + expect.objectContaining(expected.getIn(['filesToUpload', '1']).toJS()), + ]) + ); + }); + + it('should add the files to the (not empty) filesToUpload array and update the current step', () => { + const state = fromJS({ + currentStep: 'browse', + filesToDownload: ['test2', 'test3'], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }); + const action = { + type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + nextStep: 'test', + }; + + const expected = fromJS({ + currentStep: 'test', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test2', + }, + originalIndex: 2, + fileURL: 'test2', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 3, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test3', + }, + originalIndex: 3, + fileURL: 'test3', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 4, + }, + ], + }); + + const received = reducer(state, action); + + expect(received.get('currentStep')).toEqual(expected.get('currentStep')); + expect(received.get('filesToDownload')).toEqual(expected.get('filesToDownload')); + expect(received.get('filesToUpload').toJS()).toEqual( + expect.arrayContaining([ + expect.objectContaining(expected.getIn(['filesToUpload', '0']).toJS()), + expect.objectContaining(expected.getIn(['filesToUpload', '1']).toJS()), + expect.objectContaining(expected.getIn(['filesToUpload', '2']).toJS()), + expect.objectContaining(expected.getIn(['filesToUpload', '3']).toJS()), + ]) + ); + }); + }); + describe('CLEAN_FILES_ERROR', () => { it('should not change the filesToUpload property if it is empty', () => { const action = { @@ -263,6 +445,159 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { expect(reducer(state, action)).toEqual(expected); }); + + it('should not change the data containing a defined tempId key', () => { + const action = { + type: 'CLEAN_FILES_ERROR', + }; + const state = fromJS({ + currentStep: 'test', + filesToUpload: [ + { + abortController: new AbortController(), + file: { ok: true }, + hasError: true, + errorMessage: 'error1', + isUploading: false, + originalIndex: 0, + }, + { + abortController: new AbortController(), + file: { test: true }, + hasError: true, + errorMessage: 'error2', + isUploading: false, + originalIndex: 1, + tempId: 1, + }, + { + abortController: new AbortController(), + file: { test: false }, + hasError: true, + errorMessage: 'error3', + isUploading: false, + originalIndex: 2, + }, + ], + }); + + const expected = fromJS({ + currentStep: 'test', + filesToUpload: [ + { + abortController: new AbortController(), + file: { ok: true }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + }, + { + abortController: new AbortController(), + file: { test: true }, + hasError: true, + errorMessage: 'error2', + isUploading: false, + originalIndex: 1, + tempId: 1, + }, + { + abortController: new AbortController(), + file: { test: false }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 2, + }, + ], + }); + + expect(reducer(state, action)).toEqual(expected); + }); + }); + + describe('FILE_DOWLOADED', () => { + it('should update the corresponding file', () => { + const state = fromJS({ + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }); + + const action = { + type: 'FILE_DOWNLOADED', + fileTempId: 2, + blob: 'test', + }; + + const expected = fromJS({ + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: 'test', + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: false, + tempId: 2, + }, + ], + }); + + expect(reducer(state, action)).toEqual(expected); + }); }); describe('GO_TO', () => { @@ -355,6 +690,26 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { }); }); + describe('ON_CHANGE_URLS_TO_DOWNLOAD', () => { + it('should change the data correctly', () => { + const action = { + type: 'ON_CHANGE_URLS_TO_DOWNLOAD', + keys: 'test', + value: ['test 1', 'test 2'], + }; + const state = fromJS({ + filesToDownload: [], + currentStep: 'test', + }); + const expected = fromJS({ + filesToDownload: ['test 1', 'test 2'], + currentStep: 'test', + }); + + expect(reducer(state, action)).toEqual(expected); + }); + }); + describe('ON_SUBMIT_EDIT_EXISTING_FILE', () => { it('should set the isUploading key to false', () => { const action = { @@ -564,6 +919,89 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { }); }); + describe('SET_FILE_TO_DOWNLOAD_ERROR', () => { + it('should update the specified file error', () => { + const state = fromJS({ + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }); + + const action = { + type: 'SET_FILE_TO_DOWNLOAD_ERROR', + fileTempId: 2, + }; + + const expected = fromJS({ + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: true, + errorMessage: 'test1', + isUploading: false, + isDownloading: false, + tempId: 2, + }, + ], + }); + + expect(reducer(state, action)).toEqual(expected); + }); + }); + describe('SET_FILE_ERROR', () => { it('should update the specified file error', () => { const action = { diff --git a/packages/strapi-plugin-upload/admin/src/utils/createNewFilesToDownloadArray.js b/packages/strapi-plugin-upload/admin/src/utils/createNewFilesToDownloadArray.js index 661bed17fc..240accef11 100644 --- a/packages/strapi-plugin-upload/admin/src/utils/createNewFilesToDownloadArray.js +++ b/packages/strapi-plugin-upload/admin/src/utils/createNewFilesToDownloadArray.js @@ -19,8 +19,6 @@ const createNewFilesToDownloadArray = (filesURLArray, alreadyUploadedFiles) => { } const CancelToken = axios.CancelToken; - - // TODO change with axios cancel request const abortController = new AbortController(); const source = CancelToken.source(); diff --git a/packages/strapi-plugin-upload/admin/src/utils/getFilesToDownload.js b/packages/strapi-plugin-upload/admin/src/utils/getFilesToDownload.js index cc7a815498..07d3ba1c0a 100644 --- a/packages/strapi-plugin-upload/admin/src/utils/getFilesToDownload.js +++ b/packages/strapi-plugin-upload/admin/src/utils/getFilesToDownload.js @@ -1,5 +1,5 @@ const getFilesToDownload = files => { - return files.filter(file => file.isDownloading); + return files.filter(file => file.isDownloading === true); }; export default getFilesToDownload; diff --git a/packages/strapi-plugin-upload/admin/src/utils/tests/createNewFilesToDownloadArray.test.js b/packages/strapi-plugin-upload/admin/src/utils/tests/createNewFilesToDownloadArray.test.js index 55f2327ec2..7815b924f2 100644 --- a/packages/strapi-plugin-upload/admin/src/utils/tests/createNewFilesToDownloadArray.test.js +++ b/packages/strapi-plugin-upload/admin/src/utils/tests/createNewFilesToDownloadArray.test.js @@ -4,7 +4,7 @@ import createNewFilesToDownloadArray, { } from '../createNewFilesToDownloadArray'; describe('UPLOAD | utils', () => { - describe('CreateNewFilesToDownloadArray', () => { + describe('createNewFilesToDownloadArray', () => { it('should create an array containing the formatted data and filter the empty data', () => { const dataURLArray = ['', 'un', undefined, 'deux', null, 'trois']; const dataFilesArray = [ diff --git a/packages/strapi-plugin-upload/admin/src/utils/tests/getFilesToDownload.test.js b/packages/strapi-plugin-upload/admin/src/utils/tests/getFilesToDownload.test.js new file mode 100644 index 0000000000..a95cab38cf --- /dev/null +++ b/packages/strapi-plugin-upload/admin/src/utils/tests/getFilesToDownload.test.js @@ -0,0 +1,36 @@ +import getFilesToDownload from '../getFilesToDownload'; + +describe('UPLOAD | utils | getFilesToDownload', () => { + it('should return an array containing only the files that have the isDownloading key to true', () => { + const data = [ + { + fileURL: '1', + isDownloading: undefined, + }, + { + fileURL: '2', + isDownloading: null, + }, + { + fileURL: '3', + isDownloading: 'true', + }, + { + fileURL: '4', + isDownloading: false, + }, + { + fileURL: '5', + isDownloading: true, + }, + ]; + const expected = [ + { + fileURL: '5', + isDownloading: true, + }, + ]; + + expect(getFilesToDownload(data)).toEqual(expected); + }); +}); From b352e80236ceb39ed305f1dead74b8fe946df5f1 Mon Sep 17 00:00:00 2001 From: soupette Date: Wed, 1 Apr 2020 10:05:00 +0200 Subject: [PATCH 13/15] Add tests to inputmodalstepper reducer Signed-off-by: soupette --- .../tests/reducer.test.js | 395 ++++++++++++++++++ 1 file changed, 395 insertions(+) diff --git a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js index d9b9b5b760..c1e4ba1e53 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js +++ b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js @@ -170,6 +170,188 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { }); }); + describe('ADD_URLS_TO_FILES_TO_DOWNLOAD', () => { + it('should add the files to the empty filesToUpload array and update the current step', () => { + const action = { + type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + nextStep: 'test', + }; + const state = { + currentStep: 'browse', + filesToUpload: [], + filesToDownload: ['test', 'test1'], + }; + const expected = { + currentStep: 'test', + filesToDownload: [], + filesToUpload: [ + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test', + }, + originalIndex: 0, + fileURL: 'test', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 1, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }; + + const received = reducer(state, action); + + expect(received.currentStep).toEqual(expected.currentStep); + expect(received.filesToDownload).toEqual(expected.filesToDownload); + expect(received.filesToUpload).toEqual( + expect.arrayContaining([ + expect.objectContaining(expected.filesToUpload[0]), + expect.objectContaining(expected.filesToUpload[1]), + ]) + ); + }); + + it('should add the files to the (not empty) filesToUpload array and update the current step', () => { + const state = { + currentStep: 'browse', + filesToDownload: ['test2', 'test3'], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }; + const action = { + type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + nextStep: 'test', + }; + + const expected = { + currentStep: 'test', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test2', + }, + originalIndex: 2, + fileURL: 'test2', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 3, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test3', + }, + originalIndex: 3, + fileURL: 'test3', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 4, + }, + ], + }; + + const received = reducer(state, action); + + expect(received.currentStep).toEqual(expected.currentStep); + expect(received.filesToDownload).toEqual(expected.filesToDownload); + expect(received.filesToUpload).toEqual( + expect.arrayContaining([ + expect.objectContaining(expected.filesToUpload[0]), + expect.objectContaining(expected.filesToUpload[1]), + expect.objectContaining(expected.filesToUpload[2]), + expect.objectContaining(expected.filesToUpload[3]), + ]) + ); + }); + }); + describe('CLEAN_FILES_ERROR', () => { it('should not change the filesToUpload property if it is empty', () => { const action = { @@ -251,6 +433,219 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { }); }); + describe('FILE_DOWLOADED', () => { + it('should update the corresponding file', () => { + const state = { + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }; + + const action = { + type: 'FILE_DOWNLOADED', + fileTempId: 2, + blob: 'test', + }; + + const expected = { + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: 'test', + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: false, + tempId: 2, + }, + ], + }; + + expect(reducer(state, action)).toEqual(expected); + }); + }); + + describe('ON_CHANGE', () => { + it('should change the data correctly', () => { + const action = { + type: 'ON_CHANGE', + keys: 'test', + value: 'test 1', + }; + const state = { + fileToEdit: { + test: 'test', + isUploading: true, + }, + currentStep: 'test', + }; + const expected = { + fileToEdit: { + test: 'test 1', + isUploading: true, + }, + currentStep: 'test', + }; + + expect(reducer(state, action)).toEqual(expected); + }); + }); + + describe('ON_CHANGE_URLS_TO_DOWNLOAD', () => { + it('should change the data correctly', () => { + const action = { + type: 'ON_CHANGE_URLS_TO_DOWNLOAD', + keys: 'test', + value: ['test 1', 'test 2'], + }; + const state = { + filesToDownload: [], + currentStep: 'test', + }; + const expected = { + filesToDownload: ['test 1', 'test 2'], + currentStep: 'test', + }; + + expect(reducer(state, action)).toEqual(expected); + }); + }); + + describe('SET_FILE_TO_DOWNLOAD_ERROR', () => { + it('should update the specified file error', () => { + const state = { + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: false, + errorMessage: null, + isUploading: false, + isDownloading: true, + tempId: 2, + }, + ], + }; + + const action = { + type: 'SET_FILE_TO_DOWNLOAD_ERROR', + fileTempId: 2, + }; + + const expected = { + currentStep: 'browse', + filesToDownload: [], + filesToUpload: [ + { + abortController: new AbortController(), + file: { name: 'test1', ok: true }, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + hasError: false, + errorMessage: null, + isUploading: false, + originalIndex: 0, + tempId: null, + }, + { + file: null, + fileInfo: { + alternativeText: '', + caption: '', + name: 'test1', + }, + originalIndex: 1, + fileURL: 'test1', + hasError: true, + errorMessage: 'test1', + isUploading: false, + isDownloading: false, + tempId: 2, + }, + ], + }; + + expect(reducer(state, action)).toEqual(expected); + }); + }); + describe('TOGGLE_SELECT_ALL', () => { it('should select all files', () => { const action = { From d0ae68d7425ec4768b3277c8fc614f4ce9367cdf Mon Sep 17 00:00:00 2001 From: soupette Date: Wed, 1 Apr 2020 10:42:08 +0200 Subject: [PATCH 14/15] Fix PR feedback Signed-off-by: soupette --- .../src/components/InputUploadURL/Wrapper.js | 6 +-- .../InputModalStepperProvider/index.js | 2 +- .../InputModalStepperProvider/reducer.js | 37 +++++++++---------- .../tests/reducer.test.js | 6 +-- .../src/containers/ModalStepper/index.js | 2 +- .../src/containers/ModalStepper/reducer.js | 2 +- .../ModalStepper/tests/reducer.test.js | 6 +-- 7 files changed, 29 insertions(+), 32 deletions(-) diff --git a/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js b/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js index a85f70f03c..c7f6f53b18 100644 --- a/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js +++ b/packages/strapi-plugin-upload/admin/src/components/InputUploadURL/Wrapper.js @@ -2,11 +2,11 @@ import styled from 'styled-components'; import ContainerFluid from '../ContainerFluid'; const Wrapper = styled(ContainerFluid)` - margin-bottom: 3px; - padding-top: 23px; + margin-bottom: 0.3rem; + padding-top: 2.3rem; textarea { - height: 101px; + height: 10.1rem; } `; diff --git a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js index ee369a768b..430c4e8878 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js @@ -106,7 +106,7 @@ const InputModalStepperProvider = ({ const handleClickNextButton = () => { dispatch({ - type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + type: 'ADD_URLS_TO_FILES_TO_UPLOAD', nextStep: 'upload', }); }; diff --git a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/reducer.js b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/reducer.js index 7b7ba63a4c..872cd47079 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/reducer.js +++ b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/reducer.js @@ -29,7 +29,7 @@ const reducer = (state, action) => // eslint-disable-next-line consistent-return produce(state, draftState => { switch (action.type) { - case 'ADD_URLS_TO_FILES_TO_DOWNLOAD': { + case 'ADD_URLS_TO_FILES_TO_UPLOAD': { draftState.filesToUpload = [ ...draftState.filesToUpload, ...createNewFilesToDownloadArray(draftState.filesToDownload, draftState.filesToUpload), @@ -43,15 +43,13 @@ const reducer = (state, action) => break; } case 'FILE_DOWNLOADED': { - draftState.filesToUpload.forEach((file, index) => { - if (file.tempId === action.fileTempId) { - draftState.filesToUpload[index] = { - ...draftState.filesToUpload[index], - isDownloading: false, - file: action.blob, - }; - } - }); + const index = state.filesToUpload.findIndex(file => file.tempId === action.fileTempId); + + draftState.filesToUpload[index] = { + ...draftState.filesToUpload[index], + isDownloading: false, + file: action.blob, + }; break; } @@ -210,16 +208,15 @@ const reducer = (state, action) => break; } case 'SET_FILE_TO_DOWNLOAD_ERROR': { - draftState.filesToUpload.forEach((file, index) => { - if (file.tempId === action.fileTempId) { - draftState.filesToUpload[index] = { - ...draftState.filesToUpload[index], - isDownloading: false, - hasError: true, - errorMessage: draftState.filesToUpload[index].fileURL, - }; - } - }); + const index = state.filesToUpload.findIndex(file => file.tempId === action.fileTempId); + + draftState.filesToUpload[index] = { + ...draftState.filesToUpload[index], + isDownloading: false, + hasError: true, + errorMessage: draftState.filesToUpload[index].fileURL, + }; + break; } case 'SET_FORM_DISABLED': { diff --git a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js index c1e4ba1e53..7e8dd18d8d 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js +++ b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/tests/reducer.test.js @@ -170,10 +170,10 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { }); }); - describe('ADD_URLS_TO_FILES_TO_DOWNLOAD', () => { + describe('ADD_URLS_TO_FILES_TO_UPLOAD', () => { it('should add the files to the empty filesToUpload array and update the current step', () => { const action = { - type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + type: 'ADD_URLS_TO_FILES_TO_UPLOAD', nextStep: 'test', }; const state = { @@ -267,7 +267,7 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { ], }; const action = { - type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + type: 'ADD_URLS_TO_FILES_TO_UPLOAD', nextStep: 'test', }; diff --git a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js index 0ddc946ba4..bacf61845a 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js @@ -169,7 +169,7 @@ const ModalStepper = ({ const handleClickNextButton = () => { // Navigate to next step dispatch({ - type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + type: 'ADD_URLS_TO_FILES_TO_UPLOAD', nextStep: next, }); }; diff --git a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/reducer.js b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/reducer.js index a9ebf5c4ba..7968924c29 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/reducer.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/reducer.js @@ -19,7 +19,7 @@ const reducer = (state, action) => { .map((data, index) => data.set('originalIndex', index)) ) .update('currentStep', () => action.nextStep); - case 'ADD_URLS_TO_FILES_TO_DOWNLOAD': + case 'ADD_URLS_TO_FILES_TO_UPLOAD': return state .update('filesToUpload', list => list diff --git a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js index 9d37694460..1eee7450e3 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/tests/reducer.test.js @@ -184,10 +184,10 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { }); }); - describe('ADD_URLS_TO_FILES_TO_DOWNLOAD', () => { + describe('ADD_URLS_TO_FILES_TO_UPLOAD', () => { it('should add the files to the empty filesToUpload array and update the current step', () => { const action = { - type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + type: 'ADD_URLS_TO_FILES_TO_UPLOAD', nextStep: 'test', }; const state = fromJS({ @@ -281,7 +281,7 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => { ], }); const action = { - type: 'ADD_URLS_TO_FILES_TO_DOWNLOAD', + type: 'ADD_URLS_TO_FILES_TO_UPLOAD', nextStep: 'test', }; From a941a8ac512e5e352bd035df1de966b42d6682d5 Mon Sep 17 00:00:00 2001 From: soupette Date: Wed, 1 Apr 2020 11:02:03 +0200 Subject: [PATCH 15/15] Improve Card Signed-off-by: soupette --- .../admin/src/components/Card/index.js | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/strapi-plugin-upload/admin/src/components/Card/index.js b/packages/strapi-plugin-upload/admin/src/components/Card/index.js index 3f2b51ecfb..7757c17275 100644 --- a/packages/strapi-plugin-upload/admin/src/components/Card/index.js +++ b/packages/strapi-plugin-upload/admin/src/components/Card/index.js @@ -51,13 +51,21 @@ const Card = ({ {children} - - {!withoutFileInfo && name}  - {!withoutFileInfo && } - - - {!withoutFileInfo && `${getExtension(fileType)} - ${fileSize}`} - + + {!withoutFileInfo ? ( + <> + + {name} + + + + {!withoutFileInfo && `${getExtension(fileType)} - ${fileSize}`} + + + ) : ( + + )} + {hasError && {errorMessage}} );