2021-09-23 15:43:43 +05:30
|
|
|
import { Typography } from 'antd';
|
2023-01-25 20:31:42 +05:30
|
|
|
import { ChartData } from 'chart.js';
|
2021-09-23 15:43:43 +05:30
|
|
|
import Spinner from 'components/Spinner';
|
|
|
|
|
import GridGraphComponent from 'container/GridGraphComponent';
|
2023-01-25 20:31:42 +05:30
|
|
|
import usePreviousValue from 'hooks/usePreviousValue';
|
2022-09-09 17:43:25 +05:30
|
|
|
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
|
2021-09-23 15:43:43 +05:30
|
|
|
import getChartData from 'lib/getChartData';
|
2022-06-07 16:14:49 +05:30
|
|
|
import isEmpty from 'lodash-es/isEmpty';
|
2023-01-23 20:21:24 +05:30
|
|
|
import React, { memo, useCallback, useMemo, useState } from 'react';
|
2022-06-07 16:14:49 +05:30
|
|
|
import { Layout } from 'react-grid-layout';
|
2023-01-23 20:21:24 +05:30
|
|
|
import { useQuery } from 'react-query';
|
2022-03-22 12:10:31 +05:30
|
|
|
import { connect, useSelector } from 'react-redux';
|
2021-09-23 15:43:43 +05:30
|
|
|
import { bindActionCreators, Dispatch } from 'redux';
|
|
|
|
|
import { ThunkDispatch } from 'redux-thunk';
|
|
|
|
|
import {
|
|
|
|
|
DeleteWidget,
|
|
|
|
|
DeleteWidgetProps,
|
|
|
|
|
} from 'store/actions/dashboard/deleteWidget';
|
2022-06-24 15:00:21 +05:30
|
|
|
import { GetMetricQueryRange } from 'store/actions/dashboard/getQueryResults';
|
2021-09-23 15:43:43 +05:30
|
|
|
import { AppState } from 'store/reducers';
|
|
|
|
|
import AppActions from 'types/actions';
|
2021-10-20 09:24:55 +05:30
|
|
|
import { GlobalTime } from 'types/actions/globalTime';
|
2021-09-23 15:43:43 +05:30
|
|
|
import { Widgets } from 'types/api/dashboard/getAll';
|
2023-01-25 10:54:36 +05:30
|
|
|
import DashboardReducer from 'types/reducer/dashboards';
|
2022-06-24 15:00:21 +05:30
|
|
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
2021-09-23 15:43:43 +05:30
|
|
|
|
2022-06-07 16:14:49 +05:30
|
|
|
import { LayoutProps } from '..';
|
|
|
|
|
import EmptyWidget from '../EmptyWidget';
|
2022-04-19 10:57:56 +05:30
|
|
|
import WidgetHeader from '../WidgetHeader';
|
2022-06-24 15:00:21 +05:30
|
|
|
import FullView from './FullView/index.metricsBuilder';
|
2023-01-25 20:31:42 +05:30
|
|
|
import { FullViewContainer, Modal } from './styles';
|
2021-09-23 15:43:43 +05:30
|
|
|
|
2022-03-22 12:10:31 +05:30
|
|
|
function GridCardGraph({
|
2021-09-23 15:43:43 +05:30
|
|
|
widget,
|
|
|
|
|
deleteWidget,
|
2021-12-10 14:28:31 +05:30
|
|
|
name,
|
2022-03-22 12:10:31 +05:30
|
|
|
yAxisUnit,
|
2022-06-07 16:14:49 +05:30
|
|
|
layout = [],
|
|
|
|
|
setLayout,
|
2023-01-17 13:30:34 +02:00
|
|
|
onDragSelect,
|
2022-03-22 12:10:31 +05:30
|
|
|
}: GridCardGraphProps): JSX.Element {
|
2023-01-25 20:31:42 +05:30
|
|
|
const [errorMessage, setErrorMessage] = useState<string | undefined>('');
|
2022-04-19 10:57:56 +05:30
|
|
|
const [hovered, setHovered] = useState(false);
|
2021-09-23 15:43:43 +05:30
|
|
|
const [modal, setModal] = useState(false);
|
2022-06-24 15:00:21 +05:30
|
|
|
const [deleteModal, setDeleteModal] = useState(false);
|
|
|
|
|
|
2021-09-23 15:43:43 +05:30
|
|
|
const { minTime, maxTime } = useSelector<AppState, GlobalTime>(
|
|
|
|
|
(state) => state.globalTime,
|
|
|
|
|
);
|
2022-06-24 15:00:21 +05:30
|
|
|
const { selectedTime: globalSelectedInterval } = useSelector<
|
|
|
|
|
AppState,
|
|
|
|
|
GlobalReducer
|
|
|
|
|
>((state) => state.globalTime);
|
2023-01-25 10:54:36 +05:30
|
|
|
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
|
|
|
|
(state) => state.dashboards,
|
|
|
|
|
);
|
|
|
|
|
const [selectedDashboard] = dashboards;
|
|
|
|
|
const selectedData = selectedDashboard?.data;
|
|
|
|
|
const { variables } = selectedData;
|
2022-06-07 16:14:49 +05:30
|
|
|
|
2023-01-25 20:31:42 +05:30
|
|
|
const queryResponse = useQuery(
|
2023-01-23 20:21:24 +05:30
|
|
|
[
|
|
|
|
|
`GetMetricsQueryRange-${widget.timePreferance}-${globalSelectedInterval}-${widget.id}`,
|
2023-01-25 10:54:36 +05:30
|
|
|
{
|
|
|
|
|
widget,
|
|
|
|
|
maxTime,
|
|
|
|
|
minTime,
|
|
|
|
|
globalSelectedInterval,
|
|
|
|
|
variables,
|
|
|
|
|
},
|
2023-01-23 20:21:24 +05:30
|
|
|
],
|
|
|
|
|
() =>
|
|
|
|
|
GetMetricQueryRange({
|
|
|
|
|
selectedTime: widget.timePreferance,
|
|
|
|
|
graphType: widget.panelTypes,
|
|
|
|
|
query: widget.query,
|
|
|
|
|
globalSelectedInterval,
|
|
|
|
|
variables: getDashboardVariables(),
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
keepPreviousData: true,
|
|
|
|
|
refetchOnMount: false,
|
2023-01-25 20:31:42 +05:30
|
|
|
onError: (error) => {
|
|
|
|
|
if (error instanceof Error) {
|
|
|
|
|
setErrorMessage(error.message);
|
|
|
|
|
}
|
|
|
|
|
},
|
2023-01-23 20:21:24 +05:30
|
|
|
},
|
|
|
|
|
);
|
2022-06-24 15:00:21 +05:30
|
|
|
|
2023-01-23 20:21:24 +05:30
|
|
|
const chartData = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
getChartData({
|
|
|
|
|
queryData: [
|
|
|
|
|
{
|
2023-01-25 20:31:42 +05:30
|
|
|
queryData: queryResponse?.data?.payload?.data?.result || [],
|
2023-01-23 20:21:24 +05:30
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}),
|
2023-01-25 20:31:42 +05:30
|
|
|
[queryResponse],
|
2023-01-23 20:21:24 +05:30
|
|
|
);
|
2021-09-23 15:43:43 +05:30
|
|
|
|
2023-01-25 20:31:42 +05:30
|
|
|
const prevChartDataSetRef = usePreviousValue<ChartData>(chartData);
|
|
|
|
|
|
2021-09-23 15:43:43 +05:30
|
|
|
const onToggleModal = useCallback(
|
|
|
|
|
(func: React.Dispatch<React.SetStateAction<boolean>>) => {
|
|
|
|
|
func((value) => !value);
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
2022-03-24 12:06:57 +05:30
|
|
|
const onDeleteHandler = useCallback(() => {
|
2022-06-07 16:14:49 +05:30
|
|
|
const isEmptyWidget = widget?.id === 'empty' || isEmpty(widget);
|
|
|
|
|
|
|
|
|
|
const widgetId = isEmptyWidget ? layout[0].i : widget?.id;
|
|
|
|
|
|
|
|
|
|
deleteWidget({ widgetId, setLayout });
|
|
|
|
|
onToggleModal(setDeleteModal);
|
|
|
|
|
}, [deleteWidget, layout, onToggleModal, setLayout, widget]);
|
2022-03-24 12:06:57 +05:30
|
|
|
|
2023-01-24 18:53:04 +05:30
|
|
|
const getModals = (): JSX.Element => (
|
|
|
|
|
<>
|
|
|
|
|
<Modal
|
|
|
|
|
destroyOnClose
|
|
|
|
|
onCancel={(): void => onToggleModal(setDeleteModal)}
|
|
|
|
|
open={deleteModal}
|
|
|
|
|
title="Delete"
|
|
|
|
|
height="10vh"
|
|
|
|
|
onOk={onDeleteHandler}
|
|
|
|
|
centered
|
|
|
|
|
>
|
|
|
|
|
<Typography>Are you sure you want to delete this widget</Typography>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
title="View"
|
|
|
|
|
footer={[]}
|
|
|
|
|
centered
|
|
|
|
|
open={modal}
|
|
|
|
|
onCancel={(): void => onToggleModal(setModal)}
|
|
|
|
|
width="85%"
|
|
|
|
|
destroyOnClose
|
|
|
|
|
>
|
|
|
|
|
<FullViewContainer>
|
|
|
|
|
<FullView name={`${name}expanded`} widget={widget} yAxisUnit={yAxisUnit} />
|
|
|
|
|
</FullViewContainer>
|
|
|
|
|
</Modal>
|
|
|
|
|
</>
|
|
|
|
|
);
|
2022-02-11 12:00:46 +05:30
|
|
|
|
2023-01-13 17:29:51 +05:30
|
|
|
const handleOnView = (): void => {
|
|
|
|
|
onToggleModal(setModal);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleOnDelete = (): void => {
|
|
|
|
|
onToggleModal(setDeleteModal);
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-07 16:14:49 +05:30
|
|
|
const isEmptyLayout = widget?.id === 'empty' || isEmpty(widget);
|
|
|
|
|
|
2023-01-25 20:31:42 +05:30
|
|
|
if (queryResponse.isError && !isEmptyLayout) {
|
2022-02-10 22:20:31 +05:30
|
|
|
return (
|
2023-01-25 20:31:42 +05:30
|
|
|
<span>
|
2022-02-11 12:00:46 +05:30
|
|
|
{getModals()}
|
2023-01-25 20:31:42 +05:30
|
|
|
{!isEmpty(widget) && prevChartDataSetRef && (
|
|
|
|
|
<>
|
|
|
|
|
<div className="drag-handle">
|
|
|
|
|
<WidgetHeader
|
|
|
|
|
parentHover={hovered}
|
|
|
|
|
title={widget?.title}
|
|
|
|
|
widget={widget}
|
|
|
|
|
onView={handleOnView}
|
|
|
|
|
onDelete={handleOnDelete}
|
|
|
|
|
queryResponse={queryResponse}
|
|
|
|
|
errorMessage={errorMessage}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<GridGraphComponent
|
|
|
|
|
GRAPH_TYPES={widget.panelTypes}
|
|
|
|
|
data={prevChartDataSetRef}
|
|
|
|
|
isStacked={widget.isStacked}
|
|
|
|
|
opacity={widget.opacity}
|
|
|
|
|
title={' '}
|
|
|
|
|
name={name}
|
|
|
|
|
yAxisUnit={yAxisUnit}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</span>
|
2022-02-10 22:20:31 +05:30
|
|
|
);
|
2021-09-23 15:43:43 +05:30
|
|
|
}
|
|
|
|
|
|
2023-01-25 20:31:42 +05:30
|
|
|
if (prevChartDataSetRef?.labels === undefined && queryResponse.isLoading) {
|
2023-01-17 03:07:30 -03:00
|
|
|
return (
|
2023-01-25 20:31:42 +05:30
|
|
|
<span>
|
|
|
|
|
{!isEmpty(widget) && prevChartDataSetRef?.labels ? (
|
|
|
|
|
<>
|
|
|
|
|
<div className="drag-handle">
|
|
|
|
|
<WidgetHeader
|
|
|
|
|
parentHover={hovered}
|
|
|
|
|
title={widget?.title}
|
|
|
|
|
widget={widget}
|
|
|
|
|
onView={handleOnView}
|
|
|
|
|
onDelete={handleOnDelete}
|
|
|
|
|
queryResponse={queryResponse}
|
|
|
|
|
errorMessage={errorMessage}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<GridGraphComponent
|
|
|
|
|
GRAPH_TYPES={widget.panelTypes}
|
|
|
|
|
data={prevChartDataSetRef}
|
|
|
|
|
isStacked={widget.isStacked}
|
|
|
|
|
opacity={widget.opacity}
|
|
|
|
|
title={' '}
|
|
|
|
|
name={name}
|
|
|
|
|
yAxisUnit={yAxisUnit}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
<Spinner height="20vh" tip="Loading..." />
|
|
|
|
|
)}
|
|
|
|
|
</span>
|
2023-01-17 03:07:30 -03:00
|
|
|
);
|
2022-06-24 15:00:21 +05:30
|
|
|
}
|
2021-09-23 15:43:43 +05:30
|
|
|
|
|
|
|
|
return (
|
2022-04-19 10:57:56 +05:30
|
|
|
<span
|
|
|
|
|
onMouseOver={(): void => {
|
|
|
|
|
setHovered(true);
|
|
|
|
|
}}
|
|
|
|
|
onFocus={(): void => {
|
|
|
|
|
setHovered(true);
|
|
|
|
|
}}
|
|
|
|
|
onMouseOut={(): void => {
|
|
|
|
|
setHovered(false);
|
|
|
|
|
}}
|
|
|
|
|
onBlur={(): void => {
|
|
|
|
|
setHovered(false);
|
|
|
|
|
}}
|
|
|
|
|
>
|
2022-06-07 16:14:49 +05:30
|
|
|
{!isEmptyLayout && (
|
2023-01-13 17:29:51 +05:30
|
|
|
<div className="drag-handle">
|
|
|
|
|
<WidgetHeader
|
|
|
|
|
parentHover={hovered}
|
|
|
|
|
title={widget?.title}
|
|
|
|
|
widget={widget}
|
2023-01-23 20:21:24 +05:30
|
|
|
onView={handleOnView}
|
|
|
|
|
onDelete={handleOnDelete}
|
2023-01-25 20:31:42 +05:30
|
|
|
queryResponse={queryResponse}
|
|
|
|
|
errorMessage={errorMessage}
|
2023-01-13 17:29:51 +05:30
|
|
|
/>
|
|
|
|
|
</div>
|
2022-06-07 16:14:49 +05:30
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{!isEmptyLayout && getModals()}
|
|
|
|
|
|
2023-01-25 20:31:42 +05:30
|
|
|
{!isEmpty(widget) && !!queryResponse.data?.payload && (
|
2022-06-07 16:14:49 +05:30
|
|
|
<GridGraphComponent
|
2023-01-23 20:21:24 +05:30
|
|
|
GRAPH_TYPES={widget.panelTypes}
|
|
|
|
|
data={chartData}
|
|
|
|
|
isStacked={widget.isStacked}
|
|
|
|
|
opacity={widget.opacity}
|
|
|
|
|
title={' '} // empty title to accommodate absolutely positioned widget header
|
|
|
|
|
name={name}
|
|
|
|
|
yAxisUnit={yAxisUnit}
|
|
|
|
|
onDragSelect={onDragSelect}
|
2022-06-07 16:14:49 +05:30
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{isEmptyLayout && <EmptyWidget />}
|
2022-04-19 10:57:56 +05:30
|
|
|
</span>
|
2021-09-23 15:43:43 +05:30
|
|
|
);
|
2022-03-22 12:10:31 +05:30
|
|
|
}
|
2021-09-23 15:43:43 +05:30
|
|
|
|
|
|
|
|
interface DispatchProps {
|
|
|
|
|
deleteWidget: ({
|
|
|
|
|
widgetId,
|
|
|
|
|
}: DeleteWidgetProps) => (dispatch: Dispatch<AppActions>) => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface GridCardGraphProps extends DispatchProps {
|
|
|
|
|
widget: Widgets;
|
2021-12-10 14:28:31 +05:30
|
|
|
name: string;
|
2022-03-15 15:18:33 +05:30
|
|
|
yAxisUnit: string | undefined;
|
2022-06-07 16:14:49 +05:30
|
|
|
// eslint-disable-next-line react/require-default-props
|
|
|
|
|
layout?: Layout[];
|
|
|
|
|
// eslint-disable-next-line react/require-default-props
|
|
|
|
|
setLayout?: React.Dispatch<React.SetStateAction<LayoutProps[]>>;
|
2023-01-17 13:30:34 +02:00
|
|
|
onDragSelect?: (start: number, end: number) => void;
|
2021-09-23 15:43:43 +05:30
|
|
|
}
|
|
|
|
|
|
2023-01-17 13:30:34 +02:00
|
|
|
GridCardGraph.defaultProps = {
|
|
|
|
|
onDragSelect: undefined,
|
|
|
|
|
};
|
|
|
|
|
|
2021-09-23 15:43:43 +05:30
|
|
|
const mapDispatchToProps = (
|
|
|
|
|
dispatch: ThunkDispatch<unknown, unknown, AppActions>,
|
|
|
|
|
): DispatchProps => ({
|
|
|
|
|
deleteWidget: bindActionCreators(DeleteWidget, dispatch),
|
|
|
|
|
});
|
|
|
|
|
|
2022-06-07 16:14:49 +05:30
|
|
|
export default connect(null, mapDispatchToProps)(memo(GridCardGraph));
|