diff --git a/frontend/src/AppRoutes/pageComponents.ts b/frontend/src/AppRoutes/pageComponents.ts
index d6f67f11df..a4d6b89c16 100644
--- a/frontend/src/AppRoutes/pageComponents.ts
+++ b/frontend/src/AppRoutes/pageComponents.ts
@@ -15,6 +15,11 @@ export const ServiceMapPage = Loadable(
() => import(/* webpackChunkName: "ServiceMapPage" */ 'modules/Servicemap'),
);
+export const TracesExplorer = Loadable(
+ () =>
+ import(/* webpackChunkName: "Traces Explorer Page" */ 'pages/TracesExplorer'),
+);
+
export const TraceFilter = Loadable(
() => import(/* webpackChunkName: "Trace Filter Page" */ 'pages/Trace'),
);
diff --git a/frontend/src/AppRoutes/routes.ts b/frontend/src/AppRoutes/routes.ts
index d31b457c03..49d48de066 100644
--- a/frontend/src/AppRoutes/routes.ts
+++ b/frontend/src/AppRoutes/routes.ts
@@ -30,6 +30,7 @@ import {
StatusPage,
TraceDetail,
TraceFilter,
+ TracesExplorer,
UnAuthorized,
UsageExplorerPage,
} from './pageComponents';
@@ -140,6 +141,13 @@ const routes: AppRoutes[] = [
isPrivate: true,
key: 'TRACE',
},
+ {
+ path: ROUTES.TRACES_EXPLORER,
+ exact: true,
+ component: TracesExplorer,
+ isPrivate: true,
+ key: 'TRACES_EXPLORER',
+ },
{
path: ROUTES.CHANNELS_NEW,
exact: true,
diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts
index fb1ab7609f..f911b6be57 100644
--- a/frontend/src/constants/routes.ts
+++ b/frontend/src/constants/routes.ts
@@ -5,6 +5,7 @@ const ROUTES = {
SERVICE_MAP: '/service-map',
TRACE: '/trace',
TRACE_DETAIL: '/trace/:id',
+ TRACES_EXPLORER: '/traces-explorer',
SETTINGS: '/settings',
INSTRUMENTATION: '/get-started',
USAGE_EXPLORER: '/usage-explorer',
@@ -31,7 +32,6 @@ const ROUTES = {
HOME_PAGE: '/',
PASSWORD_RESET: '/password-reset',
LIST_LICENSES: '/licenses',
- TRACE_EXPLORER: '/trace-explorer',
};
export default ROUTES;
diff --git a/frontend/src/container/Controls/config.ts b/frontend/src/container/Controls/config.ts
new file mode 100644
index 0000000000..cc0378c546
--- /dev/null
+++ b/frontend/src/container/Controls/config.ts
@@ -0,0 +1,7 @@
+import { CSSProperties } from 'react';
+
+export const ITEMS_PER_PAGE_OPTIONS = [25, 50, 100, 200];
+
+export const defaultSelectStyle: CSSProperties = {
+ minWidth: '6rem',
+};
diff --git a/frontend/src/container/Controls/index.tsx b/frontend/src/container/Controls/index.tsx
new file mode 100644
index 0000000000..a9a656bfc8
--- /dev/null
+++ b/frontend/src/container/Controls/index.tsx
@@ -0,0 +1,69 @@
+import { LeftOutlined, RightOutlined } from '@ant-design/icons';
+import { Button, Select } from 'antd';
+import { memo, useMemo } from 'react';
+
+import { defaultSelectStyle, ITEMS_PER_PAGE_OPTIONS } from './config';
+import { Container } from './styles';
+
+interface ControlsProps {
+ count: number;
+ countPerPage: number;
+ isLoading: boolean;
+ handleNavigatePrevious: () => void;
+ handleNavigateNext: () => void;
+ handleCountItemsPerPageChange: (e: number) => void;
+}
+
+function Controls(props: ControlsProps): JSX.Element | null {
+ const {
+ count,
+ isLoading,
+ countPerPage,
+ handleNavigatePrevious,
+ handleNavigateNext,
+ handleCountItemsPerPageChange,
+ } = props;
+
+ const isNextAndPreviousDisabled = useMemo(
+ () => isLoading || countPerPage === 0 || count === 0 || count < countPerPage,
+ [isLoading, countPerPage, count],
+ );
+
+ return (
+
+
+
+
+
+ );
+}
+
+export default memo(Controls);
diff --git a/frontend/src/container/Controls/styles.ts b/frontend/src/container/Controls/styles.ts
new file mode 100644
index 0000000000..0407b8f790
--- /dev/null
+++ b/frontend/src/container/Controls/styles.ts
@@ -0,0 +1,7 @@
+import styled from 'styled-components';
+
+export const Container = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+`;
diff --git a/frontend/src/container/LogControls/config.ts b/frontend/src/container/LogControls/config.ts
deleted file mode 100644
index 7d3b0f71ee..0000000000
--- a/frontend/src/container/LogControls/config.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const ITEMS_PER_PAGE_OPTIONS = [25, 50, 100, 200];
diff --git a/frontend/src/container/LogControls/index.tsx b/frontend/src/container/LogControls/index.tsx
index 68c4c5a08b..d5f28ba45f 100644
--- a/frontend/src/container/LogControls/index.tsx
+++ b/frontend/src/container/LogControls/index.tsx
@@ -1,16 +1,11 @@
-import {
- CloudDownloadOutlined,
- FastBackwardOutlined,
- LeftOutlined,
- RightOutlined,
-} from '@ant-design/icons';
-import { Button, Divider, Dropdown, MenuProps, Select } from 'antd';
+import { CloudDownloadOutlined, FastBackwardOutlined } from '@ant-design/icons';
+import { Button, Divider, Dropdown, MenuProps } from 'antd';
import { Excel } from 'antd-table-saveas-excel';
+import Controls from 'container/Controls';
import { getGlobalTime } from 'container/LogsSearchFilter/utils';
import { getMinMax } from 'container/TopNav/AutoRefresh/config';
import dayjs from 'dayjs';
import { FlatLogData } from 'lib/logs/flatLogData';
-import { defaultSelectStyle } from 'pages/Logs/config';
import * as Papa from 'papaparse';
import { memo, useCallback, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
@@ -26,7 +21,6 @@ import {
import { GlobalReducer } from 'types/reducer/globalTime';
import { ILogsReducer } from 'types/reducer/logs';
-import { ITEMS_PER_PAGE_OPTIONS } from './config';
import { Container, DownloadLogButton } from './styles';
function LogControls(): JSX.Element | null {
@@ -149,15 +143,6 @@ function LogControls(): JSX.Element | null {
const isLoading = isLogsLoading || isLoadingAggregate;
- const isNextAndPreviousDisabled = useMemo(
- () =>
- isLoading ||
- logLinesPerPage === 0 ||
- logs.length === 0 ||
- logs.length < logLinesPerPage,
- [isLoading, logLinesPerPage, logs.length],
- );
-
if (liveTail !== 'STOPPED') {
return null;
}
@@ -179,37 +164,14 @@ function LogControls(): JSX.Element | null {
Go to latest
-
-
-
+
);
}
diff --git a/frontend/src/container/LogDetailedView/TableView.tsx b/frontend/src/container/LogDetailedView/TableView.tsx
index 2959be7dcc..7d4db12acc 100644
--- a/frontend/src/container/LogDetailedView/TableView.tsx
+++ b/frontend/src/container/LogDetailedView/TableView.tsx
@@ -32,7 +32,7 @@ function TableView({ logData }: TableViewProps): JSX.Element | null {
const dispatch = useDispatch>();
- const flattenLogData: Record | null = useMemo(
+ const flattenLogData: Record | null = useMemo(
() => (logData ? flattenObject(logData) : null),
[logData],
);
diff --git a/frontend/src/container/QueryBuilder/QueryBuilder.tsx b/frontend/src/container/QueryBuilder/QueryBuilder.tsx
index 564248a1a3..dae8717920 100644
--- a/frontend/src/container/QueryBuilder/QueryBuilder.tsx
+++ b/frontend/src/container/QueryBuilder/QueryBuilder.tsx
@@ -54,7 +54,7 @@ export const QueryBuilder = memo(function QueryBuilder({
);
return (
-
+
{currentQuery.builder.queryData.map((query, index) => (
diff --git a/frontend/src/container/QueryBuilder/components/AdditionalFiltersToggler/AdditionalFiltersToggler.tsx b/frontend/src/container/QueryBuilder/components/AdditionalFiltersToggler/AdditionalFiltersToggler.tsx
index 79aa1b0715..d50a754e4c 100644
--- a/frontend/src/container/QueryBuilder/components/AdditionalFiltersToggler/AdditionalFiltersToggler.tsx
+++ b/frontend/src/container/QueryBuilder/components/AdditionalFiltersToggler/AdditionalFiltersToggler.tsx
@@ -1,4 +1,4 @@
-import { Col, Row } from 'antd';
+import { Col, Row, Typography } from 'antd';
import { Fragment, memo, ReactNode, useState } from 'react';
// ** Types
@@ -46,7 +46,9 @@ export const AdditionalFiltersToggler = memo(function AdditionalFiltersToggler({
{isOpenedFilters ? : }
- {!isOpenedFilters && Add conditions for {filtersTexts}}
+ {!isOpenedFilters && (
+ Add conditions for {filtersTexts}
+ )}
{isOpenedFilters && {children}}
diff --git a/frontend/src/container/QueryBuilder/components/FilterLabel/FilterLabel.tsx b/frontend/src/container/QueryBuilder/components/FilterLabel/FilterLabel.tsx
index 8fd4421f2a..9d1c17514d 100644
--- a/frontend/src/container/QueryBuilder/components/FilterLabel/FilterLabel.tsx
+++ b/frontend/src/container/QueryBuilder/components/FilterLabel/FilterLabel.tsx
@@ -1,3 +1,4 @@
+import { Typography } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { memo } from 'react';
@@ -11,5 +12,9 @@ export const FilterLabel = memo(function FilterLabel({
}: FilterLabelProps): JSX.Element {
const isDarkMode = useIsDarkMode();
- return {label};
+ return (
+
+ {label}
+
+ );
});
diff --git a/frontend/src/container/SideNav/config.ts b/frontend/src/container/SideNav/config.ts
index 9938b54278..0246bc0e8e 100644
--- a/frontend/src/container/SideNav/config.ts
+++ b/frontend/src/container/SideNav/config.ts
@@ -30,10 +30,10 @@ export const routeConfig: Record = {
[ROUTES.SETTINGS]: [QueryParams.resourceAttributes],
[ROUTES.SIGN_UP]: [QueryParams.resourceAttributes],
[ROUTES.SOMETHING_WENT_WRONG]: [QueryParams.resourceAttributes],
+ [ROUTES.TRACES_EXPLORER]: [QueryParams.resourceAttributes],
[ROUTES.TRACE]: [QueryParams.resourceAttributes],
[ROUTES.TRACE_DETAIL]: [QueryParams.resourceAttributes],
[ROUTES.UN_AUTHORIZED]: [QueryParams.resourceAttributes],
[ROUTES.USAGE_EXPLORER]: [QueryParams.resourceAttributes],
[ROUTES.VERSION]: [QueryParams.resourceAttributes],
- [ROUTES.TRACE_EXPLORER]: [QueryParams.resourceAttributes],
};
diff --git a/frontend/src/container/SideNav/menuItems.tsx b/frontend/src/container/SideNav/menuItems.tsx
index a784a39c0a..3da53f194c 100644
--- a/frontend/src/container/SideNav/menuItems.tsx
+++ b/frontend/src/container/SideNav/menuItems.tsx
@@ -38,35 +38,36 @@ const menus: SidebarMenu[] = [
icon: ,
},
{
- key: 'traces',
+ key: ROUTES.TRACE,
label: 'Traces',
icon: ,
- children: [
- {
- key: ROUTES.TRACE,
- label: 'Traces',
- },
- // {
- // key: ROUTES.TRACE_EXPLORER,
- // label: 'Explorer',
- // },
- ],
+ // children: [
+ // {
+ // key: ROUTES.TRACE,
+ // label: 'Traces',
+ // },
+ // TODO: uncomment when will be ready explorer
+ // {
+ // key: ROUTES.TRACES_EXPLORER,
+ // label: "Explorer",
+ // },
+ // ],
},
{
- key: 'logs',
+ key: ROUTES.LOGS,
label: 'Logs',
icon: ,
- children: [
- {
- key: ROUTES.LOGS,
- label: 'Search',
- },
- // TODO: uncomment when will be ready explorer
- // {
- // key: ROUTES.LOGS_EXPLORER,
- // label: 'Views',
- // },
- ],
+ // children: [
+ // {
+ // key: ROUTES.LOGS,
+ // label: 'Search',
+ // },
+ // TODO: uncomment when will be ready explorer
+ // {
+ // key: ROUTES.LOGS_EXPLORER,
+ // label: 'Views',
+ // },
+ // ],
},
{
key: ROUTES.ALL_DASHBOARD,
diff --git a/frontend/src/container/TopNav/Breadcrumbs/index.tsx b/frontend/src/container/TopNav/Breadcrumbs/index.tsx
index d8ad3a6f40..f3bcfe560f 100644
--- a/frontend/src/container/TopNav/Breadcrumbs/index.tsx
+++ b/frontend/src/container/TopNav/Breadcrumbs/index.tsx
@@ -5,6 +5,7 @@ import { Link, RouteComponentProps, withRouter } from 'react-router-dom';
const breadcrumbNameMap = {
[ROUTES.APPLICATION]: 'Services',
[ROUTES.TRACE]: 'Traces',
+ [ROUTES.TRACES_EXPLORER]: 'Traces Explorer',
[ROUTES.SERVICE_MAP]: 'Service Map',
[ROUTES.USAGE_EXPLORER]: 'Usage Explorer',
[ROUTES.INSTRUMENTATION]: 'Get Started',
diff --git a/frontend/src/container/TracesExplorer/Controls/index.tsx b/frontend/src/container/TracesExplorer/Controls/index.tsx
new file mode 100644
index 0000000000..515fe12c67
--- /dev/null
+++ b/frontend/src/container/TracesExplorer/Controls/index.tsx
@@ -0,0 +1,25 @@
+import Controls from 'container/Controls';
+import { memo } from 'react';
+
+import { Container } from './styles';
+
+function TraceExplorerControls(): JSX.Element | null {
+ const handleCountItemsPerPageChange = (): void => {};
+ const handleNavigatePrevious = (): void => {};
+ const handleNavigateNext = (): void => {};
+
+ return (
+
+
+
+ );
+}
+
+export default memo(TraceExplorerControls);
diff --git a/frontend/src/container/TracesExplorer/Controls/styles.ts b/frontend/src/container/TracesExplorer/Controls/styles.ts
new file mode 100644
index 0000000000..f91bc43363
--- /dev/null
+++ b/frontend/src/container/TracesExplorer/Controls/styles.ts
@@ -0,0 +1,8 @@
+import styled from 'styled-components';
+
+export const Container = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 0.5rem;
+`;
diff --git a/frontend/src/container/TracesExplorer/QuerySection/index.tsx b/frontend/src/container/TracesExplorer/QuerySection/index.tsx
new file mode 100644
index 0000000000..169fa7ba79
--- /dev/null
+++ b/frontend/src/container/TracesExplorer/QuerySection/index.tsx
@@ -0,0 +1,32 @@
+import { Button } from 'antd';
+import { PANEL_TYPES } from 'constants/queryBuilder';
+import { QueryBuilder } from 'container/QueryBuilder';
+import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
+import { DataSource } from 'types/common/queryBuilder';
+
+import { ButtonWrapper, Container } from './styles';
+
+function QuerySection(): JSX.Element {
+ const { handleRunQuery } = useQueryBuilder();
+
+ return (
+
+
+
+
+ }
+ />
+
+ );
+}
+
+export default QuerySection;
diff --git a/frontend/src/container/TracesExplorer/QuerySection/styles.ts b/frontend/src/container/TracesExplorer/QuerySection/styles.ts
new file mode 100644
index 0000000000..cdb46bd580
--- /dev/null
+++ b/frontend/src/container/TracesExplorer/QuerySection/styles.ts
@@ -0,0 +1,16 @@
+import { Col } from 'antd';
+import Card from 'antd/es/card/Card';
+import styled from 'styled-components';
+
+export const Container = styled(Card)`
+ border: none;
+ background: inherit;
+
+ .ant-card-body {
+ padding: 0;
+ }
+`;
+
+export const ButtonWrapper = styled(Col)`
+ margin-left: auto;
+`;
diff --git a/frontend/src/container/TracesExplorer/TimeSeriesView/index.tsx b/frontend/src/container/TracesExplorer/TimeSeriesView/index.tsx
new file mode 100644
index 0000000000..ee531d7f40
--- /dev/null
+++ b/frontend/src/container/TracesExplorer/TimeSeriesView/index.tsx
@@ -0,0 +1,73 @@
+import Graph from 'components/Graph';
+import Spinner from 'components/Spinner';
+import { initialQueriesMap } from 'constants/queryBuilder';
+import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
+import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
+import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
+import getChartData from 'lib/getChartData';
+import { useMemo } from 'react';
+import { useSelector } from 'react-redux';
+import { AppState } from 'store/reducers';
+import { GlobalReducer } from 'types/reducer/globalTime';
+
+import { Container, ErrorText } from './styles';
+
+function TimeSeriesView(): JSX.Element {
+ const { stagedQuery } = useQueryBuilder();
+
+ const { selectedTime: globalSelectedTime, maxTime, minTime } = useSelector<
+ AppState,
+ GlobalReducer
+ >((state) => state.globalTime);
+
+ const { data, isLoading, isError } = useGetQueryRange(
+ {
+ query: stagedQuery || initialQueriesMap.traces,
+ graphType: 'graph',
+ selectedTime: 'GLOBAL_TIME',
+ globalSelectedInterval: globalSelectedTime,
+ params: {
+ dataSource: 'traces',
+ },
+ },
+ {
+ queryKey: [
+ REACT_QUERY_KEY.GET_QUERY_RANGE,
+ globalSelectedTime,
+ stagedQuery,
+ maxTime,
+ minTime,
+ ],
+ enabled: !!stagedQuery,
+ },
+ );
+
+ const chartData = useMemo(
+ () =>
+ getChartData({
+ queryData: [
+ {
+ queryData: data?.payload?.data?.result || [],
+ },
+ ],
+ }),
+ [data],
+ );
+
+ return (
+
+ {isLoading && }
+ {isError && {data?.error || 'Something went wrong'}}
+ {!isLoading && !isError && (
+
+ )}
+
+ );
+}
+
+export default TimeSeriesView;
diff --git a/frontend/src/container/TracesExplorer/TimeSeriesView/styles.ts b/frontend/src/container/TracesExplorer/TimeSeriesView/styles.ts
new file mode 100644
index 0000000000..9f002e047f
--- /dev/null
+++ b/frontend/src/container/TracesExplorer/TimeSeriesView/styles.ts
@@ -0,0 +1,17 @@
+import { Typography } from 'antd';
+import Card from 'antd/es/card/Card';
+import styled from 'styled-components';
+
+export const Container = styled(Card)`
+ position: relative;
+ margin: 0.5rem 0 3.1rem 0;
+
+ .ant-card-body {
+ height: 50vh;
+ min-height: 350px;
+ }
+`;
+
+export const ErrorText = styled(Typography)`
+ text-align: center;
+`;
diff --git a/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts b/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts
index 05707b5fa1..e9f4f1c6e1 100644
--- a/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts
+++ b/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts
@@ -1,5 +1,4 @@
-import GetMinMax from 'lib/getMinMax';
-import GetStartAndEndTime from 'lib/getStartAndEndTime';
+import getStartEndRangeTime from 'lib/getStartEndRangeTime';
import store from 'store';
export const getDashboardVariables = (): Record => {
@@ -13,16 +12,11 @@ export const getDashboardVariables = (): Record => {
data: { variables = {} },
} = selectedDashboard;
- const minMax = GetMinMax(globalTime.selectedTime, [
- globalTime.minTime / 1000000,
- globalTime.maxTime / 1000000,
- ]);
-
- const { start, end } = GetStartAndEndTime({
+ const { start, end } = getStartEndRangeTime({
type: 'GLOBAL_TIME',
- minTime: minMax.minTime,
- maxTime: minMax.maxTime,
+ interval: globalTime.selectedTime,
});
+
const variablesTuple: Record = {
SIGNOZ_START_TIME: parseInt(start, 10) * 1e3,
SIGNOZ_END_TIME: parseInt(end, 10) * 1e3,
diff --git a/frontend/src/lib/getStartEndRangeTime.ts b/frontend/src/lib/getStartEndRangeTime.ts
new file mode 100644
index 0000000000..486b6d0784
--- /dev/null
+++ b/frontend/src/lib/getStartEndRangeTime.ts
@@ -0,0 +1,48 @@
+import { ITEMS } from 'container/NewDashboard/ComponentsSlider/menuItems';
+import { timePreferenceType } from 'container/NewWidget/RightContainer/timeItems';
+import { Time } from 'container/TopNav/DateTimeSelection/config';
+import store from 'store';
+
+import getMaxMinTime from './getMaxMinTime';
+import getMinMax from './getMinMax';
+import getStartAndEndTime from './getStartAndEndTime';
+
+const getStartEndRangeTime = ({
+ type = 'GLOBAL_TIME',
+ graphType = null,
+ interval = 'custom',
+}: GetStartEndRangeTimesProps): GetStartEndRangeTimesPayload => {
+ const { globalTime } = store.getState();
+
+ const minMax = getMinMax(interval, [
+ globalTime.minTime / 1000000,
+ globalTime.maxTime / 1000000,
+ ]);
+
+ const maxMinTime = getMaxMinTime({
+ graphType,
+ maxTime: minMax.maxTime,
+ minTime: minMax.minTime,
+ });
+
+ const { end, start } = getStartAndEndTime({
+ type,
+ maxTime: maxMinTime.maxTime,
+ minTime: maxMinTime.minTime,
+ });
+
+ return { start, end };
+};
+
+interface GetStartEndRangeTimesProps {
+ type?: timePreferenceType;
+ graphType?: ITEMS | null;
+ interval?: Time;
+}
+
+interface GetStartEndRangeTimesPayload {
+ start: string;
+ end: string;
+}
+
+export default getStartEndRangeTime;
diff --git a/frontend/src/pages/TracesExplorer/constants.ts b/frontend/src/pages/TracesExplorer/constants.ts
new file mode 100644
index 0000000000..ceea4e582e
--- /dev/null
+++ b/frontend/src/pages/TracesExplorer/constants.ts
@@ -0,0 +1,6 @@
+export const CURRENT_TRACES_EXPLORER_TAB = 'currentTab';
+
+export enum TracesExplorerTabs {
+ TIME_SERIES = 'times-series',
+ TRACES = 'traces',
+}
diff --git a/frontend/src/pages/TracesExplorer/index.tsx b/frontend/src/pages/TracesExplorer/index.tsx
new file mode 100644
index 0000000000..57c2310d78
--- /dev/null
+++ b/frontend/src/pages/TracesExplorer/index.tsx
@@ -0,0 +1,59 @@
+import { Tabs } from 'antd';
+import { initialQueriesMap } from 'constants/queryBuilder';
+import QuerySection from 'container/TracesExplorer/QuerySection';
+import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
+import useUrlQuery from 'hooks/useUrlQuery';
+import { useCallback, useEffect } from 'react';
+import { useHistory, useLocation } from 'react-router-dom';
+
+import { CURRENT_TRACES_EXPLORER_TAB, TracesExplorerTabs } from './constants';
+import { Container } from './styles';
+import { getTabsItems } from './utils';
+
+function TracesExplorer(): JSX.Element {
+ const urlQuery = useUrlQuery();
+ const history = useHistory();
+ const location = useLocation();
+
+ const currentUrlTab = urlQuery.get(
+ CURRENT_TRACES_EXPLORER_TAB,
+ ) as TracesExplorerTabs;
+ const currentTab = currentUrlTab || TracesExplorerTabs.TIME_SERIES;
+ const tabsItems = getTabsItems();
+
+ const redirectWithCurrentTab = useCallback(
+ (tabKey: string): void => {
+ urlQuery.set(CURRENT_TRACES_EXPLORER_TAB, tabKey);
+ const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
+ history.push(generatedUrl);
+ },
+ [history, location, urlQuery],
+ );
+
+ const handleTabChange = useCallback(
+ (tabKey: string): void => {
+ redirectWithCurrentTab(tabKey);
+ },
+ [redirectWithCurrentTab],
+ );
+
+ useShareBuilderUrl({ defaultValue: initialQueriesMap.traces });
+
+ useEffect(() => {
+ if (currentUrlTab) return;
+
+ redirectWithCurrentTab(TracesExplorerTabs.TIME_SERIES);
+ }, [currentUrlTab, redirectWithCurrentTab]);
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
+
+export default TracesExplorer;
diff --git a/frontend/src/pages/TracesExplorer/styles.ts b/frontend/src/pages/TracesExplorer/styles.ts
new file mode 100644
index 0000000000..6da55b8d4d
--- /dev/null
+++ b/frontend/src/pages/TracesExplorer/styles.ts
@@ -0,0 +1,5 @@
+import styled from 'styled-components';
+
+export const Container = styled.div`
+ margin: 1rem 0;
+`;
diff --git a/frontend/src/pages/TracesExplorer/utils.tsx b/frontend/src/pages/TracesExplorer/utils.tsx
new file mode 100644
index 0000000000..aff29bba58
--- /dev/null
+++ b/frontend/src/pages/TracesExplorer/utils.tsx
@@ -0,0 +1,17 @@
+import { TabsProps } from 'antd';
+import TimeSeriesView from 'container/TracesExplorer/TimeSeriesView';
+
+import { TracesExplorerTabs } from './constants';
+
+export const getTabsItems = (): TabsProps['items'] => [
+ {
+ label: 'Time Series',
+ key: TracesExplorerTabs.TIME_SERIES,
+ children: ,
+ },
+ {
+ label: 'Traces',
+ key: TracesExplorerTabs.TRACES,
+ children: Traces tab
,
+ },
+];
diff --git a/frontend/src/store/actions/dashboard/getQueryResults.ts b/frontend/src/store/actions/dashboard/getQueryResults.ts
index fff445e463..c139c232c3 100644
--- a/frontend/src/store/actions/dashboard/getQueryResults.ts
+++ b/frontend/src/store/actions/dashboard/getQueryResults.ts
@@ -5,19 +5,16 @@
import { getMetricsQueryRange } from 'api/metrics/getQueryRange';
import { timePreferenceType } from 'container/NewWidget/RightContainer/timeItems';
import { Time } from 'container/TopNav/DateTimeSelection/config';
-import GetMaxMinTime from 'lib/getMaxMinTime';
-import GetMinMax from 'lib/getMinMax';
-import GetStartAndEndTime from 'lib/getStartAndEndTime';
import getStep from 'lib/getStep';
import { mapQueryDataToApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataToApi';
import { isEmpty } from 'lodash-es';
-import store from 'store';
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
import { SuccessResponse } from 'types/api';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import { EQueryType } from 'types/common/dashboard';
import { convertNewDataToOld } from 'lib/newQueryBuilder/convertNewDataToOld';
+import getStartEndRangeTime from 'lib/getStartEndRangeTime';
export async function GetMetricQueryRange({
query,
@@ -25,6 +22,7 @@ export async function GetMetricQueryRange({
graphType,
selectedTime,
variables = {},
+ params = {},
}: GetQueryResultsProps): Promise> {
const queryData = query[query.queryType];
let legendMap: Record = {};
@@ -83,30 +81,18 @@ export async function GetMetricQueryRange({
return;
}
- const { globalTime } = store.getState();
-
- const minMax = GetMinMax(globalSelectedInterval, [
- globalTime.minTime / 1000000,
- globalTime.maxTime / 1000000,
- ]);
-
- const getMaxMinTime = GetMaxMinTime({
- graphType: null,
- maxTime: minMax.maxTime,
- minTime: minMax.minTime,
- });
-
- const { end, start } = GetStartAndEndTime({
+ const { start, end } = getStartEndRangeTime({
type: selectedTime,
- maxTime: getMaxMinTime.maxTime,
- minTime: getMaxMinTime.minTime,
+ interval: globalSelectedInterval,
});
+
const response = await getMetricsQueryRange({
start: parseInt(start, 10) * 1e3,
end: parseInt(end, 10) * 1e3,
step: getStep({ start, end, inputFormat: 'ms' }),
variables,
...QueryPayload,
+ ...params,
});
if (response.statusCode >= 400) {
throw new Error(
@@ -148,4 +134,5 @@ export interface GetQueryResultsProps {
selectedTime: timePreferenceType;
globalSelectedInterval: Time;
variables?: Record;
+ params?: Record;
}
diff --git a/frontend/src/utils/permission/index.ts b/frontend/src/utils/permission/index.ts
index 9134bae30f..452d495fec 100644
--- a/frontend/src/utils/permission/index.ts
+++ b/frontend/src/utils/permission/index.ts
@@ -63,6 +63,7 @@ export const routePermission: Record = {
SETTINGS: ['ADMIN', 'EDITOR', 'VIEWER'],
SIGN_UP: ['ADMIN', 'EDITOR', 'VIEWER'],
SOMETHING_WENT_WRONG: ['ADMIN', 'EDITOR', 'VIEWER'],
+ TRACES_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'],
TRACE: ['ADMIN', 'EDITOR', 'VIEWER'],
TRACE_DETAIL: ['ADMIN', 'EDITOR', 'VIEWER'],
UN_AUTHORIZED: ['ADMIN', 'EDITOR', 'VIEWER'],
@@ -71,5 +72,4 @@ export const routePermission: Record = {
LOGS: ['ADMIN', 'EDITOR', 'VIEWER'],
LOGS_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'],
LIST_LICENSES: ['ADMIN'],
- TRACE_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'],
};