From d5c01fcd7d2a1fbbbdbab9ac1bc3a1a284b705b1 Mon Sep 17 00:00:00 2001 From: Cesar N Date: Mon, 14 Dec 2020 17:31:37 -0600 Subject: [PATCH] Integrate retention option during bucket creation on UI (#509) --- .../Console/Buckets/ListBuckets/AddBucket.tsx | 154 ++++++++++++++++-- .../src/screens/Console/Buckets/actions.ts | 57 ++++++- .../src/screens/Console/Buckets/reducers.ts | 37 +++++ .../src/screens/Console/Buckets/types.tsx | 7 + 4 files changed, 243 insertions(+), 12 deletions(-) diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx index 7882b7ead..1da70633f 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx @@ -23,6 +23,7 @@ import api from "../../../../common/api"; import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; +import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; import { factorForDropdown, getBytes } from "../../../../common/utils"; import { AppState } from "../../../../store"; import { connect } from "react-redux"; @@ -33,6 +34,10 @@ import { addBucketQuotaType, addBucketQuotaUnit, addBucketVersioned, + addBucketRetention, + addBucketRetentionMode, + addBucketRetentionUnit, + addBucketRetentionValidity, } from "../actions"; import { useDebounce } from "use-debounce"; import { MakeBucketRequest } from "../types"; @@ -71,12 +76,20 @@ interface IAddBucketProps { addBucketQuotaType: typeof addBucketQuotaType; addBucketQuotaSize: typeof addBucketQuotaSize; addBucketQuotaUnit: typeof addBucketQuotaUnit; + addBucketRetention: typeof addBucketRetention; + addBucketRetentionMode: typeof addBucketRetentionMode; + addBucketRetentionUnit: typeof addBucketRetentionUnit; + addBucketRetentionValidity: typeof addBucketRetentionValidity; bucketName: string; versioned: boolean; enableQuota: boolean; quotaType: string; quotaSize: string; quotaUnit: string; + enableRetention: boolean; + retentionMode: string; + retentionUnit: string; + retentionValidity: number; } const AddBucket = ({ @@ -89,14 +102,21 @@ const AddBucket = ({ addBucketQuotaType, addBucketQuotaSize, addBucketQuotaUnit, + addBucketRetention, + addBucketRetentionMode, + addBucketRetentionUnit, + addBucketRetentionValidity, bucketName, versioned, enableQuota, quotaType, quotaSize, quotaUnit, + enableRetention, + retentionMode, + retentionUnit, + retentionValidity, }: IAddBucketProps) => { - const [bName, setBName] = useState(bucketName); const [addLoading, setAddLoading] = useState(false); const [addError, setAddError] = useState(""); const [sendEnabled, setSendEnabled] = useState(false); @@ -122,6 +142,14 @@ const AddBucket = ({ }; } + if (enableRetention) { + request.retention = { + mode: retentionMode, + unit: retentionUnit, + validity: retentionValidity, + }; + } + api .invoke("POST", "/api/v1/buckets", request) .then((res) => { @@ -133,27 +161,33 @@ const AddBucket = ({ setAddLoading(false); setAddError(err); }); + + resetForm(); }; - const [value] = useDebounce(bName, 1000); + const [value] = useDebounce(bucketName, 1000); useEffect(() => { addBucketName(value); }, [value, addBucketName]); const resetForm = () => { - setBName(""); + addBucketName(""); addBucketVersioned(false); addBucketQuota(false); addBucketQuotaType("hard"); addBucketQuotaSize("1"); addBucketQuotaUnit("TiB"); + addBucketRetention(false); + addBucketRetentionMode("compliance"); + addBucketRetentionUnit("days"); + addBucketRetentionValidity(1); }; useEffect(() => { let valid = false; - if (bName.trim() !== "") { + if (bucketName.trim() !== "") { valid = true; } @@ -163,8 +197,35 @@ const AddBucket = ({ } } + if (!versioned || !enableRetention) { + addBucketRetention(false); + addBucketRetentionMode("compliance"); + addBucketRetentionUnit("days"); + addBucketRetentionValidity(1); + } + + if ( + enableRetention && + (Number.isNaN(retentionValidity) || retentionValidity < 1) + ) { + valid = false; + } + setSendEnabled(valid); - }, [bName, versioned, quotaType, quotaSize, quotaUnit, enableQuota]); + }, [ + bucketName, + versioned, + quotaType, + quotaSize, + quotaUnit, + enableQuota, + enableRetention, + addBucketRetention, + addBucketRetentionMode, + addBucketRetentionUnit, + addBucketRetentionValidity, + retentionValidity, + ]); return ( ) => { - setBName(event.target.value); + addBucketName(event.target.value); }} label="Bucket Name" - value={bName} + value={bucketName} /> @@ -231,15 +292,15 @@ const AddBucket = ({ {enableQuota && ( - ) => { addBucketQuotaType(e.target.value as string); }} - options={[ + selectorOptions={[ { value: "hard", label: "Hard" }, { value: "fifo", label: "FIFO" }, ]} @@ -279,6 +340,69 @@ const AddBucket = ({ )} + {versioned && ( + + ) => { + addBucketRetention(event.target.checked); + }} + label={"Enable Bucket Retention"} + indicatorLabels={["On", "Off"]} + /> + + )} + {enableRetention && ( + + + ) => { + addBucketRetentionMode(e.target.value as string); + }} + selectorOptions={[ + { value: "compliance", label: "Compliance" }, + { value: "governance", label: "Governance" }, + ]} + /> + + + ) => { + addBucketRetentionUnit(e.target.value as string); + }} + selectorOptions={[ + { value: "days", label: "Days" }, + { value: "years", label: "Years" }, + ]} + /> + + + ) => { + addBucketRetentionValidity(e.target.valueAsNumber); + }} + label="Retention Validity" + value={String(retentionValidity)} + required + min="1" + /> + + + )}