// 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 { useSelector } from "react-redux"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import get from "lodash/get"; import Grid from "@mui/material/Grid"; import { LifeCycleItem } from "../types"; import { AddIcon, TiersIcon } from "../../../../icons"; import { actionsTray, searchField, } from "../../Common/FormComponents/common/styleLibrary"; import { ErrorResponseHandler } from "../../../../common/types"; import api from "../../../../common/api"; import EditLifecycleConfiguration from "./EditLifecycleConfiguration"; import AddLifecycleModal from "./AddLifecycleModal"; import TableWrapper from "../../Common/TableWrapper/TableWrapper"; import HelpBox from "../../../../common/HelpBox"; import PanelTitle from "../../Common/PanelTitle/PanelTitle"; import { hasPermission, SecureComponent, } from "../../../../common/SecureComponent"; import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions"; import DeleteBucketLifecycleRule from "./DeleteBucketLifecycleRule"; import { selBucketDetailsLoading } from "./bucketDetailsSlice"; import { useParams } from "react-router-dom"; import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper"; import { Button } from "mds"; const styles = (theme: Theme) => createStyles({ ...searchField, ...actionsTray, twHeight: { minHeight: 400, }, }); interface IBucketLifecyclePanelProps { classes: any; } const BucketLifecyclePanel = ({ classes }: IBucketLifecyclePanelProps) => { const loadingBucket = useSelector(selBucketDetailsLoading); const params = useParams(); const [loadingLifecycle, setLoadingLifecycle] = useState(true); const [lifecycleRecords, setLifecycleRecords] = useState([]); const [addLifecycleOpen, setAddLifecycleOpen] = useState(false); const [editLifecycleOpen, setEditLifecycleOpen] = useState(false); const [selectedLifecycleRule, setSelectedLifecycleRule] = useState(null); const [deleteLifecycleOpen, setDeleteLifecycleOpen] = useState(false); const [selectedID, setSelectedID] = useState(null); const bucketName = params.bucketName || ""; const displayLifeCycleRules = hasPermission(bucketName, [ IAM_SCOPES.S3_GET_LIFECYCLE_CONFIGURATION, ]); useEffect(() => { if (loadingBucket) { setLoadingLifecycle(true); } }, [loadingBucket, setLoadingLifecycle]); useEffect(() => { if (loadingLifecycle) { if (displayLifeCycleRules) { api .invoke("GET", `/api/v1/buckets/${bucketName}/lifecycle`) .then((res: any) => { const records = get(res, "lifecycle", []); setLifecycleRecords(records || []); setLoadingLifecycle(false); }) .catch((err: ErrorResponseHandler) => { console.error(err); setLifecycleRecords([]); setLoadingLifecycle(false); }); } else { setLoadingLifecycle(false); } } }, [ loadingLifecycle, setLoadingLifecycle, bucketName, displayLifeCycleRules, ]); const closeEditLCAndRefresh = (refresh: boolean) => { setEditLifecycleOpen(false); setSelectedLifecycleRule(null); if (refresh) { setLoadingLifecycle(true); } }; const closeAddLCAndRefresh = (refresh: boolean) => { setAddLifecycleOpen(false); if (refresh) { setLoadingLifecycle(true); } }; const closeDelLCRefresh = (refresh: boolean) => { setDeleteLifecycleOpen(false); setSelectedID(null); if (refresh) { setLoadingLifecycle(true); } }; const renderStorageClass = (objectST: any) => { let stClass = get(objectST, "transition.storage_class", ""); stClass = get(objectST, "transition.noncurrent_storage_class", stClass); return stClass; }; const lifecycleColumns = [ { label: "Type", renderFullObject: true, renderFunction: (el: LifeCycleItem) => { if (!el) { return ; } if ( el.expiration && (el.expiration.days > 0 || el.expiration.noncurrent_expiration_days) ) { return Expiry; } if ( el.transition && (el.transition.days > 0 || el.transition.noncurrent_transition_days) ) { return Transition; } return ; }, }, { label: "Version", renderFullObject: true, renderFunction: (el: LifeCycleItem) => { if (!el) { return ; } if (el.expiration) { if (el.expiration.days > 0) { return Current; } else if (el.expiration.noncurrent_expiration_days) { return Non-Current; } } if (el.transition) { if (el.transition.days > 0) { return Current; } else if (el.transition.noncurrent_transition_days) { return Non-Current; } } }, }, { label: "Tier", elementKey: "storage_class", renderFunction: renderStorageClass, renderFullObject: true, }, { label: "Prefix", elementKey: "prefix", }, { label: "After", renderFullObject: true, renderFunction: (el: LifeCycleItem) => { if (!el) { return ; } if (el.expiration) { if (el.expiration.days > 0) { return {el.expiration.days} days; } else if (el.expiration.noncurrent_expiration_days) { return {el.expiration.noncurrent_expiration_days} days; } } if (el.transition) { if (el.transition.days > 0) { return {el.transition.days} days; } else if (el.transition.noncurrent_transition_days) { return {el.transition.noncurrent_transition_days} days; } } }, }, { label: "Status", elementKey: "status", }, ]; const lifecycleActions = [ { type: "view", onClick(valueToSend: any): any { setSelectedLifecycleRule(valueToSend); setEditLifecycleOpen(true); }, }, { type: "delete", onClick(valueToDelete: string): any { setSelectedID(valueToDelete); setDeleteLifecycleOpen(true); }, sendOnlyId: true, }, ]; return ( {editLifecycleOpen && selectedLifecycleRule && ( )} {addLifecycleOpen && ( )} {deleteLifecycleOpen && selectedID && ( )} Lifecycle Rules