Skip to content

Commit afe5404

Browse files
committed
FilesUploader: поддержка drag&drop
1 parent d7bebf1 commit afe5404

4 files changed

Lines changed: 186 additions & 32 deletions

File tree

hwproj.front/package-lock.json

Lines changed: 145 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hwproj.front/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"qrcode.react": "^4.1.0",
4444
"react": "^18.0.0",
4545
"react-dom": "^18.0.0",
46+
"react-drag-drop-files": "^3.1.0",
4647
"react-markdown": "^5.0.0",
4748
"react-query": "^3.21.1",
4849
"react-router-dom": "^6.5.0",

hwproj.front/src/components/Files/FilesUploader.tsx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import {Box, Snackbar} from "@material-ui/core";
2-
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
2+
import {FileUploader} from "react-drag-drop-files";
33
import * as React from "react";
44
import {styled} from "@mui/material/styles";
55
import {useEffect, useState} from "react";
66
import {IFileInfo} from "./IFileInfo";
7-
import {Alert, Button, Grid} from "@mui/material";
7+
import {Alert, Card, CardContent, Grid, Stack, Typography} from "@mui/material";
88
import FilesPreviewList from "./FilesPreviewList";
9-
import { CourseUnitType } from "./CourseUnitType";
10-
import { FileStatus } from "./FileStatus";
9+
import {CourseUnitType} from "./CourseUnitType";
10+
import {FileStatus} from "./FileStatus";
11+
import CloudUploadOutlinedIcon from '@mui/icons-material/CloudUploadOutlined';
12+
import "./filesUploaderOverrides.css";
1113

1214
interface IFilesUploaderProps {
1315
courseUnitType: CourseUnitType
@@ -43,7 +45,7 @@ const FilesUploader: React.FC<IFilesUploaderProps> = (props) => {
4345

4446
const maxFileSizeInBytes = 100 * 1024 * 1024;
4547

46-
const validateFiles = (files: FileList): boolean => {
48+
const validateFiles = (files: File[]): boolean => {
4749
for (const file of files) {
4850
if (file.size > maxFileSizeInBytes) {
4951
setError(`Файл "${file.name}" слишком большой.
@@ -56,12 +58,13 @@ const FilesUploader: React.FC<IFilesUploaderProps> = (props) => {
5658
}
5759

5860

59-
const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
60-
if (e.target.files == null) return
61-
if (!validateFiles(e.target.files)) return
61+
const handleFileInputChange = (input: Array<File> | File) => {
62+
const files = input instanceof File ? [input] : input;
63+
if (files == null) return
64+
if (!validateFiles(files)) return
6265

6366
const newFilesInfo: IFileInfo[] = []
64-
for (const file of e.target.files) {
67+
for (const file of files) {
6568
newFilesInfo.push({
6669
name: file.name,
6770
type: file.type,
@@ -80,7 +83,7 @@ const FilesUploader: React.FC<IFilesUploaderProps> = (props) => {
8083
}
8184

8285
return (
83-
<Grid container direction="row" alignItems="flex-start" spacing={1} marginBottom={props.isLoading ? 0 : 1}>
86+
<Grid container direction="column" marginBottom={props.isLoading ? 0 : 1}>
8487
{error && (
8588
<Snackbar
8689
open={!!error}
@@ -91,24 +94,28 @@ const FilesUploader: React.FC<IFilesUploaderProps> = (props) => {
9194
<Alert severity="error">{error}</Alert>
9295
</Snackbar>
9396
)}
94-
<Grid item>
95-
<Button
96-
size="small"
97-
component="label"
98-
role={undefined}
99-
variant="outlined"
100-
tabIndex={-1}
101-
startIcon={<CloudUploadIcon/>}
102-
color="primary"
103-
style={{marginTop: "10px"}}
104-
>
105-
Прикрепить файлы
106-
<VisuallyHiddenInput
107-
type="file"
108-
onChange={handleFileInputChange}
109-
multiple
110-
/>
111-
</Button>
97+
<Grid item xs={12}>
98+
<FileUploader
99+
classes="rddu-no-block"
100+
handleChange={handleFileInputChange}
101+
hoverTitle={"Перетащите файлы сюда для загрузки"}
102+
children={
103+
<Card
104+
style={{
105+
border: "1px dashed #1976d2",
106+
backgroundColor: "ghostwhite",
107+
textAlign: "center",
108+
}}
109+
variant={"outlined"}>
110+
<CardContent>
111+
<Typography color={"primary"} variant={"body1"}>
112+
Загрузите материалы задания
113+
</Typography>
114+
<CloudUploadOutlinedIcon color="primary" fontSize={"medium"}/>
115+
</CardContent>
116+
</Card>}
117+
multiple={true}
118+
name="file"/>
112119
</Grid>
113120
{props.isLoading &&
114121
<Grid item>
@@ -117,7 +124,7 @@ const FilesUploader: React.FC<IFilesUploaderProps> = (props) => {
117124
</Box>
118125
</Grid>
119126
}
120-
<Grid item>
127+
<Grid item xs={12}>
121128
<FilesPreviewList
122129
filesInfo={selectedFilesInfo}
123130
onRemoveFileInfo={(fI) => {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* Overrides for react-drag-drop-files FileUploader to prevent the hidden input from being block-level */
2+
.rddu-no-block {
3+
display: inline !important; /* make input non-blocking */
4+
}

0 commit comments

Comments
 (0)