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

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 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  
    17  import React, { Fragment, useEffect, useState } from "react";
    18  import { useSelector } from "react-redux";
    19  import { Box, Loader } from "mds";
    20  import styled from "styled-components";
    21  import get from "lodash/get";
    22  import { widgetCommon } from "../../../Common/FormComponents/common/styleLibrary";
    23  import { splitSizeMetric, widgetDetailsToPanel } from "../utils";
    24  import { IDashboardPanel } from "../types";
    25  import { ErrorResponseHandler } from "../../../../../common/types";
    26  import { setErrorSnackMessage } from "../../../../../systemSlice";
    27  import { AppState, useAppDispatch } from "../../../../../store";
    28  import api from "../../../../../common/api";
    29  
    30  interface ISingleValueWidget {
    31    title: string;
    32    panelItem: IDashboardPanel;
    33    timeStart: any;
    34    timeEnd: any;
    35    apiPrefix: string;
    36    renderFn?: (arg: Record<string, any>) => any;
    37  }
    38  
    39  const SingleValueWidgetMain = styled.div(({ theme }) => ({
    40    display: "flex",
    41    height: 140,
    42    flexDirection: "column",
    43    justifyContent: "center",
    44    "& .unitText": {
    45      color: get(theme, "mutedText", "#87888d"),
    46      fontSize: 12,
    47    },
    48    "& .loadingAlign": {
    49      width: "100%",
    50      textAlign: "center",
    51      margin: "auto",
    52    },
    53    "& .metric": {
    54      fontSize: 60,
    55      lineHeight: 1,
    56      color: get(theme, "signalColors.main", "#07193E"),
    57      fontWeight: 700,
    58    },
    59    "& .titleElement": {
    60      fontSize: 10,
    61      color: get(theme, "mutedText", "#87888d"),
    62      fontWeight: 700,
    63    },
    64    ...widgetCommon(theme),
    65  }));
    66  
    67  const SingleValueWidget = ({
    68    title,
    69    panelItem,
    70    timeStart,
    71    timeEnd,
    72    apiPrefix,
    73    renderFn,
    74  }: ISingleValueWidget) => {
    75    const dispatch = useAppDispatch();
    76  
    77    const [loading, setLoading] = useState<boolean>(false);
    78    const [data, setData] = useState<string>("");
    79    const widgetVersion = useSelector(
    80      (state: AppState) => state.dashboard.widgetLoadVersion,
    81    );
    82  
    83    useEffect(() => {
    84      setLoading(true);
    85    }, [widgetVersion]);
    86  
    87    useEffect(() => {
    88      if (loading) {
    89        let stepCalc = 0;
    90        if (timeStart !== null && timeEnd !== null) {
    91          const secondsInPeriod =
    92            timeEnd.toUnixInteger() - timeStart.toUnixInteger();
    93          const periods = Math.floor(secondsInPeriod / 60);
    94  
    95          stepCalc = periods < 1 ? 15 : periods;
    96        }
    97  
    98        api
    99          .invoke(
   100            "GET",
   101            `/api/v1/${apiPrefix}/info/widgets/${
   102              panelItem.id
   103            }/?step=${stepCalc}&${
   104              timeStart !== null ? `&start=${timeStart.toUnixInteger()}` : ""
   105            }${timeStart !== null && timeEnd !== null ? "&" : ""}${
   106              timeEnd !== null ? `end=${timeEnd.toUnixInteger()}` : ""
   107            }`,
   108          )
   109          .then((res: any) => {
   110            const widgetsWithValue = widgetDetailsToPanel(res, panelItem);
   111            setData(widgetsWithValue.data);
   112            setLoading(false);
   113          })
   114          .catch((err: ErrorResponseHandler) => {
   115            dispatch(setErrorSnackMessage(err));
   116            setLoading(false);
   117          });
   118      }
   119    }, [loading, panelItem, timeEnd, timeStart, dispatch, apiPrefix]);
   120  
   121    const valueToRender = splitSizeMetric(data);
   122  
   123    if (renderFn) {
   124      return renderFn({ valueToRender, loading, title, id: panelItem.id });
   125    }
   126    return (
   127      <SingleValueWidgetMain>
   128        {loading && (
   129          <Box className={"loadingAlign"}>
   130            <Loader />
   131          </Box>
   132        )}
   133        {!loading && (
   134          <Fragment>
   135            <Box className={"metric"}>{splitSizeMetric(data)}</Box>
   136            <Box className={"titleElement"}>{title}</Box>
   137          </Fragment>
   138        )}
   139      </SingleValueWidgetMain>
   140    );
   141  };
   142  
   143  export default SingleValueWidget;