From 5ad27679549d6c9f2ea49a1fcb5ef9de6754ff1c Mon Sep 17 00:00:00 2001 From: Adela Almasan <88068998+adela-almasan@users.noreply.github.com> Date: Fri, 8 Jul 2022 20:10:15 -0500 Subject: [PATCH] File upload error handling (#52006) --- .../components/FileDropzone/FileDropzone.tsx | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx index 1c8f24dec6e..d52f5c1b2b6 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx @@ -1,11 +1,12 @@ import { css, cx } from '@emotion/css'; -import { uniqueId, isString } from 'lodash'; +import { isString, uniqueId } from 'lodash'; import React, { ReactNode, useCallback, useState } from 'react'; -import { DropEvent, DropzoneOptions, FileRejection, useDropzone, Accept } from 'react-dropzone'; +import { Accept, DropEvent, DropzoneOptions, FileRejection, useDropzone } from 'react-dropzone'; import { GrafanaTheme2 } from '@grafana/data'; import { useTheme2 } from '../../themes'; +import { Alert } from '../Alert/Alert'; import { Icon } from '../Icon/Icon'; import { FileListItem } from './FileListItem'; @@ -58,6 +59,7 @@ export interface DropzoneFile { export function FileDropzone({ options, children, readAs, onLoad, fileListRenderer, onFileRemove }: FileDropzoneProps) { const [files, setFiles] = useState([]); + const [errorMessages, setErrorMessages] = useState([]); const setFileProperty = useCallback( (customFile: DropzoneFile, action: (customFileToModify: DropzoneFile) => void) => { @@ -83,6 +85,8 @@ export function FileDropzone({ options, children, readAs, onLoad, fileListRender setFiles((oldFiles) => [...oldFiles, ...customFiles]); } + setErrors(rejectedFiles); + if (options?.onDrop) { options.onDrop(acceptedFiles, rejectedFiles, event); } else { @@ -161,12 +165,40 @@ export function FileDropzone({ options, children, readAs, onLoad, fileListRender return ; }); + const setErrors = (rejectedFiles: FileRejection[]) => { + let errors: string[] = []; + rejectedFiles.map((rejectedFile) => { + rejectedFile.errors.map((error) => { + errors.push(error.message); + }); + }); + + setErrorMessages(errors); + }; + + const getErrorMessages = () => { + return ( +
+ + {errorMessages.map((error) => { + return
{error}
; + })} +
+
+ ); + }; + + const clearAlert = () => { + setErrorMessages([]); + }; + return (
{children ?? }
+ {errorMessages.length > 0 && getErrorMessages()} {options?.accept && ( {getAcceptedFileTypeText(options.accept)} )} @@ -276,5 +308,8 @@ function getStyles(theme: GrafanaTheme2, isDragActive?: boolean) { small: css` color: ${theme.colors.text.secondary}; `, + errorAlert: css` + padding-top: 10px; + `, }; }