diff --git a/portal-ui/src/screens/Console/Common/UsageBar/UsageBar.tsx b/portal-ui/src/screens/Console/Common/UsageBar/UsageBar.tsx new file mode 100644 index 000000000..cff7a19b9 --- /dev/null +++ b/portal-ui/src/screens/Console/Common/UsageBar/UsageBar.tsx @@ -0,0 +1,65 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2022 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import React from "react"; + +export interface ISizeBarItem { + value: number; + itemName: string; + color: string; +} + +export interface IUsageBar { + totalValue: number; + sizeItems: ISizeBarItem[]; + bgColor?: string; +} + +const UsageBar = ({ + totalValue, + sizeItems, + bgColor = "#ededed", +}: IUsageBar) => { + return ( +
+ {sizeItems.map((sizeElement) => { + const itemPercentage = (sizeElement.value * 100) / totalValue; + return ( +
+ ); + })} +
+ ); +}; + +export default UsageBar; diff --git a/portal-ui/src/screens/Console/Common/UsageBarWrapper/SummaryUsageBar.tsx b/portal-ui/src/screens/Console/Common/UsageBarWrapper/SummaryUsageBar.tsx index a1ee31558..ed340bb91 100644 --- a/portal-ui/src/screens/Console/Common/UsageBarWrapper/SummaryUsageBar.tsx +++ b/portal-ui/src/screens/Console/Common/UsageBarWrapper/SummaryUsageBar.tsx @@ -1,19 +1,23 @@ -import React from "react"; +import React, { Fragment } from "react"; import { Theme } from "@mui/material/styles"; +import { LinearProgress, Stack } from "@mui/material"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; -import { LinearProgress, Stack } from "@mui/material"; import Grid from "@mui/material/Grid"; -import ErrorBlock from "../../../shared/ErrorBlock"; +import { + CapacityValues, + ITenant, + ValueUnit, +} from "../../Tenants/ListTenants/types"; import { CircleIcon } from "../../../../icons"; -import LabelValuePair from "./LabelValuePair"; -import { ValueUnit } from "../../Tenants/ListTenants/types"; -import { niceBytes } from "../../../../common/utils"; +import { niceBytes, niceBytesInt } from "../../../../common/utils"; import Loader from "../Loader/Loader"; +import TenantCapacity from "../../Tenants/ListTenants/TenantCapacity"; +import ErrorBlock from "../../../shared/ErrorBlock"; +import LabelValuePair from "./LabelValuePair"; interface ISummaryUsageBar { - maxValue: number | undefined; - currValue: number | undefined; + tenant: ITenant; label: string; error: string; loading: boolean; @@ -57,31 +61,66 @@ export const BorderLinearProgress = withStyles((theme) => ({ const SummaryUsageBar = ({ classes, - maxValue, - currValue, + tenant, healthStatus, loading, error, }: ISummaryUsageBar) => { - var capacity: ValueUnit = { value: "n/a", unit: "" }; - var used: ValueUnit = { value: "n/a", unit: "" }; + console.log("TENANT", tenant) + let raw: ValueUnit = { value: "n/a", unit: "" }; + let capacity: ValueUnit = { value: "n/a", unit: "" }; + let used: ValueUnit = { value: "n/a", unit: "" }; + let localUse: ValueUnit = { value: "n/a", unit: "" }; + let tieredUse: ValueUnit = { value: "n/a", unit: "" }; - if (maxValue) { - const b = niceBytes(`${maxValue}`, true); + if (tenant.status?.usage?.raw) { + const b = niceBytes(`${tenant.status.usage.raw}`, true); + const parts = b.split(" "); + raw.value = parts[0]; + raw.unit = parts[1]; + } + if (tenant.status?.usage?.capacity) { + const b = niceBytes(`${tenant.status.usage.capacity}`, true); const parts = b.split(" "); capacity.value = parts[0]; capacity.unit = parts[1]; } - if (currValue) { - const b = niceBytes(`${currValue}`, true); + if (tenant.status?.usage?.capacity_usage) { + const b = niceBytesInt(tenant.status.usage.capacity_usage, true); const parts = b.split(" "); used.value = parts[0]; used.unit = parts[1]; } - let percentagelValue = 0; - if (currValue && maxValue) { - percentagelValue = (currValue * 100) / maxValue; + let spaceVariants: CapacityValues[] = []; + if (!tenant.tiers || tenant.tiers.length === 0) { + spaceVariants = [ + { value: tenant.status?.usage?.capacity_usage || 0, variant: "STANDARD" }, + ]; + } else { + spaceVariants = tenant.tiers.map((itemTenant) => { + return { value: itemTenant.size, variant: itemTenant.name }; + }); + let internalUsage = tenant.tiers + .filter((itemTenant) => { + return itemTenant.type === "internal"; + }) + .reduce((sum, itemTenant) => sum + itemTenant.size, 0); + let tieredUsage = tenant.tiers + .filter((itemTenant) => { + return itemTenant.type !== "internal"; + }) + .reduce((sum, itemTenant) => sum + itemTenant.size, 0); + + const t = niceBytesInt(tieredUsage, true); + const parts = t.split(" "); + tieredUse.value = parts[0]; + tieredUse.unit = parts[1]; + + const is = niceBytesInt(internalUsage, true); + const partsInternal = is.split(" "); + localUse.value = partsInternal[0]; + localUse.unit = partsInternal[1]; } const renderComponent = () => { @@ -90,26 +129,41 @@ const SummaryUsageBar = ({ ) : ( - - - + {(!tenant.tiers || tenant.tiers.length === 0) && ( + + + + )} + {tenant.tiers && tenant.tiers.length > 0 && ( + + + + + )} {healthStatus && ( { const colors = [ "#8dacd3", @@ -44,6 +47,8 @@ const TenantCapacity = ({ "#2781B0", ]; + const BGColor = "#ededed"; + const totalUsedSpace = usedSpaceVariants.reduce((acc, currValue) => { return acc + currValue.value; }, 0); @@ -88,15 +93,39 @@ const TenantCapacity = ({ } const plotValues: CapacityValue[] = [ - { value: emptySpace, color: "transparent", label: "Empty Space" }, { value: standardTier.value, color: standardTierColor, label: "Used Space by Tenant", }, ...tiersList, + { + value: emptySpace, + color: render === "bar" ? BGColor : "transparent", + label: "Empty Space", + }, ]; + if (render === "bar") { + const plotValuesForUsageBar: ISizeBarItem[] = plotValues.map((plotVal) => { + return { + value: plotVal.value, + color: plotVal.color, + itemName: plotVal.label, + }; + }); + + return ( +
+ +
+ ); + } + return (
diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/types.ts b/portal-ui/src/screens/Console/Tenants/ListTenants/types.ts index fe4249fb2..b27e6cbad 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/types.ts +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/types.ts @@ -148,7 +148,7 @@ export interface ITenant { image: string; pool_count: number; currentState: string; - instance_count: 4; + instance_count: number; creation_date: string; volume_size: number; volume_count: number; @@ -270,3 +270,7 @@ export interface IEditPoolItem { export interface IEditPoolRequest { pools: IEditPoolItem[]; } + +export interface IPlotBarValues { + [key: string]: CapacityValue; +} diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSummary.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSummary.tsx index c487663ce..35c12e9be 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSummary.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSummary.tsx @@ -123,10 +123,13 @@ const healthStatusToClass = (health_status: string = "red", classes: any) => { }; const StorageSummary = ({ tenant, classes }: Partial) => { + if (!tenant) { + return null; + } + return (