refs #14007 Merge branch 'origin/14007-ts-paths'
[arvados-workbench2.git] / src / components / file-upload / file-upload.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import {
7     Grid,
8     StyleRulesCallback,
9     Table, TableBody, TableCell, TableHead, TableRow,
10     Typography,
11     WithStyles
12 } from '@material-ui/core';
13 import { withStyles } from '@material-ui/core';
14 import Dropzone from 'react-dropzone';
15 import { CloudUploadIcon } from "../icon/icon";
16 import { formatFileSize, formatProgress, formatUploadSpeed } from "~/common/formatters";
17 import { UploadFile } from "~/store/collections/uploader/collection-uploader-actions";
18
19 type CssRules = "root" | "dropzone" | "container" | "uploadIcon";
20
21 const styles: StyleRulesCallback<CssRules> = theme => ({
22     root: {
23     },
24     dropzone: {
25         width: "100%",
26         height: "200px",
27         overflow: "auto",
28         border: "1px dashed black",
29         borderRadius: "5px"
30     },
31     container: {
32         height: "100%"
33     },
34     uploadIcon: {
35         verticalAlign: "middle"
36     }
37 });
38
39 interface FileUploadProps {
40     files: UploadFile[];
41     disabled: boolean;
42     onDrop: (files: File[]) => void;
43 }
44
45 export const FileUpload = withStyles(styles)(
46     ({ classes, files, disabled, onDrop }: FileUploadProps & WithStyles<CssRules>) =>
47     <Grid container direction={"column"}>
48         <Typography variant={"subheading"}>
49             Upload data
50         </Typography>
51         <Dropzone className={classes.dropzone} onDrop={files => onDrop(files)} disabled={disabled}>
52             {files.length === 0 &&
53             <Grid container justify="center" alignItems="center" className={classes.container}>
54                 <Grid item component={"span"}>
55                     <Typography variant={"subheading"}>
56                         <CloudUploadIcon className={classes.uploadIcon}/> Drag and drop data or click to browse
57                     </Typography>
58                 </Grid>
59             </Grid>}
60             {files.length > 0 &&
61                 <Table style={{width: "100%"}}>
62                     <TableHead>
63                         <TableRow>
64                             <TableCell>File name</TableCell>
65                             <TableCell>File size</TableCell>
66                             <TableCell>Upload speed</TableCell>
67                             <TableCell>Upload progress</TableCell>
68                         </TableRow>
69                     </TableHead>
70                     <TableBody>
71                     {files.map(f =>
72                         <TableRow key={f.id}>
73                             <TableCell>{f.file.name}</TableCell>
74                             <TableCell>{formatFileSize(f.file.size)}</TableCell>
75                             <TableCell>{formatUploadSpeed(f.prevLoaded, f.loaded, f.prevTime, f.currentTime)}</TableCell>
76                             <TableCell>{formatProgress(f.loaded, f.total)}</TableCell>
77                         </TableRow>
78                     )}
79                     </TableBody>
80                 </Table>
81             }
82         </Dropzone>
83     </Grid>
84 );