UX Basic Dashboard (#1799)
This commit is contained in:
committed by
GitHub
parent
f30450c3c1
commit
4647671f07
@@ -959,7 +959,7 @@ const commonStateIcon = {
|
||||
marginTop: 6,
|
||||
};
|
||||
|
||||
export const commonDashboardInfocard = {
|
||||
export const commonDashboardInfocard: any = {
|
||||
cardIconContainer: {
|
||||
display: "flex" as const,
|
||||
position: "relative" as const,
|
||||
|
||||
@@ -32,21 +32,14 @@ import ServersList from "./ServersList";
|
||||
import CounterCard from "./CounterCard";
|
||||
import ReportedUsage from "./ReportedUsage";
|
||||
|
||||
const BoxItem = ({
|
||||
children,
|
||||
background = "#ffffff",
|
||||
}: {
|
||||
children: any;
|
||||
background?: string;
|
||||
}) => {
|
||||
const BoxItem = ({ children }: { children: any }) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
border: "1px solid #f1f1f1",
|
||||
background: background,
|
||||
padding: "25px",
|
||||
maxWidth: {
|
||||
sm: "100%",
|
||||
xs: "250px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
@@ -204,22 +197,14 @@ const BasicDashboard = ({ usage }: IDashboardProps) => {
|
||||
gap: "40px",
|
||||
}}
|
||||
>
|
||||
<BoxItem
|
||||
background={
|
||||
"linear-gradient(-15deg, #2781b0 0%, #ffffff 30%) 0% 0% no-repeat padding-box"
|
||||
}
|
||||
>
|
||||
<BoxItem>
|
||||
<CounterCard
|
||||
label={"Buckets"}
|
||||
icon={<BucketsIcon />}
|
||||
counterValue={usage ? representationNumber(usage.buckets) : 0}
|
||||
/>
|
||||
</BoxItem>
|
||||
<BoxItem
|
||||
background={
|
||||
"linear-gradient(-15deg, #4CCB92 0%, #ffffff 30%) 0% 0% no-repeat padding-box"
|
||||
}
|
||||
>
|
||||
<BoxItem>
|
||||
<CounterCard
|
||||
label={"Objects"}
|
||||
icon={<TotalObjectsIcon />}
|
||||
@@ -259,9 +244,7 @@ const BasicDashboard = ({ usage }: IDashboardProps) => {
|
||||
gap: "auto",
|
||||
}}
|
||||
>
|
||||
<BoxItem>
|
||||
<ServersList data={serverList} />
|
||||
</BoxItem>
|
||||
<ServersList data={serverList} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -32,19 +32,20 @@ const CounterCard = ({
|
||||
fontFamily: "Lato,sans-serif",
|
||||
color: "#07193E",
|
||||
maxWidth: "300px",
|
||||
minHeight: "200px",
|
||||
minHeight: "143px",
|
||||
display: "flex",
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
cursor: "default",
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
//marginLeft: "25px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
flex: 1,
|
||||
height: "200px",
|
||||
minHeight: "200px",
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
padding: {
|
||||
@@ -59,7 +60,7 @@ const CounterCard = ({
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
marginTop: "32px",
|
||||
marginTop: "22px",
|
||||
zIndex: 10,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
@@ -78,10 +79,10 @@ const CounterCard = ({
|
||||
sx={{
|
||||
fontSize: {
|
||||
xl: "55px",
|
||||
lg: "40px",
|
||||
lg: "50px",
|
||||
md: "36px",
|
||||
sm: "22px",
|
||||
xs: "14px",
|
||||
sm: "35px",
|
||||
xs: "35px",
|
||||
},
|
||||
fontWeight: 600,
|
||||
overflow: "hidden",
|
||||
@@ -90,6 +91,10 @@ const CounterCard = ({
|
||||
md: 187,
|
||||
xs: 200,
|
||||
},
|
||||
flexFlow: {
|
||||
md: "row",
|
||||
xs: "column",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{counterValue}
|
||||
|
||||
@@ -19,9 +19,10 @@ 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 { niceBytes, niceBytesInt } from "../../../../common/utils";
|
||||
import { Box } from "@mui/material";
|
||||
import { CircleIcon, DrivesIcon } from "../../../../icons";
|
||||
import { Cell, Pie, PieChart } from "recharts";
|
||||
import { CircleIcon } from "../../../../icons";
|
||||
import { commonDashboardInfocard } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { STATUS_COLORS } from "./Utils";
|
||||
|
||||
@@ -46,7 +47,15 @@ const driveStatusColor = (health_status: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const DriveInfoItem = ({ classes, drive }: ICardProps) => {
|
||||
const DriveInfoItem = ({ drive }: ICardProps) => {
|
||||
const plotValues = [
|
||||
{ value: drive.totalSpace, color: "#D6D6D6", label: "Free Space" },
|
||||
{
|
||||
value: drive.usedSpace,
|
||||
color: "#073052",
|
||||
label: "Used Space",
|
||||
},
|
||||
];
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -54,21 +63,10 @@ const DriveInfoItem = ({ classes, drive }: ICardProps) => {
|
||||
flex: 1,
|
||||
alignItems: "center",
|
||||
paddingBottom: "10px",
|
||||
borderBottom: {
|
||||
xs: "1px solid #eaeaea",
|
||||
},
|
||||
padding: "20px",
|
||||
border: "1px solid #eaeaea",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
"& .min-icon": {
|
||||
fill: "#848484",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DrivesIcon />
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -97,15 +95,17 @@ const DriveInfoItem = ({ classes, drive }: ICardProps) => {
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "normal",
|
||||
wordBreak: "break-all",
|
||||
marginRight: "8px",
|
||||
fontWeight: 600,
|
||||
fontSize: {
|
||||
md: "14px",
|
||||
md: "16px",
|
||||
xs: "10px",
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
{drive.state && <CircleIcon />}
|
||||
<div className="drive-endpoint">{drive.endpoint || ""}</div>
|
||||
{drive.state && <CircleIcon />}
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
@@ -113,7 +113,6 @@ const DriveInfoItem = ({ classes, drive }: ICardProps) => {
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
paddingLeft: "20px",
|
||||
marginTop: "10px",
|
||||
flexFlow: {
|
||||
@@ -121,50 +120,105 @@ const DriveInfoItem = ({ classes, drive }: ICardProps) => {
|
||||
xs: "column",
|
||||
},
|
||||
"& .info-label": {
|
||||
color: "#8399AB",
|
||||
color: "#5E5E5E",
|
||||
fontSize: "12px",
|
||||
textAlign: "center",
|
||||
},
|
||||
"& .info-value": {
|
||||
color: "#073052",
|
||||
fontSize: "14px",
|
||||
fontSize: "18px",
|
||||
color: "#07193E",
|
||||
display: "flex",
|
||||
fontWeight: 500,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
}}
|
||||
>
|
||||
<label className="info-label">Capacity:</label>
|
||||
<div className="info-value">
|
||||
{niceBytes(drive.totalSpace ? drive.totalSpace.toString() : "0")}
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<div style={{ position: "relative", width: 110, height: 110 }}>
|
||||
<span
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
fontWeight: "bold",
|
||||
color: "#000",
|
||||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
{niceBytesInt(drive.usedSpace)}
|
||||
</span>
|
||||
<div>
|
||||
<PieChart width={110} height={110}>
|
||||
<Pie
|
||||
data={plotValues}
|
||||
cx={"50%"}
|
||||
cy={"50%"}
|
||||
dataKey="value"
|
||||
outerRadius={50}
|
||||
innerRadius={40}
|
||||
startAngle={-70}
|
||||
endAngle={360}
|
||||
animationDuration={1}
|
||||
>
|
||||
{plotValues.map((entry, index) => (
|
||||
<Cell key={`cellCapacity-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</div>
|
||||
</div>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
gap: "5%",
|
||||
alignItems: "center",
|
||||
flex: 2,
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<label className="info-label">Used:</label>
|
||||
<div className="info-value">
|
||||
{niceBytes(drive.usedSpace ? drive.usedSpace.toString() : "0")}
|
||||
</div>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
}}
|
||||
>
|
||||
<label className="info-label">Available:</label>
|
||||
<div className="info-value">
|
||||
{niceBytes(
|
||||
drive.availableSpace ? drive.availableSpace.toString() : "0"
|
||||
)}
|
||||
</div>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
}}
|
||||
>
|
||||
<div className="info-value">
|
||||
{niceBytes(
|
||||
drive.totalSpace ? drive.totalSpace.toString() : "0"
|
||||
)}
|
||||
</div>
|
||||
<label className="info-label">Capacity</label>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
}}
|
||||
>
|
||||
<div className="info-value">
|
||||
{niceBytes(drive.usedSpace ? drive.usedSpace.toString() : "0")}
|
||||
</div>
|
||||
<label className="info-label">Used</label>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
}}
|
||||
>
|
||||
<div className="info-value">
|
||||
{niceBytes(
|
||||
drive.availableSpace ? drive.availableSpace.toString() : "0"
|
||||
)}
|
||||
</div>
|
||||
<label className="info-label">Available</label>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -20,13 +20,7 @@ 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 { CircleIcon } from "../../../../icons";
|
||||
import get from "lodash/get";
|
||||
import { commonDashboardInfocard } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
@@ -51,77 +45,82 @@ const ServerStatItem = ({
|
||||
value = "",
|
||||
statusColor = "",
|
||||
hasStatus = false,
|
||||
icon = null,
|
||||
}: {
|
||||
label?: string;
|
||||
value?: any;
|
||||
hasStatus?: boolean;
|
||||
statusColor: string | undefined;
|
||||
icon?: any;
|
||||
}) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
alignItems: "center",
|
||||
alignItems: "baseline",
|
||||
padding: "5px",
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
gap: "5px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
flexFlow: "column",
|
||||
maxWidth: "40px",
|
||||
"&:first-of-type(svg)": {
|
||||
fill: "#848484",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
{hasStatus ? (
|
||||
<Box
|
||||
sx={{
|
||||
marginRight: "0px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
textAlign: "center",
|
||||
"& svg.min-icon": {
|
||||
fill: statusColor,
|
||||
width: "10px",
|
||||
height: "10px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CircleIcon />
|
||||
</Box>
|
||||
) : (
|
||||
<Box sx={{ width: "12px", height: "12px" }} />
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "flex-start",
|
||||
flexFlow: "column",
|
||||
"& .stat-text": { color: "#5E5E5E", fontSize: "14px" },
|
||||
"& .stat-text": { color: "#5E5E5E", fontSize: "12px" },
|
||||
"& .stat-value": {
|
||||
fontSize: "18px",
|
||||
color: "#07193E",
|
||||
display: "flex",
|
||||
fontWeight: 500,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div className="stat-value">
|
||||
{value}{" "}
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
flexFlow: "column",
|
||||
marginLeft: "5px",
|
||||
maxWidth: "40px",
|
||||
"&:first-of-type(svg)": {
|
||||
fill: "#848484",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{hasStatus ? (
|
||||
<Box
|
||||
sx={{
|
||||
marginRight: "0px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
textAlign: "center",
|
||||
"& svg.min-icon": {
|
||||
fill: statusColor,
|
||||
width: "10px",
|
||||
height: "10px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CircleIcon />
|
||||
</Box>
|
||||
) : (
|
||||
<Box sx={{ width: "12px", height: "12px" }} />
|
||||
)}
|
||||
</Box>
|
||||
</div>
|
||||
<div className="stat-text">{label}</div>
|
||||
<div className="stat-value">{value}</div>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const ServerInfoItem = ({ classes = {}, server, index }: ICardProps) => {
|
||||
const ServerInfoItem = ({ server }: ICardProps) => {
|
||||
const networkKeys = Object.keys(get(server, "network", {}));
|
||||
const networkTotal = networkKeys.length;
|
||||
const totalDrives = server.drives ? server.drives.length : 0;
|
||||
@@ -144,36 +143,6 @@ const ServerInfoItem = ({ classes = {}, server, index }: ICardProps) => {
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginBottom: "15px",
|
||||
}}
|
||||
>
|
||||
{server?.state && (
|
||||
<Box
|
||||
sx={{
|
||||
marginRight: "8px",
|
||||
"& .min-icon": {
|
||||
fill: serverStatusColor(server.state),
|
||||
height: "14px",
|
||||
width: "14px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CircleIcon />
|
||||
</Box>
|
||||
)}
|
||||
<Box
|
||||
sx={{
|
||||
fontWeight: 600,
|
||||
textTransform: "none",
|
||||
}}
|
||||
>
|
||||
{server.endpoint || ""}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -190,32 +159,70 @@ const ServerInfoItem = ({ classes = {}, server, index }: ICardProps) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ServerStatItem
|
||||
statusColor={getDriveStatusColor(activeDisks, totalDrives)}
|
||||
label={"Drives"}
|
||||
icon={<DrivesIcon />}
|
||||
hasStatus={true}
|
||||
value={`${activeDisks}/${totalDrives}`}
|
||||
/>
|
||||
<ServerStatItem
|
||||
statusColor={getNetworkStatusColor(activeNetwork, networkTotal)}
|
||||
label={"Network"}
|
||||
icon={<WarpIcon />}
|
||||
hasStatus={true}
|
||||
value={`${activeNetwork}/${networkTotal}`}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
fontWeight: 600,
|
||||
textTransform: "none",
|
||||
}}
|
||||
>
|
||||
{server.endpoint || ""}
|
||||
</Box>
|
||||
{server?.state && (
|
||||
<Box
|
||||
sx={{
|
||||
marginLeft: "8px",
|
||||
"& .min-icon": {
|
||||
fill: serverStatusColor(server.state),
|
||||
height: "14px",
|
||||
width: "14px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CircleIcon />
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
flex: "1.5",
|
||||
gap: {
|
||||
md: "5%",
|
||||
xs: "5%",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ServerStatItem
|
||||
statusColor={getDriveStatusColor(activeDisks, totalDrives)}
|
||||
label={"Drives"}
|
||||
hasStatus={true}
|
||||
value={`${activeDisks}/${totalDrives}`}
|
||||
/>
|
||||
<ServerStatItem
|
||||
statusColor={getNetworkStatusColor(activeNetwork, networkTotal)}
|
||||
label={"Network"}
|
||||
hasStatus={true}
|
||||
value={`${activeNetwork}/${networkTotal}`}
|
||||
/>
|
||||
|
||||
<ServerStatItem
|
||||
statusColor={"green"}
|
||||
label={"Up time"}
|
||||
value={server?.uptime ? niceDays(server.uptime) : "N/A"}
|
||||
/>
|
||||
</Box>
|
||||
<ServerStatItem
|
||||
statusColor={"green"}
|
||||
label={"Up time"}
|
||||
icon={<UptimeIcon />}
|
||||
value={server?.uptime ? niceDays(server.uptime) : "N/A"}
|
||||
/>
|
||||
|
||||
<ServerStatItem
|
||||
statusColor={"green"}
|
||||
label={"Version"}
|
||||
icon={<VersionIcon />}
|
||||
label={""}
|
||||
value={
|
||||
<Box
|
||||
sx={{
|
||||
@@ -223,11 +230,17 @@ const ServerInfoItem = ({ classes = {}, server, index }: ICardProps) => {
|
||||
color: "#000000",
|
||||
paddingLeft: "10px",
|
||||
paddingRight: "10px",
|
||||
borderRadius: "16px",
|
||||
borderRadius: "2px",
|
||||
fontSize: "12px",
|
||||
marginTop: "5px",
|
||||
|
||||
"& .label": {
|
||||
fontWeight: 600,
|
||||
marginRight: "3px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<span className="label">Version:</span>
|
||||
{server.version ? server.version : "N/A"}
|
||||
</Box>
|
||||
}
|
||||
|
||||
@@ -19,12 +19,14 @@ 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";
|
||||
import {
|
||||
MenuCollapsedIcon,
|
||||
MenuExpandedIcon,
|
||||
} from "../../../../icons/SidebarMenus";
|
||||
|
||||
const ServersList = ({ data }: { data: ServerInfo[] }) => {
|
||||
const [expanded, setExpanded] = React.useState<string>(
|
||||
@@ -36,112 +38,129 @@ const ServersList = ({ data }: { data: ServerInfo[] }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<List
|
||||
sx={{ width: "100%", flex: 1 }}
|
||||
component="nav"
|
||||
aria-labelledby="nested-list-subheader"
|
||||
subheader={
|
||||
<ListSubheader
|
||||
component="div"
|
||||
sx={{
|
||||
borderBottom: "1px solid #F8F8F8",
|
||||
}}
|
||||
>
|
||||
Servers ({data.length})
|
||||
</ListSubheader>
|
||||
}
|
||||
>
|
||||
{data.map((serverInfo, index) => {
|
||||
const key = `${serverInfo.endpoint}-${index}`;
|
||||
const isExpanded = expanded === key;
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
<ListItemButton
|
||||
disableRipple
|
||||
onClick={() => {
|
||||
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",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ServerInfoItem server={serverInfo} index={index} />
|
||||
<Box
|
||||
<Box>
|
||||
<Box
|
||||
sx={{
|
||||
marginBottom: "10px",
|
||||
}}
|
||||
>
|
||||
Servers ({data.length})
|
||||
</Box>
|
||||
<List
|
||||
sx={{ width: "100%", flex: 1, padding: "0" }}
|
||||
component="nav"
|
||||
aria-labelledby="nested-list-subheader"
|
||||
>
|
||||
{data.map((serverInfo, index) => {
|
||||
const key = `${serverInfo.endpoint}-${index}`;
|
||||
const isExpanded = expanded === key;
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
<ListItemButton
|
||||
disableRipple
|
||||
onClick={() => {
|
||||
if (!isExpanded) {
|
||||
handleClick(key);
|
||||
} else {
|
||||
handleClick("");
|
||||
}
|
||||
}}
|
||||
className={isExpanded ? "expanded" : ""}
|
||||
sx={{
|
||||
height: "25px",
|
||||
width: "25px",
|
||||
marginLeft: "25px",
|
||||
background: "#FBFAFA",
|
||||
borderRadius: "2px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
border: "1px solid #f1f1f1",
|
||||
padding: "3px 10px 3px 10px",
|
||||
|
||||
"&:hover": {
|
||||
background: "#fafafa",
|
||||
},
|
||||
display: {
|
||||
md: "block",
|
||||
xs: "none",
|
||||
background: "#bebbbb0d",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{isExpanded ? <ExpandLess /> : <ExpandMore />}
|
||||
</Box>
|
||||
</ListItemButton>
|
||||
{isExpanded ? (
|
||||
<React.Fragment key={`${serverInfo.endpoint}-${index}`}>
|
||||
<ListSubheader
|
||||
key={`${index}-drive-details`}
|
||||
component="div"
|
||||
<ServerInfoItem server={serverInfo} index={index} />
|
||||
<Box
|
||||
sx={{
|
||||
borderBottom: "1px solid #F8F8F8",
|
||||
}}
|
||||
>
|
||||
Drives ({serverInfo.drives.length})
|
||||
</ListSubheader>
|
||||
|
||||
<Collapse
|
||||
in={isExpanded}
|
||||
timeout="auto"
|
||||
unmountOnExit
|
||||
sx={{
|
||||
width: "100%",
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
padding: { md: "20px 50px", xs: "15px 15px" },
|
||||
"& .MuiCollapse-wrapperInner": {
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
gap: "15px",
|
||||
height: "25px",
|
||||
width: "25px",
|
||||
background: "#FBFAFA",
|
||||
borderRadius: "2px",
|
||||
"&:hover": {
|
||||
background: "#fafafa",
|
||||
},
|
||||
display: {
|
||||
md: "block",
|
||||
xs: "none",
|
||||
},
|
||||
"& .collapse-icon": {
|
||||
fill: "#494949",
|
||||
"& g rect": {
|
||||
fill: "#ffffff",
|
||||
},
|
||||
},
|
||||
"& .expand-icon": {
|
||||
fill: "#494949",
|
||||
"& rect": {
|
||||
fill: "#ffffff",
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
{serverInfo.drives.map((driveInfo, index) => {
|
||||
return (
|
||||
<DriveInfoItem
|
||||
drive={driveInfo}
|
||||
key={`${driveInfo.endpoint}-${index}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
) : null}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
{isExpanded ? (
|
||||
<MenuCollapsedIcon className="collapse-icon" />
|
||||
) : (
|
||||
<MenuExpandedIcon className="expand-icon" />
|
||||
)}
|
||||
</Box>
|
||||
</ListItemButton>
|
||||
{isExpanded ? (
|
||||
<Box
|
||||
key={`${serverInfo.endpoint}-${index}`}
|
||||
sx={{
|
||||
border: "1px solid #f1f1f1",
|
||||
borderTop: "0",
|
||||
}}
|
||||
>
|
||||
<ListSubheader
|
||||
key={`${index}-drive-details`}
|
||||
component="div"
|
||||
sx={{ paddingLeft: "30px" }}
|
||||
>
|
||||
Drives ({serverInfo.drives.length})
|
||||
</ListSubheader>
|
||||
|
||||
<Collapse
|
||||
in={isExpanded}
|
||||
timeout="auto"
|
||||
unmountOnExit
|
||||
sx={{
|
||||
width: "100%",
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
padding: { md: "15px 30px", xs: "10px 10px" },
|
||||
"& .MuiCollapse-wrapperInner": {
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
gap: "15px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{serverInfo.drives.map((driveInfo, index) => {
|
||||
return (
|
||||
<DriveInfoItem
|
||||
drive={driveInfo}
|
||||
key={`${driveInfo.endpoint}-${index}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Collapse>
|
||||
</Box>
|
||||
) : null}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ export const StatusCountCard = ({
|
||||
sx={{
|
||||
fontFamily: "Lato,sans-serif",
|
||||
color: "#07193E",
|
||||
maxWidth: "300px",
|
||||
minHeight: "200px",
|
||||
maxWidth: "260px",
|
||||
minHeight: "143px",
|
||||
display: "flex",
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
@@ -45,7 +45,6 @@ export const StatusCountCard = ({
|
||||
<Box
|
||||
sx={{
|
||||
flex: 1,
|
||||
height: "200px",
|
||||
display: "flex",
|
||||
padding: {
|
||||
sm: "0 8px 0 8px",
|
||||
@@ -58,14 +57,13 @@ export const StatusCountCard = ({
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
flexFlow: "column",
|
||||
marginTop: "32px",
|
||||
marginTop: "22px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 600,
|
||||
marginBottom: "24px",
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
@@ -76,25 +74,38 @@ export const StatusCountCard = ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
paddingBottom: {
|
||||
md: "0px",
|
||||
xs: "10px",
|
||||
},
|
||||
fontSize: {
|
||||
xl: "55px",
|
||||
lg: "50px",
|
||||
md: "45px",
|
||||
xs: "35px",
|
||||
},
|
||||
flexFlow: "row",
|
||||
fontWeight: 600,
|
||||
|
||||
"& .stat-text": { color: "#696969", fontSize: "12px" },
|
||||
"& .stat-text": {
|
||||
color: "#696969",
|
||||
fontSize: "12px",
|
||||
marginTop: "25px",
|
||||
},
|
||||
"& .stat-value": {
|
||||
textAlign: "center",
|
||||
height: "50px",
|
||||
},
|
||||
"& .min-icon": {
|
||||
marginRight: "8px",
|
||||
marginTop: "25px",
|
||||
height: "10px",
|
||||
width: "10px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
<Box className="stat-value">{onlineCount}</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -106,10 +117,10 @@ export const StatusCountCard = ({
|
||||
>
|
||||
<CircleIcon /> <div className="stat-text">Online</div>
|
||||
</Box>
|
||||
<Box className="stat-value">{onlineCount}</Box>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Box className="stat-value">{offlineCount}</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -121,7 +132,6 @@ export const StatusCountCard = ({
|
||||
>
|
||||
<CircleIcon /> <div className="stat-text">Offline</div>
|
||||
</Box>
|
||||
<Box className="stat-value">{offlineCount}</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user