Graph visibility state management. (#4632)

* refactor: change the state handling of graph visibility

* refactor: removed commented code
This commit is contained in:
Rajat Dabade 2024-03-08 14:11:38 +05:30 committed by GitHub
parent 7051831539
commit e519539468
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 131 additions and 41 deletions

View File

@ -5,7 +5,7 @@ import { CheckboxChangeEvent } from 'antd/es/checkbox';
import { ResizeTable } from 'components/ResizeTable';
import { useNotifications } from 'hooks/useNotifications';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { memo, useCallback, useState } from 'react';
import { memo, useCallback, useEffect, useState } from 'react';
import { getGraphManagerTableColumns } from './TableRender/GraphManagerColumns';
import { ExtendedChartDataset, GraphManagerProps } from './types';
@ -29,6 +29,10 @@ function GraphManager({
getDefaultTableDataSet(options, data),
);
useEffect(() => {
setTableDataSet(getDefaultTableDataSet(options, data));
}, [data, options]);
const { notifications } = useNotifications();
const { isDashboardLocked } = useDashboard();

View File

@ -21,7 +21,7 @@ import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariab
import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';
@ -29,7 +29,7 @@ import uPlot from 'uplot';
import { getSortedSeriesData } from 'utils/getSortedSeriesData';
import { getTimeRange } from 'utils/getTimeRange';
import { getGraphVisibilityStateOnDataChange } from '../utils';
import { getLocalStorageGraphVisibilityState } from '../utils';
import { PANEL_TYPES_VS_FULL_VIEW_TABLE } from './contants';
import GraphManager from './GraphManager';
import { GraphContainer, TimeContainer } from './styles';
@ -43,12 +43,10 @@ function FullView({
version,
originalName,
yAxisUnit,
options,
onDragSelect,
isDependedDataLoaded = false,
onToggleModelHandler,
parentChartRef,
parentGraphVisibilityState,
}: FullViewProps): JSX.Element {
const { selectedTime: globalSelectedTime } = useSelector<
AppState,
@ -61,20 +59,6 @@ function FullView({
const { selectedDashboard, isDashboardLocked } = useDashboard();
const { graphVisibilityStates: localStoredVisibilityStates } = useMemo(
() =>
getGraphVisibilityStateOnDataChange({
options,
isExpandedName: false,
name: originalName,
}),
[options, originalName],
);
const [graphsVisibilityStates, setGraphsVisibilityStates] = useState(
localStoredVisibilityStates,
);
const getSelectedTime = useCallback(
() =>
timeItems.find((e) => e.enum === (widget?.timePreferance || 'GLOBAL_TIME')),
@ -105,6 +89,20 @@ function FullView({
},
);
const [graphsVisibilityStates, setGraphsVisibilityStates] = useState<
boolean[]
>(Array(response.data?.payload.data.result.length).fill(true));
useEffect(() => {
const {
graphVisibilityStates: localStoredVisibilityState,
} = getLocalStorageGraphVisibilityState({
apiResponse: response.data?.payload.data.result || [],
name: originalName,
});
setGraphsVisibilityStates(localStoredVisibilityState);
}, [originalName, response.data?.payload.data.result]);
const canModifyChart = useChartMutable({
panelType: widget.panelTypes,
panelTypeAndGraphManagerVisibility: PANEL_TYPES_VS_FULL_VIEW_TABLE,
@ -147,6 +145,7 @@ function FullView({
: 300;
const newChartOptions = getUPlotChartOptions({
id: originalName,
yAxisUnit: yAxisUnit || '',
apiResponse: response.data?.payload,
dimensions: {
@ -174,8 +173,7 @@ function FullView({
graphsVisibilityStates?.forEach((e, i) => {
fullViewChartRef?.current?.toggleGraph(i, e);
});
parentGraphVisibilityState(graphsVisibilityStates);
}, [graphsVisibilityStates, parentGraphVisibilityState]);
}, [graphsVisibilityStates]);
const isListView = widget.panelTypes === PANEL_TYPES.LIST;

View File

@ -52,13 +52,11 @@ export interface FullViewProps {
name: string;
version?: string;
originalName: string;
options: uPlot.Options;
yAxisUnit?: string;
onDragSelect: (start: number, end: number) => void;
isDependedDataLoaded?: boolean;
onToggleModelHandler?: GraphManagerProps['onToggleModelHandler'];
parentChartRef: GraphManagerProps['lineChartRef'];
parentGraphVisibilityState: Dispatch<SetStateAction<boolean[]>>;
}
export interface GraphManagerProps extends UplotProps {

View File

@ -1,4 +1,6 @@
import { LOCALSTORAGE } from 'constants/localStorage';
import getLabelName from 'lib/getLabelName';
import { QueryData } from 'types/api/widgets/getQuery';
import uPlot from 'uplot';
import {
@ -55,6 +57,20 @@ export const getAbbreviatedLabel = (label: string): string => {
return newLabel;
};
export const showAllDataSetFromApiResponse = (
apiResponse: QueryData[],
): LegendEntryProps[] =>
apiResponse.map(
(item): LegendEntryProps => ({
label: getLabelName(
item.metric || {},
item.queryName || '',
item.legend || '',
),
show: true,
}),
);
export const showAllDataSet = (options: uPlot.Options): LegendEntryProps[] =>
options.series
.map(

View File

@ -32,7 +32,7 @@ import WidgetHeader from '../WidgetHeader';
import FullView from './FullView';
import { Modal } from './styles';
import { WidgetGraphComponentProps } from './types';
import { getGraphVisibilityStateOnDataChange } from './utils';
import { getLocalStorageGraphVisibilityState } from './utils';
function WidgetGraphComponent({
widget,
@ -63,20 +63,6 @@ function WidgetGraphComponent({
const lineChartRef = useRef<ToggleGraphProps>();
const graphRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (queryResponse.isSuccess) {
const {
graphVisibilityStates: localStoredVisibilityState,
} = getGraphVisibilityStateOnDataChange({
options,
isExpandedName: false,
name,
});
setGraphVisibility(localStoredVisibilityState);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [queryResponse.isSuccess]);
useEffect(() => {
if (!lineChartRef.current) return;
@ -219,6 +205,15 @@ function WidgetGraphComponent({
const existingSearchParams = new URLSearchParams(search);
existingSearchParams.delete(QueryParams.expandedWidgetId);
const updatedQueryParams = Object.fromEntries(existingSearchParams.entries());
if (queryResponse.data?.payload) {
const {
graphVisibilityStates: localStoredVisibilityState,
} = getLocalStorageGraphVisibilityState({
apiResponse: queryResponse.data.payload.data.result,
name,
});
setGraphVisibility(localStoredVisibilityState);
}
history.push({
pathname,
search: createQueryParams(updatedQueryParams),
@ -290,9 +285,7 @@ function WidgetGraphComponent({
yAxisUnit={widget.yAxisUnit}
onToggleModelHandler={onToggleModelHandler}
parentChartRef={lineChartRef}
parentGraphVisibilityState={setGraphVisibility}
onDragSelect={onDragSelect}
options={options}
/>
</Modal>

View File

@ -29,6 +29,7 @@ import { getTimeRange } from 'utils/getTimeRange';
import EmptyWidget from '../EmptyWidget';
import { MenuItemKeys } from '../WidgetHeader/contants';
import { GridCardGraphProps } from './types';
import { getLocalStorageGraphVisibilityState } from './utils';
import WidgetGraphComponent from './WidgetGraphComponent';
function GridCardGraph({
@ -186,6 +187,16 @@ function GridCardGraph({
Array(queryResponse.data?.payload?.data.result.length || 0).fill(true),
);
useEffect(() => {
const {
graphVisibilityStates: localStoredVisibilityState,
} = getLocalStorageGraphVisibilityState({
apiResponse: queryResponse.data?.payload.data.result || [],
name,
});
setGraphVisibility(localStoredVisibilityState);
}, [name, queryResponse.data?.payload.data.result]);
const options = useMemo(
() =>
getUPlotChartOptions({

View File

@ -1,14 +1,78 @@
/* eslint-disable sonarjs/cognitive-complexity */
import { LOCALSTORAGE } from 'constants/localStorage';
import getLabelName from 'lib/getLabelName';
import { QueryData } from 'types/api/widgets/getQuery';
import { LegendEntryProps } from './FullView/types';
import { showAllDataSet } from './FullView/utils';
import {
showAllDataSet,
showAllDataSetFromApiResponse,
} from './FullView/utils';
import {
GetGraphVisibilityStateOnLegendClickProps,
GraphVisibilityLegendEntryProps,
ToggleGraphsVisibilityInChartProps,
} from './types';
export const getLocalStorageGraphVisibilityState = ({
apiResponse,
name,
}: {
apiResponse: QueryData[];
name: string;
}): GraphVisibilityLegendEntryProps => {
const visibilityStateAndLegendEntry: GraphVisibilityLegendEntryProps = {
graphVisibilityStates: Array(apiResponse.length + 1).fill(true),
legendEntry: [
{
label: 'Timestamp',
show: true,
},
...showAllDataSetFromApiResponse(apiResponse),
],
};
if (localStorage.getItem(LOCALSTORAGE.GRAPH_VISIBILITY_STATES) !== null) {
const legendGraphFromLocalStore = localStorage.getItem(
LOCALSTORAGE.GRAPH_VISIBILITY_STATES,
);
let legendFromLocalStore: {
name: string;
dataIndex: LegendEntryProps[];
}[] = [];
try {
legendFromLocalStore = JSON.parse(legendGraphFromLocalStore || '[]');
} catch (error) {
console.error(
'Error parsing GRAPH_VISIBILITY_STATES from local storage',
error,
);
}
const newGraphVisibilityStates = Array(apiResponse.length + 1).fill(true);
legendFromLocalStore.forEach((item) => {
const newName = name;
if (item.name === newName) {
visibilityStateAndLegendEntry.legendEntry = item.dataIndex;
apiResponse.forEach((datasets, i) => {
const index = item.dataIndex.findIndex(
(dataKey) =>
dataKey.label ===
getLabelName(datasets.metric, datasets.queryName, datasets.legend || ''),
);
if (index !== -1) {
newGraphVisibilityStates[i + 1] = item.dataIndex[index].show;
}
});
visibilityStateAndLegendEntry.graphVisibilityStates = newGraphVisibilityStates;
}
});
}
return visibilityStateAndLegendEntry;
};
export const getGraphVisibilityStateOnDataChange = ({
options,
isExpandedName,

View File

@ -6,6 +6,7 @@ import './uPlotLib.styles.scss';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { FullViewProps } from 'container/GridCardLayout/GridCard/FullView/types';
import { saveLegendEntriesToLocalStorage } from 'container/GridCardLayout/GridCard/FullView/utils';
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
import { Dimensions } from 'hooks/useDimensions';
import { convertValue } from 'lib/getConvertedValue';
@ -203,6 +204,11 @@ export const getUPlotChartOptions = ({
newGraphVisibilityStates.fill(false);
newGraphVisibilityStates[index + 1] = true;
}
saveLegendEntriesToLocalStorage({
options: self,
graphVisibilityState: newGraphVisibilityStates,
name: id || '',
});
return newGraphVisibilityStates;
});
}