Skip to content

Commit 1053992

Browse files
bexsoftBenjamin Perez
andauthored
Added quota metric to buckets list & objects list (#1595)
Signed-off-by: Benjamin Perez <[email protected]> Co-authored-by: Benjamin Perez <[email protected]>
1 parent 3606870 commit 1053992

File tree

3 files changed

+39
-47
lines changed

3 files changed

+39
-47
lines changed

portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
//
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
import React from "react";
16+
import React, {Fragment} from "react";
17+
import get from "lodash/get";
1718
import { Theme } from "@mui/material/styles";
1819
import createStyles from "@mui/styles/createStyles";
1920
import withStyles from "@mui/styles/withStyles";
@@ -26,7 +27,7 @@ import {
2627
} from "../../../../icons";
2728
import { Bucket } from "../types";
2829
import { Box, Grid, Typography } from "@mui/material";
29-
import { niceBytes, prettyNumber } from "../../../../common/utils";
30+
import {calculateBytes, niceBytes, prettyNumber} from "../../../../common/utils";
3031
import CheckboxWrapper from "../../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
3132
import { Link } from "react-router-dom";
3233
import {
@@ -163,7 +164,6 @@ const styles = (theme: Theme) =>
163164
interface IBucketListItem {
164165
bucket: Bucket;
165166
classes: any;
166-
onDelete: (bucketName: string) => void;
167167
onSelect: (e: React.ChangeEvent<HTMLInputElement>) => void;
168168
selected: boolean;
169169
bulkSelect: boolean;
@@ -172,7 +172,6 @@ interface IBucketListItem {
172172
const BucketListItem = ({
173173
classes,
174174
bucket,
175-
onDelete,
176175
onSelect,
177176
selected,
178177
bulkSelect,
@@ -181,6 +180,10 @@ const BucketListItem = ({
181180
const usageScalar = usage.split(" ")[0];
182181
const usageUnit = usage.split(" ")[1];
183182

183+
const quota = get(bucket, "details.quota.quota", "0");
184+
const quotaForString = calculateBytes(quota);
185+
186+
184187
const accessToStr = (bucket: Bucket): string => {
185188
if (bucket.rw_access?.read && !bucket.rw_access?.write) {
186189
return "R";
@@ -287,6 +290,11 @@ const BucketListItem = ({
287290
<div className={classes.metricText}>
288291
{usageScalar}
289292
<span className={classes.unit}>{usageUnit}</span>
293+
{quota !== "0" && (
294+
<Fragment>
295+
{" "}/{" "}{quotaForString.total}<span className={classes.unit}>{quotaForString.unit}</span>
296+
</Fragment>
297+
)}
290298
</div>
291299
</Grid>
292300
<Grid item textAlign={"left"} className={classes.metric}>

portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,17 @@ import { LinearProgress } from "@mui/material";
2323
import Grid from "@mui/material/Grid";
2424
import { Bucket, BucketList } from "../types";
2525
import { AddIcon, BucketsIcon, LifecycleConfigIcon } from "../../../../icons";
26-
import { AppState } from "../../../../store";
2726
import { setErrorSnackMessage } from "../../../../actions";
2827
import {
2928
containerForHeader,
3029
searchField,
3130
} from "../../Common/FormComponents/common/styleLibrary";
3231
import { ErrorResponseHandler } from "../../../../common/types";
3332
import api from "../../../../common/api";
34-
import DeleteBucket from "./DeleteBucket";
3533
import PageHeader from "../../Common/PageHeader/PageHeader";
3634
import BucketListItem from "./BucketListItem";
3735
import BulkReplicationModal from "./BulkReplicationModal";
3836
import HelpBox from "../../../../common/HelpBox";
39-
import { ISessionResponse } from "../../types";
4037
import RefreshIcon from "../../../../icons/RefreshIcon";
4138
import AButton from "../../Common/AButton/AButton";
4239
import MultipleBucketsIcon from "../../../../icons/MultipleBucketsIcon";
@@ -85,19 +82,15 @@ interface IListBucketsProps {
8582
classes: any;
8683
history: any;
8784
setErrorSnackMessage: typeof setErrorSnackMessage;
88-
session: ISessionResponse;
8985
}
9086

9187
const ListBuckets = ({
9288
classes,
9389
history,
9490
setErrorSnackMessage,
95-
session,
9691
}: IListBucketsProps) => {
9792
const [records, setRecords] = useState<Bucket[]>([]);
9893
const [loading, setLoading] = useState<boolean>(true);
99-
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
100-
const [selectedBucket, setSelectedBucket] = useState<string>("");
10194
const [filterBuckets, setFilterBuckets] = useState<string>("");
10295
const [selectedBuckets, setSelectedBuckets] = useState<string[]>([]);
10396
const [replicationModalOpen, setReplicationModalOpen] =
@@ -125,28 +118,11 @@ const ListBuckets = ({
125118
}
126119
}, [loading, setErrorSnackMessage]);
127120

128-
const closeDeleteModalAndRefresh = (refresh: boolean) => {
129-
setDeleteOpen(false);
130-
if (refresh) {
131-
setLoading(true);
132-
setSelectedBuckets([]);
133-
}
134-
};
135-
136-
const confirmDeleteBucket = (bucket: string) => {
137-
setDeleteOpen(true);
138-
setSelectedBucket(bucket);
139-
};
140-
141121
const filteredRecords = records.filter((b: Bucket) => {
142122
if (filterBuckets === "") {
143123
return true;
144124
} else {
145-
if (b.name.indexOf(filterBuckets) >= 0) {
146-
return true;
147-
} else {
148-
return false;
149-
}
125+
return b.name.indexOf(filterBuckets) >= 0;
150126
}
151127
});
152128

@@ -191,7 +167,6 @@ const ListBuckets = ({
191167
return (
192168
<BucketListItem
193169
bucket={bucket}
194-
onDelete={confirmDeleteBucket}
195170
onSelect={selectListBuckets}
196171
selected={selectedBuckets.includes(bucket.name)}
197172
bulkSelect={bulkSelect}
@@ -205,15 +180,6 @@ const ListBuckets = ({
205180

206181
return (
207182
<Fragment>
208-
{deleteOpen && (
209-
<DeleteBucket
210-
deleteOpen={deleteOpen}
211-
selectedBucket={selectedBucket}
212-
closeDeleteModalAndRefresh={(refresh: boolean) => {
213-
closeDeleteModalAndRefresh(refresh);
214-
}}
215-
/>
216-
)}
217183
{replicationModalOpen && (
218184
<BulkReplicationModal
219185
open={replicationModalOpen}
@@ -378,11 +344,7 @@ const ListBuckets = ({
378344
);
379345
};
380346

381-
const mapState = (state: AppState) => ({
382-
session: state.console.session,
383-
});
384-
385-
const connector = connect(mapState, {
347+
const connector = connect(null, {
386348
setErrorSnackMessage,
387349
});
388350

portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import React, {
2424
} from "react";
2525
import { connect } from "react-redux";
2626
import { useDropzone } from "react-dropzone";
27-
2827
import { Theme } from "@mui/material/styles";
2928
import createStyles from "@mui/styles/createStyles";
3029
import withStyles from "@mui/styles/withStyles";
@@ -74,7 +73,7 @@ import {
7473
setErrorSnackMessage,
7574
setSnackBarMessage,
7675
} from "../../../../../../actions";
77-
import { BucketInfo, BucketVersioning } from "../../../types";
76+
import { BucketInfo, BucketQuota, BucketVersioning } from "../../../types";
7877
import { ErrorResponseHandler } from "../../../../../../common/types";
7978

8079
import ScreenTitle from "../../../../Common/ScreenTitle/ScreenTitle";
@@ -292,6 +291,7 @@ const ListObjects = ({
292291
const [selectedInternalPaths, setSelectedInternalPaths] = useState<
293292
string | null
294293
>(null);
294+
const [quota, setQuota] = useState<BucketQuota | null>(null);
295295

296296
const internalPaths = get(match.params, "subpaths", "");
297297
const bucketName = match.params["bucketName"];
@@ -327,6 +327,25 @@ const ListObjects = ({
327327
}
328328
}, [selectedObjects]);
329329

330+
useEffect(() => {
331+
if (!quota) {
332+
api
333+
.invoke("GET", `/api/v1/buckets/${bucketName}/quota`)
334+
.then((res: BucketQuota) => {
335+
let quotaVals = null;
336+
337+
if (res.quota) {
338+
quotaVals = res;
339+
}
340+
341+
setQuota(quotaVals);
342+
})
343+
.catch(() => {
344+
setQuota(null);
345+
});
346+
}
347+
}, [quota, bucketName]);
348+
330349
const displayDeleteObject = hasPermission(bucketName, [
331350
IAM_SCOPES.S3_DELETE_OBJECT,
332351
]);
@@ -1176,7 +1195,10 @@ const ListObjects = ({
11761195
{bucketInfo.size && (
11771196
<Fragment>{niceBytesInt(bucketInfo.size)}</Fragment>
11781197
)}
1179-
{bucketInfo.size && bucketInfo.objects ? " / " : ""}
1198+
{bucketInfo.size && quota && (
1199+
<Fragment> / {niceBytesInt(quota.quota)}</Fragment>
1200+
)}
1201+
{bucketInfo.size && bucketInfo.objects ? " - " : ""}
11801202
{bucketInfo.objects && (
11811203
<Fragment>
11821204
{bucketInfo.objects}&nbsp;Object

0 commit comments

Comments
 (0)