Fix Add Bucket Lifecycle Rule (#1797)

Fix Add Bucket Lifecycle Rule
Fix Edit ILM Rule
Update Bucket ILM Rules Listing

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-04-04 19:13:59 -07:00
committed by GitHub
parent c18c843d03
commit 822724a4f1
8 changed files with 591 additions and 469 deletions

View File

@@ -20,7 +20,15 @@ import { connect } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Button, LinearProgress, SelectChangeEvent } from "@mui/material";
import {
Accordion,
AccordionDetails,
AccordionSummary,
Button,
LinearProgress,
SelectChangeEvent,
Typography,
} from "@mui/material";
import Grid from "@mui/material/Grid";
import { setModalErrorSnackMessage } from "../../../../actions";
import {
@@ -42,6 +50,9 @@ import {
} from "../../Common/FormComponents/common/styleLibrary";
import { LifecycleConfigIcon } from "../../../../icons";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import { BucketVersioning } from "../types";
import { AppState } from "../../../../store";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
interface IReplicationModal {
open: boolean;
@@ -49,6 +60,7 @@ interface IReplicationModal {
classes: any;
bucketName: string;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
distributedSetup: boolean;
}
export interface ITiersDropDown {
@@ -73,6 +85,9 @@ const styles = (theme: Theme) =>
},
},
},
formFieldRowFilter: {
"& .MuiPaper-root": { padding: 0 },
},
...spacingUtils,
...modalStyleUtils,
...formFieldStyles,
@@ -85,19 +100,25 @@ const AddLifecycleModal = ({
classes,
bucketName,
setModalErrorSnackMessage,
distributedSetup,
}: IReplicationModal) => {
const [loadingTiers, setLoadingTiers] = useState<boolean>(true);
const [tiersList, setTiersList] = useState<ITiersDropDown[]>([]);
const [addLoading, setAddLoading] = useState(false);
const [isVersioned, setIsVersioned] = useState<boolean>(false);
const [prefix, setPrefix] = useState("");
const [tags, setTags] = useState<string>("");
const [storageClass, setStorageClass] = useState("");
const [NCExpirationDays, setNCExpirationDays] = useState<string>("");
const [NCTransitionDays, setNCTransitionDays] = useState<string>("");
const [ilmType, setIlmType] = useState<string>("expiry");
const [expiryDays, setExpiryDays] = useState<string>("");
const [transitionDays, setTransitionDays] = useState<string>("");
const [targetVersion, setTargetVersion] = useState<"current" | "noncurrent">(
"current"
);
const [lifecycleDays, setLifecycleDays] = useState<string>("");
const [isFormValid, setIsFormValid] = useState<boolean>(false);
const [expiredObjectDM, setExpiredObjectDM] = useState<boolean>(false);
const [loadingVersioning, setLoadingVersioning] = useState<boolean>(true);
useEffect(() => {
if (loadingTiers) {
@@ -136,39 +157,56 @@ const AddLifecycleModal = ({
}
}
setIsFormValid(valid);
}, [ilmType, expiryDays, transitionDays, storageClass]);
}, [ilmType, lifecycleDays, storageClass]);
useEffect(() => {
if (loadingVersioning && distributedSetup) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/versioning`)
.then((res: BucketVersioning) => {
setIsVersioned(res.is_versioned);
setLoadingVersioning(false);
})
.catch((err: ErrorResponseHandler) => {
setModalErrorSnackMessage(err);
setLoadingVersioning(false);
});
}
}, [
loadingVersioning,
setModalErrorSnackMessage,
bucketName,
distributedSetup,
]);
const addRecord = () => {
let rules = {};
let markerOn = false;
if (ilmType === "expiry") {
let expiry = {
expiry_days: parseInt(expiryDays),
};
let expiry: { [key: string]: number } = {};
if (parseInt(expiryDays) > 0 && parseInt(NCExpirationDays) > 0) {
markerOn = true;
if (targetVersion === "current") {
expiry["expiry_days"] = parseInt(lifecycleDays);
} else {
expiry["noncurrentversion_expiration_days"] = parseInt(lifecycleDays);
}
rules = {
...expiry,
noncurrentversion_expiration_days: parseInt(NCExpirationDays),
};
} else {
let transition = {
transition_days: parseInt(transitionDays),
};
if (parseInt(transitionDays) > 0 && parseInt(NCTransitionDays) > 0) {
markerOn = true;
let transition: { [key: string]: number | string } = {};
if (targetVersion === "current") {
transition["transition_days"] = parseInt(lifecycleDays);
transition["storage_class"] = storageClass;
} else {
transition["noncurrentversion_transition_days"] =
parseInt(lifecycleDays);
transition["noncurrentversion_transition_storage_class"] = storageClass;
}
rules = {
...transition,
noncurrentversion_transition_days: parseInt(NCTransitionDays),
storage_class: storageClass,
};
}
@@ -176,7 +214,7 @@ const AddLifecycleModal = ({
type: ilmType,
prefix,
tags,
expired_object_delete_marker: markerOn,
expired_object_delete_marker: expiredObjectDM,
...rules,
};
@@ -226,13 +264,13 @@ const AddLifecycleModal = ({
<Grid container>
<Grid item xs={12} className={classes.formScrollable}>
<Grid item xs={12}>
<Grid container>
<Grid item xs={3} textAlign={"left"}>
<Grid container spacing={1}>
<Grid item xs={12}>
<RadioGroupSelector
currentSelection={ilmType}
id="quota_type"
name="quota_type"
label=""
id="ilm_type"
name="ilm_type"
label="Type of lifecycle"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setIlmType(e.target.value as string);
}}
@@ -242,65 +280,56 @@ const AddLifecycleModal = ({
]}
/>
</Grid>
<Grid item xs={9} />
{ilmType === "expiry" ? (
<Fragment>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id="expiry_days"
name="expiry_days"
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
if (e.target.validity.valid) {
setExpiryDays(e.target.value);
}
}}
pattern={"[0-9]*"}
label="Delete Latest Version After"
value={expiryDays}
overlayObject={
<InputUnitMenu
id={"expire-current-unit"}
unitSelected={"days"}
unitsList={[{ label: "Days", value: "days" }]}
disabled={true}
/>
}
/>
</Grid>
{isVersioned && (
<Grid item xs={12}>
<SelectWrapper
value={targetVersion}
id="object_version"
name="object_version"
label="Object Version"
onChange={(e) => {
setTargetVersion(
e.target.value as "current" | "noncurrent"
);
}}
options={[
{ value: "current", label: "Current Version" },
{ value: "noncurrent", label: "Non-Current Version" },
]}
/>
</Grid>
)}
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id="noncurrentversion_expiration_days"
name="noncurrentversion_expiration_days"
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
if (e.target.validity.valid) {
setNCExpirationDays(e.target.value);
}
}}
pattern={"[0-9]*"}
label="Delete Older Versions After"
value={NCExpirationDays}
min="0"
overlayObject={
<InputUnitMenu
id={"expire-noncurrent-unit"}
unitSelected={"days"}
unitsList={[{ label: "Days", value: "days" }]}
disabled={true}
/>
}
<Grid item xs={12}>
<InputBoxWrapper
id="expiry_days"
name="expiry_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.validity.valid) {
setLifecycleDays(e.target.value);
}
}}
pattern={"[0-9]*"}
label="After"
value={lifecycleDays}
overlayObject={
<InputUnitMenu
id={"expire-current-unit"}
unitSelected={"days"}
unitsList={[{ label: "Days", value: "days" }]}
disabled={true}
/>
</Grid>
</Fragment>
}
/>
</Grid>
{ilmType === "expiry" ? (
<Fragment></Fragment>
) : (
<Fragment>
<Grid item xs={12} className={classes.formFieldRow}>
<Grid item xs={12}>
<SelectWrapper
label="Tier"
label="To Tier"
id="storage_class"
name="storage_class"
value={storageClass}
@@ -310,90 +339,73 @@ const AddLifecycleModal = ({
options={tiersList}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id="transition_days"
name="transition_days"
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
if (e.target.validity.valid) {
setTransitionDays(e.target.value);
}
}}
pattern={"[0-9]*"}
label="Transition Latest Version"
value={transitionDays}
min="0"
overlayObject={
<InputUnitMenu
id={"transition-current-unit"}
unitSelected={"days"}
unitsList={[{ label: "Days", value: "days" }]}
disabled={true}
/>
}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
type="number"
id="noncurrentversion_transition_days"
name="noncurrentversion_transition_days"
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
if (e.target.validity.valid) {
setNCTransitionDays(e.target.value);
}
}}
label="Transition Older Versions"
value={NCTransitionDays}
pattern={"[0-9]*"}
overlayObject={
<InputUnitMenu
id={"transition-noncurrent-unit"}
unitSelected={"days"}
unitsList={[{ label: "Days", value: "days" }]}
disabled={true}
/>
}
/>
</Grid>
</Fragment>
)}
<Grid item xs={12} className={classes.formFieldRowFilter}>
<Accordion>
<AccordionSummary>
<Typography>Filters</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid item xs={12}>
<InputBoxWrapper
id="prefix"
name="prefix"
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
setPrefix(e.target.value);
}}
label="Prefix"
value={prefix}
/>
</Grid>
<Grid item xs={12}>
<QueryMultiSelector
name="tags"
label="Tags"
elements={""}
onChange={(vl: string) => {
setTags(vl);
}}
keyPlaceholder="Tag Key"
valuePlaceholder="Tag Value"
withBorder
/>
</Grid>
</AccordionDetails>
</Accordion>
</Grid>
{ilmType === "expiry" && targetVersion === "noncurrent" && (
<Grid item xs={12} className={classes.formFieldRowFilter}>
<Accordion>
<AccordionSummary>
<Typography>Advanced</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid item xs={12}>
<FormSwitchWrapper
value="expired_delete_marker"
id="expired_delete_marker"
name="expired_delete_marker"
checked={expiredObjectDM}
onChange={(
event: React.ChangeEvent<HTMLInputElement>
) => {
setExpiredObjectDM(event.target.checked);
}}
label={"Expire Delete Marker"}
description={
"Remove the reference to the object if no versions are left"
}
/>
</Grid>
</AccordionDetails>
</Accordion>
</Grid>
)}
</Grid>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<fieldset className={classes.fieldGroup}>
<legend className={classes.descriptionText}>Filters</legend>
<Grid item xs={12}>
<InputBoxWrapper
id="prefix"
name="prefix"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPrefix(e.target.value);
}}
label="Prefix"
value={prefix}
/>
</Grid>
<Grid item xs={12}>
<QueryMultiSelector
name="tags"
label="Tags"
elements={""}
onChange={(vl: string) => {
setTags(vl);
}}
keyPlaceholder="Tag Key"
valuePlaceholder="Tag Value"
withBorder
/>
</Grid>
</fieldset>
</Grid>
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>
<Button
@@ -428,7 +440,11 @@ const AddLifecycleModal = ({
);
};
const connector = connect(null, {
const mapState = (state: AppState) => ({
distributedSetup: state.system.distributedSetup,
});
const connector = connect(mapState, {
setModalErrorSnackMessage,
});

View File

@@ -20,7 +20,6 @@ import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import get from "lodash/get";
import * as reactMoment from "react-moment";
import Grid from "@mui/material/Grid";
import { BucketInfo, LifeCycleItem } from "../types";
import { AddIcon, TiersIcon } from "../../../../icons";
@@ -38,8 +37,8 @@ import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import HelpBox from "../../../../common/HelpBox";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
import {
SecureComponent,
hasPermission,
SecureComponent,
} from "../../../../common/SecureComponent";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import RBIconButton from "./SummaryItems/RBIconButton";
@@ -142,62 +141,96 @@ const BucketLifecyclePanel = ({
}
};
const expirationRender = (expiration: any) => {
if (expiration.days) {
return `${expiration.days} day${expiration.days > 1 ? "s" : ""}`;
}
if (expiration.date === "0001-01-01T00:00:00Z") {
return "";
}
return <reactMoment.default>{expiration.date}</reactMoment.default>;
};
const transitionRender = (transition: any) => {
if (transition.days) {
return `${transition.days} day${transition.days > 1 ? "s" : ""}`;
}
if (transition.date === "0001-01-01T00:00:00Z") {
return "";
}
return <reactMoment.default>{transition.date}</reactMoment.default>;
};
const renderStorageClass = (objectST: any) => {
const stClass = get(objectST, "transition.storage_class", "");
let stClass = get(objectST, "transition.storage_class", "");
stClass = get(objectST, "transition.noncurrent_storage_class", stClass);
return stClass;
};
const lifecycleColumns = [
{ label: "ID", elementKey: "id" },
{
label: "Type",
renderFullObject: true,
renderFunction: (el: LifeCycleItem) => {
if (!el) {
return <Fragment />;
}
if (
el.expiration &&
(el.expiration.days > 0 || el.expiration.noncurrent_expiration_days)
) {
return <span>Expiry</span>;
}
if (
el.transition &&
(el.transition.days > 0 || el.transition.noncurrent_transition_days)
) {
return <span>Transition</span>;
}
return <Fragment />;
},
},
{
label: "Version",
renderFullObject: true,
renderFunction: (el: LifeCycleItem) => {
if (!el) {
return <Fragment />;
}
if (el.expiration) {
if (el.expiration.days > 0) {
return <span>Current</span>;
} else if (el.expiration.noncurrent_expiration_days) {
return <span>Non-Current</span>;
}
}
if (el.transition) {
if (el.transition.days > 0) {
return <span>Current</span>;
} else if (el.transition.noncurrent_transition_days) {
return <span>Non-Current</span>;
}
}
},
},
{
label: "Tier",
elementKey: "storage_class",
renderFunction: renderStorageClass,
renderFullObject: true,
},
{
label: "Prefix",
elementKey: "prefix",
},
{
label: "After",
renderFullObject: true,
renderFunction: (el: LifeCycleItem) => {
if (!el) {
return <Fragment />;
}
if (el.expiration) {
if (el.expiration.days > 0) {
return <span>{el.expiration.days} days</span>;
} else if (el.expiration.noncurrent_expiration_days) {
return <span>{el.expiration.noncurrent_expiration_days} days</span>;
}
}
if (el.transition) {
if (el.transition.days > 0) {
return <span>{el.transition.days} days</span>;
} else if (el.transition.noncurrent_transition_days) {
return <span>{el.transition.noncurrent_transition_days} days</span>;
}
}
},
},
{
label: "Status",
elementKey: "status",
},
{
label: "Expiration",
elementKey: "expiration",
renderFunction: expirationRender,
},
{
label: "Transition",
elementKey: "transition",
renderFunction: transitionRender,
},
{
label: "Storage Class",
elementKey: "storage_class",
renderFunction: renderStorageClass,
renderFullObject: true,
},
];
const lifecycleActions = [
@@ -226,7 +259,7 @@ const BucketLifecyclePanel = ({
open={editLifecycleOpen}
closeModalAndRefresh={closeEditLCAndRefresh}
selectedBucket={bucketName}
lifecycle={selectedLifecycleRule}
lifecycleRule={selectedLifecycleRule}
/>
)}
{addLifecycleOpen && (

View File

@@ -16,7 +16,15 @@
import React, { useEffect, useState, Fragment } from "react";
import { connect } from "react-redux";
import { Button, LinearProgress, SelectChangeEvent } from "@mui/material";
import {
Accordion,
AccordionDetails,
AccordionSummary,
Button,
LinearProgress,
SelectChangeEvent,
Typography,
} from "@mui/material";
import { Theme } from "@mui/material/styles";
import get from "lodash/get";
import Grid from "@mui/material/Grid";
@@ -62,6 +70,9 @@ const styles = (theme: Theme) =>
},
},
},
formFieldRowAccordion: {
"& .MuiPaper-root": { padding: 0 },
},
...spacingUtils,
...modalStyleUtils,
...formFieldStyles,
@@ -72,7 +83,7 @@ interface IAddUserContentProps {
classes: any;
closeModalAndRefresh: (reload: boolean) => void;
selectedBucket: string;
lifecycle: LifeCycleItem;
lifecycleRule: LifeCycleItem;
open: boolean;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
@@ -81,7 +92,7 @@ const EditLifecycleConfiguration = ({
classes,
closeModalAndRefresh,
selectedBucket,
lifecycle,
lifecycleRule,
open,
setModalErrorSnackMessage,
}: IAddUserContentProps) => {
@@ -141,40 +152,66 @@ const EditLifecycleConfiguration = ({
}, [ilmType, expiryDays, transitionDays, storageClass]);
useEffect(() => {
if (lifecycle.status === "Enabled") {
if (lifecycleRule.status === "Enabled") {
setEnabled(true);
}
let transitionMode = false;
if (lifecycle.transition) {
if (lifecycle.transition.days && lifecycle.transition.days !== 0) {
setTransitionDays(lifecycle.transition.days.toString());
if (lifecycleRule.transition) {
if (
lifecycleRule.transition.days &&
lifecycleRule.transition.days !== 0
) {
setTransitionDays(lifecycleRule.transition.days.toString());
setIlmType("transition");
transitionMode = true;
}
if (
lifecycleRule.transition.noncurrent_transition_days &&
lifecycleRule.transition.noncurrent_transition_days !== 0
) {
setNCTransitionDays(
lifecycleRule.transition.noncurrent_transition_days.toString()
);
setIlmType("transition");
transitionMode = true;
}
// Fallback to old rules by date
if (
lifecycle.transition.date &&
lifecycle.transition.date !== "0001-01-01T00:00:00Z"
lifecycleRule.transition.date &&
lifecycleRule.transition.date !== "0001-01-01T00:00:00Z"
) {
setIlmType("transition");
transitionMode = true;
}
}
if (lifecycle.expiration) {
if (lifecycle.expiration.days && lifecycle.expiration.days !== 0) {
setExpiryDays(lifecycle.expiration.days.toString());
if (lifecycleRule.expiration) {
if (
lifecycleRule.expiration.days &&
lifecycleRule.expiration.days !== 0
) {
setExpiryDays(lifecycleRule.expiration.days.toString());
setIlmType("expiry");
transitionMode = false;
}
if (
lifecycleRule.expiration.noncurrent_expiration_days &&
lifecycleRule.expiration.noncurrent_expiration_days !== 0
) {
setNCExpirationDays(
lifecycleRule.expiration.noncurrent_expiration_days.toString()
);
setIlmType("expiry");
transitionMode = false;
}
// Fallback to old rules by date
if (
lifecycle.expiration.date &&
lifecycle.expiration.date !== "0001-01-01T00:00:00Z"
lifecycleRule.expiration.date &&
lifecycleRule.expiration.date !== "0001-01-01T00:00:00Z"
) {
setIlmType("expiry");
transitionMode = false;
@@ -183,23 +220,25 @@ const EditLifecycleConfiguration = ({
// Transition fields
if (transitionMode) {
setStorageClass(lifecycle.transition?.storage_class || "");
setStorageClass(lifecycleRule.transition?.storage_class || "");
setNCTransitionDays(
lifecycle.transition?.noncurrent_transition_days?.toString() || "0"
lifecycleRule.transition?.noncurrent_transition_days?.toString() || "0"
);
setNCTransitionSC(
lifecycleRule.transition?.noncurrent_storage_class || ""
);
setNCTransitionSC(lifecycle.transition?.noncurrent_storage_class || "");
} else {
// Expiry fields
setNCExpirationDays(
lifecycle.expiration?.noncurrent_expiration_days?.toString() || "0"
lifecycleRule.expiration?.noncurrent_expiration_days?.toString() || "0"
);
}
setExpiredObjectDM(!!lifecycle.expiration?.delete_marker);
setPrefix(lifecycle.prefix || "");
setExpiredObjectDM(!!lifecycleRule.expiration?.delete_marker);
setPrefix(lifecycleRule.prefix || "");
if (lifecycle.tags) {
const tgs = lifecycle.tags.reduce(
if (lifecycleRule.tags) {
const tgs = lifecycleRule.tags.reduce(
(stringLab: string, currItem: any, index: number) => {
return `${stringLab}${index !== 0 ? "&" : ""}${currItem.key}=${
currItem.value
@@ -210,7 +249,7 @@ const EditLifecycleConfiguration = ({
setTags(tgs);
}
}, [lifecycle]);
}, [lifecycleRule]);
const saveRecord = (event: React.FormEvent) => {
event.preventDefault();
@@ -219,28 +258,45 @@ const EditLifecycleConfiguration = ({
return;
}
setAddLoading(true);
if (selectedBucket !== null && lifecycle !== null) {
if (selectedBucket !== null && lifecycleRule !== null) {
let rules = {};
if (ilmType === "expiry") {
let expiry = {
expiry_days: parseInt(expiryDays),
};
let expiry: { [key: string]: number } = {};
if (
lifecycleRule.expiration?.days &&
lifecycleRule.expiration?.days > 0
) {
expiry["expiry_days"] = parseInt(expiryDays);
}
if (lifecycleRule.expiration?.noncurrent_expiration_days) {
expiry["noncurrentversion_expiration_days"] =
parseInt(NCExpirationDays);
}
rules = {
...expiry,
noncurrentversion_expiration_days: parseInt(NCExpirationDays),
};
} else {
let transition = {
transition_days: parseInt(transitionDays),
};
let transition: { [key: string]: number | string } = {};
if (
lifecycleRule.expiration?.days &&
lifecycleRule.expiration?.days > 0
) {
transition["transition_days"] = parseInt(expiryDays);
transition["storage_class"] = storageClass;
}
if (lifecycleRule.expiration?.noncurrent_expiration_days) {
transition["noncurrentversion_transition_days"] =
parseInt(NCExpirationDays);
transition["noncurrentversion_transition_storage_class"] =
NCTransitionSC;
}
rules = {
...transition,
noncurrentversion_transition_days: parseInt(NCTransitionDays),
noncurrentversion_transition_storage_class: NCTransitionSC,
storage_class: storageClass,
};
}
@@ -256,7 +312,7 @@ const EditLifecycleConfiguration = ({
api
.invoke(
"PUT",
`/api/v1/buckets/${selectedBucket}/lifecycle/${lifecycle.id}`,
`/api/v1/buckets/${selectedBucket}/lifecycle/${lifecycleRule.id}`,
lifecycleUpdate
)
.then((res) => {
@@ -288,95 +344,111 @@ const EditLifecycleConfiguration = ({
>
<Grid container>
<Grid item xs={12} className={classes.formScrollable}>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id="id"
name="id"
label="Id"
value={lifecycle.id}
onChange={() => {}}
disabled
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<FormSwitchWrapper
label="Rule State"
indicatorLabels={["Enabled", "Disabled"]}
checked={enabled}
value={"user_enabled"}
id="user-status"
name="user-status"
onChange={(e) => {
setEnabled(e.target.checked);
}}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<fieldset className={classes.fieldGroup}>
<legend className={classes.descriptionText}>
Lifecycle Configuration
</legend>
<Grid container spacing={1}>
<Grid item xs={12}>
<InputBoxWrapper
id="id"
name="id"
label="Id"
value={lifecycleRule.id}
onChange={() => {}}
disabled
/>
</Grid>
<Grid item xs={12}>
<FormSwitchWrapper
label="Status"
indicatorLabels={["Enabled", "Disabled"]}
checked={enabled}
value={"user_enabled"}
id="rule_status"
name="rule_status"
onChange={(e) => {
setEnabled(e.target.checked);
}}
/>
</Grid>
<Grid item xs={12}>
<RadioGroupSelector
currentSelection={ilmType}
id="rule_type"
name="rule_type"
label="Rule Type"
selectorOptions={[
{ value: "expiry", label: "Expiry" },
{ value: "transition", label: "Transition" },
]}
onChange={() => {}}
disableOptions
/>
</Grid>
{ilmType === "expiry" && lifecycleRule.expiration?.days && (
<Grid item xs={12}>
<RadioGroupSelector
currentSelection={ilmType}
id="quota_type"
name="quota_type"
label="ILM Rule"
selectorOptions={[
{ value: "expiry", label: "Expiry" },
{ value: "transition", label: "Transition" },
]}
onChange={() => {}}
disableOptions
<InputBoxWrapper
type="number"
id="expiry_days"
name="expiry_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setExpiryDays(e.target.value);
}}
label="Expiry Days"
value={expiryDays}
min="0"
/>
</Grid>
{ilmType === "expiry" ? (
<Fragment>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
type="number"
id="expiry_days"
name="expiry_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setExpiryDays(e.target.value);
}}
label="Expiry Days"
value={expiryDays}
min="0"
/>
</Grid>
)}
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
type="number"
id="noncurrentversion_expiration_days"
name="noncurrentversion_expiration_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setNCExpirationDays(e.target.value);
}}
label="Non-current Expiration Days"
value={NCExpirationDays}
min="0"
/>
</Grid>
</Fragment>
) : (
{ilmType === "expiry" &&
lifecycleRule.expiration?.noncurrent_expiration_days && (
<Grid item xs={12}>
<InputBoxWrapper
type="number"
id="noncurrentversion_expiration_days"
name="noncurrentversion_expiration_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setNCExpirationDays(e.target.value);
}}
label="Non-current Expiration Days"
value={NCExpirationDays}
min="0"
/>
</Grid>
)}
{ilmType === "transition" && lifecycleRule.transition?.days && (
<Fragment>
<Grid item xs={12}>
<InputBoxWrapper
type="number"
id="transition_days"
name="transition_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTransitionDays(e.target.value);
}}
label="Transition Days"
value={transitionDays}
min="0"
/>
</Grid>
<Grid item xs={12}>
<SelectWrapper
label="Storage Class"
id="storage_class"
name="storage_class"
value={storageClass}
onChange={(e: SelectChangeEvent<string>) => {
setStorageClass(e.target.value as string);
}}
options={tiersList}
/>
</Grid>
</Fragment>
)}
{ilmType === "transition" &&
lifecycleRule.transition?.noncurrent_transition_days && (
<Fragment>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
type="number"
id="transition_days"
name="transition_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTransitionDays(e.target.value);
}}
label="Transition Days"
value={transitionDays}
min="0"
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<Grid item xs={12}>
<InputBoxWrapper
type="number"
id="noncurrentversion_transition_days"
@@ -389,7 +461,8 @@ const EditLifecycleConfiguration = ({
min="0"
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<Grid item xs={12}>
<InputBoxWrapper
id="noncurrentversion_t_SC"
name="noncurrentversion_t_SC"
@@ -401,65 +474,69 @@ const EditLifecycleConfiguration = ({
value={NCTransitionSC}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<SelectWrapper
label="Storage Class"
id="storage_class"
name="storage_class"
value={storageClass}
onChange={(e: SelectChangeEvent<string>) => {
setStorageClass(e.target.value as string);
}}
options={tiersList}
/>
</Grid>
</Fragment>
)}
</fieldset>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<fieldset className={classes.fieldGroup}>
<legend className={classes.descriptionText}>
File Configuration
</legend>
<Grid item xs={12} className={classes.formFieldRowAccordion}>
<Accordion>
<AccordionSummary>
<Typography>Filters</Typography>
</AccordionSummary>
<Grid item xs={12}>
<InputBoxWrapper
id="prefix"
name="prefix"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPrefix(e.target.value);
}}
label="Prefix"
value={prefix}
/>
</Grid>
<Grid item xs={12}>
<QueryMultiSelector
name="tags"
label="Tags"
elements={tags}
onChange={(vl: string) => {
setTags(vl);
}}
keyPlaceholder="Tag Key"
valuePlaceholder="Tag Value"
withBorder
/>
</Grid>
<Grid item xs={12}>
<FormSwitchWrapper
value="expired_delete_marker"
id="expired_delete_marker"
name="expired_delete_marker"
checked={expiredObjectDM}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setExpiredObjectDM(event.target.checked);
}}
label={"Expired Object Delete Marker"}
/>
</Grid>
</fieldset>
<AccordionDetails>
<Grid item xs={12}>
<InputBoxWrapper
id="prefix"
name="prefix"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPrefix(e.target.value);
}}
label="Prefix"
value={prefix}
/>
</Grid>
<Grid item xs={12}>
<QueryMultiSelector
name="tags"
label="Tags"
elements={tags}
onChange={(vl: string) => {
setTags(vl);
}}
keyPlaceholder="Tag Key"
valuePlaceholder="Tag Value"
withBorder
/>
</Grid>
</AccordionDetails>
</Accordion>
</Grid>
{ilmType === "expiry" &&
lifecycleRule.expiration?.noncurrent_expiration_days && (
<Grid item xs={12} className={classes.formFieldRowAccordion}>
<Accordion>
<AccordionSummary>
<Typography>Advanced</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid item xs={12}>
<FormSwitchWrapper
value="expired_delete_marker"
id="expired_delete_marker"
name="expired_delete_marker"
checked={expiredObjectDM}
onChange={(
event: React.ChangeEvent<HTMLInputElement>
) => {
setExpiredObjectDM(event.target.checked);
}}
label={"Expired Object Delete Marker"}
/>
</Grid>
</AccordionDetails>
</Accordion>
</Grid>
)}
</Grid>
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>

