Skip to content

Commit

Permalink
Added decimal support to bucket quota selectors (#2126)
Browse files Browse the repository at this point in the history
- Fixed an issue with calculateBytes function
- Fixed add bucket validation form

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
  • Loading branch information
bexsoft committed Jun 15, 2022
1 parent a5c1479 commit 7ecc102
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 220 deletions.
2 changes: 1 addition & 1 deletion portal-ui/src/common/utils.ts
Expand Up @@ -596,7 +596,7 @@ export const calculateBytes = (
// Get unit for measure
const i = Math.floor(Math.log(bytes) / Math.log(k));

const fractionDigits = showDecimals ? 0 : 1;
const fractionDigits = showDecimals ? 1 : 0;

const bytesUnit = bytes / Math.pow(k, i);

Expand Down
2 changes: 0 additions & 2 deletions portal-ui/src/history.ts
@@ -1,5 +1,3 @@
// check if we are using base path, if not this always is `/`
const baseLocation = new URL(document.baseURI);
export const baseUrl = baseLocation.pathname;


Expand Up @@ -70,21 +70,34 @@ const EnableQuota = ({
const [quotaEnabled, setQuotaEnabled] = useState<boolean>(false);
const [quotaSize, setQuotaSize] = useState<string>("1");
const [quotaUnit, setQuotaUnit] = useState<string>("Ti");
const [validInput, setValidInput] = useState<boolean>(false);

useEffect(() => {
if (enabled) {
setQuotaEnabled(true);
if (cfg) {
const unitCalc = calculateBytes(cfg.quota, false, false, true);
const unitCalc = calculateBytes(cfg.quota, true, false, true);

setQuotaSize(unitCalc.total.toString());
setQuotaUnit(unitCalc.unit);
setValidInput(true);
}
}
}, [enabled, cfg]);

useEffect(() => {
const valRegExp = /^\d*(?:\.\d{1,2})?$/;

if (!quotaEnabled) {
setValidInput(true);
return;
}

setValidInput(valRegExp.test(quotaSize));
}, [quotaEnabled, quotaSize]);

const enableBucketEncryption = () => {
if (loading) {
if (loading || !validInput) {
return;
}
let req = {
Expand Down Expand Up @@ -145,11 +158,13 @@ const EnableQuota = ({
id="quota_size"
name="quota_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.validity.valid) {
setQuotaSize(e.target.value);
setQuotaSize(e.target.value);
if (!e.target.validity.valid) {
setValidInput(false);
} else {
setValidInput(true);
}
}}
pattern={"[0-9]*"}
label="Quota"
value={quotaSize}
required
Expand All @@ -165,6 +180,7 @@ const EnableQuota = ({
disabled={false}
/>
}
error={!validInput ? "Please enter a valid quota" : ""}
/>
</Grid>
</Grid>
Expand All @@ -189,7 +205,7 @@ const EnableQuota = ({
type="submit"
variant="contained"
color="primary"
disabled={loading}
disabled={loading || !validInput}
>
Save
</Button>
Expand Down
Expand Up @@ -130,7 +130,7 @@ const AddBucket = ({ classes }: IsetProps) => {
(state: AppState) => state.addBucket.retentionValidity
);
const addLoading = useSelector((state: AppState) => state.addBucket.loading);
const valid = useSelector((state: AppState) => state.addBucket.valid);
const invalidFields = useSelector((state: AppState) => state.addBucket.invalidFields);
const lockingFieldDisabled = useSelector(
(state: AppState) => state.addBucket.lockingFieldDisabled
);
Expand Down Expand Up @@ -285,19 +285,16 @@ const AddBucket = ({ classes }: IsetProps) => {
<React.Fragment>
<Grid item xs={12}>
<InputBoxWrapper
type="number"
type="string"
id="quota_size"
name="quota_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.validity.valid) {
dispatch(setQuotaSize(e.target.value));
}
}}
label="Capacity"
value={quotaSize}
required
min="1"
pattern={"[0-9]*"}
overlayObject={
<InputUnitMenu
id={"quota_unit"}
Expand All @@ -309,6 +306,7 @@ const AddBucket = ({ classes }: IsetProps) => {
disabled={false}
/>
}
error={invalidFields.includes("quotaSize") ? "Please enter a valid quota" : ""}
/>
</Grid>
</React.Fragment>
Expand Down Expand Up @@ -387,7 +385,7 @@ const AddBucket = ({ classes }: IsetProps) => {
type="submit"
variant="contained"
color="primary"
disabled={addLoading || valid}
disabled={addLoading || invalidFields.length > 0}
>
Create Bucket
</Button>
Expand Down
Expand Up @@ -19,7 +19,7 @@ import { addBucketAsync } from "./addBucketThunks";

export interface AddBucketState {
loading: boolean;
valid: boolean;
invalidFields: string[];
name: string;
versioningEnabled: boolean;
lockingEnabled: boolean;
Expand All @@ -36,7 +36,7 @@ export interface AddBucketState {

const initialState: AddBucketState = {
loading: false,
valid: false,
invalidFields: ["name"],
name: "",
versioningEnabled: false,
lockingEnabled: false,
Expand All @@ -57,8 +57,11 @@ export const addBucketsSlice = createSlice({
reducers: {
setName: (state, action: PayloadAction<string>) => {
state.name = action.payload;

if (state.name.trim() === "") {
state.valid = false;
state.invalidFields = [...state.invalidFields, "name"];
} else {
state.invalidFields = state.invalidFields.filter((field) => field !== "name");
}
},
setVersioning: (state, action: PayloadAction<boolean>) => {
Expand All @@ -75,13 +78,22 @@ export const addBucketsSlice = createSlice({
},
setQuota: (state, action: PayloadAction<boolean>) => {
state.quotaEnabled = action.payload;

if(!action.payload) {
state.quotaSize = "1";
state.quotaUnit = "Ti";

state.invalidFields = state.invalidFields.filter((field) => field !== "quotaSize");
}
},
setQuotaSize: (state, action: PayloadAction<string>) => {
state.quotaSize = action.payload;

if (state.quotaEnabled && state.valid) {
if (state.quotaSize.trim() === "" || parseInt(state.quotaSize) === 0) {
state.valid = false;
if (state.quotaEnabled) {
if (state.quotaSize.trim() === "" || parseInt(state.quotaSize) === 0 || !(/^\d*(?:\.\d{1,2})?$/.test(state.quotaSize))) {
state.invalidFields = [...state.invalidFields, "quotaSize"];
} else {
state.invalidFields = state.invalidFields.filter((field) => field !== "quotaSize");
}
}
},
Expand Down Expand Up @@ -109,7 +121,9 @@ export const addBucketsSlice = createSlice({
state.retentionEnabled &&
(Number.isNaN(state.retentionValidity) || state.retentionValidity < 1)
) {
state.valid = false;
state.invalidFields = [...state.invalidFields, "retentionValidity"];
} else {
state.invalidFields = state.invalidFields.filter((field) => field !== "retentionValidity");
}
},
setRetentionMode: (state, action: PayloadAction<string>) => {
Expand All @@ -121,10 +135,12 @@ export const addBucketsSlice = createSlice({
setRetentionValidity: (state, action: PayloadAction<number>) => {
state.retentionValidity = action.payload;
if (
state.retentionEnabled &&
(Number.isNaN(state.retentionValidity) || state.retentionValidity < 1)
state.retentionEnabled &&
(Number.isNaN(state.retentionValidity) || state.retentionValidity < 1)
) {
state.valid = false;
state.invalidFields = [...state.invalidFields, "retentionValidity"];
} else {
state.invalidFields = state.invalidFields.filter((field) => field !== "retentionValidity");
}
},

Expand Down
Expand Up @@ -177,7 +177,7 @@ const BucketListItem = ({
const usageUnit = usage.split(" ")[1];

const quota = get(bucket, "details.quota.quota", "0");
const quotaForString = calculateBytes(quota);
const quotaForString = calculateBytes(quota, true, false);

const accessToStr = (bucket: Bucket): string => {
if (bucket.rw_access?.read && !bucket.rw_access?.write) {
Expand Down
Expand Up @@ -78,9 +78,7 @@ interface IAddNotificationEndpointProps {
classes: any;
}

const AddTierConfiguration = ({
classes,
}: IAddNotificationEndpointProps) => {
const AddTierConfiguration = ({ classes }: IAddNotificationEndpointProps) => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const params = useParams();
Expand Down
11 changes: 6 additions & 5 deletions portal-ui/src/screens/Console/Policies/PolicySelectors.tsx
Expand Up @@ -85,11 +85,13 @@ const PolicySelectors = ({
const [loading, isLoading] = useState<boolean>(false);
const [filter, setFilter] = useState<string>("");

const currentPolicies = useSelector((state: AppState) => state.createUser.selectedPolicies);
const currentPolicies = useSelector(
(state: AppState) => state.createUser.selectedPolicies
);

const fetchPolicies = useCallback(() => {
isLoading(true);

api
.invoke("GET", `/api/v1/policies?limit=1000`)
.then((res: PolicyList) => {
Expand All @@ -115,11 +117,10 @@ const PolicySelectors = ({
}, [loading, fetchPolicies]);

const selectionChanged = (e: React.ChangeEvent<HTMLInputElement>) => {

const targetD = e.target;
const value = targetD.value;
const checked = targetD.checked;

let elements: string[] = [...currentPolicies]; // We clone the checkedUsers array

if (checked) {
Expand All @@ -131,7 +132,7 @@ const PolicySelectors = ({
}
// remove empty values
elements = elements.filter((element) => element !== "");

dispatch(setSelectedPolicies(elements));
};

Expand Down
10 changes: 4 additions & 6 deletions portal-ui/src/screens/Console/Policies/SetPolicy.tsx
Expand Up @@ -48,8 +48,6 @@ interface ISetPolicyProps {
open: boolean;
}



const styles = (theme: Theme) =>
createStyles({
...modalBasic,
Expand All @@ -76,7 +74,9 @@ const SetPolicy = ({
const [loading, setLoading] = useState<boolean>(false);
const [actualPolicy, setActualPolicy] = useState<string[]>([]);
const [selectedPolicy, setSelectedPolicy] = useState<string[]>([]);
const currentPolicies = useSelector((state: AppState) => state.createUser.selectedPolicies);
const currentPolicies = useSelector(
(state: AppState) => state.createUser.selectedPolicies
);
const setPolicyAction = () => {
let users = null;
let groups = null;
Expand Down Expand Up @@ -175,9 +175,7 @@ const SetPolicy = ({
)}
<Grid item xs={12}>
<div className={classes.tableBlock}>
<PolicySelectors
selectedPolicy={selectedPolicy}
/>
<PolicySelectors selectedPolicy={selectedPolicy} />
</div>
</Grid>
</Grid>
Expand Down

0 comments on commit 7ecc102

Please sign in to comment.