github.com/minio/console@v1.4.1/web-app/src/screens/Console/Dashboard/BasicDashboard/ServerInfoItem.tsx (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2022 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  import React from "react";
    17  import styled from "styled-components";
    18  import get from "lodash/get";
    19  import { Box, breakPoints, CircleIcon } from "mds";
    20  import { niceDays } from "../../../../common/utils";
    21  import {
    22    getDriveStatusColor,
    23    getNetworkStatusColor,
    24    serverStatusColor,
    25  } from "./Utils";
    26  import { ServerProperties } from "api/consoleApi";
    27  
    28  interface ICardProps {
    29    server: ServerProperties;
    30    index: number;
    31  }
    32  
    33  const ServerStatItemMain = styled.div(({ theme }) => ({
    34    alignItems: "baseline",
    35    padding: "5px",
    36    display: "flex",
    37    gap: "5px",
    38    "& .StatBox": {
    39      display: "flex",
    40      alignItems: "center",
    41      justifyContent: "center",
    42      flexFlow: "column",
    43      "& .stat-text": {
    44        color: get(theme, "mutedText", "#87888d"),
    45        fontSize: "12px",
    46      },
    47      "& .stat-value": {
    48        fontSize: "18px",
    49        color: get(theme, "signalColors.main", "#07193E"),
    50        display: "flex",
    51        fontWeight: 500,
    52        overflow: "hidden",
    53        textOverflow: "ellipsis",
    54        whiteSpace: "nowrap",
    55        "& .stat-container": {
    56          display: "flex",
    57          alignItems: "center",
    58          justifyContent: "center",
    59          flexFlow: "column",
    60          marginLeft: "5px",
    61          maxWidth: "40px",
    62          "&:first-of-type(svg)": {
    63            fill: get(theme, "mutedText", "#87888d"),
    64          },
    65          "& .stat-indicator": {
    66            marginRight: "0px",
    67            justifyContent: "center",
    68            alignItems: "center",
    69            textAlign: "center",
    70            "& svg.min-icon": {
    71              width: "10px",
    72              height: "10px",
    73            },
    74            "&.good": {
    75              "& svg.min-icon": {
    76                fill: get(theme, "signalColors.good", "#4CCB92"),
    77              },
    78            },
    79            "&.warn": {
    80              "& svg.min-icon": {
    81                fill: get(theme, "signalColors.warning", "#FFBD62"),
    82              },
    83            },
    84            "&.bad": {
    85              "& svg.min-icon": {
    86                fill: get(theme, "signalColors.danger", "#C51B3F"),
    87              },
    88            },
    89          },
    90        },
    91      },
    92    },
    93  }));
    94  
    95  const ServerInfoItemMain = styled.div(({ theme }) => ({
    96    display: "flex",
    97    alignItems: "flex-start",
    98    flexFlow: "column",
    99    flex: 1,
   100    "& .server-state": {
   101      marginLeft: "8px",
   102      "& .min-icon": {
   103        height: "14px",
   104        width: "14px",
   105      },
   106      "&.good": {
   107        "& svg.min-icon": {
   108          fill: get(theme, "signalColors.good", "#4CCB92"),
   109        },
   110      },
   111      "&.warn": {
   112        "& svg.min-icon": {
   113          fill: get(theme, "signalColors.warning", "#FFBD62"),
   114        },
   115      },
   116      "&.bad": {
   117        "& svg.min-icon": {
   118          fill: get(theme, "signalColors.danger", "#C51B3F"),
   119        },
   120      },
   121    },
   122  }));
   123  
   124  const ServerStatItem = ({
   125    label = "",
   126    value = "",
   127    statusColor = "warn",
   128    hasStatus = false,
   129  }: {
   130    label?: string;
   131    value?: any;
   132    hasStatus?: boolean;
   133    statusColor?: "good" | "warn" | "bad";
   134  }) => {
   135    return (
   136      <ServerStatItemMain>
   137        <Box className={"StatBox"}>
   138          <div className="stat-value">
   139            {value}{" "}
   140            <Box className={"stat-container"}>
   141              {hasStatus ? (
   142                <Box className={`stat-indicator ${statusColor}`}>
   143                  <CircleIcon />
   144                </Box>
   145              ) : (
   146                <Box sx={{ width: "12px", height: "12px" }} />
   147              )}
   148            </Box>
   149          </div>
   150          <div className="stat-text">{label}</div>
   151        </Box>
   152      </ServerStatItemMain>
   153    );
   154  };
   155  
   156  const ServerInfoItem = ({ server }: ICardProps) => {
   157    const networkKeys = Object.keys(get(server, "network", {}));
   158    const networkTotal = networkKeys.length;
   159    const totalDrives = server.drives ? server.drives.length : 0;
   160    const activeNetwork = networkKeys.reduce((acc: number, currValue: string) => {
   161      const item = server.network ? server.network[currValue] : "";
   162      if (item === "online") {
   163        return acc + 1;
   164      }
   165      return acc;
   166    }, 0);
   167    const activeDisks = server.drives
   168      ? server.drives.filter((element) => element.state === "ok").length
   169      : 0;
   170    return (
   171      <ServerInfoItemMain>
   172        <Box
   173          sx={{
   174            display: "flex",
   175            alignItems: "center",
   176            padding: "3px",
   177            gap: "15px",
   178            justifyContent: "space-between",
   179            width: "100%",
   180            paddingLeft: "20px",
   181            flexFlow: "row",
   182            [`@media (max-width: ${breakPoints.md}px)`]: {
   183              flexFlow: "column",
   184            },
   185          }}
   186        >
   187          <Box
   188            sx={{
   189              display: "flex",
   190              alignItems: "center",
   191            }}
   192          >
   193            <Box
   194              sx={{
   195                fontWeight: 600,
   196                textTransform: "none",
   197              }}
   198            >
   199              {server.endpoint || ""}
   200            </Box>
   201            {server?.state && (
   202              <Box className={`server-state ${serverStatusColor(server.state)}`}>
   203                <CircleIcon />
   204              </Box>
   205            )}
   206          </Box>
   207  
   208          <Box
   209            sx={{
   210              display: "flex",
   211              alignItems: "center",
   212              justifyContent: "center",
   213              flex: "1.5",
   214              gap: "5%",
   215            }}
   216          >
   217            <ServerStatItem
   218              statusColor={getDriveStatusColor(activeDisks, totalDrives)}
   219              label={"Drives"}
   220              hasStatus={true}
   221              value={`${activeDisks}/${totalDrives}`}
   222            />
   223            <ServerStatItem
   224              statusColor={getNetworkStatusColor(activeNetwork, networkTotal)}
   225              label={"Network"}
   226              hasStatus={true}
   227              value={`${activeNetwork}/${networkTotal}`}
   228            />
   229            <ServerStatItem
   230              statusColor={"good"}
   231              label={"Up time"}
   232              value={server?.uptime ? niceDays(`${server.uptime}`) : "N/A"}
   233            />
   234          </Box>
   235          <ServerStatItem
   236            statusColor={"good"}
   237            label={""}
   238            value={
   239              <Box
   240                sx={{
   241                  background: "rgb(235, 236, 237)",
   242                  color: "#000000",
   243                  paddingLeft: "10px",
   244                  paddingRight: "10px",
   245                  borderRadius: "2px",
   246                  fontSize: "12px",
   247                  marginTop: "5px",
   248  
   249                  "& .label": {
   250                    fontWeight: 600,
   251                    marginRight: "3px",
   252                  },
   253                }}
   254              >
   255                <span className="label">Version:</span>
   256                {server.version ? server.version : "N/A"}
   257              </Box>
   258            }
   259          />
   260        </Box>
   261      </ServerInfoItemMain>
   262    );
   263  };
   264  export default ServerInfoItem;