Exclude some units from tenant size dropdown (#1615)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-02-22 15:55:49 -08:00
committed by GitHub
parent 83fc075bc9
commit 5f1c830f47
7 changed files with 113 additions and 137 deletions

View File

@@ -101,10 +101,17 @@ export const factorForDropdown = () => {
}; };
// units to be used in a dropdown // units to be used in a dropdown
export const k8sfactorForDropdown = () => { export const k8sScalarUnitsExcluding = (exclude?: string[]) => {
return k8sUnits.map((unit) => { return k8sUnits
return { label: unit, value: unit }; .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 //getBytes, converts from a value and a unit from units array to bytes

View File

@@ -36,9 +36,10 @@ import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import api from "../../../../common/api"; import api from "../../../../common/api";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; 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 QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
import { BucketReplicationIcon } from "../../../../icons"; import { BucketReplicationIcon } from "../../../../icons";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
interface IReplicationModal { interface IReplicationModal {
open: boolean; open: boolean;
@@ -317,24 +318,26 @@ const AddReplicationModal = ({
id="bandwidth_scalar" id="bandwidth_scalar"
name="bandwidth_scalar" name="bandwidth_scalar"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => { onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setBandwidthScalar(e.target.value as string); if (e.target.validity.valid) {
setBandwidthScalar(e.target.value as string);
}
}} }}
label="Bandwidth" label="Bandwidth"
value={bandwidthScalar} value={bandwidthScalar}
min="0" min="0"
pattern={"[0-9]*"}
overlayObject={
<InputUnitMenu
id={"quota_unit"}
onUnitChange={(newValue) => {
setBandwidthUnit(newValue);
}}
unitSelected={bandwidthUnit}
unitsList={k8sScalarUnitsExcluding(["Ki"])}
disabled={false}
/>
}
/> />
<div className={classes.sizeFactorContainer}>
<SelectWrapper
label={" "}
id="bandwidth_unit"
name="bandwidth_unit"
value={bandwidthUnit}
onChange={(e: SelectChangeEvent<string>) => {
setBandwidthUnit(e.target.value as string);
}}
options={k8sfactorForDropdown()}
/>
</div>
</div> </div>
</Grid> </Grid>
)} )}

View File

@@ -16,12 +16,16 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { connect } from "react-redux"; 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 { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles"; import withStyles from "@mui/styles/withStyles";
import Grid from "@mui/material/Grid"; 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 { BucketQuota } from "../types";
import { setModalErrorSnackMessage } from "../../../../actions"; import { setModalErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types"; import { ErrorResponseHandler } from "../../../../common/types";
@@ -30,12 +34,11 @@ import {
modalStyleUtils, modalStyleUtils,
} from "../../Common/FormComponents/common/styleLibrary"; } from "../../Common/FormComponents/common/styleLibrary";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import api from "../../../../common/api"; import api from "../../../../common/api";
import { BucketQuotaIcon } from "../../../../icons"; import { BucketQuotaIcon } from "../../../../icons";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
const styles = (theme: Theme) => const styles = (theme: Theme) =>
createStyles({ createStyles({
@@ -64,7 +67,6 @@ const EnableQuota = ({
}: IEnableQuotaProps) => { }: IEnableQuotaProps) => {
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [quotaEnabled, setQuotaEnabled] = useState<boolean>(false); const [quotaEnabled, setQuotaEnabled] = useState<boolean>(false);
const [quotaType, setQuotaType] = useState<string>("hard");
const [quotaSize, setQuotaSize] = useState<string>("1"); const [quotaSize, setQuotaSize] = useState<string>("1");
const [quotaUnit, setQuotaUnit] = useState<string>("TiB"); const [quotaUnit, setQuotaUnit] = useState<string>("TiB");
@@ -72,9 +74,8 @@ const EnableQuota = ({
if (enabled) { if (enabled) {
setQuotaEnabled(true); setQuotaEnabled(true);
if (cfg) { if (cfg) {
setQuotaType(cfg.type);
setQuotaSize(`${cfg.quota}`); setQuotaSize(`${cfg.quota}`);
setQuotaUnit(`B`); setQuotaUnit(`Gi`);
let maxUnit = "B"; let maxUnit = "B";
let maxQuota = cfg.quota; let maxQuota = cfg.quota;
@@ -93,15 +94,14 @@ const EnableQuota = ({
} }
}, [enabled, cfg]); }, [enabled, cfg]);
const enableBucketEncryption = (event: React.FormEvent) => { const enableBucketEncryption = () => {
event.preventDefault();
if (loading) { if (loading) {
return; return;
} }
let req = { let req = {
enabled: quotaEnabled, enabled: quotaEnabled,
amount: parseInt(getBytes(quotaSize, quotaUnit, false)), amount: parseInt(getBytes(quotaSize, quotaUnit, true)),
quota_type: quotaType, quota_type: "hard",
}; };
api api
@@ -129,7 +129,8 @@ const EnableQuota = ({
noValidate noValidate
autoComplete="off" autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => { onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
enableBucketEncryption(e); e.preventDefault();
enableBucketEncryption();
}} }}
> >
<Grid container> <Grid container>
@@ -143,53 +144,40 @@ const EnableQuota = ({
onChange={(event: React.ChangeEvent<HTMLInputElement>) => { onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setQuotaEnabled(event.target.checked); setQuotaEnabled(event.target.checked);
}} }}
label={"Quota"} label={"Enabled"}
/> />
</Grid> </Grid>
{quotaEnabled && ( {quotaEnabled && (
<React.Fragment> <React.Fragment>
<Grid item xs={12} className={classes.formFieldRow}>
<RadioGroupSelector
currentSelection={quotaType}
id="quota_type"
name="quota_type"
label="Quota Type"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setQuotaType(e.target.value as string);
}}
selectorOptions={[{ value: "hard", label: "Hard" }]}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}> <Grid item xs={12} className={classes.formFieldRow}>
<Grid container> <Grid container>
<Grid item xs={10}> <Grid item xs={12}>
<InputBoxWrapper <InputBoxWrapper
type="number"
id="quota_size" id="quota_size"
name="quota_size" name="quota_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => { onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setQuotaSize(e.target.value); if (e.target.validity.valid) {
setQuotaSize(e.target.value);
}
}} }}
pattern={"[0-9]*"}
label="Quota" label="Quota"
value={quotaSize} value={quotaSize}
required required
min="1" min="1"
overlayObject={
<InputUnitMenu
id={"quota_unit"}
onUnitChange={(newValue) => {
setQuotaUnit(newValue);
}}
unitSelected={quotaUnit}
unitsList={k8sScalarUnitsExcluding(["Ki"])}
disabled={false}
/>
}
/> />
</Grid> </Grid>
<Grid item xs={2}>
<div style={{ width: 100 }}>
<SelectWrapper
label=""
id="quota_unit"
name="quota_unit"
value={quotaUnit}
onChange={(e: SelectChangeEvent<string>) => {
setQuotaUnit(e.target.value as string);
}}
options={factorForDropdown()}
/>
</div>
</Grid>
</Grid> </Grid>
</Grid> </Grid>
</React.Fragment> </React.Fragment>

View File

@@ -16,16 +16,15 @@
import React, { Fragment, useEffect, useState } from "react"; import React, { Fragment, useEffect, useState } from "react";
import Grid from "@mui/material/Grid"; 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 { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles"; import withStyles from "@mui/styles/withStyles";
import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary"; import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary";
import api from "../../../../common/api"; import api from "../../../../common/api";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
import { factorForDropdown, getBytes } from "../../../../common/utils"; import { getBytes, k8sScalarUnitsExcluding } from "../../../../common/utils";
import { AppState } from "../../../../store"; import { AppState } from "../../../../store";
import history from "../../../../history"; import history from "../../../../history";
import { connect } from "react-redux"; import { connect } from "react-redux";
@@ -51,6 +50,7 @@ import BackLink from "../../../../common/BackLink";
import { BucketsIcon } from "../../../../icons"; import { BucketsIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions"; import { setErrorSnackMessage } from "../../../../actions";
import PageLayout from "../../Common/Layout/PageLayout"; import PageLayout from "../../Common/Layout/PageLayout";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
const styles = (theme: Theme) => const styles = (theme: Theme) =>
createStyles({ createStyles({
@@ -159,7 +159,7 @@ const AddBucket = ({
if (distributedSetup) { if (distributedSetup) {
if (quotaEnabled) { if (quotaEnabled) {
const amount = getBytes(quotaSize, quotaUnit, false); const amount = getBytes(quotaSize, quotaUnit, true);
request.quota = { request.quota = {
enabled: true, enabled: true,
quota_type: quotaType, quota_type: quotaType,
@@ -375,52 +375,32 @@ const AddBucket = ({
{quotaEnabled && distributedSetup && ( {quotaEnabled && distributedSetup && (
<React.Fragment> <React.Fragment>
<Grid item xs={12}> <Grid item xs={12}>
<RadioGroupSelector <InputBoxWrapper
currentSelection={quotaType} type="number"
id="quota_type" id="quota_size"
name="quota_type" name="quota_size"
label="Quota Type" onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
onChange={( if (e.target.validity.valid) {
e: React.ChangeEvent<{ value: unknown }> addBucketQuotaSize(e.target.value);
) => { }
addBucketQuotaType(e.target.value as string);
}} }}
selectorOptions={[{ value: "hard", label: "Hard" }]} label="Quota"
/> value={quotaSize}
</Grid> required
<Grid item xs={12}> min="1"
<Grid container> pattern={"[0-9]*"}
<Grid item xs={10}> overlayObject={
<InputBoxWrapper <InputUnitMenu
type="number" id={"quota_unit"}
id="quota_size" onUnitChange={(newValue) => {
name="quota_size" addBucketQuotaUnit(newValue);
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
addBucketQuotaSize(e.target.value);
}} }}
label="Quota" unitSelected={quotaUnit}
value={quotaSize} unitsList={k8sScalarUnitsExcluding(["Ki"])}
required disabled={false}
min="1"
/> />
</Grid> }
<Grid item xs={2}> />
<div style={{ width: 100 }}>
<SelectWrapper
label=""
id="quota_unit"
name="quota_unit"
value={quotaUnit}
onChange={(e: SelectChangeEvent<string>) => {
addBucketQuotaUnit(e.target.value as string);
}}
options={factorForDropdown()}
/>
</div>
</Grid>
</Grid>
</Grid> </Grid>
</React.Fragment> </React.Fragment>
)} )}

View File

@@ -38,8 +38,9 @@ import GenericWizard from "../../Common/GenericWizard/GenericWizard";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { SelectorTypes } from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; 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 { ErrorResponseHandler } from "../../../../common/types";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
interface IBulkReplicationModal { interface IBulkReplicationModal {
open: boolean; open: boolean;
@@ -408,35 +409,31 @@ const AddBulkReplicationModal = ({
</Grid> </Grid>
{replicationMode === "async" && ( {replicationMode === "async" && (
<Grid item xs={12}> <Grid item xs={12}>
<div className={classes.multiContainer}> <InputBoxWrapper
<div> type="number"
<InputBoxWrapper id="bandwidth_scalar"
type="number" name="bandwidth_scalar"
id="bandwidth_scalar" onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
name="bandwidth_scalar" if (e.target.validity.valid) {
onChange={( setBandwidthScalar(e.target.value as string);
e: React.ChangeEvent<HTMLInputElement> }
) => { }}
setBandwidthScalar(e.target.value as string); label="Bandwidth"
value={bandwidthScalar}
min="0"
pattern={"[0-9]*"}
overlayObject={
<InputUnitMenu
id={"quota_unit"}
onUnitChange={(newValue) => {
setBandwidthUnit(newValue);
}} }}
label="Bandwidth" unitSelected={bandwidthUnit}
value={bandwidthScalar} unitsList={k8sScalarUnitsExcluding(["Ki"])}
min="0" disabled={false}
/> />
</div> }
<div className={classes.sizeFactorContainer}> />
<SelectWrapper
label={"Unit"}
id="bandwidth_unit"
name="bandwidth_unit"
value={bandwidthUnit}
onChange={(e: SelectChangeEvent<string>) => {
setBandwidthUnit(e.target.value as string);
}}
options={k8sfactorForDropdown()}
/>
</div>
</div>
</Grid> </Grid>
)} )}
<Grid item xs={12}> <Grid item xs={12}>

View File

@@ -71,6 +71,7 @@ const InputUnitMenu = ({
onClick={handleClick} onClick={handleClick}
className={classes.buttonTrigger} className={classes.buttonTrigger}
disabled={disabled} disabled={disabled}
type={"button"}
> >
{unitSelected} {unitSelected}
</button> </button>

View File

@@ -32,7 +32,7 @@ import {
calculateDistribution, calculateDistribution,
erasureCodeCalc, erasureCodeCalc,
getBytes, getBytes,
k8sfactorForDropdown, k8sScalarUnitsExcluding,
niceBytes, niceBytes,
} from "../../../../../../common/utils"; } from "../../../../../../common/utils";
import { clearValidationError } from "../../../utils"; import { clearValidationError } from "../../../utils";
@@ -333,7 +333,7 @@ const TenantSize = ({
updateField("sizeFactor", newValue); updateField("sizeFactor", newValue);
}} }}
unitSelected={sizeFactor} unitSelected={sizeFactor}
unitsList={k8sfactorForDropdown()} unitsList={k8sScalarUnitsExcluding(["Ki", "Mi"])}
disabled={selectedStorageClass === ""} disabled={selectedStorageClass === ""}
/> />
} }