mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 12:28:59 +08:00
fix: restructure code to handle loading state for panel type change (#5378)
* fix: restructure code to handle loading state for panel type change * fix: add inline comments
This commit is contained in:
parent
b34509215e
commit
02106277a6
@ -12,6 +12,7 @@ function WidgetGraphContainer({
|
|||||||
queryResponse,
|
queryResponse,
|
||||||
setRequestData,
|
setRequestData,
|
||||||
selectedWidget,
|
selectedWidget,
|
||||||
|
isLoadingPanelData,
|
||||||
}: WidgetGraphContainerProps): JSX.Element {
|
}: WidgetGraphContainerProps): JSX.Element {
|
||||||
if (queryResponse.data && selectedGraph === PANEL_TYPES.BAR) {
|
if (queryResponse.data && selectedGraph === PANEL_TYPES.BAR) {
|
||||||
const sortedSeriesData = getSortedSeriesData(
|
const sortedSeriesData = getSortedSeriesData(
|
||||||
@ -36,6 +37,10 @@ function WidgetGraphContainer({
|
|||||||
return <Spinner size="large" tip="Loading..." />;
|
return <Spinner size="large" tip="Loading..." />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isLoadingPanelData) {
|
||||||
|
return <Spinner size="large" tip="Loading..." />;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
selectedGraph !== PANEL_TYPES.LIST &&
|
selectedGraph !== PANEL_TYPES.LIST &&
|
||||||
queryResponse.data?.payload.data?.result?.length === 0
|
queryResponse.data?.payload.data?.result?.length === 0
|
||||||
|
@ -17,6 +17,7 @@ function WidgetGraph({
|
|||||||
queryResponse,
|
queryResponse,
|
||||||
setRequestData,
|
setRequestData,
|
||||||
selectedWidget,
|
selectedWidget,
|
||||||
|
isLoadingPanelData,
|
||||||
}: WidgetGraphContainerProps): JSX.Element {
|
}: WidgetGraphContainerProps): JSX.Element {
|
||||||
const { currentQuery } = useQueryBuilder();
|
const { currentQuery } = useQueryBuilder();
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ function WidgetGraph({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<WidgetGraphComponent
|
<WidgetGraphComponent
|
||||||
|
isLoadingPanelData={isLoadingPanelData}
|
||||||
selectedGraph={selectedGraph}
|
selectedGraph={selectedGraph}
|
||||||
queryResponse={queryResponse}
|
queryResponse={queryResponse}
|
||||||
setRequestData={setRequestData}
|
setRequestData={setRequestData}
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
import './LeftContainer.styles.scss';
|
import './LeftContainer.styles.scss';
|
||||||
|
|
||||||
import { DEFAULT_ENTITY_VERSION } from 'constants/app';
|
import { DEFAULT_ENTITY_VERSION } from 'constants/app';
|
||||||
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
||||||
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
|
|
||||||
import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults';
|
|
||||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
import { memo, useEffect, useState } from 'react';
|
import { memo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
import { getGraphType, getGraphTypeForFormat } from 'utils/getGraphType';
|
|
||||||
|
|
||||||
import { WidgetGraphProps } from '../types';
|
import { WidgetGraphProps } from '../types';
|
||||||
import ExplorerColumnsRenderer from './ExplorerColumnsRenderer';
|
import ExplorerColumnsRenderer from './ExplorerColumnsRenderer';
|
||||||
@ -27,68 +24,17 @@ function LeftContainer({
|
|||||||
selectedTracesFields,
|
selectedTracesFields,
|
||||||
setSelectedTracesFields,
|
setSelectedTracesFields,
|
||||||
selectedWidget,
|
selectedWidget,
|
||||||
selectedTime,
|
requestData,
|
||||||
|
setRequestData,
|
||||||
|
isLoadingPanelData,
|
||||||
}: WidgetGraphProps): JSX.Element {
|
}: WidgetGraphProps): JSX.Element {
|
||||||
const { stagedQuery, redirectWithQueryBuilderData } = useQueryBuilder();
|
const { stagedQuery } = useQueryBuilder();
|
||||||
const { selectedDashboard } = useDashboard();
|
const { selectedDashboard } = useDashboard();
|
||||||
|
|
||||||
const { selectedTime: globalSelectedInterval } = useSelector<
|
const { selectedTime: globalSelectedInterval } = useSelector<
|
||||||
AppState,
|
AppState,
|
||||||
GlobalReducer
|
GlobalReducer
|
||||||
>((state) => state.globalTime);
|
>((state) => state.globalTime);
|
||||||
|
|
||||||
const [requestData, setRequestData] = useState<GetQueryResultsProps>(() => {
|
|
||||||
if (selectedWidget && selectedGraph !== PANEL_TYPES.LIST) {
|
|
||||||
return {
|
|
||||||
selectedTime: selectedWidget?.timePreferance,
|
|
||||||
graphType: getGraphType(selectedGraph || selectedWidget.panelTypes),
|
|
||||||
query: stagedQuery || initialQueriesMap.metrics,
|
|
||||||
globalSelectedInterval,
|
|
||||||
formatForWeb:
|
|
||||||
getGraphTypeForFormat(selectedGraph || selectedWidget.panelTypes) ===
|
|
||||||
PANEL_TYPES.TABLE,
|
|
||||||
variables: getDashboardVariables(selectedDashboard?.data.variables),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const updatedQuery = { ...(stagedQuery || initialQueriesMap.metrics) };
|
|
||||||
updatedQuery.builder.queryData[0].pageSize = 10;
|
|
||||||
redirectWithQueryBuilderData(updatedQuery);
|
|
||||||
return {
|
|
||||||
query: updatedQuery,
|
|
||||||
graphType: PANEL_TYPES.LIST,
|
|
||||||
selectedTime: selectedTime.enum || 'GLOBAL_TIME',
|
|
||||||
globalSelectedInterval,
|
|
||||||
tableParams: {
|
|
||||||
pagination: {
|
|
||||||
offset: 0,
|
|
||||||
limit: updatedQuery.builder.queryData[0].limit || 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (stagedQuery) {
|
|
||||||
setRequestData((prev) => ({
|
|
||||||
...prev,
|
|
||||||
selectedTime: selectedTime.enum || prev.selectedTime,
|
|
||||||
globalSelectedInterval,
|
|
||||||
graphType: getGraphType(selectedGraph || selectedWidget.panelTypes),
|
|
||||||
query: stagedQuery,
|
|
||||||
fillGaps: selectedWidget.fillSpans || false,
|
|
||||||
formatForWeb:
|
|
||||||
getGraphTypeForFormat(selectedGraph || selectedWidget.panelTypes) ===
|
|
||||||
PANEL_TYPES.TABLE,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [
|
|
||||||
stagedQuery,
|
|
||||||
selectedTime,
|
|
||||||
selectedWidget.fillSpans,
|
|
||||||
globalSelectedInterval,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const queryResponse = useGetQueryRange(
|
const queryResponse = useGetQueryRange(
|
||||||
requestData,
|
requestData,
|
||||||
selectedDashboard?.data?.version || DEFAULT_ENTITY_VERSION,
|
selectedDashboard?.data?.version || DEFAULT_ENTITY_VERSION,
|
||||||
@ -110,6 +56,7 @@ function LeftContainer({
|
|||||||
queryResponse={queryResponse}
|
queryResponse={queryResponse}
|
||||||
setRequestData={setRequestData}
|
setRequestData={setRequestData}
|
||||||
selectedWidget={selectedWidget}
|
selectedWidget={selectedWidget}
|
||||||
|
isLoadingPanelData={isLoadingPanelData}
|
||||||
/>
|
/>
|
||||||
<QueryContainer className="query-section-left-container">
|
<QueryContainer className="query-section-left-container">
|
||||||
<QuerySection selectedGraph={selectedGraph} queryResponse={queryResponse} />
|
<QuerySection selectedGraph={selectedGraph} queryResponse={queryResponse} />
|
||||||
|
@ -7,7 +7,7 @@ import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn';
|
|||||||
import { chartHelpMessage } from 'components/facingIssueBtn/util';
|
import { chartHelpMessage } from 'components/facingIssueBtn/util';
|
||||||
import { FeatureKeys } from 'constants/features';
|
import { FeatureKeys } from 'constants/features';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { DashboardShortcuts } from 'constants/shortcuts/DashboardShortcuts';
|
import { DashboardShortcuts } from 'constants/shortcuts/DashboardShortcuts';
|
||||||
import { DEFAULT_BUCKET_COUNT } from 'container/PanelWrapper/constants';
|
import { DEFAULT_BUCKET_COUNT } from 'container/PanelWrapper/constants';
|
||||||
@ -18,6 +18,8 @@ import useAxiosError from 'hooks/useAxiosError';
|
|||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
|
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
|
||||||
|
import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { defaultTo, isUndefined } from 'lodash-es';
|
import { defaultTo, isUndefined } from 'lodash-es';
|
||||||
import { Check, X } from 'lucide-react';
|
import { Check, X } from 'lucide-react';
|
||||||
@ -38,6 +40,8 @@ import { IField } from 'types/api/logs/fields';
|
|||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
|
import { getGraphType, getGraphTypeForFormat } from 'utils/getGraphType';
|
||||||
|
|
||||||
import LeftContainer from './LeftContainer';
|
import LeftContainer from './LeftContainer';
|
||||||
import QueryTypeTag from './LeftContainer/QueryTypeTag';
|
import QueryTypeTag from './LeftContainer/QueryTypeTag';
|
||||||
@ -83,6 +87,10 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
const { featureResponse } = useSelector<AppState, AppReducer>(
|
const { featureResponse } = useSelector<AppState, AppReducer>(
|
||||||
(state) => state.app,
|
(state) => state.app,
|
||||||
);
|
);
|
||||||
|
const { selectedTime: globalSelectedInterval } = useSelector<
|
||||||
|
AppState,
|
||||||
|
GlobalReducer
|
||||||
|
>((state) => state.globalTime);
|
||||||
|
|
||||||
const { widgets = [] } = selectedDashboard?.data || {};
|
const { widgets = [] } = selectedDashboard?.data || {};
|
||||||
|
|
||||||
@ -278,6 +286,65 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
|
|
||||||
const handleError = useAxiosError();
|
const handleError = useAxiosError();
|
||||||
|
|
||||||
|
// this loading state is to take care of mismatch in the responses for table and other panels
|
||||||
|
// hence while changing the query contains the older value and the processing logic fails
|
||||||
|
const [isLoadingPanelData, setIsLoadingPanelData] = useState<boolean>(false);
|
||||||
|
|
||||||
|
// request data should be handled by the parent and the child components should consume the same
|
||||||
|
// this has been moved here from the left container
|
||||||
|
const [requestData, setRequestData] = useState<GetQueryResultsProps>(() => {
|
||||||
|
if (selectedWidget && selectedGraph !== PANEL_TYPES.LIST) {
|
||||||
|
return {
|
||||||
|
selectedTime: selectedWidget?.timePreferance,
|
||||||
|
graphType: getGraphType(selectedGraph || selectedWidget.panelTypes),
|
||||||
|
query: stagedQuery || initialQueriesMap.metrics,
|
||||||
|
globalSelectedInterval,
|
||||||
|
formatForWeb:
|
||||||
|
getGraphTypeForFormat(selectedGraph || selectedWidget.panelTypes) ===
|
||||||
|
PANEL_TYPES.TABLE,
|
||||||
|
variables: getDashboardVariables(selectedDashboard?.data.variables),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const updatedQuery = { ...(stagedQuery || initialQueriesMap.metrics) };
|
||||||
|
updatedQuery.builder.queryData[0].pageSize = 10;
|
||||||
|
redirectWithQueryBuilderData(updatedQuery);
|
||||||
|
return {
|
||||||
|
query: updatedQuery,
|
||||||
|
graphType: PANEL_TYPES.LIST,
|
||||||
|
selectedTime: selectedTime.enum || 'GLOBAL_TIME',
|
||||||
|
globalSelectedInterval,
|
||||||
|
tableParams: {
|
||||||
|
pagination: {
|
||||||
|
offset: 0,
|
||||||
|
limit: updatedQuery.builder.queryData[0].limit || 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (stagedQuery) {
|
||||||
|
setIsLoadingPanelData(false);
|
||||||
|
setRequestData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
selectedTime: selectedTime.enum || prev.selectedTime,
|
||||||
|
globalSelectedInterval,
|
||||||
|
graphType: getGraphType(selectedGraph || selectedWidget.panelTypes),
|
||||||
|
query: stagedQuery,
|
||||||
|
fillGaps: selectedWidget.fillSpans || false,
|
||||||
|
formatForWeb:
|
||||||
|
getGraphTypeForFormat(selectedGraph || selectedWidget.panelTypes) ===
|
||||||
|
PANEL_TYPES.TABLE,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [
|
||||||
|
stagedQuery,
|
||||||
|
selectedTime,
|
||||||
|
selectedWidget.fillSpans,
|
||||||
|
globalSelectedInterval,
|
||||||
|
]);
|
||||||
|
|
||||||
const onClickSaveHandler = useCallback(() => {
|
const onClickSaveHandler = useCallback(() => {
|
||||||
if (!selectedDashboard) {
|
if (!selectedDashboard) {
|
||||||
return;
|
return;
|
||||||
@ -402,6 +469,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
}, [dashboardId]);
|
}, [dashboardId]);
|
||||||
|
|
||||||
const setGraphHandler = (type: PANEL_TYPES): void => {
|
const setGraphHandler = (type: PANEL_TYPES): void => {
|
||||||
|
setIsLoadingPanelData(true);
|
||||||
const updatedQuery = handleQueryChange(type as any, supersetQuery);
|
const updatedQuery = handleQueryChange(type as any, supersetQuery);
|
||||||
setGraphType(type);
|
setGraphType(type);
|
||||||
redirectWithQueryBuilderData(
|
redirectWithQueryBuilderData(
|
||||||
@ -527,6 +595,9 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
setSelectedTracesFields={setSelectedTracesFields}
|
setSelectedTracesFields={setSelectedTracesFields}
|
||||||
selectedWidget={selectedWidget}
|
selectedWidget={selectedWidget}
|
||||||
selectedTime={selectedTime}
|
selectedTime={selectedTime}
|
||||||
|
requestData={requestData}
|
||||||
|
setRequestData={setRequestData}
|
||||||
|
isLoadingPanelData={isLoadingPanelData}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</LeftContainerWrapper>
|
</LeftContainerWrapper>
|
||||||
|
@ -24,6 +24,9 @@ export interface WidgetGraphProps {
|
|||||||
selectedWidget: Widgets;
|
selectedWidget: Widgets;
|
||||||
selectedGraph: PANEL_TYPES;
|
selectedGraph: PANEL_TYPES;
|
||||||
selectedTime: timePreferance;
|
selectedTime: timePreferance;
|
||||||
|
requestData: GetQueryResultsProps;
|
||||||
|
setRequestData: Dispatch<SetStateAction<GetQueryResultsProps>>;
|
||||||
|
isLoadingPanelData: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WidgetGraphContainerProps = {
|
export type WidgetGraphContainerProps = {
|
||||||
@ -34,4 +37,5 @@ export type WidgetGraphContainerProps = {
|
|||||||
setRequestData: Dispatch<SetStateAction<GetQueryResultsProps>>;
|
setRequestData: Dispatch<SetStateAction<GetQueryResultsProps>>;
|
||||||
selectedGraph: PANEL_TYPES;
|
selectedGraph: PANEL_TYPES;
|
||||||
selectedWidget: Widgets;
|
selectedWidget: Widgets;
|
||||||
|
isLoadingPanelData: boolean;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user