- {splitedDrives.map((drive, index) => (
-
-
-
- ))}
-
-
-
- {!usage?.prometheusNotReady && (
-
-
+ )}
+
+ {!usage?.prometheusNotReady && (
}
- title={"Monitoring"}
+ iconComponent={}
+ title={"We can’t retrieve advanced metrics at this time."}
help={
-
- The MinIO Dashboard is displaying basic metrics only due to
- missing the{" "}
-
+
- necessary settings
- {" "}
- for displaying extended metrics.
-
-
- See{" "}
-
+ theme.colors.link,
+ },
+ }}
>
- Collect MinIO Metrics Using Prometheus
- {" "}
- for a complete tutorial on scraping and visualizing MinIO
- metrics with Prometheus.
-
+
+ Read more about Prometheus on our Docs site.
+
+
+
}
/>
-
-
- )}
-
+ )}
+
+
+
+
+
+ }
+ counterValue={usage ? representationNumber(usage.buckets) : 0}
+ />
+
+
+ }
+ counterValue={usage ? representationNumber(usage.objects) : 0}
+ />
+
+
+ }
+ />
+
+
+ }
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
-export default withStyles(styles)(BasicDashboard);
+export default BasicDashboard;
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/CounterCard.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/CounterCard.tsx
new file mode 100644
index 000000000..a865faa05
--- /dev/null
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/CounterCard.tsx
@@ -0,0 +1,118 @@
+// 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 { Box, Tooltip } from "@mui/material";
+import React from "react";
+
+const CounterCard = ({
+ counterValue,
+ label = "",
+ icon = null,
+}: {
+ counterValue: string | number;
+ label?: any;
+ icon?: any;
+}) => {
+ return (
+
+
+
+
+ {label}
+
+
+
+
+ {counterValue}
+
+
+
+
+ {icon}
+
+
+
+ );
+};
+
+export default CounterCard;
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/DriveInfoCard.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/DriveInfoCard.tsx
deleted file mode 100644
index 24d1e241f..000000000
--- a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/DriveInfoCard.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-// This file is part of MinIO Console Server
-// Copyright (c) 2021 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, { Fragment } from "react";
-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 { IDriveInfo } from "../types";
-import { niceBytes } from "../../../../common/utils";
-import { Card, CardHeader } from "@mui/material";
-import { CircleIcon } from "../../../../icons";
-import { commonDashboardInfocard } from "../../Common/FormComponents/common/styleLibrary";
-
-const styles = (theme: Theme) =>
- createStyles({
- ...commonDashboardInfocard,
- });
-
-interface ICardProps {
- classes: any;
- drive: IDriveInfo;
-}
-
-const DriveInfoCard = ({ classes, drive }: ICardProps) => {
- const driveStatusToClass = (health_status: string) => {
- switch (health_status) {
- case "offline":
- return classes.redState;
- case "ok":
- return classes.greenState;
- default:
- return classes.greyState;
- }
- };
-
- return (
-
-
-
- {drive.state && (
-
-
-
- )}
- {drive.endpoint || ""}
-
- }
- subheader={
-
-
- Capacity:{" "}
- {niceBytes(
- drive.totalSpace ? drive.totalSpace.toString() : "0"
- )}
-
-
- Used:{" "}
- {niceBytes(drive.usedSpace ? drive.usedSpace.toString() : "0")}
-
-
- Available:{" "}
- {niceBytes(
- drive.availableSpace ? drive.availableSpace.toString() : "0"
- )}
-
-
- }
- />
-
-
- );
-};
-
-export default withStyles(styles)(DriveInfoCard);
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/DriveInfoItem.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/DriveInfoItem.tsx
new file mode 100644
index 000000000..abf83c541
--- /dev/null
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/DriveInfoItem.tsx
@@ -0,0 +1,175 @@
+// 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";
+import { Theme } from "@mui/material/styles";
+import createStyles from "@mui/styles/createStyles";
+import withStyles from "@mui/styles/withStyles";
+import { IDriveInfo } from "../types";
+import { niceBytes } from "../../../../common/utils";
+import { Box } from "@mui/material";
+import { CircleIcon, DrivesIcon } from "../../../../icons";
+import { commonDashboardInfocard } from "../../Common/FormComponents/common/styleLibrary";
+import { STATUS_COLORS } from "./Utils";
+
+const styles = (theme: Theme) =>
+ createStyles({
+ ...commonDashboardInfocard,
+ });
+
+interface ICardProps {
+ classes?: any;
+ drive: IDriveInfo;
+}
+
+const driveStatusColor = (health_status: string) => {
+ switch (health_status) {
+ case "offline":
+ return STATUS_COLORS.RED;
+ case "ok":
+ return STATUS_COLORS.GREEN;
+ default:
+ return STATUS_COLORS.YELLOW;
+ }
+};
+
+const DriveInfoItem = ({ classes, drive }: ICardProps) => {
+ return (
+
+
+
+
+
+
+
+ {drive.state && }
+
+
+
+
+
+ );
+};
+
+export default withStyles(styles)(DriveInfoItem);
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ReportedUsage.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ReportedUsage.tsx
new file mode 100644
index 000000000..aaeef0e62
--- /dev/null
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ReportedUsage.tsx
@@ -0,0 +1,85 @@
+// 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 { ReportedUsageIcon } from "../../../../icons";
+import { Box, Tooltip } from "@mui/material";
+import React from "react";
+
+const ReportedUsage = ({
+ usageValue,
+ total,
+ unit,
+}: {
+ usageValue: string;
+ total: number | string;
+ unit: string;
+}) => {
+ return (
+
+
+ Reported Usage
+
+
+
+
+
+
+
+ );
+};
+
+export default ReportedUsage;
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServerInfoCard.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServerInfoCard.tsx
deleted file mode 100644
index 1a1380e89..000000000
--- a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServerInfoCard.tsx
+++ /dev/null
@@ -1,121 +0,0 @@
-// This file is part of MinIO Console Server
-// Copyright (c) 2021 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";
-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 { ServerInfo } from "../types";
-import { niceDays } from "../../../../common/utils";
-import { Card, CardHeader } from "@mui/material";
-import { CircleIcon, VersionIcon } from "../../../../icons";
-import get from "lodash/get";
-import { commonDashboardInfocard } from "../../Common/FormComponents/common/styleLibrary";
-
-const styles = (theme: Theme) =>
- createStyles({
- ...commonDashboardInfocard,
- });
-
-interface ICardProps {
- classes: any;
- server: ServerInfo;
- index: number;
-}
-
-const ServerInfoCard = ({ classes, server, index }: ICardProps) => {
- const serverStatusToClass = (health_status: string) => {
- switch (health_status) {
- case "offline":
- return classes.redState;
- case "online":
- return classes.greenState;
- default:
- return classes.greyState;
- }
- };
- const networkKeys = Object.keys(get(server, "network", {}));
- const networkTotal = networkKeys.length;
- const totalDrives = server.drives ? server.drives.length : 0;
- const activeNetwork = networkKeys.reduce((acc: number, currValue: string) => {
- const item = server.network[currValue];
- if (item === "online") {
- return acc + 1;
- }
- return acc;
- }, 0);
- const activeDisks = server.drives
- ? server.drives.filter((element) => element.state === "ok").length
- : 0;
- return (
-
-
-
-
- }
- subheader={
-
-
-
-
-
- Drives: {activeDisks}/{totalDrives}{" "}
-
-
-
-
-
- Network: {activeNetwork}/{networkTotal}{" "}
-
-
- Uptime: {server.uptime ? niceDays(server.uptime) : "N/A"}
-
-
-
- Version {server.version ? server.version : "N/A"}
-
-
- }
- />
-
- );
-};
-export default withStyles(styles)(ServerInfoCard);
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServerInfoItem.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServerInfoItem.tsx
new file mode 100644
index 000000000..0bcb41fd6
--- /dev/null
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServerInfoItem.tsx
@@ -0,0 +1,239 @@
+// 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";
+import { Theme } from "@mui/material/styles";
+import createStyles from "@mui/styles/createStyles";
+import withStyles from "@mui/styles/withStyles";
+import { ServerInfo } from "../types";
+import { niceDays } from "../../../../common/utils";
+import { Box } from "@mui/material";
+import {
+ CircleIcon,
+ DrivesIcon,
+ UptimeIcon,
+ VersionIcon,
+ WarpIcon,
+} from "../../../../icons";
+import get from "lodash/get";
+import { commonDashboardInfocard } from "../../Common/FormComponents/common/styleLibrary";
+import {
+ getDriveStatusColor,
+ getNetworkStatusColor,
+ serverStatusColor,
+} from "./Utils";
+
+const styles = (theme: Theme) =>
+ createStyles({
+ ...commonDashboardInfocard,
+ });
+
+interface ICardProps {
+ classes?: any;
+ server: ServerInfo;
+ index: number;
+}
+
+const ServerStatItem = ({
+ label = "",
+ value = "",
+ statusColor = "",
+ hasStatus = false,
+ icon = null,
+}: {
+ label?: string;
+ value?: any;
+ hasStatus?: boolean;
+ statusColor: string | undefined;
+ icon?: any;
+}) => {
+ return (
+
+
+ {icon}
+ {hasStatus ? (
+
+
+
+ ) : (
+
+ )}
+
+
+
{label}
+
{value}
+
+
+ );
+};
+
+const ServerInfoItem = ({ classes = {}, server, index }: ICardProps) => {
+ const networkKeys = Object.keys(get(server, "network", {}));
+ const networkTotal = networkKeys.length;
+ const totalDrives = server.drives ? server.drives.length : 0;
+ const activeNetwork = networkKeys.reduce((acc: number, currValue: string) => {
+ const item = server.network[currValue];
+ if (item === "online") {
+ return acc + 1;
+ }
+ return acc;
+ }, 0);
+ const activeDisks = server.drives
+ ? server.drives.filter((element) => element.state === "ok").length
+ : 0;
+ return (
+
+
+ {server?.state && (
+
+
+
+ )}
+
+ {server.endpoint || ""}
+
+
+
+ }
+ hasStatus={true}
+ value={`${activeDisks}/${totalDrives}`}
+ />
+ }
+ hasStatus={true}
+ value={`${activeNetwork}/${networkTotal}`}
+ />
+
+ }
+ value={server?.uptime ? niceDays(server.uptime) : "N/A"}
+ />
+
+ }
+ value={
+
+ {server.version ? server.version : "N/A"}
+
+ }
+ />
+
+
+ );
+};
+export default withStyles(styles)(ServerInfoItem);
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServersList.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServersList.tsx
new file mode 100644
index 000000000..77ef9de53
--- /dev/null
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/ServersList.tsx
@@ -0,0 +1,146 @@
+// 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";
+import ListSubheader from "@mui/material/ListSubheader";
+import List from "@mui/material/List";
+import ListItemButton from "@mui/material/ListItemButton";
+import Collapse from "@mui/material/Collapse";
+import ExpandLess from "@mui/icons-material/ExpandLess";
+import ExpandMore from "@mui/icons-material/ExpandMore";
+import { ServerInfo } from "../types";
+import ServerInfoItem from "./ServerInfoItem";
+import { Box } from "@mui/material";
+import DriveInfoItem from "./DriveInfoItem";
+
+const ServersList = ({ data }: { data: ServerInfo[] }) => {
+ const [expanded, setExpanded] = React.useState("");
+
+ const handleClick = (key: string) => {
+ setExpanded(key);
+ };
+
+ return (
+
+ Servers ({data.length})
+
+ }
+ >
+ {data.map((serverInfo, index) => {
+ const key = `${serverInfo.endpoint}-${index}`;
+ const isExpanded = expanded === key;
+ return (
+
+ {
+ if (!isExpanded) {
+ handleClick(key);
+ } else {
+ handleClick("");
+ }
+ }}
+ className={isExpanded ? "expanded" : ""}
+ sx={{
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "space-between",
+ borderBottom: "1px solid #eaeaea",
+ "&:hover": {
+ background: "#F8F8F8",
+ },
+ "&.expanded": {
+ borderBottom: "none",
+ },
+ }}
+ >
+
+
+ {isExpanded ? : }
+
+
+ {isExpanded ? (
+
+
+ Drives ({serverInfo.drives.length})
+
+
+
+ {serverInfo.drives.map((driveInfo, index) => {
+ return (
+
+ );
+ })}
+
+
+ ) : null}
+
+ );
+ })}
+
+ );
+};
+
+export default ServersList;
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/StatusCountCard.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/StatusCountCard.tsx
new file mode 100644
index 000000000..eae190290
--- /dev/null
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/StatusCountCard.tsx
@@ -0,0 +1,147 @@
+// 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";
+import { Box } from "@mui/material";
+import { CircleIcon } from "../../../../icons";
+
+export const StatusCountCard = ({
+ onlineCount = 0,
+ offlineCount = 0,
+ icon = null,
+ label = "",
+}: {
+ icon: any;
+ onlineCount: number;
+ offlineCount: number;
+ label: string;
+}) => {
+ return (
+
+
+
+
+ {label}
+
+
+
+
+
+
Online
+
+ {onlineCount}
+
+
+
+
+
Offline
+
+ {offlineCount}
+
+
+
+
+ {icon}
+
+
+
+ );
+};
+
+export default StatusCountCard;
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/Utils.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/Utils.tsx
new file mode 100644
index 000000000..d8a3dc032
--- /dev/null
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/Utils.tsx
@@ -0,0 +1,61 @@
+// 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 .
+
+export const STATUS_COLORS = {
+ RED: "#C83B51",
+ GREEN: "#4CCB92",
+ YELLOW: "#E7A219",
+};
+
+export const getDriveStatusColor = (
+ activeDisks: number,
+ totalDrives: number
+) => {
+ if (activeDisks <= totalDrives / 2) {
+ return STATUS_COLORS.RED;
+ }
+ if (totalDrives !== 2 && activeDisks === totalDrives / 2 + 1) {
+ return STATUS_COLORS.YELLOW;
+ }
+ if (activeDisks === totalDrives) {
+ return STATUS_COLORS.GREEN;
+ }
+};
+
+export const serverStatusColor = (health_status: string) => {
+ switch (health_status) {
+ case "offline":
+ return STATUS_COLORS.RED;
+ case "online":
+ return STATUS_COLORS.GREEN;
+ default:
+ return STATUS_COLORS.YELLOW;
+ }
+};
+export const getNetworkStatusColor = (
+ activeNetwork: number,
+ networkTotal: number
+) => {
+ if (activeNetwork <= networkTotal / 2) {
+ return STATUS_COLORS.RED;
+ }
+ if (activeNetwork === networkTotal / 2 + 1) {
+ return STATUS_COLORS.YELLOW;
+ }
+ if (activeNetwork === networkTotal) {
+ return STATUS_COLORS.GREEN;
+ }
+};
diff --git a/portal-ui/src/screens/Console/Dashboard/Dashboard.tsx b/portal-ui/src/screens/Console/Dashboard/Dashboard.tsx
index 195d1797b..78fa81230 100644
--- a/portal-ui/src/screens/Console/Dashboard/Dashboard.tsx
+++ b/portal-ui/src/screens/Console/Dashboard/Dashboard.tsx
@@ -24,12 +24,12 @@ import { containerForHeader } from "../Common/FormComponents/common/styleLibrary
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
-import BasicDashboard from "./BasicDashboard/BasicDashboard";
import { LinearProgress } from "@mui/material";
import api from "../../../common/api";
import { Usage } from "./types";
import { setErrorSnackMessage } from "../../../actions";
import { ErrorResponseHandler } from "../../../common/types";
+import BasicDashboard from "./BasicDashboard/BasicDashboard";
interface IDashboardSimple {
classes: any;
@@ -82,9 +82,7 @@ const Dashboard = ({ classes, displayErrorMessage }: IDashboardSimple) => {
) : (
-
-
-
+
)}
)}