diff --git a/portal-ui/src/icons/CreateIcon.tsx b/portal-ui/src/icons/CreateIcon.tsx index 0a7f98b5c1..2c56607516 100644 --- a/portal-ui/src/icons/CreateIcon.tsx +++ b/portal-ui/src/icons/CreateIcon.tsx @@ -1,5 +1,5 @@ // This file is part of MinIO Console Server -// Copyright (c) 2019 MinIO, Inc. +// Copyright (c) 2020 MinIO, Inc. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -15,21 +15,36 @@ // along with this program. If not, see . import React from "react"; -import {SvgIcon} from "@material-ui/core"; +import { SvgIcon } from "@material-ui/core"; class CreateIcon extends React.Component { - render() { - return ( - - ic_h_create-new_sl - - - - - - - ) - } + render() { + return ( + + + + + + + + + ); + } } export default CreateIcon; diff --git a/portal-ui/src/icons/UploadFile.tsx b/portal-ui/src/icons/UploadFile.tsx new file mode 100644 index 0000000000..4f0083e8be --- /dev/null +++ b/portal-ui/src/icons/UploadFile.tsx @@ -0,0 +1,41 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2020 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import React from "react"; +import { SvgIcon } from "@material-ui/core"; + +class UploadFile extends React.Component { + render() { + return ( + + + + + + + + + ); + } +} + +export default UploadFile; diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/CreateFolderModal.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/CreateFolderModal.tsx new file mode 100644 index 0000000000..cf5ad14bf4 --- /dev/null +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/CreateFolderModal.tsx @@ -0,0 +1,116 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2020 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import React, { useState } from "react"; +import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper"; +import { Button, Grid, LinearProgress } from "@material-ui/core"; +import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary"; +import { connect } from "react-redux"; +import { createFolder } from "../../../../ObjectBrowser/actions"; + +interface ICreateFolder { + classes: any; + modalOpen: boolean; + folderName: string; + createFolder: (newFolder: string) => any; + onClose: () => any; +} + +const styles = (theme: Theme) => + createStyles({ + buttonContainer: { + textAlign: "right", + }, + pathLabel: { + marginTop: 0, + marginBottom: 32, + }, + ...modalBasic, + }); + +const CreateFolderModal = ({ + modalOpen, + folderName, + onClose, + createFolder, + classes, +}: ICreateFolder) => { + const [pathUrl, setPathUrl] = useState(""); + + const resetForm = () => { + setPathUrl(""); + }; + + const createProcess = () => { + createFolder(pathUrl); + onClose(); + }; + + const folderTruncated = folderName.split("/").slice(2).join("/"); + + return ( + + + +

+ Current Path: {folderTruncated}/ +

+ + { + setPathUrl(e.target.value); + }} + /> + + + + + +
+
+
+ ); +}; + +const mapDispatchToProps = { + createFolder, +}; + +const connector = connect(null, mapDispatchToProps); + +export default connector(withStyles(styles)(CreateFolderModal)); diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx index f1f76e4221..44f1076c46 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx @@ -45,6 +45,9 @@ import { withRouter } from "react-router-dom"; import { addRoute, setAllRoutes } from "../../../../ObjectBrowser/actions"; import { connect } from "react-redux"; import { ObjectBrowserState, Route } from "../../../../ObjectBrowser/reducers"; +import CreateFolderModal from "./CreateFolderModal"; +import { create } from "domain"; +import UploadFile from "../../../../../../icons/UploadFile"; const commonIcon = { backgroundRepeat: "no-repeat", @@ -96,6 +99,11 @@ const styles = (theme: Theme) => backgroundImage: "url(/images/ob_file_clear.svg)", ...commonIcon, }, + buttonsContainer: { + "& .MuiButtonBase-root": { + marginLeft: 10, + }, + }, "@global": { ".rowElementRaw:hover .iconFileElm": { backgroundImage: "url(/images/ob_file_filled.svg)", @@ -134,6 +142,7 @@ const ListObjects = ({ const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [deleteOpen, setDeleteOpen] = useState(false); + const [createFolderOpen, setCreateFolderOpen] = useState(false); const [deleteError, setDeleteError] = useState(""); const [selectedObject, setSelectedObject] = useState(""); const [selectedBucket, setSelectedBucket] = useState(""); @@ -182,6 +191,10 @@ const ListObjects = ({ } }; + const closeAddFolderModal = () => { + setCreateFolderOpen(false); + }; + const showSnackBarMessage = (text: string) => { setSnackbarMessage(text); setOpenSnackbar(true); @@ -310,10 +323,21 @@ const ListObjects = ({ }; const uploadObject = (e: any): void => { - // TODO: handle deeper paths/folders + // Handle of deeper routes. + const currentPath = routesList[routesList.length - 1].route; + const splitPaths = currentPath + .split("/") + .filter((item) => item.trim() !== ""); + + let path = ""; + + if (splitPaths.length > 2) { + path = `${splitPaths.slice(2).join("/")}/`; + } + let file = e.target.files[0]; showSnackBarMessage(`Uploading: ${file.name}`); - upload(e, selectedBucket, ""); + upload(e, selectedBucket, path); }; const snackBarAction = ( @@ -375,6 +399,13 @@ const ListObjects = ({ closeDeleteModalAndRefresh={closeDeleteModalAndRefresh} /> )} + {createFolderOpen && ( + + )} -
+
+