1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import * as classnames from 'classnames';
10 Table, TableBody, TableCell, TableHead, TableRow,
13 } from '@material-ui/core';
14 import { withStyles } from '@material-ui/core';
15 import Dropzone from 'react-dropzone';
16 import { CloudUploadIcon } from "../icon/icon";
17 import { formatFileSize, formatProgress, formatUploadSpeed } from "~/common/formatters";
18 import { UploadFile } from '~/store/file-uploader/file-uploader-actions';
20 type CssRules = "root" | "dropzone" | "dropzoneWrapper" | "container" | "uploadIcon"
21 | "dropzoneBorder" | "dropzoneBorderLeft" | "dropzoneBorderRight" | "dropzoneBorderTop" | "dropzoneBorderBottom"
22 | "dropzoneBorderHorzActive" | "dropzoneBorderVertActive";
24 const styles: StyleRulesCallback<CssRules> = theme => ({
36 border: "1px solid rgba(0, 0, 0, 0.42)"
41 transition: "transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms",
42 pointerEvents: "none",
43 backgroundColor: "#6a1b9a"
50 transform: "scaleY(0)",
52 dropzoneBorderRight: {
57 transform: "scaleY(0)",
64 transform: "scaleX(0)",
66 dropzoneBorderBottom: {
71 transform: "scaleX(0)",
73 dropzoneBorderHorzActive: {
74 transform: "scaleY(1)"
76 dropzoneBorderVertActive: {
77 transform: "scaleX(1)"
83 verticalAlign: "middle"
87 interface FileUploadPropsData {
90 onDrop: (files: File[]) => void;
93 interface FileUploadState {
97 export type FileUploadProps = FileUploadPropsData & WithStyles<CssRules>;
99 export const FileUpload = withStyles(styles)(
100 class extends React.Component<FileUploadProps, FileUploadState> {
101 constructor(props: FileUploadProps) {
108 const { classes, onDrop, disabled, files } = this.props;
109 return <div className={"file-upload-dropzone " + classes.dropzoneWrapper}>
110 <div className={classnames(classes.dropzoneBorder, classes.dropzoneBorderLeft, { [classes.dropzoneBorderHorzActive]: this.state.focused })}/>
111 <div className={classnames(classes.dropzoneBorder, classes.dropzoneBorderRight, { [classes.dropzoneBorderHorzActive]: this.state.focused })}/>
112 <div className={classnames(classes.dropzoneBorder, classes.dropzoneBorderTop, { [classes.dropzoneBorderVertActive]: this.state.focused })}/>
113 <div className={classnames(classes.dropzoneBorder, classes.dropzoneBorderBottom, { [classes.dropzoneBorderVertActive]: this.state.focused })}/>
114 <Dropzone className={classes.dropzone}
115 onDrop={files => onDrop(files)}
117 const el = document.getElementsByClassName("file-upload-dropzone")[0];
118 const inputs = el.getElementsByTagName("input");
119 if (inputs.length > 0) {
136 {files.length === 0 &&
137 <Grid container justify="center" alignItems="center" className={classes.container}>
138 <Grid item component={"span"}>
139 <Typography variant={"subheading"}>
140 <CloudUploadIcon className={classes.uploadIcon} /> Drag and drop data or click to browse
145 <Table style={{ width: "100%" }}>
148 <TableCell>File name</TableCell>
149 <TableCell>File size</TableCell>
150 <TableCell>Upload speed</TableCell>
151 <TableCell>Upload progress</TableCell>
156 <TableRow key={f.id}>
157 <TableCell>{f.file.name}</TableCell>
158 <TableCell>{formatFileSize(f.file.size)}</TableCell>
159 <TableCell>{formatUploadSpeed(f.prevLoaded, f.loaded, f.prevTime, f.currentTime)}</TableCell>
160 <TableCell>{formatProgress(f.loaded, f.total)}</TableCell>