View File

@@ -50,10 +50,6 @@ interface ICodeWrapper {
const styles = (theme: Theme) =>
createStyles({
...fieldBasic,
inputLabel: {
...fieldBasic.inputLabel,
fontWeight: "normal",
},
});
const langHighlight: Record<string, any> = {

View File

@@ -174,48 +174,40 @@ const FormSwitchWrapper = ({
return (
<div className={classes.divContainer}>
<Grid container alignItems={"center"}>
<Grid item xs>
<Grid container>
<Grid
item
xs={12}
sm={description !== "" ? 4 : 10}
md={description !== "" ? 3 : 9}
>
{label !== "" && (
<InputLabel htmlFor={id} className={classes.inputLabel}>
<span>{label}</span>
{tooltip !== "" && (
<div className={classes.tooltipContainer}>
<Tooltip title={tooltip} placement="top-start">
<div className={classes.tooltip}>
<HelpIcon />
</div>
</Tooltip>
<Grid item xs={12} sm={8} md={8}>
{label !== "" && (
<InputLabel htmlFor={id} className={classes.inputLabel}>
<span>{label}</span>
{tooltip !== "" && (
<div className={classes.tooltipContainer}>
<Tooltip title={tooltip} placement="top-start">
<div className={classes.tooltip}>
<HelpIcon />
</div>
)}
</InputLabel>
</Tooltip>
</div>
)}
</Grid>
<Grid item xs={12} sm textAlign={"left"}>
{description !== "" && (
<Typography component="p" className={classes.fieldDescription}>
{description}
</Typography>
)}
</Grid>
</Grid>
</InputLabel>
)}
</Grid>
<Grid
item
xs={12}
sm={2}
sm={4}
md={4}
textAlign={"right"}
justifyContent={"end"}
className={classes.switchContainer}
>
{switchComponent}
</Grid>
{description !== "" && (
<Grid item xs={12} textAlign={"left"}>
<Typography component="p" className={classes.fieldDescription}>
{description}
</Typography>
</Grid>
)}
</Grid>
</div>
);

View File

@@ -86,10 +86,6 @@ const styles = (theme: Theme) =>
top: 5,
},
},
inputLabel: {
...fieldBasic.inputLabel,
fontWeight: "normal",
},
});
const inputStyles = makeStyles((theme: Theme) =>

View File

@@ -51,12 +51,6 @@ const styles = (theme: Theme) =>
createStyles({
...fieldBasic,
...tooltipHelper,
inputLabel: {
...fieldBasic.inputLabel,
"& span": {
fontWeight: "normal",
},
},
fieldContainer: {
display: "flex",
"@media (max-width: 600px)": {

View File

@@ -181,19 +181,24 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params user_api
}
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
TransitionDays: strconv.Itoa(int(params.Body.TransitionDays)),
StorageClass: strings.ToUpper(params.Body.StorageClass),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays),
NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass),
IsTransitionDaysSet: params.Body.TransitionDays != 0,
IsNoncurrentVersionTransitionDaysSet: params.Body.NoncurrentversionTransitionDays != 0,
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
IsTransitionDaysSet: params.Body.TransitionDays != 0,
IsNoncurrentVersionTransitionDaysSet: params.Body.NoncurrentversionTransitionDays != 0,
}
if params.Body.NoncurrentversionTransitionDays > 0 {
opts.NoncurrentVersionTransitionDays = int(params.Body.NoncurrentversionTransitionDays)
opts.NoncurrentVersionTransitionStorageClass = strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass)
} else {
opts.TransitionDays = strconv.Itoa(int(params.Body.TransitionDays))
opts.StorageClass = strings.ToUpper(params.Body.StorageClass)
}
} else if params.Body.Type == models.AddBucketLifecycleTypeExpiry {
// Verify if expiry items are set
if params.Body.NoncurrentversionTransitionDays != 0 {
@@ -205,14 +210,18 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params user_api
}
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiryDays: strconv.Itoa(int(params.Body.ExpiryDays)),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays),
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
}
if params.Body.NoncurrentversionExpirationDays > 0 {
opts.NoncurrentVersionExpirationDays = int(params.Body.NoncurrentversionExpirationDays)
} else {
opts.ExpiryDays = strconv.Itoa(int(params.Body.ExpiryDays))
}
} else {
@@ -271,19 +280,24 @@ func editBucketLifecycle(ctx context.Context, client MinioClient, params user_ap
}
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
TransitionDays: strconv.Itoa(int(params.Body.TransitionDays)),
StorageClass: strings.ToUpper(params.Body.StorageClass),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays),
NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass),
IsTransitionDaysSet: params.Body.TransitionDays != 0,
IsNoncurrentVersionTransitionDaysSet: params.Body.NoncurrentversionTransitionDays != 0,
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
IsTransitionDaysSet: params.Body.TransitionDays != 0,
IsNoncurrentVersionTransitionDaysSet: params.Body.NoncurrentversionTransitionDays != 0,
}
if params.Body.NoncurrentversionTransitionDays > 0 {
opts.NoncurrentVersionTransitionDays = int(params.Body.NoncurrentversionTransitionDays)
opts.NoncurrentVersionTransitionStorageClass = strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass)
} else {
opts.TransitionDays = strconv.Itoa(int(params.Body.TransitionDays))
opts.StorageClass = strings.ToUpper(params.Body.StorageClass)
}
} else if *params.Body.Type == models.UpdateBucketLifecycleTypeExpiry { // Verify if expiry configuration is set
if params.Body.NoncurrentversionTransitionDays != 0 {
return errors.New("non current version Transition Days cannot be set when expiry is being configured")
@@ -294,14 +308,18 @@ func editBucketLifecycle(ctx context.Context, client MinioClient, params user_ap
}
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiryDays: strconv.Itoa(int(params.Body.ExpiryDays)),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays),
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
}
if params.Body.NoncurrentversionExpirationDays > 0 {
opts.NoncurrentVersionExpirationDays = int(params.Body.NoncurrentversionExpirationDays)
} else {
opts.ExpiryDays = strconv.Itoa(int(params.Body.ExpiryDays))
}
} else {