From 99f62c12806febd5242fb31a8e1d43db9a537888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Thu, 4 Jul 2024 09:41:29 +0100 Subject: [PATCH] feat: Add error handling for failed file uploads --- .../@planx/components/FileUpload/Public.tsx | 11 ++ .../components/FileUploadAndLabel/Public.tsx | 5 +- .../components/FileUploadAndLabel/schema.ts | 17 ++- .../PrivateFileUpload/UploadedFileCard.tsx | 144 ++++++++++-------- 4 files changed, 106 insertions(+), 71 deletions(-) diff --git a/editor.planx.uk/src/@planx/components/FileUpload/Public.tsx b/editor.planx.uk/src/@planx/components/FileUpload/Public.tsx index e821865e94..fbe600753c 100644 --- a/editor.planx.uk/src/@planx/components/FileUpload/Public.tsx +++ b/editor.planx.uk/src/@planx/components/FileUpload/Public.tsx @@ -42,6 +42,17 @@ const slotsSchema = array() !slots.some((slot) => slot.status === "uploading"), ); }, + }) + .test({ + name: "errorStatus", + message: "Remove files which failed to upload", + test: (slots?: Array) => { + return Boolean( + slots && + slots.length > 0 && + !slots.some((slot) => slot.status === "error"), + ); + }, }); const FileUpload: React.FC = (props) => { diff --git a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Public.tsx b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Public.tsx index 2233382ef2..6efbb1e2e0 100644 --- a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Public.tsx +++ b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Public.tsx @@ -148,6 +148,7 @@ function Component(props: Props) { break; } case "allRequiredFilesUploaded": + case "errorStatus": setFileListError(err?.message); break; } @@ -188,10 +189,6 @@ function Component(props: Props) { return ( slot.url && slot.status === "success") - } > diff --git a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/schema.ts b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/schema.ts index 42d242f883..25d82a238b 100644 --- a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/schema.ts +++ b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/schema.ts @@ -91,10 +91,21 @@ export const slotsSchema = array() name: "nonUploading", message: "Please wait for upload to complete", test: (slots?: Array) => { - const isEveryUploadComplete = Boolean( - slots?.every((slot) => slot.status === "success"), + const isAnyUploadInProgress = Boolean( + slots?.some((slot) => slot.status === "uploading"), + ); + return !isAnyUploadInProgress; + }, + }) + .test({ + name: "errorStatus", + message: "Remove files which failed to upload", + test: (slots?: Array) => { + return Boolean( + slots && + slots.length > 0 && + !slots.some((slot) => slot.status === "error"), ); - return isEveryUploadComplete; }, }); diff --git a/editor.planx.uk/src/@planx/components/shared/PrivateFileUpload/UploadedFileCard.tsx b/editor.planx.uk/src/@planx/components/shared/PrivateFileUpload/UploadedFileCard.tsx index 283d21b2fd..f0ad4ba588 100644 --- a/editor.planx.uk/src/@planx/components/shared/PrivateFileUpload/UploadedFileCard.tsx +++ b/editor.planx.uk/src/@planx/components/shared/PrivateFileUpload/UploadedFileCard.tsx @@ -11,6 +11,7 @@ import { visuallyHidden } from "@mui/utils"; import { FileUploadSlot } from "@planx/components/FileUpload/Public"; import ImagePreview from "components/ImagePreview"; import React from "react"; +import ErrorWrapper from "ui/shared/ErrorWrapper"; interface Props extends FileUploadSlot { removeFile: () => void; @@ -19,12 +20,12 @@ interface Props extends FileUploadSlot { } const Root = styled(Box)(({ theme }) => ({ - border: `1px solid ${theme.palette.border.main}`, marginBottom: theme.spacing(0.5), marginTop: theme.spacing(5), })); const FileCard = styled(Box)(({ theme }) => ({ + border: `1px solid ${theme.palette.border.main}`, position: "relative", height: "auto", display: "flex", @@ -91,74 +92,89 @@ export const UploadedFileCard: React.FC = ({ removeFile, onChange, tags, + status, }) => ( - - - - {file instanceof File && file?.type?.includes("image") ? ( - - ) : ( - - )} - - - - + <> + + + + {file instanceof File && file?.type?.includes("image") ? ( + + ) : ( + + )} + + - {file.path} - - {formatBytes(file.size)} - - {removeFile && ( - - - - )} - - - {tags && ( - - - {tags.map((tag) => ( - - + + {file.path} + + {formatBytes(file.size)} + + {removeFile && ( + - - ))} - - onChange && onChange()} - sx={{ fontFamily: "inherit", fontSize: "inherit" }} - component="button" - variant="body2" - > - Change - - the list of what file {file.path} shows + aria-label={`Delete ${file.path}`} + title={`Delete ${file.path}`} + onClick={removeFile} + > + + + )} - - - )} + + {tags && ( + + + {tags.map((tag) => ( + + + + ))} + + onChange && onChange()} + sx={{ fontFamily: "inherit", fontSize: "inherit" }} + component="button" + variant="body2" + > + Change + + the list of what file {file.path} shows + + + + )} + + );