Improved folder drop upload behavior (#1331)

This commit is contained in:
jinapurapu
2021-12-30 13:43:33 -08:00
committed by GitHub
parent 3d357c8c22
commit 3f4b595779
3 changed files with 183 additions and 120 deletions

View File

@@ -1,100 +1,101 @@
{
"name": "portal-ui",
"version": "0.1.0",
"homepage": ".",
"private": true,
"dependencies": {
"@date-io/moment": "1.x",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"@hot-loader/react-dom": "17.0.1",
"@mui/icons-material": "^5.0.4",
"@mui/lab": "^5.0.0-alpha.30",
"@mui/material": "^5.0.4",
"@mui/styled-engine-sc": "^5.0.3",
"@mui/styles": "^5.0.1",
"@types/history": "^4.7.3",
"@types/jest": "24.0.23",
"@types/lodash": "^4.14.149",
"@types/node": "12.12.8",
"@types/react": "17.0.0",
"@types/react-copy-to-clipboard": "^4.3.0",
"@types/react-dom": "16.9.4",
"@types/react-grid-layout": "^1.1.1",
"@types/react-redux": "^7.1.5",
"@types/react-router": "^5.1.3",
"@types/react-router-dom": "^5.1.2",
"@types/react-virtualized": "^9.21.10",
"@types/superagent": "^4.1.12",
"@types/webpack-env": "^1.14.1",
"@types/websocket": "^1.0.0",
"ansi-to-react": "^6.0.5",
"chart.js": "^2.9.3",
"codemirror": "^5.52.2",
"history": "^4.10.1",
"local-storage-fallback": "^4.1.1",
"lodash": "^4.17.21",
"moment": "^2.29.1",
"react": "^17.0.2",
"react-async-hook": "^3.6.1",
"react-chartjs-2": "^2.9.0",
"react-codemirror2": "^7.1.0",
"react-copy-to-clipboard": "^5.0.2",
"react-dom": "17.0.1",
"react-grid-layout": "^1.2.0",
"react-hot-loader": "^4.13.0",
"react-moment": "^1.1.1",
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-virtualized": "^9.22.2",
"react-window-infinite-loader": "^1.0.5",
"recharts": "^2.1.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"styled-components": "^5.3.1",
"superagent": "^6.1.0",
"typeface-roboto": "^0.0.75",
"use-debounce": "^5.0.1",
"websocket": "^1.0.31"
},
"scripts": {
"start": "PORT=5005 react-app-rewired start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:9090/",
"devDependencies": {
"@types/recharts": "^1.8.22",
"prettier": "2.5.1",
"react-app-rewire-hot-loader": "^2.0.1",
"react-app-rewired": "^2.1.6",
"react-scripts": "4.0.3",
"typescript": "^4.4.3"
},
"resolutions": {
"@types/jest/**/ansi-regex": "^5.0.1",
"react-scripts/**/ansi-regex": "^5.0.1",
"react-scripts/**/nth-check": "^2.0.1",
"react-scripts/**/set-value": "^4.0.1",
"react-scripts/**/immer": "^9.0.6",
"react-scripts/**/glob-parent": "^5.1.2",
"react-scripts/**/browserslist": "^4.16.5",
"react-scripts/**/ansi-html": "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz"
}
"name": "portal-ui",
"version": "0.1.0",
"homepage": ".",
"private": true,
"dependencies": {
"@date-io/moment": "1.x",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"@hot-loader/react-dom": "17.0.1",
"@mui/icons-material": "^5.0.4",
"@mui/lab": "^5.0.0-alpha.30",
"@mui/material": "^5.0.4",
"@mui/styled-engine-sc": "^5.0.3",
"@mui/styles": "^5.0.1",
"@types/history": "^4.7.3",
"@types/jest": "24.0.23",
"@types/lodash": "^4.14.149",
"@types/node": "12.12.8",
"@types/react": "17.0.0",
"@types/react-copy-to-clipboard": "^4.3.0",
"@types/react-dom": "16.9.4",
"@types/react-grid-layout": "^1.1.1",
"@types/react-redux": "^7.1.5",
"@types/react-router": "^5.1.3",
"@types/react-router-dom": "^5.1.2",
"@types/react-virtualized": "^9.21.10",
"@types/superagent": "^4.1.12",
"@types/webpack-env": "^1.14.1",
"@types/websocket": "^1.0.0",
"ansi-to-react": "^6.0.5",
"chart.js": "^2.9.3",
"codemirror": "^5.52.2",
"history": "^4.10.1",
"local-storage-fallback": "^4.1.1",
"lodash": "^4.17.21",
"moment": "^2.29.1",
"react": "^17.0.2",
"react-async-hook": "^3.6.1",
"react-chartjs-2": "^2.9.0",
"react-codemirror2": "^7.1.0",
"react-copy-to-clipboard": "^5.0.2",
"react-dom": "17.0.1",
"react-dropzone": "^11.4.2",
"react-grid-layout": "^1.2.0",
"react-hot-loader": "^4.13.0",
"react-moment": "^1.1.1",
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-virtualized": "^9.22.2",
"react-window-infinite-loader": "^1.0.5",
"recharts": "^2.1.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"styled-components": "^5.3.1",
"superagent": "^6.1.0",
"typeface-roboto": "^0.0.75",
"use-debounce": "^5.0.1",
"websocket": "^1.0.31"
},
"scripts": {
"start": "PORT=5005 react-app-rewired start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:9090/",
"devDependencies": {
"@types/recharts": "^1.8.22",
"prettier": "2.3.2",
"react-app-rewire-hot-loader": "^2.0.1",
"react-app-rewired": "^2.1.6",
"react-scripts": "4.0.3",
"typescript": "^4.4.3"
},
"resolutions": {
"@types/jest/**/ansi-regex": "^5.0.1",
"react-scripts/**/ansi-regex": "^5.0.1",
"react-scripts/**/nth-check": "^2.0.1",
"react-scripts/**/set-value": "^4.0.1",
"react-scripts/**/immer": "^9.0.6",
"react-scripts/**/glob-parent": "^5.1.2",
"react-scripts/**/browserslist": "^4.16.5",
"react-scripts/**/ansi-html": "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz"
}
}

View File

@@ -16,6 +16,8 @@
import React, { Fragment, useEffect, useRef, useState } from "react";
import { connect } from "react-redux";
import {useDropzone} from 'react-dropzone'
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -83,6 +85,7 @@ import withSuspense from "../../../../Common/Components/withSuspense";
import { displayName } from "./utils";
import { DownloadIcon, UploadFolderIcon } from "../../../../../../icons";
const AddFolderIcon = React.lazy(
() => import("../../../../../../icons/AddFolderIcon")
);
@@ -250,6 +253,10 @@ const ListObjects = ({
>("ASC");
const [currentSortField, setCurrentSortField] = useState<string>("name");
const [iniLoad, setIniLoad] = useState<boolean>(false);
const internalPaths = get(match.params, "subpaths", "");
const bucketName = match.params["bucketName"];
@@ -572,29 +579,38 @@ const ListObjects = ({
setCreateFolderOpen(false);
};
const upload = (e: any, bucketName: string, path: string) => {
if (
const handleUploadButton = (e: any) => {
if (
e === null ||
e === undefined ||
e.target === null ||
e.target === undefined
e.target.files === null ||
e.target.files === undefined
) {
return;
}
e.preventDefault();
var newFiles : File[] = [];
let files = e.target.files;
for (var i=0; i<e.target.files.length; i++) {
newFiles.push(e.target.files[i])
}
uploadObject(newFiles, "");
}
const upload = (files: File[], bucketName: string, path: string, folderPath: string) => {
if (files.length > 0) {
for (let file of files) {
for (let file of files) {
let uploadUrl = `api/v1/buckets/${bucketName}/objects/upload`;
const fileName = file.name;
const blobFile = new Blob([file], { type: file.type });
let encodedPath = "";
const relativeFolderPath = get(file, "webkitRelativePath", "");
const relativeFolderPath = get(file, "webkitRelativePath", "") !== ""
? get(file, "webkitRelativePath", "")
: folderPath
if (path !== "" || relativeFolderPath !== "") {
const finalFolderPath = relativeFolderPath
.split("/")
@@ -672,13 +688,14 @@ const ListObjects = ({
};
const formData = new FormData();
formData.append(file.size, blobFile, fileName);
if (file.size !== undefined){
formData.append(file.size.toString(), blobFile, fileName);
xhr.send(formData);
}
}
}
e.target.value = null;
};
const displayParsedDate = (object: BucketObject) => {
@@ -741,15 +758,26 @@ const ListObjects = ({
return;
};
const uploadObject = (e: any): void => {
const uploadObject = (files: File[], folderPath: string): void => {
let pathPrefix = "";
if (internalPaths) {
const decodedPath = decodeFileName(internalPaths);
pathPrefix = decodedPath.endsWith("/") ? decodedPath : decodedPath + "/";
}
upload(e, bucketName, pathPrefix);
}
upload(files, bucketName, pathPrefix, folderPath);
};
const onDrop = React.useCallback(acceptedFiles => {
let newFolderPath: string = acceptedFiles[0].path;
uploadObject(acceptedFiles , newFolderPath);
}, [uploadObject]);
const {getRootProps, getInputProps} = useDropzone({noClick: true, onDrop});
const openPreview = (fileObject: BucketObject) => {
setSelectedPreview(fileObject);
setPreviewOpen(true);
@@ -969,6 +997,8 @@ const ListObjects = ({
}
};
return (
<React.Fragment>
{shareFileModalOpen && selectedPreview && (
@@ -1086,7 +1116,7 @@ const ListObjects = ({
<input
type="file"
multiple
onChange={(e) => uploadObject(e)}
onChange={handleUploadButton}
id="file-input"
style={{ display: "none" }}
ref={fileUpload}
@@ -1110,11 +1140,19 @@ const ListObjects = ({
>
<UploadFolderIcon />
</BoxIconButton>
<input
type="file"
multiple
onChange={handleUploadButton}
id="file-input"
style={{ display: "none" }}
ref={folderUpload}
/>
</SecureComponent>
<input
type="file"
multiple
onChange={(e) => uploadObject(e)}
onChange={handleUploadButton}
id="file-input"
style={{ display: "none" }}
ref={folderUpload}
@@ -1212,6 +1250,8 @@ const ListObjects = ({
<Grid item xs={12}>
<br />
</Grid>
<div {...getRootProps()}>
<input {...getInputProps()} />
<Grid item xs={12} className={classes.tableBlock}>
<SecureComponent
scopes={[IAM_SCOPES.S3_LIST_BUCKET]}
@@ -1241,7 +1281,8 @@ const ListObjects = ({
/>
</SecureComponent>
</Grid>
</PageLayout>
</div>
</PageLayout>
</React.Fragment>
);
};

View File

@@ -3045,6 +3045,11 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
attr-accept@^2.2.1:
version "2.2.2"
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
autoprefixer@^9.6.1:
version "9.8.8"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a"
@@ -5640,6 +5645,13 @@ file-loader@6.1.1:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
file-selector@^0.2.2:
version "0.2.4"
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.2.4.tgz#7b98286f9dbb9925f420130ea5ed0a69238d4d80"
integrity sha512-ZDsQNbrv6qRi1YTDOEWzf5J2KjZ9KMI1Q2SGeTkCJmNNW25Jg4TW4UMcmoqcg4WrAyKRcpBXdbWRxkfrOzVRbA==
dependencies:
tslib "^2.0.3"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
@@ -9612,10 +9624,10 @@ prepend-http@^1.0.0:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
prettier@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
prettier@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
pretty-bytes@^5.3.0:
version "5.6.0"
@@ -9956,6 +9968,15 @@ react-draggable@^4.0.0, react-draggable@^4.0.3:
clsx "^1.1.1"
prop-types "^15.6.0"
react-dropzone@^11.4.2:
version "11.4.2"
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-11.4.2.tgz#1eb99e9def4cc7520f4f58e85c853ce52c483d56"
integrity sha512-ocYzYn7Qgp0tFc1gQtUTOaHHSzVTwhWHxxY+r7cj2jJTPfMTZB5GWSJHdIVoxsl+EQENpjJ/6Zvcw0BqKZQ+Eg==
dependencies:
attr-accept "^2.2.1"
file-selector "^0.2.2"
prop-types "^15.7.2"
react-error-overlay@^6.0.9:
version "6.0.9"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"