Added legal hold modal (#436)

This commit is contained in:
Alex
2020-11-24 18:39:16 -06:00
committed by GitHub
parent d573007747
commit 2caad9964f
3 changed files with 189 additions and 20 deletions

View File

@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import get from "lodash/get";
import * as reactMoment from "react-moment";
import clsx from "clsx";
@@ -33,9 +34,11 @@ import {
containerForHeader,
searchField,
} from "../../../../Common/FormComponents/common/styleLibrary";
import history from "../../../../../../history";
import { IFileInfo } from "./types";
import { removeRouteLevel } from "../../../../ObjectBrowser/actions";
import { Route } from "../../../../ObjectBrowser/reducers";
import { download } from "../utils";
import history from "../../../../../../history";
import api from "../../../../../../common/api";
import PageHeader from "../../../../Common/PageHeader/PageHeader";
import ShareIcon from "../../../../../../icons/ShareIcon";
@@ -46,10 +49,9 @@ import PencilIcon from "../../../../Common/TableWrapper/TableActionIcons/PencilI
import SetRetention from "./SetRetention";
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
import DeleteObject from "../ListObjects/DeleteObject";
import { removeRouteLevel } from "../../../../ObjectBrowser/actions";
import { connect } from "react-redux";
import AddTagModal from "./AddTagModal";
import DeleteTagModal from "./DeleteTagModal";
import SetLegalHoldModal from "./SetLegalHoldModal";
const styles = (theme: Theme) =>
createStyles({
@@ -136,18 +138,6 @@ interface IObjectDetailsProps {
removeRouteLevel: (newRoute: string) => any;
}
interface IFileInfo {
is_latest?: boolean;
last_modified: string;
legal_hold_status?: string;
name: string;
retention_mode?: string;
retention_until_date?: string;
size?: string;
tags?: object;
version_id: string;
}
const emptyFile: IFileInfo = {
is_latest: true,
last_modified: "",
@@ -171,6 +161,7 @@ const ObjectDetails = ({
const [tagModalOpen, setTagModalOpen] = useState<boolean>(false);
const [deleteTagModalOpen, setDeleteTagModalOpen] = useState<boolean>(false);
const [selectedTag, setSelectedTag] = useState<[string, string]>(["", ""]);
const [legalholdOpen, setLegalholdOpen] = useState<boolean>(false);
const [actualInfo, setActualInfo] = useState<IFileInfo>(emptyFile);
const [versions, setVersions] = useState<IFileInfo[]>([]);
const [filterVersion, setFilterVersion] = useState<string>("");
@@ -213,22 +204,18 @@ const ObjectDetails = ({
const openRetentionModal = () => {
setRetentionModalOpen(true);
console.log("open retention modal");
};
const closeRetentionModal = () => {
setRetentionModalOpen(false);
console.log("close retention modal");
};
const shareObject = () => {
setShareFileModalOpen(true);
console.log("share object");
};
const closeShareModal = () => {
setShareFileModalOpen(false);
console.log("close share modal");
};
const deleteTag = (tagKey: string, tagLabel: string) => {
@@ -272,6 +259,14 @@ const ObjectDetails = ({
}
};
const closeLegalholdModal = (reload: boolean) => {
setLegalholdOpen(false);
if (reload) {
setLoadObjectData(true);
}
};
const closeDeleteTagModal = (reloadObjectData: boolean) => {
setDeleteTagModalOpen(false);
@@ -325,6 +320,15 @@ const ObjectDetails = ({
selectedTag={selectedTag}
/>
)}
{legalholdOpen && (
<SetLegalHoldModal
open={legalholdOpen}
closeModalAndRefresh={closeLegalholdModal}
objectName={pathInBucket}
bucketName={bucketName}
actualInfo={actualInfo}
/>
)}
<Grid container>
<Grid item xs={12} className={classes.container}>
<Grid item xs={12} className={classes.obTitleSection}>
@@ -350,7 +354,7 @@ const ObjectDetails = ({
size="small"
className={classes.propertiesIcon}
onClick={() => {
console.log("open legal hold modal");
setLegalholdOpen(true);
}}
>
<PencilIcon active={true} />

View File

@@ -0,0 +1,138 @@
import React, { useState, useEffect } from "react";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import get from "lodash/get";
import Grid from "@material-ui/core/Grid";
import Button from "@material-ui/core/Button";
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
import { IFileInfo } from "./types";
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
import FormSwitchWrapper from "../../../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import api from "../../../../../../common/api";
const styles = (theme: Theme) =>
createStyles({
objectName: {
fontSize: 18,
fontWeight: 700,
marginBottom: 40,
},
buttonContainer: {
textAlign: "right",
},
errorBlock: {
color: "red",
},
...modalBasic,
});
interface ISetRetentionProps {
classes: any;
open: boolean;
closeModalAndRefresh: (reload: boolean) => void;
objectName: string;
bucketName: string;
actualInfo: IFileInfo;
}
const SetLegalHoldModal = ({
classes,
open,
closeModalAndRefresh,
objectName,
bucketName,
actualInfo,
}: ISetRetentionProps) => {
const [legalHoldEnabled, setLegalHoldEnabled] = useState<boolean>(false);
const [isSaving, setIsSaving] = useState<boolean>(false);
const [error, setError] = useState<string>("");
const versionId = actualInfo.version_id;
useEffect(() => {
const status = get(actualInfo, "legal_hold_status", "OFF");
setLegalHoldEnabled(status === "ON");
}, []);
const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
setIsSaving(true);
api
.invoke(
"PUT",
`/api/v1/buckets/${bucketName}/objects/legalhold?prefix=${objectName}&version_id=${versionId}`,
{ status: legalHoldEnabled ? "enabled" : "disabled" }
)
.then((res) => {
setIsSaving(false);
closeModalAndRefresh(true);
})
.catch((error) => {
setError(error);
setIsSaving(false);
});
};
const resetForm = () => {
setLegalHoldEnabled(false);
};
return (
<ModalWrapper
title="Set Legal Hold"
modalOpen={open}
onClose={() => {
resetForm();
closeModalAndRefresh(false);
}}
>
{error !== "" && <span className={classes.errorBlock}>{error}</span>}
<Grid item xs={12} className={classes.objectName}>
{objectName}
</Grid>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
onSubmit(e);
}}
>
<Grid item xs={12}>
<FormSwitchWrapper
value="legalhold"
id="legalhold"
name="legalhold"
checked={legalHoldEnabled}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setLegalHoldEnabled(!legalHoldEnabled);
}}
label={"Legal Hold Status"}
indicatorLabels={["Enabled", "Disabled"]}
tooltip={
"To enable this feature you need to enable versioning on the bucket before creation"
}
/>
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
<button
type="button"
color="primary"
className={classes.clearButton}
onClick={resetForm}
>
Reset
</button>
<Button
type="submit"
variant="contained"
color="primary"
disabled={isSaving}
>
Save
</Button>
</Grid>
</form>
</ModalWrapper>
);
};
export default withStyles(styles)(SetLegalHoldModal);

View File

@@ -0,0 +1,27 @@
// 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/>.
export interface IFileInfo {
is_latest?: boolean;
last_modified: string;
legal_hold_status?: string;
name: string;
retention_mode?: string;
retention_until_date?: string;
size?: string;
tags?: object;
version_id: string;
}