Added zoom option to line charts & bar charts in prometheus dashboard (#1104)
This commit is contained in:
@@ -42,7 +42,6 @@ import { setErrorSnackMessage } from "../../../../../actions";
|
||||
import { snackBarMessage } from "../../../../../types";
|
||||
import {
|
||||
setModalErrorSnackMessage,
|
||||
setModalSnackMessage,
|
||||
} from "../../../../../actions";
|
||||
|
||||
interface ImodalErrorProps {
|
||||
|
||||
@@ -431,6 +431,8 @@ export const widgetCommon = {
|
||||
borderBottom: "#eef1f4 1px solid",
|
||||
paddingBottom: 14,
|
||||
marginBottom: 5,
|
||||
display: "flex" as const,
|
||||
justifyContent: "space-between" as const,
|
||||
},
|
||||
contentContainer: {
|
||||
justifyContent: "center" as const,
|
||||
@@ -470,6 +472,26 @@ export const widgetCommon = {
|
||||
overflow: "hidden" as const,
|
||||
textOverflow: "ellipsis" as const,
|
||||
},
|
||||
zoomChartCont: {
|
||||
position: "relative" as const,
|
||||
height: 340,
|
||||
width: "100%",
|
||||
},
|
||||
zoomChartIcon: {
|
||||
backgroundColor: "transparent",
|
||||
border: 0,
|
||||
padding: 0,
|
||||
cursor: "pointer",
|
||||
"& svg": {
|
||||
color: "#D0D0D0",
|
||||
height: 16,
|
||||
},
|
||||
"&:hover": {
|
||||
"& svg": {
|
||||
color: "#404143",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const widgetContainerCommon = {
|
||||
|
||||
@@ -25,27 +25,26 @@ import {
|
||||
actionsTray,
|
||||
widgetContainerCommon,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { IDashboardPanel, widgetType } from "./types";
|
||||
import { IDashboardPanel } from "./types";
|
||||
import { getWidgetsWithValue, panelsConfiguration } from "./utils";
|
||||
import { TabPanel } from "../../../shared/tabs";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import { setErrorSnackMessage } from "../../../../actions";
|
||||
import SingleValueWidget from "./Widgets/SingleValueWidget";
|
||||
import LinearGraphWidget from "./Widgets/LinearGraphWidget";
|
||||
import BarChartWidget from "./Widgets/BarChartWidget";
|
||||
import PieChartWidget from "./Widgets/PieChartWidget";
|
||||
import SingleRepWidget from "./Widgets/SingleRepWidget";
|
||||
import DateTimePickerWrapper from "../../Common/FormComponents/DateTimePickerWrapper/DateTimePickerWrapper";
|
||||
import api from "../../../../common/api";
|
||||
import SyncIcon from "../../../../icons/SyncIcon";
|
||||
import TabSelector from "../../Common/TabSelector/TabSelector";
|
||||
import SimpleWidget from "./Widgets/SimpleWidget";
|
||||
import MergedWidgets from "./MergedWidgets";
|
||||
import { componentToUse } from "./widgetUtils";
|
||||
import ZoomWidget from "./ZoomWidget";
|
||||
import { AppState } from "../../../../store";
|
||||
|
||||
interface IPrDashboard {
|
||||
classes: any;
|
||||
displayErrorMessage: typeof setErrorSnackMessage;
|
||||
apiPrefix?: string;
|
||||
zoomOpen: boolean;
|
||||
zoomWidget: null | IDashboardPanel;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -82,6 +81,8 @@ const PrDashboard = ({
|
||||
classes,
|
||||
displayErrorMessage,
|
||||
apiPrefix = "admin",
|
||||
zoomOpen,
|
||||
zoomWidget,
|
||||
}: IPrDashboard) => {
|
||||
const [timeStart, setTimeStart] = useState<any>(null);
|
||||
const [timeEnd, setTimeEnd] = useState<any>(null);
|
||||
@@ -92,88 +93,6 @@ const PrDashboard = ({
|
||||
|
||||
const panels = useCallback(
|
||||
(tabName: string, filterPanels?: number[][] | null) => {
|
||||
const componentToUse = (value: IDashboardPanel, index: number) => {
|
||||
switch (value.type) {
|
||||
case widgetType.singleValue:
|
||||
return (
|
||||
<SingleValueWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
);
|
||||
case widgetType.simpleWidget:
|
||||
return (
|
||||
<SimpleWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
iconWidget={value.widgetIcon}
|
||||
/>
|
||||
);
|
||||
case widgetType.pieChart:
|
||||
return (
|
||||
<PieChartWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
);
|
||||
case widgetType.linearGraph:
|
||||
case widgetType.areaGraph:
|
||||
return (
|
||||
<LinearGraphWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
hideYAxis={value.disableYAxis}
|
||||
xAxisFormatter={value.xAxisFormatter}
|
||||
yAxisFormatter={value.yAxisFormatter}
|
||||
apiPrefix={apiPrefix}
|
||||
areaWidget={value.type === widgetType.areaGraph}
|
||||
/>
|
||||
);
|
||||
case widgetType.barChart:
|
||||
return (
|
||||
<BarChartWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
);
|
||||
case widgetType.singleRep:
|
||||
const fillColor = value.fillColor ? value.fillColor : value.color;
|
||||
return (
|
||||
<SingleRepWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
color={value.color as string}
|
||||
fillColor={fillColor as string}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return filterPanels?.map((panelLine, indexLine) => {
|
||||
const totalPanelsContained = panelLine.length;
|
||||
|
||||
@@ -216,16 +135,28 @@ const PrDashboard = ({
|
||||
title={panelInfo.title}
|
||||
leftComponent={componentToUse(
|
||||
panelInfo.mergedPanels[0],
|
||||
0
|
||||
timeStart,
|
||||
timeEnd,
|
||||
loading,
|
||||
apiPrefix
|
||||
)}
|
||||
rightComponent={componentToUse(
|
||||
panelInfo.mergedPanels[1],
|
||||
1
|
||||
timeStart,
|
||||
timeEnd,
|
||||
loading,
|
||||
apiPrefix
|
||||
)}
|
||||
/>
|
||||
</Fragment>
|
||||
) : (
|
||||
componentToUse(panelInfo, indexPanel)
|
||||
componentToUse(
|
||||
panelInfo,
|
||||
timeStart,
|
||||
timeEnd,
|
||||
loading,
|
||||
apiPrefix
|
||||
)
|
||||
)}
|
||||
</Fragment>
|
||||
) : null}
|
||||
@@ -313,6 +244,16 @@ const PrDashboard = ({
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{zoomOpen && (
|
||||
<ZoomWidget
|
||||
modalOpen={zoomOpen}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
widgetRender={0}
|
||||
value={zoomWidget}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
)}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
@@ -379,11 +320,13 @@ const PrDashboard = ({
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
/*
|
||||
<
|
||||
*/
|
||||
|
||||
const connector = connect(null, {
|
||||
const mapState = (state: AppState) => ({
|
||||
zoomOpen: state.dashboard.zoom.openZoom,
|
||||
zoomWidget: state.dashboard.zoom.widgetRender,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
displayErrorMessage: setErrorSnackMessage,
|
||||
});
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import { MaterialUiPickersDate } from "@material-ui/pickers/typings/date";
|
||||
import { CircularProgress } from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import ZoomOutMapIcon from "@material-ui/icons/ZoomOutMap";
|
||||
import { IBarChartConfiguration } from "./types";
|
||||
import { widgetCommon } from "../../../Common/FormComponents/common/styleLibrary";
|
||||
import BarChartTooltip from "./tooltips/BarChartTooltip";
|
||||
@@ -36,6 +37,7 @@ import { IDashboardPanel } from "../types";
|
||||
import { widgetDetailsToPanel } from "../utils";
|
||||
import { ErrorResponseHandler } from "../../../../../common/types";
|
||||
import api from "../../../../../common/api";
|
||||
import { openZoomPage } from "../../actions";
|
||||
|
||||
interface IBarChartWidget {
|
||||
classes: any;
|
||||
@@ -46,6 +48,8 @@ interface IBarChartWidget {
|
||||
propLoading: boolean;
|
||||
displayErrorMessage: any;
|
||||
apiPrefix: string;
|
||||
zoomActivated?: boolean;
|
||||
openZoomPage: typeof openZoomPage;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -84,6 +88,8 @@ const BarChartWidget = ({
|
||||
propLoading,
|
||||
displayErrorMessage,
|
||||
apiPrefix,
|
||||
zoomActivated = false,
|
||||
openZoomPage,
|
||||
}: IBarChartWidget) => {
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [data, setData] = useState<any>([]);
|
||||
@@ -147,15 +153,31 @@ const BarChartWidget = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.singleValueContainer}>
|
||||
<div className={classes.titleContainer}>{title}</div>
|
||||
<div className={zoomActivated ? "" : classes.singleValueContainer}>
|
||||
{!zoomActivated && (
|
||||
<div className={classes.titleContainer}>
|
||||
{title}{" "}
|
||||
<button
|
||||
onClick={() => {
|
||||
openZoomPage(panelItem);
|
||||
}}
|
||||
className={classes.zoomChartIcon}
|
||||
>
|
||||
<ZoomOutMapIcon />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{loading && (
|
||||
<div className={classes.loadingAlign}>
|
||||
<CircularProgress />
|
||||
</div>
|
||||
)}
|
||||
{!loading && (
|
||||
<div className={classes.contentContainer}>
|
||||
<div
|
||||
className={
|
||||
zoomActivated ? classes.zoomChartCont : classes.contentContainer
|
||||
}
|
||||
>
|
||||
<ResponsiveContainer width="99%">
|
||||
<BarChart
|
||||
data={data as object[]}
|
||||
@@ -178,7 +200,7 @@ const BarChartWidget = ({
|
||||
dataKey={bar.dataKey}
|
||||
fill={bar.color}
|
||||
background={bar.background}
|
||||
barSize={12}
|
||||
barSize={zoomActivated ? 25 : 12}
|
||||
>
|
||||
{barChartConfiguration.length === 1 ? (
|
||||
<Fragment>
|
||||
@@ -214,6 +236,7 @@ const BarChartWidget = ({
|
||||
|
||||
const connector = connect(null, {
|
||||
displayErrorMessage: setErrorSnackMessage,
|
||||
openZoomPage: openZoomPage,
|
||||
});
|
||||
|
||||
export default withStyles(styles)(connector(BarChartWidget));
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import {
|
||||
Area,
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import { CircularProgress } from "@material-ui/core";
|
||||
import { MaterialUiPickersDate } from "@material-ui/pickers/typings/date";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import ZoomOutMapIcon from "@material-ui/icons/ZoomOutMap";
|
||||
import { ILinearGraphConfiguration } from "./types";
|
||||
import { widgetCommon } from "../../../Common/FormComponents/common/styleLibrary";
|
||||
import { IDashboardPanel } from "../types";
|
||||
@@ -36,6 +37,7 @@ import { widgetDetailsToPanel } from "../utils";
|
||||
import { ErrorResponseHandler } from "../../../../../common/types";
|
||||
import api from "../../../../../common/api";
|
||||
import LineChartTooltip from "./tooltips/LineChartTooltip";
|
||||
import { openZoomPage } from "../../actions";
|
||||
|
||||
interface ILinearGraphWidget {
|
||||
classes: any;
|
||||
@@ -50,6 +52,8 @@ interface ILinearGraphWidget {
|
||||
yAxisFormatter?: (item: string) => string;
|
||||
xAxisFormatter?: (item: string) => string;
|
||||
areaWidget?: boolean;
|
||||
zoomActivated?: boolean;
|
||||
openZoomPage: typeof openZoomPage;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -61,6 +65,9 @@ const styles = (theme: Theme) =>
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
},
|
||||
verticalAlignment: {
|
||||
flexDirection: "column",
|
||||
},
|
||||
chartCont: {
|
||||
position: "relative",
|
||||
height: 140,
|
||||
@@ -70,7 +77,7 @@ const styles = (theme: Theme) =>
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flex: "0 1 auto",
|
||||
height: 130,
|
||||
maxHeight: 130,
|
||||
margin: 0,
|
||||
overflowY: "auto",
|
||||
position: "relative",
|
||||
@@ -99,6 +106,8 @@ const LinearGraphWidget = ({
|
||||
areaWidget = false,
|
||||
yAxisFormatter = (item: string) => item,
|
||||
xAxisFormatter = (item: string) => item,
|
||||
zoomActivated = false,
|
||||
openZoomPage,
|
||||
}: ILinearGraphWidget) => {
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [data, setData] = useState<object[]>([]);
|
||||
@@ -174,13 +183,33 @@ const LinearGraphWidget = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classes.singleValueContainer}>
|
||||
<div className={classes.titleContainer}>{title}</div>
|
||||
<div className={classes.containerElements}>
|
||||
<div className={zoomActivated ? "" : classes.singleValueContainer}>
|
||||
{!zoomActivated && (
|
||||
<div className={classes.titleContainer}>
|
||||
{title}{" "}
|
||||
<button
|
||||
onClick={() => {
|
||||
openZoomPage(panelItem);
|
||||
}}
|
||||
className={classes.zoomChartIcon}
|
||||
>
|
||||
<ZoomOutMapIcon />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={
|
||||
zoomActivated ? classes.verticalAlignment : classes.containerElements
|
||||
}
|
||||
>
|
||||
{loading && <CircularProgress className={classes.loadingAlign} />}
|
||||
{!loading && (
|
||||
<React.Fragment>
|
||||
<div className={classes.chartCont}>
|
||||
<div
|
||||
className={
|
||||
zoomActivated ? classes.zoomChartCont : classes.chartCont
|
||||
}
|
||||
>
|
||||
<ResponsiveContainer width="99%">
|
||||
<AreaChart
|
||||
data={data}
|
||||
@@ -267,24 +296,33 @@ const LinearGraphWidget = ({
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
{!areaWidget && (
|
||||
<div className={classes.legendChart}>
|
||||
{linearConfiguration.map((section, index) => {
|
||||
return (
|
||||
<div
|
||||
className={classes.singleLegendContainer}
|
||||
key={`legend-${section.keyLabel}-${index.toString()}`}
|
||||
>
|
||||
<Fragment>
|
||||
{zoomActivated && (
|
||||
<Fragment>
|
||||
<strong>Series</strong>
|
||||
<br />
|
||||
<br />
|
||||
</Fragment>
|
||||
)}
|
||||
<div className={classes.legendChart}>
|
||||
{linearConfiguration.map((section, index) => {
|
||||
return (
|
||||
<div
|
||||
className={classes.colorContainer}
|
||||
style={{ backgroundColor: section.lineColor }}
|
||||
/>
|
||||
<div className={classes.legendLabel}>
|
||||
{section.keyLabel}
|
||||
className={classes.singleLegendContainer}
|
||||
key={`legend-${section.keyLabel}-${index.toString()}`}
|
||||
>
|
||||
<div
|
||||
className={classes.colorContainer}
|
||||
style={{ backgroundColor: section.lineColor }}
|
||||
/>
|
||||
<div className={classes.legendLabel}>
|
||||
{section.keyLabel}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Fragment>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
@@ -295,6 +333,7 @@ const LinearGraphWidget = ({
|
||||
|
||||
const connector = connect(null, {
|
||||
displayErrorMessage: setErrorSnackMessage,
|
||||
openZoomPage: openZoomPage,
|
||||
});
|
||||
|
||||
export default withStyles(styles)(connector(LinearGraphWidget));
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import { IDashboardPanel } from "./types";
|
||||
import { componentToUse } from "./widgetUtils";
|
||||
import { closeZoomPage } from "../actions";
|
||||
|
||||
interface IZoomWidget {
|
||||
widgetRender: number;
|
||||
value: IDashboardPanel | null;
|
||||
modalOpen: boolean;
|
||||
timeStart: any;
|
||||
timeEnd: any;
|
||||
apiPrefix: string;
|
||||
onCloseAction: typeof closeZoomPage;
|
||||
}
|
||||
const ZoomWidget = ({
|
||||
value,
|
||||
modalOpen,
|
||||
timeStart,
|
||||
timeEnd,
|
||||
apiPrefix,
|
||||
onCloseAction,
|
||||
}: IZoomWidget) => {
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
title={value.title}
|
||||
onClose={() => {
|
||||
onCloseAction();
|
||||
}}
|
||||
modalOpen={modalOpen}
|
||||
wideLimit={false}
|
||||
noContentPadding
|
||||
>
|
||||
<Fragment>
|
||||
{componentToUse(value, timeStart, timeEnd, true, apiPrefix, true)}
|
||||
</Fragment>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const connector = connect(null, {
|
||||
onCloseAction: closeZoomPage,
|
||||
});
|
||||
|
||||
export default connector(ZoomWidget);
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
} from "../../../../common/utils";
|
||||
import HealIcon from "../../../../icons/HealIcon";
|
||||
import DiagnosticsIcon from "../../../../icons/DiagnosticsIcon";
|
||||
import HistoryIcon from "../../../../icons/HistoryIcon";
|
||||
import { UptimeIcon } from "../../../../icons";
|
||||
|
||||
const colorsMain = [
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import { IDashboardPanel, widgetType } from "./types";
|
||||
import BarChartWidget from "./Widgets/BarChartWidget";
|
||||
import LinearGraphWidget from "./Widgets/LinearGraphWidget";
|
||||
import PieChartWidget from "./Widgets/PieChartWidget";
|
||||
import SimpleWidget from "./Widgets/SimpleWidget";
|
||||
import SingleRepWidget from "./Widgets/SingleRepWidget";
|
||||
import SingleValueWidget from "./Widgets/SingleValueWidget";
|
||||
|
||||
export const componentToUse = (
|
||||
value: IDashboardPanel,
|
||||
timeStart: any,
|
||||
timeEnd: any,
|
||||
loading: boolean,
|
||||
apiPrefix: string,
|
||||
zoomActivated: boolean = false
|
||||
) => {
|
||||
switch (value.type) {
|
||||
case widgetType.singleValue:
|
||||
return (
|
||||
<SingleValueWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
);
|
||||
case widgetType.simpleWidget:
|
||||
return (
|
||||
<SimpleWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
iconWidget={value.widgetIcon}
|
||||
/>
|
||||
);
|
||||
case widgetType.pieChart:
|
||||
return (
|
||||
<PieChartWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
);
|
||||
case widgetType.linearGraph:
|
||||
case widgetType.areaGraph:
|
||||
return (
|
||||
<LinearGraphWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
hideYAxis={value.disableYAxis}
|
||||
xAxisFormatter={value.xAxisFormatter}
|
||||
yAxisFormatter={value.yAxisFormatter}
|
||||
apiPrefix={apiPrefix}
|
||||
areaWidget={value.type === widgetType.areaGraph}
|
||||
zoomActivated={zoomActivated}
|
||||
/>
|
||||
);
|
||||
case widgetType.barChart:
|
||||
return (
|
||||
<BarChartWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
apiPrefix={apiPrefix}
|
||||
zoomActivated={zoomActivated}
|
||||
/>
|
||||
);
|
||||
case widgetType.singleRep:
|
||||
const fillColor = value.fillColor ? value.fillColor : value.color;
|
||||
return (
|
||||
<SingleRepWidget
|
||||
title={value.title}
|
||||
panelItem={value}
|
||||
timeStart={timeStart}
|
||||
timeEnd={timeEnd}
|
||||
propLoading={loading}
|
||||
color={value.color as string}
|
||||
fillColor={fillColor as string}
|
||||
apiPrefix={apiPrefix}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
44
portal-ui/src/screens/Console/Dashboard/actions.ts
Normal file
44
portal-ui/src/screens/Console/Dashboard/actions.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { IDashboardPanel } from "./Prometheus/types";
|
||||
|
||||
export const DASHBOARD_OPEN_ZOOM = "DASHBOARD/OPEN_ZOOM";
|
||||
export const DASHBOARD_CLOSE_ZOOM = "DASHBOARD/CLOSE_ZOOM";
|
||||
|
||||
interface OpenChartZoom {
|
||||
type: typeof DASHBOARD_OPEN_ZOOM;
|
||||
widget: IDashboardPanel;
|
||||
}
|
||||
|
||||
interface CloseChartZoom {
|
||||
type: typeof DASHBOARD_CLOSE_ZOOM;
|
||||
}
|
||||
|
||||
export type ZoomActionTypes = OpenChartZoom | CloseChartZoom;
|
||||
|
||||
export function openZoomPage(widget: IDashboardPanel) {
|
||||
return {
|
||||
type: DASHBOARD_OPEN_ZOOM,
|
||||
widget,
|
||||
};
|
||||
}
|
||||
|
||||
export function closeZoomPage() {
|
||||
return {
|
||||
type: DASHBOARD_CLOSE_ZOOM,
|
||||
};
|
||||
}
|
||||
55
portal-ui/src/screens/Console/Dashboard/reducer.ts
Normal file
55
portal-ui/src/screens/Console/Dashboard/reducer.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { zoomState } from "./types";
|
||||
import { ZoomActionTypes, DASHBOARD_OPEN_ZOOM, DASHBOARD_CLOSE_ZOOM } from "./actions";
|
||||
|
||||
export interface DashboardState {
|
||||
zoom: zoomState;
|
||||
}
|
||||
|
||||
const initialState: DashboardState = {
|
||||
zoom: {
|
||||
openZoom: false,
|
||||
widgetRender: null,
|
||||
},
|
||||
};
|
||||
|
||||
export function dashboardReducer(
|
||||
state = initialState,
|
||||
action: ZoomActionTypes
|
||||
): DashboardState {
|
||||
switch (action.type) {
|
||||
case DASHBOARD_OPEN_ZOOM:
|
||||
return {
|
||||
...state,
|
||||
zoom: {
|
||||
openZoom: true,
|
||||
widgetRender: { ...action.widget },
|
||||
},
|
||||
};
|
||||
case DASHBOARD_CLOSE_ZOOM:
|
||||
return {
|
||||
...state,
|
||||
zoom: {
|
||||
openZoom: false,
|
||||
widgetRender: null,
|
||||
},
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { IDashboardPanel } from "./Prometheus/types";
|
||||
|
||||
export interface Usage {
|
||||
usage: number;
|
||||
buckets: number;
|
||||
@@ -45,3 +47,8 @@ export interface IDriveInfo {
|
||||
usedSpace: number;
|
||||
availableSpace: number;
|
||||
}
|
||||
|
||||
export interface zoomState {
|
||||
openZoom: boolean,
|
||||
widgetRender: null | IDashboardPanel,
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import { bucketsReducer } from "./screens/Console/Buckets/reducers";
|
||||
import { objectBrowserReducer } from "./screens/Console/ObjectBrowser/reducers";
|
||||
import { tenantsReducer } from "./screens/Console/Tenants/reducer";
|
||||
import { directCSIReducer } from "./screens/Console/DirectCSI/reducer";
|
||||
import { dashboardReducer } from "./screens/Console/Dashboard/reducer";
|
||||
|
||||
const globalReducer = combineReducers({
|
||||
system: systemReducer,
|
||||
@@ -38,6 +39,7 @@ const globalReducer = combineReducers({
|
||||
healthInfo: healthInfoReducer,
|
||||
tenants: tenantsReducer,
|
||||
directCSI: directCSIReducer,
|
||||
dashboard: dashboardReducer,
|
||||
});
|
||||
|
||||
declare global {
|
||||
|
||||
Reference in New Issue
Block a user