From 98745fc30799fb3264aee3e0f98968d8950323a2 Mon Sep 17 00:00:00 2001 From: Rajat Dabade Date: Thu, 13 Jul 2023 15:17:59 +0530 Subject: [PATCH] Refactor the Metric Application Layer (#2984) * refactor: seperate the dependency of top overview query * refactor: added error handle for api call using usequery * refactor: update api layar and condition in component * fix: onDragSelect re-render all graph data * refactor: removed console * refactor: corrected names and updated implemented required condition * fix: the api call issue * refactor: removed useeffect * refactor: reverted the unnecessary changes * refactor: removed the login from service level * refactor: removed the unwanted code * refactor: reverted the unwanted changes in getDashboardVariable * refactor: instead of useQuery used useQueries * refactor: changed the dependencies of useQuery key * refactor: linter fixes * refactor: delete the unrequired files * fix: generecity of the type * fix: moved the type to component * fix: move the logic from container layer to pages layer * refactor: optimised some part of the code * refactor: review changes * refactor: optimised the checks * refactor: checking if the dependency data loaded in full view * refactor: resolve the error of props in overview.ts * refactor: small changes * refactor: enforced the typecasting of constant variable * refactor: refactoring in some of the changes are updated * refactor: refactoring in some of the changes are updated * refactor: removed the extra parameter from useGetQueryRange * refactor: revert the changes back for tab * refactor: metrics application is updated * chore: loading condition is updated for full view component * chore: moved the serviceDataProps type to api layer * chore: message name is updated --------- Co-authored-by: Srikanth Chekuri Co-authored-by: Palash Gupta --- frontend/src/AppRoutes/pageComponents.ts | 2 +- .../src/api/metrics/getServiceOverview.ts | 32 +-- .../src/api/metrics/getTopLevelOperations.ts | 24 +- frontend/src/api/metrics/getTopOperations.ts | 30 +-- frontend/src/constants/api.ts | 4 +- .../Graph/FullView/index.metricsBuilder.tsx | 8 +- .../MetricsApplication/Tabs/Overview.tsx | 220 +++++++++++++----- .../container/MetricsApplication/index.tsx | 90 ------- .../src/pages/MetricApplication/index.tsx | 76 ------ .../src/pages/MetricsApplication/config.ts | 8 + .../src/pages/MetricsApplication/index.tsx | 54 +++++ .../src/pages/MetricsApplication/types.ts | 11 + .../useMetricsApplicationTabKey.tsx | 14 ++ .../src/pages/MetricsApplication/utils.ts | 17 ++ .../store/actions/metrics/getInitialData.ts | 137 ----------- frontend/src/store/reducers/global.ts | 4 +- 16 files changed, 305 insertions(+), 426 deletions(-) delete mode 100644 frontend/src/container/MetricsApplication/index.tsx delete mode 100644 frontend/src/pages/MetricApplication/index.tsx create mode 100644 frontend/src/pages/MetricsApplication/config.ts create mode 100644 frontend/src/pages/MetricsApplication/index.tsx create mode 100644 frontend/src/pages/MetricsApplication/types.ts create mode 100644 frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx create mode 100644 frontend/src/pages/MetricsApplication/utils.ts delete mode 100644 frontend/src/store/actions/metrics/getInitialData.ts diff --git a/frontend/src/AppRoutes/pageComponents.ts b/frontend/src/AppRoutes/pageComponents.ts index a4d6b89c16..f7bc5e1704 100644 --- a/frontend/src/AppRoutes/pageComponents.ts +++ b/frontend/src/AppRoutes/pageComponents.ts @@ -7,7 +7,7 @@ export const ServicesTablePage = Loadable( export const ServiceMetricsPage = Loadable( () => import( - /* webpackChunkName: "ServiceMetricsPage" */ 'pages/MetricApplication' + /* webpackChunkName: "ServiceMetricsPage" */ 'pages/MetricsApplication' ), ); diff --git a/frontend/src/api/metrics/getServiceOverview.ts b/frontend/src/api/metrics/getServiceOverview.ts index ea0ddb4062..47febaa3d8 100644 --- a/frontend/src/api/metrics/getServiceOverview.ts +++ b/frontend/src/api/metrics/getServiceOverview.ts @@ -1,30 +1,16 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; import { PayloadProps, Props } from 'types/api/metrics/getServiceOverview'; -const getServiceOverview = async ( - props: Props, -): Promise | ErrorResponse> => { - try { - const response = await axios.post(`/service/overview`, { - start: `${props.start}`, - end: `${props.end}`, - service: props.service, - step: props.step, - tags: props.selectedTags, - }); +const getServiceOverview = async (props: Props): Promise => { + const response = await axios.post(`/service/overview`, { + start: `${props.start}`, + end: `${props.end}`, + service: props.service, + step: props.step, + tags: props.selectedTags, + }); - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } + return response.data; }; export default getServiceOverview; diff --git a/frontend/src/api/metrics/getTopLevelOperations.ts b/frontend/src/api/metrics/getTopLevelOperations.ts index 5ecfd2a67a..2f5a2026b2 100644 --- a/frontend/src/api/metrics/getTopLevelOperations.ts +++ b/frontend/src/api/metrics/getTopLevelOperations.ts @@ -1,24 +1,12 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/metrics/getTopLevelOperations'; -const getTopLevelOperations = async ( - props: Props, -): Promise | ErrorResponse> => { - try { - const response = await axios.post(`/service/top_level_operations`); +const getTopLevelOperations = async (): Promise => { + const response = await axios.post(`/service/top_level_operations`); + return response.data; +}; - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data[props.service], - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } +export type ServiceDataProps = { + [serviceName: string]: string[]; }; export default getTopLevelOperations; diff --git a/frontend/src/api/metrics/getTopOperations.ts b/frontend/src/api/metrics/getTopOperations.ts index cf07f0ee5d..9c85602e40 100644 --- a/frontend/src/api/metrics/getTopOperations.ts +++ b/frontend/src/api/metrics/getTopOperations.ts @@ -1,29 +1,15 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; import { PayloadProps, Props } from 'types/api/metrics/getTopOperations'; -const getTopOperations = async ( - props: Props, -): Promise | ErrorResponse> => { - try { - const response = await axios.post(`/service/top_operations`, { - start: `${props.start}`, - end: `${props.end}`, - service: props.service, - tags: props.selectedTags, - }); +const getTopOperations = async (props: Props): Promise => { + const response = await axios.post(`/service/top_operations`, { + start: `${props.start}`, + end: `${props.end}`, + service: props.service, + tags: props.selectedTags, + }); - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } + return response.data; }; export default getTopOperations; diff --git a/frontend/src/constants/api.ts b/frontend/src/constants/api.ts index 8ebfe3b73c..abb7d42ad6 100644 --- a/frontend/src/constants/api.ts +++ b/frontend/src/constants/api.ts @@ -1,3 +1,5 @@ +const SOMETHING_WENT_WRONG = 'Something went wrong'; + const getVersion = 'version'; -export { getVersion }; +export { getVersion, SOMETHING_WENT_WRONG }; diff --git a/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx b/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx index f500a0a098..3208517b86 100644 --- a/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx +++ b/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx @@ -26,6 +26,7 @@ function FullView({ name, yAxisUnit, onDragSelect, + isDependedDataLoaded = false, }: FullViewProps): JSX.Element { const { selectedTime: globalSelectedTime } = useSelector< AppState, @@ -61,6 +62,7 @@ function FullView({ }, { queryKey, + enabled: !isDependedDataLoaded, }, ); @@ -76,9 +78,7 @@ function FullView({ [response], ); - const isLoading = response.isLoading === true; - - if (isLoading) { + if (response.status === 'idle' || response.status === 'loading') { return ; } @@ -123,6 +123,7 @@ interface FullViewProps { name: string; yAxisUnit?: string; onDragSelect?: (start: number, end: number) => void; + isDependedDataLoaded?: boolean; } FullView.defaultProps = { @@ -130,6 +131,7 @@ FullView.defaultProps = { onClickHandler: undefined, yAxisUnit: undefined, onDragSelect: undefined, + isDependedDataLoaded: undefined, }; export default FullView; diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index 701e6ff219..5cd571a548 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -1,5 +1,13 @@ +import { Typography } from 'antd'; +import getServiceOverview from 'api/metrics/getServiceOverview'; +import getTopLevelOperations, { + ServiceDataProps, +} from 'api/metrics/getTopLevelOperations'; +import getTopOperations from 'api/metrics/getTopOperations'; +import axios from 'axios'; import { ActiveElement, Chart, ChartData, ChartEvent } from 'chart.js'; import Graph from 'components/Graph'; +import Spinner from 'components/Spinner'; import { QueryParams } from 'constants/query'; import ROUTES from 'constants/routes'; import FullView from 'container/GridGraphLayout/Graph/FullView/index.metricsBuilder'; @@ -12,16 +20,22 @@ import { } from 'hooks/useResourceAttribute/utils'; import convertToNanoSecondsToSecond from 'lib/convertToNanoSecondsToSecond'; import { colors } from 'lib/getRandomColor'; +import getStep from 'lib/getStep'; import history from 'lib/history'; import { useCallback, useMemo, useState } from 'react'; +import { useQueries, UseQueryResult } from 'react-query'; import { useDispatch, useSelector } from 'react-redux'; import { useLocation, useParams } from 'react-router-dom'; import { UpdateTimeInterval } from 'store/actions'; import { AppState } from 'store/reducers'; +import { PayloadProps } from 'types/api/metrics/getServiceOverview'; +import { PayloadProps as PayloadPropsTopOpertions } from 'types/api/metrics/getTopOperations'; import { EQueryType } from 'types/common/dashboard'; -import MetricReducer from 'types/reducer/metrics'; +import { GlobalReducer } from 'types/reducer/globalTime'; +import { Tags } from 'types/reducer/trace'; import { v4 as uuid } from 'uuid'; +import { SOMETHING_WENT_WRONG } from '../../../constants/api'; import { getWidgetQueryBuilder } from '../MetricsApplication.factory'; import { errorPercentage, @@ -37,9 +51,17 @@ import { } from './util'; function Application(): JSX.Element { + const { maxTime, minTime } = useSelector( + (state) => state.globalTime, + ); const { servicename } = useParams<{ servicename?: string }>(); const [selectedTimeStamp, setSelectedTimeStamp] = useState(0); const { search } = useLocation(); + const { queries } = useResourceAttribute(); + const selectedTags = useMemo( + () => (convertRawQueriesToTraceSelectedTags(queries) as Tags[]) || [], + [queries], + ); const handleSetTimeStamp = useCallback((selectTime: number) => { setSelectedTimeStamp(selectTime); @@ -64,12 +86,53 @@ function Application(): JSX.Element { [handleSetTimeStamp], ); - const { topOperations, serviceOverview, topLevelOperations } = useSelector< - AppState, - MetricReducer - >((state) => state.metrics); + const queryResult = useQueries< + [ + UseQueryResult, + UseQueryResult, + UseQueryResult, + ] + >([ + { + queryKey: [servicename, selectedTags, minTime, maxTime], + queryFn: (): Promise => + getServiceOverview({ + service: servicename || '', + start: minTime, + end: maxTime, + step: getStep({ + start: minTime, + end: maxTime, + inputFormat: 'ns', + }), + selectedTags, + }), + }, + { + queryKey: [minTime, maxTime, servicename, selectedTags], + queryFn: (): Promise => + getTopOperations({ + service: servicename || '', + start: minTime, + end: maxTime, + selectedTags, + }), + }, + { + queryKey: [servicename, minTime, maxTime, selectedTags], + queryFn: (): Promise => getTopLevelOperations(), + }, + ]); - const { queries } = useResourceAttribute(); + const serviceOverview = queryResult[0].data; + const serviceOverviewError = queryResult[0].error; + const serviceOverviewIsError = queryResult[0].isError; + const serviceOverviewIsLoading = queryResult[0].isLoading; + const topOperations = queryResult[1].data; + const topLevelOperations = queryResult[2].data; + const topLevelOperationsError = queryResult[2].error; + const topLevelOperationsIsError = queryResult[2].isError; + const topLevelOperationsIsLoading = queryResult[2].isLoading; const selectedTraceTags: string = JSON.stringify( convertRawQueriesToTraceSelectedTags(queries) || [], @@ -89,7 +152,9 @@ function Application(): JSX.Element { builder: operationPerSec({ servicename, tagFilterItems, - topLevelOperations, + topLevelOperations: topLevelOperations + ? topLevelOperations[servicename || ''] + : [], }), clickhouse_sql: [], id: uuid(), @@ -105,7 +170,9 @@ function Application(): JSX.Element { builder: errorPercentage({ servicename, tagFilterItems, - topLevelOperations, + topLevelOperations: topLevelOperations + ? topLevelOperations[servicename || ''] + : [], }), clickhouse_sql: [], id: uuid(), @@ -158,8 +225,12 @@ function Application(): JSX.Element { [], ); - const dataSets = useMemo( - () => [ + const dataSets = useMemo(() => { + if (!serviceOverview) { + return []; + } + + return [ { data: serviceOverview.map((e) => parseFloat(convertToNanoSecondsToSecond(e.p99)), @@ -178,19 +249,25 @@ function Application(): JSX.Element { ), ...generalChartDataProperties('p50 Latency', 2), }, - ], - [generalChartDataProperties, serviceOverview], - ); + ]; + }, [generalChartDataProperties, serviceOverview]); - const data = useMemo( - () => ({ + const data = useMemo(() => { + if (!serviceOverview) { + return { + datasets: [], + labels: [], + }; + } + + return { datasets: dataSets, labels: serviceOverview.map( (e) => new Date(parseFloat(convertToNanoSecondsToSecond(e.timestamp))), ), - }), - [serviceOverview, dataSets], - ); + }; + }, [serviceOverview, dataSets]); + return ( <> @@ -208,18 +285,33 @@ function Application(): JSX.Element { View Traces - Latency - - - + {serviceOverviewIsError ? ( + + {axios.isAxiosError(serviceOverviewError) + ? serviceOverviewError.response?.data + : SOMETHING_WENT_WRONG} + + ) : ( + <> + Latency + {serviceOverviewIsLoading && ( + + )} + {!serviceOverviewIsLoading && ( + + + + )} + + )} @@ -237,17 +329,28 @@ function Application(): JSX.Element { View Traces - Rate (ops/s) - - - + {topLevelOperationsIsError ? ( + + {axios.isAxiosError(topLevelOperationsError) + ? topLevelOperationsError.response?.data + : SOMETHING_WENT_WRONG} + + ) : ( + <> + Rate (ops/s) + + + + + )} @@ -265,23 +368,34 @@ function Application(): JSX.Element { - Error Percentage - - - + {topLevelOperationsIsError ? ( + + {axios.isAxiosError(topLevelOperationsError) + ? topLevelOperationsError.response?.data + : SOMETHING_WENT_WRONG} + + ) : ( + <> + Error Percentage + + + + + )} - + diff --git a/frontend/src/container/MetricsApplication/index.tsx b/frontend/src/container/MetricsApplication/index.tsx deleted file mode 100644 index 5709742b33..0000000000 --- a/frontend/src/container/MetricsApplication/index.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import RouteTab from 'components/RouteTab'; -import ROUTES from 'constants/routes'; -import ResourceAttributesFilter from 'container/ResourceAttributesFilter'; -import history from 'lib/history'; -import { memo, useMemo } from 'react'; -import { generatePath, useParams } from 'react-router-dom'; -import { useLocation } from 'react-use'; - -import DBCall from './Tabs/DBCall'; -import External from './Tabs/External'; -import Overview from './Tabs/Overview'; - -function OverViewTab(): JSX.Element { - return ; -} - -function DbCallTab(): JSX.Element { - return ; -} - -function ExternalTab(): JSX.Element { - return ; -} - -function ServiceMetrics(): JSX.Element { - const { search } = useLocation(); - const { servicename } = useParams<{ servicename: string }>(); - - const searchParams = new URLSearchParams(search); - const tab = searchParams.get('tab'); - - const overMetrics = 'Overview Metrics'; - const dbCallMetrics = 'Database Calls'; - const externalMetrics = 'External Calls'; - - const getActiveKey = (): string => { - switch (tab) { - case null: { - return overMetrics; - } - case dbCallMetrics: { - return dbCallMetrics; - } - case externalMetrics: { - return externalMetrics; - } - default: { - return overMetrics; - } - } - }; - - const activeKey = getActiveKey(); - - const routes = useMemo( - () => [ - { - Component: OverViewTab, - name: overMetrics, - route: `${generatePath(ROUTES.SERVICE_METRICS, { - servicename, - })}?tab=${overMetrics}`, - }, - { - Component: DbCallTab, - name: dbCallMetrics, - route: `${generatePath(ROUTES.SERVICE_METRICS, { - servicename, - })}?tab=${dbCallMetrics}`, - }, - { - Component: ExternalTab, - name: externalMetrics, - route: `${generatePath(ROUTES.SERVICE_METRICS, { - servicename, - })}?tab=${externalMetrics}`, - }, - ], - [servicename], - ); - - return ( - <> - - - - ); -} - -export default memo(ServiceMetrics); diff --git a/frontend/src/pages/MetricApplication/index.tsx b/frontend/src/pages/MetricApplication/index.tsx deleted file mode 100644 index 9ed0fd3ab2..0000000000 --- a/frontend/src/pages/MetricApplication/index.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { Typography } from 'antd'; -import Spinner from 'components/Spinner'; -import MetricsApplicationContainer from 'container/MetricsApplication'; -import useResourceAttribute from 'hooks/useResourceAttribute'; -import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils'; -import { useEffect, useMemo } from 'react'; -import { connect, useSelector } from 'react-redux'; -import { useParams } from 'react-router-dom'; -import { bindActionCreators } from 'redux'; -import { ThunkDispatch } from 'redux-thunk'; -import { - GetInitialData, - GetInitialDataProps, -} from 'store/actions/metrics/getInitialData'; -import { AppState } from 'store/reducers'; -import AppActions from 'types/actions'; -import { GlobalReducer } from 'types/reducer/globalTime'; -import MetricReducer from 'types/reducer/metrics'; -import { Tags } from 'types/reducer/trace'; - -function MetricsApplication({ getInitialData }: MetricsProps): JSX.Element { - const { minTime, maxTime } = useSelector( - (state) => state.globalTime, - ); - const { error, errorMessage, metricsApplicationLoading } = useSelector< - AppState, - MetricReducer - >((state) => state.metrics); - - const { servicename } = useParams(); - const { queries } = useResourceAttribute(); - - const selectedTags = useMemo( - () => (convertRawQueriesToTraceSelectedTags(queries) as Tags[]) || [], - [queries], - ); - - useEffect(() => { - if (servicename !== undefined) { - getInitialData({ - serviceName: servicename, - maxTime, - minTime, - selectedTags, - }); - } - }, [servicename, getInitialData, maxTime, minTime, selectedTags]); - - if (metricsApplicationLoading) { - return ; - } - - if (error) { - return {errorMessage}; - } - - return ; -} - -interface DispatchProps { - getInitialData: (props: GetInitialDataProps) => void; -} - -interface ServiceProps { - servicename?: string; -} - -const mapDispatchToProps = ( - dispatch: ThunkDispatch, -): DispatchProps => ({ - getInitialData: bindActionCreators(GetInitialData, dispatch), -}); - -type MetricsProps = DispatchProps; - -export default connect(null, mapDispatchToProps)(MetricsApplication); diff --git a/frontend/src/pages/MetricsApplication/config.ts b/frontend/src/pages/MetricsApplication/config.ts new file mode 100644 index 0000000000..1e29113b86 --- /dev/null +++ b/frontend/src/pages/MetricsApplication/config.ts @@ -0,0 +1,8 @@ +import { MetricsApplicationTab } from './types'; + +export const TAB_KEYS_VS_METRICS_APPLICATION_KEY = { + [MetricsApplicationTab.DB_CALL_METRICS]: MetricsApplicationTab.DB_CALL_METRICS, + [MetricsApplicationTab.EXTERNAL_METRICS]: + MetricsApplicationTab.EXTERNAL_METRICS, + [MetricsApplicationTab.OVER_METRICS]: MetricsApplicationTab.OVER_METRICS, +}; diff --git a/frontend/src/pages/MetricsApplication/index.tsx b/frontend/src/pages/MetricsApplication/index.tsx new file mode 100644 index 0000000000..230fbe9c8f --- /dev/null +++ b/frontend/src/pages/MetricsApplication/index.tsx @@ -0,0 +1,54 @@ +import RouteTab from 'components/RouteTab'; +import ROUTES from 'constants/routes'; +import DBCall from 'container/MetricsApplication/Tabs/DBCall'; +import External from 'container/MetricsApplication/Tabs/External'; +import Overview from 'container/MetricsApplication/Tabs/Overview'; +import ResourceAttributesFilter from 'container/ResourceAttributesFilter'; +import history from 'lib/history'; +import { useMemo } from 'react'; +import { generatePath, useParams } from 'react-router-dom'; + +import { MetricsApplicationTab, TAB_KEY_VS_LABEL } from './types'; +import useMetricsApplicationTabKey from './useMetricsApplicationTabKey'; + +function MetricsApplication(): JSX.Element { + const { servicename } = useParams<{ servicename: string }>(); + + const activeKey = useMetricsApplicationTabKey(); + + const routes = useMemo( + () => [ + { + Component: Overview, + name: TAB_KEY_VS_LABEL[MetricsApplicationTab.OVER_METRICS], + route: `${generatePath(ROUTES.SERVICE_METRICS, { + servicename, + })}?tab=${MetricsApplicationTab.OVER_METRICS}`, + }, + { + Component: DBCall, + name: TAB_KEY_VS_LABEL[MetricsApplicationTab.DB_CALL_METRICS], + route: `${generatePath(ROUTES.SERVICE_METRICS, { + servicename, + })}?tab=${MetricsApplicationTab.DB_CALL_METRICS}`, + }, + { + Component: External, + name: TAB_KEY_VS_LABEL[MetricsApplicationTab.EXTERNAL_METRICS], + route: `${generatePath(ROUTES.SERVICE_METRICS, { + servicename, + })}?tab=${MetricsApplicationTab.EXTERNAL_METRICS}`, + }, + ], + [servicename], + ); + + return ( + <> + + + + ); +} + +export default MetricsApplication; diff --git a/frontend/src/pages/MetricsApplication/types.ts b/frontend/src/pages/MetricsApplication/types.ts new file mode 100644 index 0000000000..0bd7166eaa --- /dev/null +++ b/frontend/src/pages/MetricsApplication/types.ts @@ -0,0 +1,11 @@ +export enum MetricsApplicationTab { + OVER_METRICS = 'OVER_METRICS', + DB_CALL_METRICS = 'DB_CALL_METRICS', + EXTERNAL_METRICS = 'EXTERNAL_METRICS', +} + +export const TAB_KEY_VS_LABEL = { + [MetricsApplicationTab.OVER_METRICS]: 'Overview', + [MetricsApplicationTab.DB_CALL_METRICS]: 'DB Call Metrics', + [MetricsApplicationTab.EXTERNAL_METRICS]: 'External Metrics', +}; diff --git a/frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx b/frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx new file mode 100644 index 0000000000..ff2131f727 --- /dev/null +++ b/frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx @@ -0,0 +1,14 @@ +import useUrlQuery from 'hooks/useUrlQuery'; + +import { TAB_KEY_VS_LABEL } from './types'; +import { getMetricsApplicationKey } from './utils'; + +const useMetricsApplicationTabKey = (): string => { + const urlParams = useUrlQuery(); + + const tab = urlParams.get('tab'); + + return TAB_KEY_VS_LABEL[getMetricsApplicationKey(tab)]; +}; + +export default useMetricsApplicationTabKey; diff --git a/frontend/src/pages/MetricsApplication/utils.ts b/frontend/src/pages/MetricsApplication/utils.ts new file mode 100644 index 0000000000..ec47b3ca62 --- /dev/null +++ b/frontend/src/pages/MetricsApplication/utils.ts @@ -0,0 +1,17 @@ +import { TAB_KEYS_VS_METRICS_APPLICATION_KEY } from './config'; +import { MetricsApplicationTab } from './types'; + +export const isMetricsApplicationTab = ( + tab: string, +): tab is MetricsApplicationTab => + Object.values(MetricsApplicationTab).includes(tab as MetricsApplicationTab); + +export const getMetricsApplicationKey = ( + tab: string | null, +): MetricsApplicationTab => { + if (tab && isMetricsApplicationTab(tab)) { + return TAB_KEYS_VS_METRICS_APPLICATION_KEY[tab]; + } + + return MetricsApplicationTab.OVER_METRICS; +}; diff --git a/frontend/src/store/actions/metrics/getInitialData.ts b/frontend/src/store/actions/metrics/getInitialData.ts deleted file mode 100644 index 205aed6ed4..0000000000 --- a/frontend/src/store/actions/metrics/getInitialData.ts +++ /dev/null @@ -1,137 +0,0 @@ -// import getDBOverView from 'api/metrics/getDBOverView'; -// import getExternalAverageDuration from 'api/metrics/getExternalAverageDuration'; -// import getExternalError from 'api/metrics/getExternalError'; -// import getExternalService from 'api/metrics/getExternalService'; -import getServiceOverview from 'api/metrics/getServiceOverview'; -import getTopLevelOperations from 'api/metrics/getTopLevelOperations'; -import getTopOperations from 'api/metrics/getTopOperations'; -import { AxiosError } from 'axios'; -import GetMinMax from 'lib/getMinMax'; -import getStep from 'lib/getStep'; -import { Dispatch } from 'redux'; -import { AppState } from 'store/reducers'; -import AppActions from 'types/actions'; -import { Props } from 'types/api/metrics/getDBOverview'; -import { GlobalReducer } from 'types/reducer/globalTime'; -import { Tags } from 'types/reducer/trace'; - -export const GetInitialData = ( - props: GetInitialDataProps, -): (( - dispatch: Dispatch, - getState: () => AppState, -) => void) => async (dispatch, getState): Promise => { - try { - const { globalTime } = getState(); - - /** - * @description This is because we keeping the store as source of truth - */ - if ( - props.maxTime !== globalTime.maxTime && - props.minTime !== globalTime.minTime - ) { - return; - } - - dispatch({ - type: 'GET_INITIAL_APPLICATION_LOADING', - }); - - const { maxTime, minTime } = GetMinMax(globalTime.selectedTime, [ - globalTime.minTime / 1000000, - globalTime.maxTime / 1000000, - ]); - - const [ - // getDBOverViewResponse, - // getExternalAverageDurationResponse, - // getExternalErrorResponse, - // getExternalServiceResponse, - getServiceOverviewResponse, - getTopOperationsResponse, - getTopLevelOperationsResponse, - ] = await Promise.all([ - // getDBOverView({ - // ...props, - // }), - // getExternalAverageDuration({ - // ...props, - // }), - // getExternalError({ - // ...props, - // }), - // getExternalService({ - // ...props, - // }), - getServiceOverview({ - end: maxTime, - service: props.serviceName, - start: minTime, - step: getStep({ start: minTime, end: maxTime, inputFormat: 'ns' }), - selectedTags: props.selectedTags, - }), - getTopOperations({ - end: maxTime, - service: props.serviceName, - start: minTime, - selectedTags: props.selectedTags, - }), - getTopLevelOperations({ - service: props.serviceName, - }), - ]); - - if ( - // getDBOverViewResponse.statusCode === 200 && - // getExternalAverageDurationResponse.statusCode === 200 && - // getExternalErrorResponse.statusCode === 200 && - // getExternalServiceResponse.statusCode === 200 && - getServiceOverviewResponse.statusCode === 200 && - getTopOperationsResponse.statusCode === 200 && - getTopLevelOperationsResponse.statusCode === 200 - ) { - dispatch({ - type: 'GET_INTIAL_APPLICATION_DATA', - payload: { - // dbOverView: getDBOverViewResponse.payload, - // externalAverageDuration: getExternalAverageDurationResponse.payload, - // externalError: getExternalErrorResponse.payload, - // externalService: getExternalServiceResponse.payload, - serviceOverview: getServiceOverviewResponse.payload, - topOperations: getTopOperationsResponse.payload, - topLevelOperations: getTopLevelOperationsResponse.payload, - }, - }); - } else { - dispatch({ - type: 'GET_INITIAL_APPLICATION_ERROR', - payload: { - errorMessage: - getTopOperationsResponse.error || - getServiceOverviewResponse.error || - getTopLevelOperationsResponse.error || - // getExternalServiceResponse.error || - // getExternalErrorResponse.error || - // getExternalAverageDurationResponse.error || - // getDBOverViewResponse.error || - 'Something went wrong', - }, - }); - } - } catch (error) { - dispatch({ - type: 'GET_INITIAL_APPLICATION_ERROR', - payload: { - errorMessage: (error as AxiosError).toString() || 'Something went wrong', - }, - }); - } -}; - -export interface GetInitialDataProps { - serviceName: Props['service']; - maxTime: GlobalReducer['maxTime']; - minTime: GlobalReducer['minTime']; - selectedTags: Tags[]; -} diff --git a/frontend/src/store/reducers/global.ts b/frontend/src/store/reducers/global.ts index 6c430eefe0..121f27218b 100644 --- a/frontend/src/store/reducers/global.ts +++ b/frontend/src/store/reducers/global.ts @@ -12,7 +12,7 @@ import { } from 'types/actions/logs'; import { GlobalReducer } from 'types/reducer/globalTime'; -const intitalState: GlobalReducer = { +const initialState: GlobalReducer = { maxTime: Date.now() * 1000000, minTime: (Date.now() - 15 * 60 * 1000) * 1000000, loading: true, @@ -24,7 +24,7 @@ const intitalState: GlobalReducer = { }; const globalTimeReducer = ( - state = intitalState, + state = initialState, action: GlobalTimeAction, ): GlobalReducer => { switch (action.type) {