Connected delete & download buttons for object details (#399)

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
This commit is contained in:
Alex
2020-11-18 18:06:34 -06:00
committed by GitHub
parent f1db949abc
commit b21123e1cd
4 changed files with 126 additions and 49 deletions

View File

@@ -51,6 +51,7 @@ import { connect } from "react-redux";
import { ObjectBrowserState, Route } from "../../../../ObjectBrowser/reducers";
import CreateFolderModal from "./CreateFolderModal";
import UploadFile from "../../../../../../icons/UploadFile";
import { download } from "../utils";
const commonIcon = {
backgroundRepeat: "no-repeat",
@@ -297,37 +298,6 @@ const ListObjects = ({
e.target.value = null;
};
const download = (bucketName: string, objectName: string) => {
const anchor = document.createElement("a");
document.body.appendChild(anchor);
const token: string = storage.getItem("token")!;
const xhr = new XMLHttpRequest();
xhr.open(
"GET",
`/api/v1/buckets/${bucketName}/objects/download?prefix=${objectName}`,
true
);
xhr.responseType = "blob";
xhr.onload = function (e) {
if (this.status === 200) {
const blob = new Blob([this.response], {
type: "octet/stream",
});
const blobUrl = window.URL.createObjectURL(blob);
anchor.href = blobUrl;
anchor.download = objectName;
anchor.click();
window.URL.revokeObjectURL(blobUrl);
anchor.remove();
}
};
xhr.send();
};
const displayParsedDate = (date: string) => {
return <reactMoment.default>{date}</reactMoment.default>;
};

View File

@@ -1,3 +1,19 @@
// 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 <http://www.gnu.org/licenses/>.
import React, { useEffect } from "react";
import ListObjects from "./ListObjects";
import ObjectDetails from "../ObjectDetails/ObjectDetails";

View File

@@ -1,5 +1,21 @@
// 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 <http://www.gnu.org/licenses/>.
import React, { useState, useEffect } from "react";
import { withRouter } from "react-router-dom";
import get from "lodash/get";
import * as reactMoment from "react-moment";
import clsx from "clsx";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
@@ -17,6 +33,10 @@ import {
containerForHeader,
searchField,
} from "../../../../Common/FormComponents/common/styleLibrary";
import history from "../../../../../../history";
import { Route } from "../../../../ObjectBrowser/reducers";
import { download } from "../utils";
import api from "../../../../../../common/api";
import PageHeader from "../../../../Common/PageHeader/PageHeader";
import ShareIcon from "../../../../../../icons/ShareIcon";
import DownloadIcon from "../../../../../../icons/DownloadIcon";
@@ -25,13 +45,9 @@ import TableWrapper from "../../../../Common/TableWrapper/TableWrapper";
import PencilIcon from "../../../../Common/TableWrapper/TableActionIcons/PencilIcon";
import SetRetention from "./SetRetention";
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
import { Button, Input } from "@material-ui/core";
import { CreateIcon } from "../../../../../../icons";
import UploadFile from "../../../../../../icons/UploadFile";
import DeleteObject from "../ListObjects/DeleteObject";
import { removeRouteLevel } from "../../../../ObjectBrowser/actions";
import { connect } from "react-redux";
import api from "../../../../../../common/api";
import { ObjectBrowserState, Route } from "../../../../ObjectBrowser/reducers";
import get from "lodash/get";
const styles = (theme: Theme) =>
createStyles({
@@ -115,6 +131,7 @@ const styles = (theme: Theme) =>
interface IObjectDetailsProps {
classes: any;
routesList: Route[];
removeRouteLevel: (newRoute: string) => any;
}
interface IFileInfo {
@@ -141,12 +158,17 @@ const emptyFile: IFileInfo = {
version_id: "",
};
const ObjectDetails = ({ classes, routesList }: IObjectDetailsProps) => {
const ObjectDetails = ({
classes,
routesList,
removeRouteLevel,
}: IObjectDetailsProps) => {
const [shareFileModalOpen, setShareFileModalOpen] = useState<boolean>(false);
const [retentionModalOpen, setRetentionModalOpen] = useState<boolean>(false);
const [actualInfo, setActualInfo] = useState<IFileInfo>(emptyFile);
const [versions, setVersions] = useState<IFileInfo[]>([]);
const [filterVersion, setFilterVersion] = useState<string>("");
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const [error, setError] = useState<string>("");
const currentItem = routesList[routesList.length - 1];
@@ -197,12 +219,8 @@ const ObjectDetails = ({ classes, routesList }: IObjectDetailsProps) => {
console.log("delete tag");
};
const downloadObject = () => {
console.log("download object");
};
const confirmDeleteObject = () => {
console.log("confirm delete object");
const downloadObject = (path: string) => {
download(bucketName, path);
};
const tableActions = [
@@ -218,6 +236,17 @@ const ObjectDetails = ({ classes, routesList }: IObjectDetailsProps) => {
return <reactMoment.default>{date}</reactMoment.default>;
};
const closeDeleteModal = (redirectBack: boolean) => {
setDeleteOpen(false);
if (redirectBack) {
const newPath = allPathData.slice(0, -1).join("/");
removeRouteLevel(newPath);
history.push(newPath);
}
};
return (
<React.Fragment>
<PageHeader label={"Object Browser"} />
@@ -234,6 +263,14 @@ const ObjectDetails = ({ classes, routesList }: IObjectDetailsProps) => {
objectName={objectName}
/>
)}
{deleteOpen && (
<DeleteObject
deleteOpen={deleteOpen}
selectedBucket={bucketName}
selectedObject={pathInBucket}
closeDeleteModalAndRefresh={closeDeleteModal}
/>
)}
<Grid container>
<Grid item xs={12} className={classes.container}>
<Grid item xs={12} className={classes.obTitleSection}>
@@ -307,11 +344,11 @@ const ObjectDetails = ({ classes, routesList }: IObjectDetailsProps) => {
<div className={classes.actionsIconContainer}>
<IconButton
color="primary"
aria-label="download/upload"
aria-label="download"
size="small"
className={classes.actionsIcon}
onClick={() => {
console.log("download/upload");
downloadObject(pathInBucket);
}}
>
<DownloadIcon />
@@ -324,7 +361,7 @@ const ObjectDetails = ({ classes, routesList }: IObjectDetailsProps) => {
size="small"
className={classes.actionsIcon}
onClick={() => {
console.log("delete");
setDeleteOpen(true);
}}
>
<DeleteIcon />
@@ -404,4 +441,10 @@ const ObjectDetails = ({ classes, routesList }: IObjectDetailsProps) => {
);
};
export default withStyles(styles)(ObjectDetails);
const mapDispatchToProps = {
removeRouteLevel,
};
const connector = connect(null, mapDispatchToProps);
export default connector(withStyles(styles)(ObjectDetails));

View File

@@ -0,0 +1,48 @@
// 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 <http://www.gnu.org/licenses/>.
import storage from "local-storage-fallback";
export const download = (bucketName: string, objectName: string) => {
const anchor = document.createElement("a");
document.body.appendChild(anchor);
const token: string = storage.getItem("token")!;
const xhr = new XMLHttpRequest();
xhr.open(
"GET",
`/api/v1/buckets/${bucketName}/objects/download?prefix=${objectName}`,
true
);
xhr.responseType = "blob";
xhr.onload = function (e) {
if (this.status === 200) {
const blob = new Blob([this.response], {
type: "octet/stream",
});
const blobUrl = window.URL.createObjectURL(blob);
anchor.href = blobUrl;
anchor.download = objectName;
anchor.click();
window.URL.revokeObjectURL(blobUrl);
anchor.remove();
}
};
xhr.send();
};