From 2213d36f9c9940bbd38843953e8b36efc27e304e Mon Sep 17 00:00:00 2001 From: mfrachet Date: Wed, 22 Sep 2021 14:39:38 +0200 Subject: [PATCH 1/5] ml iterations --- .../src/components/PaginationFooter/index.js | 32 ++++++++ .../src/pages/App/components/ListView.js | 73 ++++++++++--------- 2 files changed, 72 insertions(+), 33 deletions(-) create mode 100644 packages/core/upload/admin/src/components/PaginationFooter/index.js diff --git a/packages/core/upload/admin/src/components/PaginationFooter/index.js b/packages/core/upload/admin/src/components/PaginationFooter/index.js new file mode 100644 index 0000000000..7387ae50e6 --- /dev/null +++ b/packages/core/upload/admin/src/components/PaginationFooter/index.js @@ -0,0 +1,32 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Box, Row } from '@strapi/parts'; +import { PaginationURLQuery, PageSizeURLQuery } from '@strapi/helper-plugin'; + +export const PaginationFooter = ({ pagination }) => { + return ( + + + + + + + ); +}; + +PaginationFooter.defaultProps = { + pagination: { + pageCount: 0, + pageSize: 10, + total: 0, + }, +}; + +PaginationFooter.propTypes = { + pagination: PropTypes.shape({ + page: PropTypes.number, + pageCount: PropTypes.number, + pageSize: PropTypes.number, + total: PropTypes.number, + }), +}; diff --git a/packages/core/upload/admin/src/pages/App/components/ListView.js b/packages/core/upload/admin/src/pages/App/components/ListView.js index 3c35313d2e..31af2784c4 100644 --- a/packages/core/upload/admin/src/pages/App/components/ListView.js +++ b/packages/core/upload/admin/src/pages/App/components/ListView.js @@ -7,50 +7,57 @@ import { ImageAssetCard } from '../../../components/AssetCard/ImageAssetCard'; import { VideoAssetCard } from '../../../components/AssetCard/VideoAssetCard'; import { DocAssetCard } from '../../../components/AssetCard/DocAssetCard'; import { AssetType } from '../../../constants'; +import { PaginationFooter } from '../../../components/PaginationFooter'; export const ListView = ({ assets }) => { return ( - - - {assets.map(asset => { - if (asset.mime.includes(AssetType.Video)) { + <> + + + {assets.map(asset => { + if (asset.mime.includes(AssetType.Video)) { + return ( + + ); + } + + if (asset.mime.includes(AssetType.Image)) { + return ( + + ); + } + return ( - ); - } + })} + + - if (asset.mime.includes(AssetType.Image)) { - return ( - - ); - } - - return ( - - ); - })} - - + + ); }; From d7a2affe48dce64e25ad41abbad8c424055661a0 Mon Sep 17 00:00:00 2001 From: mfrachet Date: Wed, 22 Sep 2021 15:17:33 +0200 Subject: [PATCH 2/5] Cancelling assets --- .../components/AssetCard/UploadingAssetCard.js | 15 ++++++++++++--- .../PendingAssetStep/PendingAssetStep.js | 4 +++- .../tests/PendingAssetStep.test.js | 1 + .../UploadAssetDialog/UploadAssetDialog.js | 17 ++++++++++++++++- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js b/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js index a97f906631..165ca9950f 100644 --- a/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js +++ b/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js @@ -53,7 +53,7 @@ const CancelButton = styled.button` } `; -export const UploadingAssetCard = ({ name, extension, assetType, file }) => { +export const UploadingAssetCard = ({ name, extension, assetType, file, onCancel }) => { const { upload, cancel, error, progress } = useUpload(); const { formatMessage } = useIntl(); @@ -78,9 +78,17 @@ export const UploadingAssetCard = ({ name, extension, assetType, file }) => { useEffect(() => { upload(file); + + return () => { + cancel(); + }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const handleCancel = () => { + onCancel(file); + }; + return ( @@ -97,11 +105,11 @@ export const UploadingAssetCard = ({ name, extension, assetType, file }) => { <> - {progress}/100% + {`${progress}/100%`} - + {formatMessage({ id: 'app.components.Button.cancel', @@ -142,4 +150,5 @@ UploadingAssetCard.propTypes = { extension: PropTypes.string.isRequired, name: PropTypes.string.isRequired, file: PropTypes.instanceOf(File).isRequired, + onCancel: PropTypes.func.isRequired, }; diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js index c4625870c0..34ec2a89aa 100644 --- a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +++ b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js @@ -16,7 +16,7 @@ import { UploadingAssetCard } from '../../AssetCard/UploadingAssetCard'; import { getTrad } from '../../../utils'; import { AssetType, AssetSource } from '../../../constants'; -export const PendingAssetStep = ({ onClose, assets, onClickAddAsset }) => { +export const PendingAssetStep = ({ onClose, assets, onClickAddAsset, onCancelUpload }) => { const { formatMessage } = useIntl(); const [isUploading, setIsUploading] = useState(false); @@ -79,6 +79,7 @@ export const PendingAssetStep = ({ onClose, assets, onClickAddAsset }) => { assetType={asset.type} file={asset.rawFile} size="S" + onCancel={onCancelUpload} /> ); @@ -173,4 +174,5 @@ PendingAssetStep.propTypes = { ).isRequired, onClose: PropTypes.func.isRequired, onClickAddAsset: PropTypes.func.isRequired, + onCancelUpload: PropTypes.func.isRequired, }; diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js index 8e1e9bea7c..42b7fb98c9 100644 --- a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js +++ b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js @@ -62,6 +62,7 @@ describe('PendingAssetStep', () => { onClose={jest.fn()} onAddAsset={jest.fn()} onClickAddAsset={jest.fn()} + onCancelUpload={jest.fn()} /> diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js b/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js index 65926b8e40..b47838857a 100644 --- a/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js +++ b/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js @@ -23,13 +23,28 @@ export const UploadAssetDialog = ({ onSuccess, onClose }) => { setStep(Steps.AddAsset); }; + const handleCancelUpload = file => { + const nextAssets = assets.filter(asset => asset.rawFile !== file); + setAssets(nextAssets); + + // When there's no asset, transition to the AddAsset step + if (nextAssets.length === 0) { + moveToAddAsset(); + } + }; + return ( {step === Steps.AddAsset && ( )} {step === Steps.PendingAsset && ( - + )} ); From 955a98eeb0aa66dbd7b18cf99492d200b339cade Mon Sep 17 00:00:00 2001 From: mfrachet Date: Wed, 22 Sep 2021 16:12:59 +0200 Subject: [PATCH 3/5] Cancelling assets --- .../AssetCard/UploadingAssetCard.js | 21 +++++++++++++------ .../PendingAssetStep/PendingAssetStep.js | 20 +++++++++++++++--- .../tests/PendingAssetStep.test.js | 1 + .../UploadAssetDialog/UploadAssetDialog.js | 10 +++++++++ .../core/upload/admin/src/hooks/useUpload.js | 8 ++++++- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js b/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js index 165ca9950f..5d40a3625c 100644 --- a/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js +++ b/packages/core/upload/admin/src/components/AssetCard/UploadingAssetCard.js @@ -53,8 +53,15 @@ const CancelButton = styled.button` } `; -export const UploadingAssetCard = ({ name, extension, assetType, file, onCancel }) => { - const { upload, cancel, error, progress } = useUpload(); +export const UploadingAssetCard = ({ + name, + extension, + assetType, + file, + onCancel, + onStatusChange, +}) => { + const { upload, cancel, error, progress, status } = useUpload(); const { formatMessage } = useIntl(); let badgeContent; @@ -78,14 +85,15 @@ export const UploadingAssetCard = ({ name, extension, assetType, file, onCancel useEffect(() => { upload(file); - - return () => { - cancel(); - }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + onStatusChange(status); + }, [status, onStatusChange]); + const handleCancel = () => { + cancel(); onCancel(file); }; @@ -151,4 +159,5 @@ UploadingAssetCard.propTypes = { name: PropTypes.string.isRequired, file: PropTypes.instanceOf(File).isRequired, onCancel: PropTypes.func.isRequired, + onStatusChange: PropTypes.func.isRequired, }; diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js index 34ec2a89aa..4d614da392 100644 --- a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +++ b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js @@ -16,7 +16,13 @@ import { UploadingAssetCard } from '../../AssetCard/UploadingAssetCard'; import { getTrad } from '../../../utils'; import { AssetType, AssetSource } from '../../../constants'; -export const PendingAssetStep = ({ onClose, assets, onClickAddAsset, onCancelUpload }) => { +export const PendingAssetStep = ({ + onClose, + assets, + onClickAddAsset, + onCancelUpload, + onUploadSucceed, +}) => { const { formatMessage } = useIntl(); const [isUploading, setIsUploading] = useState(false); @@ -26,6 +32,12 @@ export const PendingAssetStep = ({ onClose, assets, onClickAddAsset, onCancelUpl setIsUploading(true); }; + const handleStatusChange = (status, file) => { + if (status === 'success') { + onUploadSucceed(file); + } + }; + return (
@@ -66,8 +78,8 @@ export const PendingAssetStep = ({ onClose, assets, onClickAddAsset, onCancelUpl - {assets.map((asset, idx) => { - const assetKey = `${asset.url}-${idx}`; + {assets.map(asset => { + const assetKey = asset.url; if (isUploading) { return ( @@ -80,6 +92,7 @@ export const PendingAssetStep = ({ onClose, assets, onClickAddAsset, onCancelUpl file={asset.rawFile} size="S" onCancel={onCancelUpload} + onStatusChange={status => handleStatusChange(status, asset.rawFile)} /> ); @@ -174,5 +187,6 @@ PendingAssetStep.propTypes = { ).isRequired, onClose: PropTypes.func.isRequired, onClickAddAsset: PropTypes.func.isRequired, + onUploadSucceed: PropTypes.func.isRequired, onCancelUpload: PropTypes.func.isRequired, }; diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js index 42b7fb98c9..682d6c801e 100644 --- a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js +++ b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/tests/PendingAssetStep.test.js @@ -63,6 +63,7 @@ describe('PendingAssetStep', () => { onAddAsset={jest.fn()} onClickAddAsset={jest.fn()} onCancelUpload={jest.fn()} + onUploadSucceed={jest.fn()} /> diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js b/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js index b47838857a..28ff32ac8c 100644 --- a/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js +++ b/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js @@ -33,6 +33,15 @@ export const UploadAssetDialog = ({ onSuccess, onClose }) => { } }; + const handleUploadSuccess = file => { + const nextAssets = assets.filter(asset => asset.rawFile !== file); + setAssets(nextAssets); + + if (nextAssets.length === 0) { + onClose(); + } + }; + return ( {step === Steps.AddAsset && ( @@ -44,6 +53,7 @@ export const UploadAssetDialog = ({ onSuccess, onClose }) => { assets={assets} onClickAddAsset={moveToAddAsset} onCancelUpload={handleCancelUpload} + onUploadSucceed={handleUploadSuccess} /> )} diff --git a/packages/core/upload/admin/src/hooks/useUpload.js b/packages/core/upload/admin/src/hooks/useUpload.js index 46f1183241..709de2544c 100644 --- a/packages/core/upload/admin/src/hooks/useUpload.js +++ b/packages/core/upload/admin/src/hooks/useUpload.js @@ -44,5 +44,11 @@ export const useUpload = () => { formatMessage({ id: getTrad('modal.upload.cancelled'), defaultMessage: '' }) ); - return { upload, cancel, error: mutation.error, progress }; + return { + upload, + cancel, + error: mutation.error, + progress, + status: mutation.status, + }; }; From b51937320245bf139feb7f12842773e7fb83c143 Mon Sep 17 00:00:00 2001 From: mfrachet Date: Wed, 22 Sep 2021 16:27:59 +0200 Subject: [PATCH 4/5] fix tests --- .../PendingAssetStep/PendingAssetStep.js | 29 +- .../App/components/tests/ListView.test.js | 335 +++++++++++++++++- 2 files changed, 356 insertions(+), 8 deletions(-) diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js index 4d614da392..b88331b98e 100644 --- a/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +++ b/packages/core/upload/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useRef } from 'react'; import PropTypes from 'prop-types'; import { ModalHeader, ModalBody, ModalFooter } from '@strapi/parts/ModalLayout'; import { ButtonText, Text } from '@strapi/parts/Text'; @@ -16,6 +16,12 @@ import { UploadingAssetCard } from '../../AssetCard/UploadingAssetCard'; import { getTrad } from '../../../utils'; import { AssetType, AssetSource } from '../../../constants'; +const Status = { + Idle: 'IDLE', + Uploading: 'UPLOADING', + Intermediate: 'INTERMEDIATE', +}; + export const PendingAssetStep = ({ onClose, assets, @@ -23,16 +29,29 @@ export const PendingAssetStep = ({ onCancelUpload, onUploadSucceed, }) => { + const assetCountRef = useRef(0); const { formatMessage } = useIntl(); - const [isUploading, setIsUploading] = useState(false); + const [uploadStatus, setUploadStatus] = useState(Status.Idle); const handleSubmit = async e => { e.preventDefault(); - setIsUploading(true); + setUploadStatus(Status.Uploading); }; const handleStatusChange = (status, file) => { + if (status === 'success' || status === 'error') { + assetCountRef.current++; + + // There's no "terminated" status. When all the files have called their + // onUploadSucceed callback, the parent component filters the asset list + // and closes the modal when the asset list is empty + if (assetCountRef.current === assets.length) { + assetCountRef.current = 0; + setUploadStatus(Status.Intermediate); + } + } + if (status === 'success') { onUploadSucceed(file); } @@ -81,7 +100,7 @@ export const PendingAssetStep = ({ {assets.map(asset => { const assetKey = asset.url; - if (isUploading) { + if (uploadStatus === Status.Uploading || uploadStatus === Status.Intermediate) { return ( } endActions={ - + + + + + + + + + +

Date: Wed, 22 Sep 2021 16:43:17 +0200 Subject: [PATCH 5/5] fix tests --- .../core/upload/admin/src/components/PaginationFooter/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/upload/admin/src/components/PaginationFooter/index.js b/packages/core/upload/admin/src/components/PaginationFooter/index.js index 7387ae50e6..61ba17541a 100644 --- a/packages/core/upload/admin/src/components/PaginationFooter/index.js +++ b/packages/core/upload/admin/src/components/PaginationFooter/index.js @@ -7,7 +7,7 @@ export const PaginationFooter = ({ pagination }) => { return ( - +