From: mateuszrojecki Date: Sun, 23 Jun 2019 23:52:17 +0000 (+0200) Subject: Added removing files during upload feature X-Git-Tag: 2.0.0~22^2 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/e586962e68a264bc6a8cf2830475e4fb2c910046 Added removing files during upload feature Feature #15256 Arvados-DCO-1.1-Signed-off-by: mateuszrojecki --- diff --git a/src/components/file-upload-dialog/file-upload-dialog.tsx b/src/components/file-upload-dialog/file-upload-dialog.tsx index b178cdae..81558493 100644 --- a/src/components/file-upload-dialog/file-upload-dialog.tsx +++ b/src/components/file-upload-dialog/file-upload-dialog.tsx @@ -14,6 +14,7 @@ export interface FilesUploadDialogProps { uploading: boolean; onSubmit: () => void; onChange: (files: File[]) => void; + onDelete: (files: File[]) => void; } export const FilesUploadDialog = (props: FilesUploadDialogProps & WithDialogProps<{}>) => @@ -28,6 +29,7 @@ export const FilesUploadDialog = (props: FilesUploadDialogProps & WithDialogProp files={props.files} disabled={props.uploading} onDrop={props.onChange} + onDelete={props.onDelete} /> diff --git a/src/components/file-upload/file-upload.tsx b/src/components/file-upload/file-upload.tsx index 64656e48..23afc0be 100644 --- a/src/components/file-upload/file-upload.tsx +++ b/src/components/file-upload/file-upload.tsx @@ -9,17 +9,18 @@ import { StyleRulesCallback, Table, TableBody, TableCell, TableHead, TableRow, Typography, - WithStyles + WithStyles, + IconButton } from '@material-ui/core'; import { withStyles } from '@material-ui/core'; import Dropzone from 'react-dropzone'; -import { CloudUploadIcon } from "../icon/icon"; +import { CloudUploadIcon, RemoveIcon } from "../icon/icon"; import { formatFileSize, formatProgress, formatUploadSpeed } from "~/common/formatters"; import { UploadFile } from '~/store/file-uploader/file-uploader-actions'; type CssRules = "root" | "dropzone" | "dropzoneWrapper" | "container" | "uploadIcon" | "dropzoneBorder" | "dropzoneBorderLeft" | "dropzoneBorderRight" | "dropzoneBorderTop" | "dropzoneBorderBottom" - | "dropzoneBorderHorzActive" | "dropzoneBorderVertActive"; + | "dropzoneBorderHorzActive" | "dropzoneBorderVertActive" | "deleteButton" | "deleteButtonDisabled" | "deleteIcon"; const styles: StyleRulesCallback = theme => ({ root: { @@ -81,6 +82,15 @@ const styles: StyleRulesCallback = theme => ({ }, uploadIcon: { verticalAlign: "middle" + }, + deleteButton: { + cursor: "pointer" + }, + deleteButtonDisabled: { + cursor: "not-allowed" + }, + deleteIcon: { + marginLeft: "-6px" } }); @@ -88,6 +98,7 @@ interface FileUploadPropsData { files: UploadFile[]; disabled: boolean; onDrop: (files: File[]) => void; + onDelete: (files: File[]) => void; } interface FileUploadState { @@ -104,6 +115,15 @@ export const FileUpload = withStyles(styles)( focused: false }; } + onDelete = (event: React.MouseEvent, file: any): void => { + const { onDelete, disabled } = this.props; + + event.stopPropagation(); + + if (!disabled) { + onDelete([file]); + } + } render() { const { classes, onDrop, disabled, files } = this.props; return
@@ -149,6 +169,7 @@ export const FileUpload = withStyles(styles)( File size Upload speed Upload progress + Delete @@ -158,7 +179,16 @@ export const FileUpload = withStyles(styles)( {formatFileSize(f.file.size)} {formatUploadSpeed(f.prevLoaded, f.loaded, f.prevTime, f.currentTime)} {formatProgress(f.loaded, f.total)} - + + ) => this.onDelete(event, f)} + className={disabled ? classnames(classes.deleteButtonDisabled, classes.deleteIcon) : classnames(classes.deleteButton, classes.deleteIcon)} + > + + + + )} diff --git a/src/store/file-uploader/file-uploader-actions.ts b/src/store/file-uploader/file-uploader-actions.ts index f4a30a23..5a82958d 100644 --- a/src/store/file-uploader/file-uploader-actions.ts +++ b/src/store/file-uploader/file-uploader-actions.ts @@ -17,12 +17,17 @@ export interface UploadFile { currentTime: number; } +export interface FileWithId extends File { + id: number; +} + export const fileUploaderActions = unionize({ CLEAR_UPLOAD: ofType(), SET_UPLOAD_FILES: ofType(), UPDATE_UPLOAD_FILES: ofType(), SET_UPLOAD_PROGRESS: ofType<{ fileId: number, loaded: number, total: number, currentTime: number }>(), START_UPLOAD: ofType(), + DELETE_UPLOAD_FILE: ofType(), }); export type FileUploaderAction = UnionOf; diff --git a/src/store/file-uploader/file-uploader-reducer.ts b/src/store/file-uploader/file-uploader-reducer.ts index 9ea63131..bf24505b 100644 --- a/src/store/file-uploader/file-uploader-reducer.ts +++ b/src/store/file-uploader/file-uploader-reducer.ts @@ -37,6 +37,12 @@ export const fileUploaderReducer = (state: UploaderState = initialState, action: return uniqUpdatedState; }, + DELETE_UPLOAD_FILE: files => { + const idToDelete: number = files[0].id; + const updatedState = state.filter( file => file.id !== idToDelete); + + return updatedState; + }, START_UPLOAD: () => { const startTime = Date.now(); return state.map(f => ({ ...f, startTime, prevTime: startTime })); diff --git a/src/views-components/file-uploader/file-uploader.tsx b/src/views-components/file-uploader/file-uploader.tsx index 83808016..f14c54fe 100644 --- a/src/views-components/file-uploader/file-uploader.tsx +++ b/src/views-components/file-uploader/file-uploader.tsx @@ -8,7 +8,7 @@ import { connect } from 'react-redux'; import { RootState } from '~/store/store'; import { FileUploadProps } from '../../components/file-upload/file-upload'; import { Dispatch } from 'redux'; -import { fileUploaderActions, getFileUploaderState } from '~/store/file-uploader/file-uploader-actions'; +import { fileUploaderActions, getFileUploaderState, FileWithId } from '~/store/file-uploader/file-uploader-actions'; import { WrappedFieldProps } from 'redux-form'; import { Typography } from '@material-ui/core'; @@ -19,7 +19,7 @@ const mapStateToProps = (state: RootState, { disabled }: FileUploaderProps): Pic files: state.fileUploader, }); -const mapDispatchToProps = (dispatch: Dispatch, { onDrop }: FileUploaderProps): Pick => ({ +const mapDispatchToProps = (dispatch: Dispatch, { onDrop }: FileUploaderProps): Pick => ({ onDrop: files => { const state = dispatch(getFileUploaderState()); if (files.length > 0 && state.length === 0) { @@ -30,6 +30,7 @@ const mapDispatchToProps = (dispatch: Dispatch, { onDrop }: FileUploaderProps): onDrop(files); } }, + onDelete: files => dispatch(fileUploaderActions.DELETE_UPLOAD_FILE(files as FileWithId[])), }); export const FileUploader = connect(mapStateToProps, mapDispatchToProps)(FileUpload);