File upload error handling (#52006)

This commit is contained in:
Adela Almasan 2022-07-08 20:10:15 -05:00 committed by GitHub
parent 7e9194e6e2
commit 5ad2767954
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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<DropzoneFile[]>([]);
const [errorMessages, setErrorMessages] = useState<string[]>([]);
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 <FileListItem key={file.id} file={file} removeFile={removeFile} />;
});
const setErrors = (rejectedFiles: FileRejection[]) => {
let errors: string[] = [];
rejectedFiles.map((rejectedFile) => {
rejectedFile.errors.map((error) => {
errors.push(error.message);
});
});
setErrorMessages(errors);
};
const getErrorMessages = () => {
return (
<div className={styles.errorAlert}>
<Alert title="Upload failed" severity="error" onRemove={clearAlert}>
{errorMessages.map((error) => {
return <div key={error}>{error}</div>;
})}
</Alert>
</div>
);
};
const clearAlert = () => {
setErrorMessages([]);
};
return (
<div className={styles.container}>
<div data-testid="dropzone" {...getRootProps({ className: styles.dropzone })}>
<input {...getInputProps()} />
{children ?? <FileDropzoneDefaultChildren primaryText={getPrimaryText(files, options)} />}
</div>
{errorMessages.length > 0 && getErrorMessages()}
{options?.accept && (
<small className={cx(styles.small, styles.acceptMargin)}>{getAcceptedFileTypeText(options.accept)}</small>
)}
@ -276,5 +308,8 @@ function getStyles(theme: GrafanaTheme2, isDragActive?: boolean) {
small: css`
color: ${theme.colors.text.secondary};
`,
errorAlert: css`
padding-top: 10px;
`,
};
}