Fixed Delete all object versions selector functionality (#2516)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
// 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 } from "react";
|
||||
import React, { Fragment, useState } from "react";
|
||||
import { DialogContentText } from "@mui/material";
|
||||
|
||||
import { ErrorResponseHandler } from "../../../../../../common/types";
|
||||
@@ -96,18 +96,42 @@ const DeleteObject = ({
|
||||
Are you sure you want to delete the selected {selectedObjects.length}{" "}
|
||||
objects?{" "}
|
||||
{versioning && (
|
||||
<FormSwitchWrapper
|
||||
label={"Delete All Versions"}
|
||||
indicatorLabels={["Yes", "No"]}
|
||||
checked={deleteVersions}
|
||||
value={"delete_versions"}
|
||||
id="delete-versions"
|
||||
name="delete-versions"
|
||||
onChange={(e) => {
|
||||
setDeleteVersions(!deleteVersions);
|
||||
}}
|
||||
description=""
|
||||
/>
|
||||
<Fragment>
|
||||
<br />
|
||||
<br />
|
||||
<FormSwitchWrapper
|
||||
label={"Delete All Versions"}
|
||||
indicatorLabels={["Yes", "No"]}
|
||||
checked={deleteVersions}
|
||||
value={"delete_versions"}
|
||||
id="delete-versions"
|
||||
name="delete-versions"
|
||||
onChange={(e) => {
|
||||
setDeleteVersions(!deleteVersions);
|
||||
}}
|
||||
description=""
|
||||
/>
|
||||
{deleteVersions && (
|
||||
<Fragment>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
border: "#c83b51 1px solid",
|
||||
borderRadius: 3,
|
||||
padding: 5,
|
||||
backgroundColor: "#c83b5120",
|
||||
color: "#c83b51",
|
||||
}}
|
||||
>
|
||||
This will remove the objects as well as all of their
|
||||
versions, <br />
|
||||
This action is irreversible.
|
||||
</div>
|
||||
<br />
|
||||
Are you sure you want to continue?
|
||||
</Fragment>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</DialogContentText>
|
||||
}
|
||||
|
||||
@@ -81,7 +81,11 @@ const DeleteObject = ({
|
||||
onConfirm={onConfirmDelete}
|
||||
onClose={onClose}
|
||||
confirmationContent={
|
||||
<DialogContentText>
|
||||
<DialogContentText
|
||||
sx={{
|
||||
width: "430px",
|
||||
}}
|
||||
>
|
||||
Are you sure you want to delete: <br />
|
||||
<b>{decodeURLString(selectedObject)}</b>{" "}
|
||||
{selectedVersion !== "" ? (
|
||||
@@ -98,18 +102,40 @@ const DeleteObject = ({
|
||||
? <br />
|
||||
<br />
|
||||
{versioning && selectedVersion === "" && (
|
||||
<FormSwitchWrapper
|
||||
label={"Delete All Versions"}
|
||||
indicatorLabels={["Yes", "No"]}
|
||||
checked={deleteVersions}
|
||||
value={"delete_versions"}
|
||||
id="delete-versions"
|
||||
name="delete-versions"
|
||||
onChange={(e) => {
|
||||
setDeleteVersions(!deleteVersions);
|
||||
}}
|
||||
description=""
|
||||
/>
|
||||
<Fragment>
|
||||
<FormSwitchWrapper
|
||||
label={"Delete All Versions"}
|
||||
indicatorLabels={["Yes", "No"]}
|
||||
checked={deleteVersions}
|
||||
value={"delete_versions"}
|
||||
id="delete-versions"
|
||||
name="delete-versions"
|
||||
onChange={(e) => {
|
||||
setDeleteVersions(!deleteVersions);
|
||||
}}
|
||||
description=""
|
||||
/>
|
||||
{deleteVersions && (
|
||||
<Fragment>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
border: "#c83b51 1px solid",
|
||||
borderRadius: 3,
|
||||
padding: 5,
|
||||
backgroundColor: "#c83b5120",
|
||||
color: "#c83b51",
|
||||
}}
|
||||
>
|
||||
This will remove the object as well as all of its versions,{" "}
|
||||
<br />
|
||||
This action is irreversible.
|
||||
</div>
|
||||
<br />
|
||||
Are you sure you want to continue?
|
||||
</Fragment>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</DialogContentText>
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ type MCClient interface {
|
||||
addNotificationConfig(ctx context.Context, arn string, events []string, prefix, suffix string, ignoreExisting bool) *probe.Error
|
||||
removeNotificationConfig(ctx context.Context, arn string, event string, prefix string, suffix string) *probe.Error
|
||||
watch(ctx context.Context, options mc.WatchOptions) (*mc.WatchObject, *probe.Error)
|
||||
remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult
|
||||
remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult
|
||||
list(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent
|
||||
get(ctx context.Context, opts mc.GetOptions) (io.ReadCloser, *probe.Error)
|
||||
shareDownload(ctx context.Context, versionID string, expires time.Duration) (string, *probe.Error)
|
||||
@@ -269,8 +269,8 @@ func (c mcClient) setVersioning(ctx context.Context, status string) *probe.Error
|
||||
return c.client.SetVersion(ctx, status, []string{}, false)
|
||||
}
|
||||
|
||||
func (c mcClient) remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
return c.client.Remove(ctx, isIncomplete, isRemoveBucket, isBypass, false, contentCh)
|
||||
func (c mcClient) remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
return c.client.Remove(ctx, isIncomplete, isRemoveBucket, isBypass, forceDelete, contentCh)
|
||||
}
|
||||
|
||||
func (c mcClient) list(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent {
|
||||
|
||||
@@ -664,7 +664,7 @@ func deleteObjects(ctx context.Context, client MCClient, bucket string, path str
|
||||
return deleteNonCurrentVersions(ctx, client, bucket, path)
|
||||
}
|
||||
|
||||
if recursive {
|
||||
if recursive || allVersions {
|
||||
return deleteMultipleObjects(ctx, client, recursive, allVersions)
|
||||
}
|
||||
|
||||
@@ -675,10 +675,16 @@ func deleteObjects(ctx context.Context, client MCClient, bucket string, path str
|
||||
//
|
||||
// Use cases:
|
||||
// * Remove objects recursively
|
||||
func deleteMultipleObjects(ctx context.Context, client MCClient, recursive bool, allVersions bool) error {
|
||||
func deleteMultipleObjects(ctx context.Context, client MCClient, recursive, allVersions bool) error {
|
||||
isBypass := false
|
||||
isIncomplete := false
|
||||
isRemoveBucket := false
|
||||
forceDelete := false
|
||||
|
||||
if recursive || allVersions {
|
||||
forceDelete = true
|
||||
}
|
||||
|
||||
listOpts := mc.ListOptions{
|
||||
Recursive: recursive,
|
||||
Incomplete: isIncomplete,
|
||||
@@ -707,7 +713,7 @@ func deleteMultipleObjects(ctx context.Context, client MCClient, recursive bool,
|
||||
}
|
||||
}()
|
||||
|
||||
for result := range client.remove(ctx, isIncomplete, isRemoveBucket, isBypass, contentCh) {
|
||||
for result := range client.remove(ctx, isIncomplete, isRemoveBucket, isBypass, forceDelete, contentCh) {
|
||||
if result.Err != nil {
|
||||
return result.Err.Cause
|
||||
}
|
||||
@@ -726,7 +732,7 @@ func deleteSingleObject(ctx context.Context, client MCClient, bucket, object str
|
||||
isIncomplete := false
|
||||
isRemoveBucket := false
|
||||
|
||||
resultCh := client.remove(ctx, isIncomplete, isRemoveBucket, isBypass, contentCh)
|
||||
resultCh := client.remove(ctx, isIncomplete, isRemoveBucket, isBypass, false, contentCh)
|
||||
for result := range resultCh {
|
||||
if result.Err != nil {
|
||||
return result.Err.Cause
|
||||
@@ -767,7 +773,7 @@ func deleteNonCurrentVersions(ctx context.Context, client MCClient, bucket, path
|
||||
}
|
||||
}()
|
||||
|
||||
for result := range client.remove(ctx, false, false, false, contentCh) {
|
||||
for result := range client.remove(ctx, false, false, false, false, contentCh) {
|
||||
if result.Err != nil {
|
||||
return result.Err.Cause
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ var (
|
||||
|
||||
var (
|
||||
mcListMock func(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent
|
||||
mcRemoveMock func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult
|
||||
mcRemoveMock func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult
|
||||
mcGetMock func(ctx context.Context, opts mc.GetOptions) (io.ReadCloser, *probe.Error)
|
||||
mcShareDownloadMock func(ctx context.Context, versionID string, expires time.Duration) (string, *probe.Error)
|
||||
)
|
||||
@@ -96,8 +96,8 @@ func (c s3ClientMock) list(ctx context.Context, opts mc.ListOptions) <-chan *mc.
|
||||
return mcListMock(ctx, opts)
|
||||
}
|
||||
|
||||
func (c s3ClientMock) remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
return mcRemoveMock(ctx, isIncomplete, isRemoveBucket, isBypass, contentCh)
|
||||
func (c s3ClientMock) remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
return mcRemoveMock(ctx, isIncomplete, isRemoveBucket, isBypass, forceDelete, contentCh)
|
||||
}
|
||||
|
||||
func (c s3ClientMock) get(ctx context.Context, opts mc.GetOptions) (io.ReadCloser, *probe.Error) {
|
||||
@@ -595,7 +595,7 @@ func Test_deleteObjects(t *testing.T) {
|
||||
recursive bool
|
||||
nonCurrent bool
|
||||
listFunc func(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent
|
||||
removeFunc func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult
|
||||
removeFunc func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult
|
||||
}
|
||||
tests := []struct {
|
||||
test string
|
||||
@@ -609,7 +609,7 @@ func Test_deleteObjects(t *testing.T) {
|
||||
versionID: "",
|
||||
recursive: false,
|
||||
nonCurrent: false,
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
resultCh := make(chan mc.RemoveResult, 1)
|
||||
resultCh <- mc.RemoveResult{Err: nil}
|
||||
close(resultCh)
|
||||
@@ -625,7 +625,7 @@ func Test_deleteObjects(t *testing.T) {
|
||||
versionID: "",
|
||||
recursive: false,
|
||||
nonCurrent: false,
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
resultCh := make(chan mc.RemoveResult, 1)
|
||||
resultCh <- mc.RemoveResult{Err: probe.NewError(errors.New("probe error"))}
|
||||
close(resultCh)
|
||||
@@ -641,7 +641,7 @@ func Test_deleteObjects(t *testing.T) {
|
||||
versionID: "",
|
||||
recursive: true,
|
||||
nonCurrent: false,
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
resultCh := make(chan mc.RemoveResult, 1)
|
||||
resultCh <- mc.RemoveResult{Err: nil}
|
||||
close(resultCh)
|
||||
@@ -665,7 +665,7 @@ func Test_deleteObjects(t *testing.T) {
|
||||
versionID: "",
|
||||
recursive: true,
|
||||
nonCurrent: false,
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
resultCh := make(chan mc.RemoveResult, 1)
|
||||
resultCh <- mc.RemoveResult{Err: probe.NewError(errors.New("probe error"))}
|
||||
close(resultCh)
|
||||
@@ -687,7 +687,7 @@ func Test_deleteObjects(t *testing.T) {
|
||||
versionID: "",
|
||||
recursive: true,
|
||||
nonCurrent: true,
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
resultCh := make(chan mc.RemoveResult, 1)
|
||||
resultCh <- mc.RemoveResult{Err: nil}
|
||||
close(resultCh)
|
||||
@@ -711,7 +711,7 @@ func Test_deleteObjects(t *testing.T) {
|
||||
versionID: "",
|
||||
recursive: true,
|
||||
nonCurrent: true,
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
removeFunc: func(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||
resultCh := make(chan mc.RemoveResult, 1)
|
||||
resultCh <- mc.RemoveResult{Err: probe.NewError(errors.New("probe error"))}
|
||||
close(resultCh)
|
||||
|
||||
Reference in New Issue
Block a user