diff --git a/portal-ui/src/common/utils.ts b/portal-ui/src/common/utils.ts index 170fe52dd..2cd341bf3 100644 --- a/portal-ui/src/common/utils.ts +++ b/portal-ui/src/common/utils.ts @@ -101,10 +101,17 @@ export const factorForDropdown = () => { }; // units to be used in a dropdown -export const k8sfactorForDropdown = () => { - return k8sUnits.map((unit) => { - return { label: unit, value: unit }; - }); +export const k8sScalarUnitsExcluding = (exclude?: string[]) => { + return k8sUnits + .filter((unit) => { + if (exclude && exclude.includes(unit)) { + return false; + } + return true; + }) + .map((unit) => { + return { label: unit, value: unit }; + }); }; //getBytes, converts from a value and a unit from units array to bytes diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx index 392fd2439..9386f294b 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx @@ -36,9 +36,10 @@ import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; import api from "../../../../common/api"; import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; -import { getBytes, k8sfactorForDropdown } from "../../../../common/utils"; +import { getBytes, k8sScalarUnitsExcluding } from "../../../../common/utils"; import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector"; import { BucketReplicationIcon } from "../../../../icons"; +import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu"; interface IReplicationModal { open: boolean; @@ -317,24 +318,26 @@ const AddReplicationModal = ({ id="bandwidth_scalar" name="bandwidth_scalar" onChange={(e: React.ChangeEvent) => { - setBandwidthScalar(e.target.value as string); + if (e.target.validity.valid) { + setBandwidthScalar(e.target.value as string); + } }} label="Bandwidth" value={bandwidthScalar} min="0" + pattern={"[0-9]*"} + overlayObject={ + { + setBandwidthUnit(newValue); + }} + unitSelected={bandwidthUnit} + unitsList={k8sScalarUnitsExcluding(["Ki"])} + disabled={false} + /> + } /> -
- ) => { - setBandwidthUnit(e.target.value as string); - }} - options={k8sfactorForDropdown()} - /> -
)} diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/EnableQuota.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/EnableQuota.tsx index bba4620d9..17e655954 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/EnableQuota.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/EnableQuota.tsx @@ -16,12 +16,16 @@ import React, { useEffect, useState } from "react"; import { connect } from "react-redux"; -import { Button, LinearProgress, SelectChangeEvent } from "@mui/material"; +import { Button, LinearProgress } from "@mui/material"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import Grid from "@mui/material/Grid"; -import { factorForDropdown, getBytes, units } from "../../../../common/utils"; +import { + getBytes, + k8sScalarUnitsExcluding, + units, +} from "../../../../common/utils"; import { BucketQuota } from "../types"; import { setModalErrorSnackMessage } from "../../../../actions"; import { ErrorResponseHandler } from "../../../../common/types"; @@ -30,12 +34,11 @@ import { modalStyleUtils, } from "../../Common/FormComponents/common/styleLibrary"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; -import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; -import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; import api from "../../../../common/api"; import { BucketQuotaIcon } from "../../../../icons"; +import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu"; const styles = (theme: Theme) => createStyles({ @@ -64,7 +67,6 @@ const EnableQuota = ({ }: IEnableQuotaProps) => { const [loading, setLoading] = useState(false); const [quotaEnabled, setQuotaEnabled] = useState(false); - const [quotaType, setQuotaType] = useState("hard"); const [quotaSize, setQuotaSize] = useState("1"); const [quotaUnit, setQuotaUnit] = useState("TiB"); @@ -72,9 +74,8 @@ const EnableQuota = ({ if (enabled) { setQuotaEnabled(true); if (cfg) { - setQuotaType(cfg.type); setQuotaSize(`${cfg.quota}`); - setQuotaUnit(`B`); + setQuotaUnit(`Gi`); let maxUnit = "B"; let maxQuota = cfg.quota; @@ -93,15 +94,14 @@ const EnableQuota = ({ } }, [enabled, cfg]); - const enableBucketEncryption = (event: React.FormEvent) => { - event.preventDefault(); + const enableBucketEncryption = () => { if (loading) { return; } let req = { enabled: quotaEnabled, - amount: parseInt(getBytes(quotaSize, quotaUnit, false)), - quota_type: quotaType, + amount: parseInt(getBytes(quotaSize, quotaUnit, true)), + quota_type: "hard", }; api @@ -129,7 +129,8 @@ const EnableQuota = ({ noValidate autoComplete="off" onSubmit={(e: React.FormEvent) => { - enableBucketEncryption(e); + e.preventDefault(); + enableBucketEncryption(); }} > @@ -143,53 +144,40 @@ const EnableQuota = ({ onChange={(event: React.ChangeEvent) => { setQuotaEnabled(event.target.checked); }} - label={"Quota"} + label={"Enabled"} /> {quotaEnabled && ( - - ) => { - setQuotaType(e.target.value as string); - }} - selectorOptions={[{ value: "hard", label: "Hard" }]} - /> - - + ) => { - setQuotaSize(e.target.value); + if (e.target.validity.valid) { + setQuotaSize(e.target.value); + } }} + pattern={"[0-9]*"} label="Quota" value={quotaSize} required min="1" + overlayObject={ + { + setQuotaUnit(newValue); + }} + unitSelected={quotaUnit} + unitsList={k8sScalarUnitsExcluding(["Ki"])} + disabled={false} + /> + } /> - -
- ) => { - setQuotaUnit(e.target.value as string); - }} - options={factorForDropdown()} - /> -
-
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx index 9e6cfa5a6..a36b415ba 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket.tsx @@ -16,16 +16,15 @@ import React, { Fragment, useEffect, useState } from "react"; import Grid from "@mui/material/Grid"; -import { Button, LinearProgress, SelectChangeEvent } from "@mui/material"; +import { Button, LinearProgress } from "@mui/material"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary"; import api from "../../../../common/api"; 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 { getBytes, k8sScalarUnitsExcluding } from "../../../../common/utils"; import { AppState } from "../../../../store"; import history from "../../../../history"; import { connect } from "react-redux"; @@ -51,6 +50,7 @@ import BackLink from "../../../../common/BackLink"; import { BucketsIcon } from "../../../../icons"; import { setErrorSnackMessage } from "../../../../actions"; import PageLayout from "../../Common/Layout/PageLayout"; +import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu"; const styles = (theme: Theme) => createStyles({ @@ -159,7 +159,7 @@ const AddBucket = ({ if (distributedSetup) { if (quotaEnabled) { - const amount = getBytes(quotaSize, quotaUnit, false); + const amount = getBytes(quotaSize, quotaUnit, true); request.quota = { enabled: true, quota_type: quotaType, @@ -375,52 +375,32 @@ const AddBucket = ({ {quotaEnabled && distributedSetup && ( - - ) => { - addBucketQuotaType(e.target.value as string); + ) => { + if (e.target.validity.valid) { + addBucketQuotaSize(e.target.value); + } }} - selectorOptions={[{ value: "hard", label: "Hard" }]} - /> - - - - - - ) => { - addBucketQuotaSize(e.target.value); + label="Quota" + value={quotaSize} + required + min="1" + pattern={"[0-9]*"} + overlayObject={ + { + addBucketQuotaUnit(newValue); }} - label="Quota" - value={quotaSize} - required - min="1" + unitSelected={quotaUnit} + unitsList={k8sScalarUnitsExcluding(["Ki"])} + disabled={false} /> - - -
- ) => { - addBucketQuotaUnit(e.target.value as string); - }} - options={factorForDropdown()} - /> -
-
-
+ } + />
)} diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/BulkReplicationModal.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/BulkReplicationModal.tsx index cdbdc0261..190b1855a 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/BulkReplicationModal.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/BulkReplicationModal.tsx @@ -38,8 +38,9 @@ import GenericWizard from "../../Common/GenericWizard/GenericWizard"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; import { SelectorTypes } from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; -import { getBytes, k8sfactorForDropdown } from "../../../../common/utils"; +import { getBytes, k8sScalarUnitsExcluding } from "../../../../common/utils"; import { ErrorResponseHandler } from "../../../../common/types"; +import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu"; interface IBulkReplicationModal { open: boolean; @@ -408,35 +409,31 @@ const AddBulkReplicationModal = ({ {replicationMode === "async" && ( -
-
- - ) => { - setBandwidthScalar(e.target.value as string); + ) => { + if (e.target.validity.valid) { + setBandwidthScalar(e.target.value as string); + } + }} + label="Bandwidth" + value={bandwidthScalar} + min="0" + pattern={"[0-9]*"} + overlayObject={ + { + setBandwidthUnit(newValue); }} - label="Bandwidth" - value={bandwidthScalar} - min="0" + unitSelected={bandwidthUnit} + unitsList={k8sScalarUnitsExcluding(["Ki"])} + disabled={false} /> -
-
- ) => { - setBandwidthUnit(e.target.value as string); - }} - options={k8sfactorForDropdown()} - /> -
-
+ } + />
)} diff --git a/portal-ui/src/screens/Console/Common/FormComponents/InputUnitMenu/InputUnitMenu.tsx b/portal-ui/src/screens/Console/Common/FormComponents/InputUnitMenu/InputUnitMenu.tsx index 263a2dcb4..8ae23fbde 100644 --- a/portal-ui/src/screens/Console/Common/FormComponents/InputUnitMenu/InputUnitMenu.tsx +++ b/portal-ui/src/screens/Console/Common/FormComponents/InputUnitMenu/InputUnitMenu.tsx @@ -71,6 +71,7 @@ const InputUnitMenu = ({ onClick={handleClick} className={classes.buttonTrigger} disabled={disabled} + type={"button"} > {unitSelected} diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantResources/TenantSize.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantResources/TenantSize.tsx index e7a2c538e..54f7ce3ed 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantResources/TenantSize.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantResources/TenantSize.tsx @@ -32,7 +32,7 @@ import { calculateDistribution, erasureCodeCalc, getBytes, - k8sfactorForDropdown, + k8sScalarUnitsExcluding, niceBytes, } from "../../../../../../common/utils"; import { clearValidationError } from "../../../utils"; @@ -333,7 +333,7 @@ const TenantSize = ({ updateField("sizeFactor", newValue); }} unitSelected={sizeFactor} - unitsList={k8sfactorForDropdown()} + unitsList={k8sScalarUnitsExcluding(["Ki", "Mi"])} disabled={selectedStorageClass === ""} /> }