// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
import React, { Fragment, useEffect, useState } from "react";
import get from "lodash/get";
import {
Accordion,
AlertIcon,
Button,
FormLayout,
Grid,
HelpTip,
InputBox,
LifecycleConfigIcon,
ProgressBar,
RadioGroup,
Select,
Switch,
} from "mds";
import { useSelector } from "react-redux";
import { api } from "api";
import { BucketVersioningResponse } from "api/consoleApi";
import { errorToHandler } from "api/errors";
import { modalStyleUtils } from "../../Common/FormComponents/common/styleLibrary";
import { selDistSet, setModalErrorSnackMessage } from "../../../../systemSlice";
import { useAppDispatch } from "../../../../store";
import { ITiersDropDown } from "../types";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import { IAM_PAGES } from "common/SecureComponent/permissions";
interface IReplicationModal {
open: boolean;
closeModalAndRefresh: (refresh: boolean) => any;
bucketName: string;
}
const AddLifecycleModal = ({
open,
closeModalAndRefresh,
bucketName,
}: IReplicationModal) => {
const dispatch = useAppDispatch();
const distributedSetup = useSelector(selDistSet);
const [loadingTiers, setLoadingTiers] = useState(true);
const [tiersList, setTiersList] = useState([]);
const [addLoading, setAddLoading] = useState(false);
const [versioningInfo, setVersioningInfo] =
useState(null);
const [prefix, setPrefix] = useState("");
const [tags, setTags] = useState("");
const [storageClass, setStorageClass] = useState("");
const [ilmType, setIlmType] = useState<"expiry" | "transition">("expiry");
const [targetVersion, setTargetVersion] = useState<"current" | "noncurrent">(
"current",
);
const [lifecycleDays, setLifecycleDays] = useState("");
const [isFormValid, setIsFormValid] = useState(false);
const [expiredObjectDM, setExpiredObjectDM] = useState(false);
const [expiredAllVersionsDM, setExpiredAllVersionsDM] =
useState(false);
const [loadingVersioning, setLoadingVersioning] = useState(true);
const [expandedAdv, setExpandedAdv] = useState(false);
const [expanded, setExpanded] = useState(false);
const [expiryUnit, setExpiryUnit] = useState("days");
/*To be removed on component replacement*/
const formFieldRowFilter = {
"& .MuiPaper-root": { padding: 0 },
};
useEffect(() => {
if (loadingTiers) {
api.admin
.tiersListNames()
.then((res) => {
const tiersList: string[] | null = get(res.data, "items", []);
if (tiersList !== null && tiersList.length >= 1) {
const objList = tiersList.map((tierName: string) => {
return { label: tierName, value: tierName };
});
setTiersList(objList);
if (objList.length > 0) {
setStorageClass(objList[0].value);
}
}
setLoadingTiers(false);
})
.catch((err) => {
setLoadingTiers(false);
dispatch(setModalErrorSnackMessage(errorToHandler(err.error)));
});
}
}, [dispatch, loadingTiers]);
useEffect(() => {
let valid = true;
if (ilmType !== "expiry") {
if (storageClass === "") {
valid = false;
}
}
if (!lifecycleDays || parseInt(lifecycleDays) === 0) {
valid = false;
}
if (parseInt(lifecycleDays) > 2147483647) {
//values over int32 cannot be parsed
valid = false;
}
setIsFormValid(valid);
}, [ilmType, lifecycleDays, storageClass]);
useEffect(() => {
if (loadingVersioning && distributedSetup) {
api.buckets
.getBucketVersioning(bucketName)
.then((res) => {
setVersioningInfo(res.data);
setLoadingVersioning(false);
})
.catch((err) => {
dispatch(setModalErrorSnackMessage(errorToHandler(err)));
setLoadingVersioning(false);
});
}
}, [loadingVersioning, dispatch, bucketName, distributedSetup]);
const addRecord = () => {
let rules = {};
if (ilmType === "expiry") {
let expiry: { [key: string]: number } = {};
if (targetVersion === "current") {
expiry["expiry_days"] = parseInt(lifecycleDays);
} else if (expiryUnit === "days") {
expiry["noncurrentversion_expiration_days"] = parseInt(lifecycleDays);
} else {
expiry["newer_noncurrentversion_expiration_versions"] =
parseInt(lifecycleDays);
}
rules = {
...expiry,
};
} else {
let transition: { [key: string]: number | string } = {};
if (targetVersion === "current") {
transition["transition_days"] = parseInt(lifecycleDays);
transition["storage_class"] = storageClass;
} else if (expiryUnit === "days") {
transition["noncurrentversion_transition_days"] =
parseInt(lifecycleDays);
transition["noncurrentversion_transition_storage_class"] = storageClass;
}
rules = {
...transition,
};
}
const lifecycleInsert = {
type: ilmType,
prefix,
tags,
expired_object_delete_marker: expiredObjectDM,
expired_object_delete_all: expiredAllVersionsDM,
...rules,
};
api.buckets
.addBucketLifecycle(bucketName, lifecycleInsert)
.then(() => {
setAddLoading(false);
closeModalAndRefresh(true);
})
.catch((err) => {
setAddLoading(false);
dispatch(setModalErrorSnackMessage(errorToHandler(err)));
});
};
return (
{
closeModalAndRefresh(false);
}}
title="Add Lifecycle Rule"
titleIcon={}
>
{loadingTiers && (
)}
{!loadingTiers && (
)}
);
};
export default AddLifecycleModal;