Skip to content

Commit 5ab5232

Browse files
authored
Delete Non-current versions (#1735)
- Delete Non-current API - Delete non current modal implementation Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
1 parent d7fef8d commit 5ab5232

File tree

11 files changed

+366
-24
lines changed

11 files changed

+366
-24
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2022 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import * as React from "react";
18+
import { SVGProps } from "react";
19+
20+
const DeleteNonCurrentIcon = (props: SVGProps<SVGSVGElement>) => (
21+
<svg
22+
xmlns="http://www.w3.org/2000/svg"
23+
className={"min-icon"}
24+
viewBox="0 0 256 256"
25+
fill={"currentcolor"}
26+
{...props}
27+
>
28+
<path
29+
d="M222.83,0H114.08a5.38,5.38,0,0,0-5.38,5.37V118.1c.62.39,1.24.79,1.85,1.2a74.53,74.53,0,0,1,22.09,100.36h90.19a5.36,5.36,0,0,0,5.37-5.37V5.37A5.37,5.37,0,0,0,222.83,0Z"
30+
/>
31+
<path
32+
d="M106,125.38a68,68,0,1,0,30,56.35A67.59,67.59,0,0,0,106,125.38Zm8.16,94.78-7.77,7.76L68,189.5,29.56,227.92l-7.77-7.76,38.42-38.43L21.79,143.31l7.77-7.77L68,174l38.42-38.42,7.77,7.77L75.75,181.73Z"
33+
/>
34+
</svg>
35+
);
36+
37+
export default DeleteNonCurrentIcon;

portal-ui/src/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,4 @@ export { default as ArrowRightLink } from "./ArrowRightLink";
180180
export { default as LicenseDocIcon } from "./LicenseDocIcon";
181181
export { default as SelectAllIcon } from "./SelectAllIcon";
182182
export { default as BackIcon } from "./BackIcon";
183+
export { default as DeleteNonCurrentIcon } from "./DeleteNonCurrentIcon";
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2022 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import React, { useState, useEffect } from "react";
18+
import { connect } from "react-redux";
19+
import { DialogContentText } from "@mui/material";
20+
import Grid from "@mui/material/Grid";
21+
import { setErrorSnackMessage } from "../../../../../../actions";
22+
import { ErrorResponseHandler } from "../../../../../../common/types";
23+
import { decodeFileName } from "../../../../../../common/utils";
24+
import { ConfirmDeleteIcon } from "../../../../../../icons";
25+
import ConfirmDialog from "../../../../Common/ModalWrapper/ConfirmDialog";
26+
import api from "../../../../../../common/api";
27+
import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
28+
29+
interface IDeleteNonCurrentProps {
30+
closeDeleteModalAndRefresh: (refresh: boolean) => void;
31+
deleteOpen: boolean;
32+
selectedObject: string;
33+
selectedBucket: string;
34+
setErrorSnackMessage: typeof setErrorSnackMessage;
35+
}
36+
37+
const DeleteNonCurrentVersions = ({
38+
closeDeleteModalAndRefresh,
39+
deleteOpen,
40+
selectedBucket,
41+
selectedObject,
42+
setErrorSnackMessage,
43+
}: IDeleteNonCurrentProps) => {
44+
const [deleteLoading, setDeleteLoading] = useState<boolean>(false);
45+
const [typeConfirm, setTypeConfirm] = useState<string>("");
46+
47+
useEffect(() => {
48+
if (deleteLoading) {
49+
api
50+
.invoke(
51+
"DELETE",
52+
`/api/v1/buckets/${selectedBucket}/objects?path=${selectedObject}&non_current_versions=true`
53+
)
54+
.then(() => {
55+
closeDeleteModalAndRefresh(true);
56+
})
57+
.catch((error: ErrorResponseHandler) => {
58+
setErrorSnackMessage(error);
59+
setDeleteLoading(false);
60+
});
61+
}
62+
}, [
63+
deleteLoading,
64+
closeDeleteModalAndRefresh,
65+
setErrorSnackMessage,
66+
selectedObject,
67+
selectedBucket,
68+
]);
69+
70+
if (!selectedObject) {
71+
return null;
72+
}
73+
const onConfirmDelete = () => {
74+
setDeleteLoading(true);
75+
};
76+
77+
return (
78+
<ConfirmDialog
79+
title={`Delete Non-Current versions`}
80+
confirmText={"Delete"}
81+
isOpen={deleteOpen}
82+
titleIcon={<ConfirmDeleteIcon />}
83+
isLoading={deleteLoading}
84+
onConfirm={onConfirmDelete}
85+
onClose={() => closeDeleteModalAndRefresh(false)}
86+
confirmButtonProps={{
87+
disabled: typeConfirm !== "YES, PROCEED" || deleteLoading,
88+
}}
89+
confirmationContent={
90+
<DialogContentText>
91+
Are you sure you want to delete all the non-current versions for:{" "}
92+
<b>{decodeFileName(selectedObject)}</b>? <br />
93+
<br />
94+
To continue please type <b>YES, PROCEED</b> in the box.
95+
<Grid item xs={12}>
96+
<InputBoxWrapper
97+
id="type-confirm"
98+
name="retype-tenant"
99+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
100+
setTypeConfirm(event.target.value);
101+
}}
102+
label=""
103+
value={typeConfirm}
104+
/>
105+
</Grid>
106+
</DialogContentText>
107+
}
108+
/>
109+
);
110+
};
111+
112+
const mapDispatchToProps = {
113+
setErrorSnackMessage,
114+
};
115+
116+
const connector = connect(null, mapDispatchToProps);
117+
118+
export default connector(DeleteNonCurrentVersions);

portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/VersionsNavigator.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,13 @@ import {
5555
} from "../../../../ObjectBrowser/actions";
5656

5757
import { AppState } from "../../../../../../store";
58-
import { VersionsIcon } from "../../../../../../icons";
58+
import { DeleteNonCurrentIcon, VersionsIcon } from "../../../../../../icons";
5959
import VirtualizedList from "../../../../Common/VirtualizedList/VirtualizedList";
6060
import FileVersionItem from "./FileVersionItem";
6161
import SelectWrapper from "../../../../Common/FormComponents/SelectWrapper/SelectWrapper";
6262
import PreviewFileModal from "../Preview/PreviewFileModal";
63+
import RBIconButton from "../../../BucketDetails/SummaryItems/RBIconButton";
64+
import DeleteNonCurrent from "../ListObjects/DeleteNonCurrent";
6365

6466
const styles = (theme: Theme) =>
6567
createStyles({
@@ -160,6 +162,8 @@ const VersionsNavigator = ({
160162
const [restoreVersion, setRestoreVersion] = useState<string>("");
161163
const [sortValue, setSortValue] = useState<string>("date");
162164
const [previewOpen, setPreviewOpen] = useState<boolean>(false);
165+
const [deleteNonCurrentOpen, setDeleteNonCurrentOpen] =
166+
useState<boolean>(false);
163167

164168
// calculate object name to display
165169
let objectNameArray: string[] = [];
@@ -283,6 +287,16 @@ const VersionsNavigator = ({
283287
}
284288
};
285289

290+
const closeDeleteNonCurrent = (reloadAfterDelete: boolean) => {
291+
setDeleteNonCurrentOpen(false);
292+
293+
if (reloadAfterDelete) {
294+
setLoadingVersions(true);
295+
setSelectedVersion("");
296+
setLoadingObjectInfo(true);
297+
}
298+
};
299+
286300
const totalSpace = versions.reduce((acc: number, currValue: IFileInfo) => {
287301
if (currValue.size) {
288302
return acc + parseInt(currValue.size);
@@ -376,6 +390,14 @@ const VersionsNavigator = ({
376390
}}
377391
/>
378392
)}
393+
{deleteNonCurrentOpen && (
394+
<DeleteNonCurrent
395+
deleteOpen={deleteNonCurrentOpen}
396+
closeDeleteModalAndRefresh={closeDeleteNonCurrent}
397+
selectedBucket={bucketName}
398+
selectedObject={internalPaths}
399+
/>
400+
)}
379401
<Grid container className={classes.versionsContainer}>
380402
{!actualInfo && (
381403
<Grid item xs={12}>
@@ -417,6 +439,18 @@ const VersionsNavigator = ({
417439
}
418440
actions={
419441
<Fragment>
442+
<RBIconButton
443+
id={"delete-non-current"}
444+
tooltip={"Delete Non Current Versions"}
445+
onClick={() => {
446+
setDeleteNonCurrentOpen(true);
447+
}}
448+
text={""}
449+
icon={<DeleteNonCurrentIcon />}
450+
color="secondary"
451+
style={{ marginRight: 15 }}
452+
disabled={versions.length <= 1}
453+
/>
420454
<span className={classes.sortByLabel}>Sort by</span>
421455
<SelectWrapper
422456
id={"sort-by"}

portal-ui/src/screens/Console/Common/IconsScreen.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@ const IconsScreen = ({ classes }: IIconsScreenSimple) => {
343343
DeleteIcon
344344
</Grid>
345345

346+
<Grid item xs={3} sm={2} md={1}>
347+
<cicons.DeleteNonCurrentIcon />
348+
<br />
349+
DeleteNonCurrentIcon
350+
</Grid>
351+
346352
<Grid item xs={3} sm={2} md={1}>
347353
<cicons.DiagnosticsFeatureIcon />
348354
<br />

restapi/embedded_spec.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

restapi/operations/user_api/delete_object_parameters.go

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

restapi/operations/user_api/delete_object_urlbuilder.go

Lines changed: 13 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)