github.com/minio/console@v1.4.1/web-app/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/DeleteNonCurrent.tsx (about) 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, { Fragment, useEffect, useState } from "react"; 18 19 import { decodeURLString } from "../../../../../../common/utils"; 20 import { ConfirmDeleteIcon, Switch, Grid, InputBox } from "mds"; 21 import ConfirmDialog from "../../../../Common/ModalWrapper/ConfirmDialog"; 22 import { setErrorSnackMessage } from "../../../../../../systemSlice"; 23 import { AppState, useAppDispatch } from "../../../../../../store"; 24 import { hasPermission } from "../../../../../../common/SecureComponent"; 25 import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions"; 26 import { useSelector } from "react-redux"; 27 import { api } from "api"; 28 import { errorToHandler } from "api/errors"; 29 30 interface IDeleteNonCurrentProps { 31 closeDeleteModalAndRefresh: (refresh: boolean) => void; 32 deleteOpen: boolean; 33 selectedObject: string; 34 selectedBucket: string; 35 } 36 37 const DeleteNonCurrentVersions = ({ 38 closeDeleteModalAndRefresh, 39 deleteOpen, 40 selectedBucket, 41 selectedObject, 42 }: IDeleteNonCurrentProps) => { 43 const dispatch = useAppDispatch(); 44 const [deleteLoading, setDeleteLoading] = useState<boolean>(false); 45 const [typeConfirm, setTypeConfirm] = useState<string>(""); 46 const [bypassGovernance, setBypassGovernance] = useState<boolean>(false); 47 48 const retentionConfig = useSelector( 49 (state: AppState) => state.objectBrowser.retentionConfig, 50 ); 51 52 const canBypass = 53 hasPermission( 54 [selectedBucket], 55 [IAM_SCOPES.S3_BYPASS_GOVERNANCE_RETENTION], 56 ) && retentionConfig?.mode === "governance"; 57 58 useEffect(() => { 59 if (deleteLoading) { 60 api.buckets 61 .deleteObject(selectedBucket, { 62 prefix: selectedObject, 63 non_current_versions: true, 64 bypass: bypassGovernance, 65 }) 66 .then(() => { 67 closeDeleteModalAndRefresh(true); 68 }) 69 .catch((err) => { 70 dispatch(setErrorSnackMessage(errorToHandler(err.error))); 71 setDeleteLoading(false); 72 }); 73 } 74 }, [ 75 deleteLoading, 76 closeDeleteModalAndRefresh, 77 dispatch, 78 selectedObject, 79 selectedBucket, 80 bypassGovernance, 81 ]); 82 83 if (!selectedObject) { 84 return null; 85 } 86 const onConfirmDelete = () => { 87 setDeleteLoading(true); 88 }; 89 90 return ( 91 <ConfirmDialog 92 title={`Delete Non-Current versions`} 93 confirmText={"Delete"} 94 isOpen={deleteOpen} 95 titleIcon={<ConfirmDeleteIcon />} 96 isLoading={deleteLoading} 97 onConfirm={onConfirmDelete} 98 onClose={() => closeDeleteModalAndRefresh(false)} 99 confirmButtonProps={{ 100 disabled: typeConfirm !== "YES, PROCEED" || deleteLoading, 101 }} 102 confirmationContent={ 103 <Fragment> 104 Are you sure you want to delete all the non-current versions for:{" "} 105 <b>{decodeURLString(selectedObject)}</b>? <br /> 106 {canBypass && ( 107 <Fragment> 108 <div 109 style={{ 110 marginTop: 10, 111 }} 112 > 113 <Switch 114 label={"Bypass Governance Mode"} 115 indicatorLabels={["Yes", "No"]} 116 checked={bypassGovernance} 117 value={"bypass_governance"} 118 id="bypass_governance" 119 name="bypass_governance" 120 onChange={(e) => { 121 setBypassGovernance(!bypassGovernance); 122 }} 123 description="" 124 /> 125 </div> 126 </Fragment> 127 )} 128 <br /> 129 To continue please type <b>YES, PROCEED</b> in the box. 130 <br /> 131 <br /> 132 <Grid item xs={12}> 133 <InputBox 134 id="type-confirm" 135 name="retype-tenant" 136 onChange={(event: React.ChangeEvent<HTMLInputElement>) => { 137 setTypeConfirm(event.target.value); 138 }} 139 label="" 140 value={typeConfirm} 141 /> 142 </Grid> 143 </Fragment> 144 } 145 /> 146 ); 147 }; 148 149 export default DeleteNonCurrentVersions;