mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
File upload error handling (#52006)
This commit is contained in:
parent
7e9194e6e2
commit
5ad2767954
@ -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;
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user