diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/AddLifecycleModal.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/AddLifecycleModal.tsx index 182423212..8b80fbf12 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/AddLifecycleModal.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/AddLifecycleModal.tsx @@ -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(true); const [tiersList, setTiersList] = useState([]); const [addLoading, setAddLoading] = useState(false); + const [isVersioned, setIsVersioned] = useState(false); const [prefix, setPrefix] = useState(""); const [tags, setTags] = useState(""); const [storageClass, setStorageClass] = useState(""); - const [NCExpirationDays, setNCExpirationDays] = useState(""); - const [NCTransitionDays, setNCTransitionDays] = useState(""); + const [ilmType, setIlmType] = useState("expiry"); - const [expiryDays, setExpiryDays] = useState(""); - const [transitionDays, setTransitionDays] = useState(""); + const [targetVersion, setTargetVersion] = useState<"current" | "noncurrent">( + "current" + ); + + const [lifecycleDays, setLifecycleDays] = useState(""); const [isFormValid, setIsFormValid] = useState(false); + const [expiredObjectDM, setExpiredObjectDM] = useState(false); + const [loadingVersioning, setLoadingVersioning] = useState(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 = ({ - - + + ) => { setIlmType(e.target.value as string); }} @@ -242,65 +280,56 @@ const AddLifecycleModal = ({ ]} /> - - {ilmType === "expiry" ? ( - - - - ) => { - if (e.target.validity.valid) { - setExpiryDays(e.target.value); - } - }} - pattern={"[0-9]*"} - label="Delete Latest Version After" - value={expiryDays} - overlayObject={ - - } - /> - + {isVersioned && ( + + { + setTargetVersion( + e.target.value as "current" | "noncurrent" + ); + }} + options={[ + { value: "current", label: "Current Version" }, + { value: "noncurrent", label: "Non-Current Version" }, + ]} + /> + + )} - - - ) => { - if (e.target.validity.valid) { - setNCExpirationDays(e.target.value); - } - }} - pattern={"[0-9]*"} - label="Delete Older Versions After" - value={NCExpirationDays} - min="0" - overlayObject={ - - } + + ) => { + if (e.target.validity.valid) { + setLifecycleDays(e.target.value); + } + }} + pattern={"[0-9]*"} + label="After" + value={lifecycleDays} + overlayObject={ + - - + } + /> + + + {ilmType === "expiry" ? ( + ) : ( - + - - - ) => { - if (e.target.validity.valid) { - setTransitionDays(e.target.value); - } - }} - pattern={"[0-9]*"} - label="Transition Latest Version" - value={transitionDays} - min="0" - overlayObject={ - - } - /> - - - - ) => { - if (e.target.validity.valid) { - setNCTransitionDays(e.target.value); - } - }} - label="Transition Older Versions" - value={NCTransitionDays} - pattern={"[0-9]*"} - overlayObject={ - - } - /> - )} + + + + Filters + + + + + ) => { + setPrefix(e.target.value); + }} + label="Prefix" + value={prefix} + /> + + + { + setTags(vl); + }} + keyPlaceholder="Tag Key" + valuePlaceholder="Tag Value" + withBorder + /> + + + + + {ilmType === "expiry" && targetVersion === "noncurrent" && ( + + + + Advanced + + + + + ) => { + setExpiredObjectDM(event.target.checked); + }} + label={"Expire Delete Marker"} + description={ + "Remove the reference to the object if no versions are left" + } + /> + + + + + )} - -
- Filters - - - ) => { - setPrefix(e.target.value); - }} - label="Prefix" - value={prefix} - /> - - - { - setTags(vl); - }} - keyPlaceholder="Tag Key" - valuePlaceholder="Tag Value" - withBorder - /> - -
-