diff --git a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml index db2f162718..8220c0905b 100644 --- a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml @@ -137,7 +137,7 @@ services: condition: on-failure query-service: - image: signoz/query-service:0.25.1 + image: signoz/query-service:0.25.2 command: ["-config=/root/config/prometheus.yml"] # ports: # - "6060:6060" # pprof port @@ -166,7 +166,7 @@ services: <<: *clickhouse-depend frontend: - image: signoz/frontend:0.25.1 + image: signoz/frontend:0.25.2 deploy: restart_policy: condition: on-failure diff --git a/deploy/docker/clickhouse-setup/docker-compose.yaml b/deploy/docker/clickhouse-setup/docker-compose.yaml index 1c5839f232..55fd8844a2 100644 --- a/deploy/docker/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker/clickhouse-setup/docker-compose.yaml @@ -153,7 +153,7 @@ services: # Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md` query-service: - image: signoz/query-service:${DOCKER_TAG:-0.25.1} + image: signoz/query-service:${DOCKER_TAG:-0.25.2} container_name: query-service command: ["-config=/root/config/prometheus.yml"] # ports: @@ -181,7 +181,7 @@ services: <<: *clickhouse-depend frontend: - image: signoz/frontend:${DOCKER_TAG:-0.25.1} + image: signoz/frontend:${DOCKER_TAG:-0.25.2} container_name: frontend restart: on-failure depends_on: diff --git a/frontend/public/locales/en-GB/routes.json b/frontend/public/locales/en-GB/routes.json index ac17990f3b..5dd331eaf7 100644 --- a/frontend/public/locales/en-GB/routes.json +++ b/frontend/public/locales/en-GB/routes.json @@ -6,6 +6,7 @@ "overview_metrics": "Overview Metrics", "dbcall_metrics": "Database Calls", "external_metrics": "External Calls", + "pipeline": "Pipeline", "pipelines": "Pipelines", "archives": "Archives", "logs_to_metrics": "Logs To Metrics" diff --git a/frontend/public/locales/en-GB/translation.json b/frontend/public/locales/en-GB/translation.json index 33442c8369..c1bd296cc7 100644 --- a/frontend/public/locales/en-GB/translation.json +++ b/frontend/public/locales/en-GB/translation.json @@ -13,6 +13,7 @@ "general": "General", "alert_channels": "Alert Channels", "all_errors": "All Exceptions", + "index_fields": "Index Fields", "pipelines": "Pipelines" } } diff --git a/frontend/public/locales/en/routes.json b/frontend/public/locales/en/routes.json index ac17990f3b..5dd331eaf7 100644 --- a/frontend/public/locales/en/routes.json +++ b/frontend/public/locales/en/routes.json @@ -6,6 +6,7 @@ "overview_metrics": "Overview Metrics", "dbcall_metrics": "Database Calls", "external_metrics": "External Calls", + "pipeline": "Pipeline", "pipelines": "Pipelines", "archives": "Archives", "logs_to_metrics": "Logs To Metrics" diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json index 39e7a79fda..08b795db97 100644 --- a/frontend/public/locales/en/translation.json +++ b/frontend/public/locales/en/translation.json @@ -13,6 +13,7 @@ "general": "General", "alert_channels": "Alert Channels", "all_errors": "All Exceptions", + "index_fields": "Index Fields", "pipelines": "Pipelines" } } diff --git a/frontend/src/AppRoutes/pageComponents.ts b/frontend/src/AppRoutes/pageComponents.ts index b993a4790a..ba9e4eb617 100644 --- a/frontend/src/AppRoutes/pageComponents.ts +++ b/frontend/src/AppRoutes/pageComponents.ts @@ -133,6 +133,11 @@ export const LicensePage = Loadable( () => import(/* webpackChunkName: "All Channels" */ 'pages/License'), ); +export const LogsIndexToFields = Loadable( + () => + import(/* webpackChunkName: "LogsIndexToFields Page" */ 'pages/LogsSettings'), +); + export const PipelinePage = Loadable( () => import(/* webpackChunkName: "Pipelines" */ 'pages/Pipelines'), ); diff --git a/frontend/src/AppRoutes/routes.ts b/frontend/src/AppRoutes/routes.ts index ef7bd5d302..ecf74b5253 100644 --- a/frontend/src/AppRoutes/routes.ts +++ b/frontend/src/AppRoutes/routes.ts @@ -17,6 +17,7 @@ import { Login, Logs, LogsExplorer, + LogsIndexToFields, MySettings, NewDashboardPage, OrganizationSettings, @@ -44,6 +45,13 @@ const routes: AppRoutes[] = [ isPrivate: false, key: 'SIGN_UP', }, + { + component: LogsIndexToFields, + path: ROUTES.LOGS_INDEX_FIELDS, + exact: true, + isPrivate: true, + key: 'LOGS_INDEX_FIELDS', + }, { component: ServicesTablePage, path: ROUTES.APPLICATION, diff --git a/frontend/src/components/RouteTab/RouteTab.test.tsx b/frontend/src/components/RouteTab/RouteTab.test.tsx index 21894cb006..af20927e2a 100644 --- a/frontend/src/components/RouteTab/RouteTab.test.tsx +++ b/frontend/src/components/RouteTab/RouteTab.test.tsx @@ -3,6 +3,7 @@ import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; import RouteTab from './index'; +import { RouteTabProps } from './types'; function DummyComponent1(): JSX.Element { return
Dummy Component 1
; @@ -11,16 +12,18 @@ function DummyComponent2(): JSX.Element { return
Dummy Component 2
; } -const testRoutes = [ +const testRoutes: RouteTabProps['routes'] = [ { name: 'Tab1', route: '/tab1', Component: DummyComponent1, + key: 'Tab1', }, { name: 'Tab2', route: '/tab2', Component: DummyComponent2, + key: 'Tab2', }, ]; diff --git a/frontend/src/components/RouteTab/index.tsx b/frontend/src/components/RouteTab/index.tsx index 4e4a9fe72e..c76e3e2f99 100644 --- a/frontend/src/components/RouteTab/index.tsx +++ b/frontend/src/components/RouteTab/index.tsx @@ -1,5 +1,6 @@ import { Tabs, TabsProps } from 'antd'; -import { History } from 'history'; + +import { RouteTabProps } from './types'; function RouteTab({ routes, @@ -13,16 +14,16 @@ function RouteTab({ onChangeHandler(); } - const selectedRoute = routes.find((e) => e.name === activeRoute); + const selectedRoute = routes.find((e) => e.key === activeRoute); if (selectedRoute) { history.push(selectedRoute.route); } }; - const items = routes.map(({ Component, name, route }) => ({ + const items = routes.map(({ Component, name, route, key }) => ({ label: name, - key: name, + key, tabKey: route, children: , })); @@ -32,6 +33,7 @@ function RouteTab({ onChange={onChange} destroyInactiveTabPane activeKey={activeKey} + defaultActiveKey={activeKey} animated items={items} // eslint-disable-next-line react/jsx-props-no-spreading @@ -40,17 +42,6 @@ function RouteTab({ ); } -interface RouteTabProps { - routes: { - name: string; - route: string; - Component: () => JSX.Element; - }[]; - activeKey: TabsProps['activeKey']; - onChangeHandler?: VoidFunction; - history: History; -} - RouteTab.defaultProps = { onChangeHandler: undefined, }; diff --git a/frontend/src/components/RouteTab/types.ts b/frontend/src/components/RouteTab/types.ts new file mode 100644 index 0000000000..b8cb5eb722 --- /dev/null +++ b/frontend/src/components/RouteTab/types.ts @@ -0,0 +1,14 @@ +import { TabsProps } from 'antd'; +import { History } from 'history'; + +export interface RouteTabProps { + routes: { + name: React.ReactNode; + route: string; + Component: () => JSX.Element; + key: string; + }[]; + activeKey: TabsProps['activeKey']; + onChangeHandler?: VoidFunction; + history: History; +} diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index 468c6042bb..65b9fd6477 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -32,6 +32,8 @@ const ROUTES = { HOME_PAGE: '/', PASSWORD_RESET: '/password-reset', LIST_LICENSES: '/licenses', + LOGS_INDEX_FIELDS: '/logs-explorer/index-fields', + LOGS_PIPELINE: '/logs-explorer/pipeline', TRACE_EXPLORER: '/trace-explorer', PIPELINES: '/pipelines', }; diff --git a/frontend/src/container/GridGraphLayout/Graph/index.tsx b/frontend/src/container/GridGraphLayout/Graph/index.tsx index 839710584f..f3675c2da8 100644 --- a/frontend/src/container/GridGraphLayout/Graph/index.tsx +++ b/frontend/src/container/GridGraphLayout/Graph/index.tsx @@ -173,6 +173,7 @@ function GridCardGraph({ allowClone={allowClone} allowDelete={allowDelete} allowEdit={allowEdit} + onClickHandler={onClickHandler} /> )} diff --git a/frontend/src/container/LogsIndexToFields/index.tsx b/frontend/src/container/LogsIndexToFields/index.tsx new file mode 100644 index 0000000000..cb12498ff4 --- /dev/null +++ b/frontend/src/container/LogsIndexToFields/index.tsx @@ -0,0 +1,7 @@ +import { Typography } from 'antd'; + +function LogsIndexToFields(): JSX.Element { + return LogsIndexToFields; +} + +export default LogsIndexToFields; diff --git a/frontend/src/pages/AlertChannelCreate/config.tsx b/frontend/src/pages/AlertChannelCreate/config.tsx new file mode 100644 index 0000000000..fad322c119 --- /dev/null +++ b/frontend/src/pages/AlertChannelCreate/config.tsx @@ -0,0 +1,19 @@ +import ROUTES from 'constants/routes'; +import CreateAlertChannels from 'container/CreateAlertChannels'; +import GeneralSettings from 'container/GeneralSettings'; +import { t } from 'i18next'; + +export const alertsRoutesConfig = [ + { + Component: GeneralSettings, + name: t('routes.general'), + route: ROUTES.SETTINGS, + key: ROUTES.SETTINGS, + }, + { + Component: (): JSX.Element => , + name: t('routes.alert_channels'), + route: ROUTES.ALL_CHANNELS, + key: ROUTES.ALL_CHANNELS, + }, +]; diff --git a/frontend/src/pages/AlertChannelCreate/index.tsx b/frontend/src/pages/AlertChannelCreate/index.tsx index 3ed6348969..deb036b8d2 100644 --- a/frontend/src/pages/AlertChannelCreate/index.tsx +++ b/frontend/src/pages/AlertChannelCreate/index.tsx @@ -1,35 +1,17 @@ -/* eslint-disable react/no-unstable-nested-components */ import RouteTab from 'components/RouteTab'; -import ROUTES from 'constants/routes'; -import CreateAlertChannels from 'container/CreateAlertChannels'; -import GeneralSettings from 'container/GeneralSettings'; import history from 'lib/history'; -import { useTranslation } from 'react-i18next'; +import { useLocation } from 'react-router-dom'; + +import { alertsRoutesConfig } from './config'; function SettingsPage(): JSX.Element { - const pathName = history.location.pathname; - const { t } = useTranslation(); + const { pathname } = useLocation(); + return ( , - name: t('routes.alert_channels'), - route: ROUTES.ALL_CHANNELS, - }, - ], - activeKey: - pathName === ROUTES.SETTINGS - ? t('routes.general') - : t('routes.alert_channels'), - }} + routes={alertsRoutesConfig} + activeKey={pathname} /> ); } diff --git a/frontend/src/pages/AllErrors/config.ts b/frontend/src/pages/AllErrors/config.ts new file mode 100644 index 0000000000..ebb8a592cf --- /dev/null +++ b/frontend/src/pages/AllErrors/config.ts @@ -0,0 +1,12 @@ +import ROUTES from 'constants/routes'; +import AllErrorsContainer from 'container/AllError'; +import { t } from 'i18next'; + +export const routes = [ + { + Component: AllErrorsContainer, + name: t('routes.all_errors'), + route: ROUTES.ALL_ERROR, + key: ROUTES.ALL_ERROR, + }, +]; diff --git a/frontend/src/pages/AllErrors/index.tsx b/frontend/src/pages/AllErrors/index.tsx index b63a256fd6..44f0d3bcdd 100644 --- a/frontend/src/pages/AllErrors/index.tsx +++ b/frontend/src/pages/AllErrors/index.tsx @@ -1,33 +1,17 @@ import RouteTab from 'components/RouteTab'; -import ROUTES from 'constants/routes'; -import AllErrorsContainer from 'container/AllError'; import ResourceAttributesFilter from 'container/ResourceAttributesFilter'; import history from 'lib/history'; -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; +import { useLocation } from 'react-router-dom'; + +import { routes } from './config'; function AllErrors(): JSX.Element { - const { t } = useTranslation(); - - const routes = useMemo( - () => [ - { - Component: AllErrorsContainer, - name: t('routes.all_errors'), - route: ROUTES.ALL_ERROR, - }, - ], - [t], - ); + const { pathname } = useLocation(); return ( <> - + ); } diff --git a/frontend/src/pages/LogsSettings/components/TabLabel.tsx b/frontend/src/pages/LogsSettings/components/TabLabel.tsx new file mode 100644 index 0000000000..cb97869ad6 --- /dev/null +++ b/frontend/src/pages/LogsSettings/components/TabLabel.tsx @@ -0,0 +1,14 @@ +import { Typography } from 'antd'; +import { useLocation } from 'react-router-dom'; + +import { TableLabel } from '../types'; + +function TabLabel({ routeKey, label }: TableLabel): JSX.Element { + const { pathname } = useLocation(); + + if (pathname === routeKey) return {label}; + + return {label}; +} + +export default TabLabel; diff --git a/frontend/src/pages/LogsSettings/config.tsx b/frontend/src/pages/LogsSettings/config.tsx new file mode 100644 index 0000000000..95c8431dc9 --- /dev/null +++ b/frontend/src/pages/LogsSettings/config.tsx @@ -0,0 +1,21 @@ +import { RouteTabProps } from 'components/RouteTab/types'; +import ROUTES from 'constants/routes'; +import LogsIndexToFields from 'container/LogsIndexToFields'; +import { TFunction } from 'react-i18next'; + +import TabLabel from './components/TabLabel'; +import { TABS_KEY, TABS_TITLE } from './constant'; + +export const getLogsSettingsRoute = (t: TFunction): RouteTabProps['routes'] => [ + { + Component: LogsIndexToFields, + name: ( + + ), + route: ROUTES.LOGS_INDEX_FIELDS, + key: ROUTES.LOGS_INDEX_FIELDS, + }, +]; diff --git a/frontend/src/pages/LogsSettings/constant.ts b/frontend/src/pages/LogsSettings/constant.ts new file mode 100644 index 0000000000..a7272f19a0 --- /dev/null +++ b/frontend/src/pages/LogsSettings/constant.ts @@ -0,0 +1,11 @@ +import { TFunction } from 'i18next'; + +export const TABS_KEY = { + LOGS_INDEX_FIELDS: 'LOGS_INDEX_FIELDS', + LOGS_PIPELINE: 'LOGS_PIPELINE', +}; + +export const TABS_TITLE = (t: TFunction): Record => ({ + [TABS_KEY.LOGS_INDEX_FIELDS]: t('routes.index_fields'), + [TABS_KEY.LOGS_PIPELINE]: t('routes.pipeline'), +}); diff --git a/frontend/src/pages/LogsSettings/index.tsx b/frontend/src/pages/LogsSettings/index.tsx new file mode 100644 index 0000000000..3b91118d35 --- /dev/null +++ b/frontend/src/pages/LogsSettings/index.tsx @@ -0,0 +1,18 @@ +import RouteTab from 'components/RouteTab'; +import history from 'lib/history'; +import { useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useLocation } from 'react-router-dom'; + +import { getLogsSettingsRoute } from './config'; + +function LogsSettings(): JSX.Element { + const { pathname } = useLocation(); + const { t } = useTranslation(); + + const routes = useMemo(() => getLogsSettingsRoute(t), [t]); + + return ; +} + +export default LogsSettings; diff --git a/frontend/src/pages/LogsSettings/types.ts b/frontend/src/pages/LogsSettings/types.ts new file mode 100644 index 0000000000..1618781993 --- /dev/null +++ b/frontend/src/pages/LogsSettings/types.ts @@ -0,0 +1 @@ +export type TableLabel = { routeKey: string; label: string }; diff --git a/frontend/src/pages/MetricsApplication/index.tsx b/frontend/src/pages/MetricsApplication/index.tsx index 230fbe9c8f..afd5fc4881 100644 --- a/frontend/src/pages/MetricsApplication/index.tsx +++ b/frontend/src/pages/MetricsApplication/index.tsx @@ -24,6 +24,7 @@ function MetricsApplication(): JSX.Element { route: `${generatePath(ROUTES.SERVICE_METRICS, { servicename, })}?tab=${MetricsApplicationTab.OVER_METRICS}`, + key: MetricsApplicationTab.OVER_METRICS, }, { Component: DBCall, @@ -31,6 +32,7 @@ function MetricsApplication(): JSX.Element { route: `${generatePath(ROUTES.SERVICE_METRICS, { servicename, })}?tab=${MetricsApplicationTab.DB_CALL_METRICS}`, + key: MetricsApplicationTab.DB_CALL_METRICS, }, { Component: External, @@ -38,6 +40,7 @@ function MetricsApplication(): JSX.Element { route: `${generatePath(ROUTES.SERVICE_METRICS, { servicename, })}?tab=${MetricsApplicationTab.EXTERNAL_METRICS}`, + key: MetricsApplicationTab.EXTERNAL_METRICS, }, ], [servicename], diff --git a/frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx b/frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx index ff2131f727..222135a898 100644 --- a/frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx +++ b/frontend/src/pages/MetricsApplication/useMetricsApplicationTabKey.tsx @@ -1,6 +1,5 @@ import useUrlQuery from 'hooks/useUrlQuery'; -import { TAB_KEY_VS_LABEL } from './types'; import { getMetricsApplicationKey } from './utils'; const useMetricsApplicationTabKey = (): string => { @@ -8,7 +7,7 @@ const useMetricsApplicationTabKey = (): string => { const tab = urlParams.get('tab'); - return TAB_KEY_VS_LABEL[getMetricsApplicationKey(tab)]; + return getMetricsApplicationKey(tab); }; export default useMetricsApplicationTabKey; diff --git a/frontend/src/pages/Settings/config.ts b/frontend/src/pages/Settings/config.ts new file mode 100644 index 0000000000..ceb06b7bb5 --- /dev/null +++ b/frontend/src/pages/Settings/config.ts @@ -0,0 +1,30 @@ +import { RouteTabProps } from 'components/RouteTab/types'; +import ROUTES from 'constants/routes'; +import AlertChannels from 'container/AllAlertChannels'; +import GeneralSettings from 'container/GeneralSettings'; +import OrganizationSettings from 'container/OrganizationSettings'; +import { TFunction } from 'i18next'; + +export const commonRoutes = (t: TFunction): RouteTabProps['routes'] => [ + { + Component: GeneralSettings, + name: t('routes:general').toString(), + route: ROUTES.SETTINGS, + key: ROUTES.SETTINGS, + }, + { + Component: AlertChannels, + name: t('routes:alert_channels').toString(), + route: ROUTES.ALL_CHANNELS, + key: ROUTES.ALL_CHANNELS, + }, +]; + +export const organizationSettings = (t: TFunction): RouteTabProps['routes'] => [ + { + Component: OrganizationSettings, + name: t('routes:organization_settings').toString(), + route: ROUTES.ORG_SETTINGS, + key: ROUTES.ORG_SETTINGS, + }, +]; diff --git a/frontend/src/pages/Settings/index.tsx b/frontend/src/pages/Settings/index.tsx index 9e1be1f4f0..6e98edf774 100644 --- a/frontend/src/pages/Settings/index.tsx +++ b/frontend/src/pages/Settings/index.tsx @@ -1,62 +1,30 @@ import RouteTab from 'components/RouteTab'; -import ROUTES from 'constants/routes'; -import AlertChannels from 'container/AllAlertChannels'; -import GeneralSettings from 'container/GeneralSettings'; -import OrganizationSettings from 'container/OrganizationSettings'; import useComponentPermission from 'hooks/useComponentPermission'; import history from 'lib/history'; +import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; +import { useLocation } from 'react-router-dom'; import { AppState } from 'store/reducers'; import AppReducer from 'types/reducer/app'; +import { getRoutes } from './utils'; + function SettingsPage(): JSX.Element { - const pathName = history.location.pathname; - const { t } = useTranslation(['routes']); + const { pathname } = useLocation(); const { role } = useSelector((state) => state.app); - const [currentOrgSettings] = useComponentPermission( + const [isCurrentOrgSettings] = useComponentPermission( ['current_org_settings'], role, ); + const { t } = useTranslation(['routes']); - const getActiveKey = (pathname: string): string => { - if (pathname === ROUTES.SETTINGS) { - return t('general'); - } - if (pathname === ROUTES.ORG_SETTINGS && currentOrgSettings) { - return t('organization_settings'); - } - return t('alert_channels'); - }; + const routes = useMemo(() => getRoutes(isCurrentOrgSettings, t), [ + isCurrentOrgSettings, + t, + ]); - const common = [ - { - Component: GeneralSettings, - name: t('general'), - route: ROUTES.SETTINGS, - }, - { - Component: AlertChannels, - name: t('alert_channels'), - route: ROUTES.ALL_CHANNELS, - }, - ]; - - if (currentOrgSettings) { - common.push({ - Component: OrganizationSettings, - name: t('organization_settings'), - route: ROUTES.ORG_SETTINGS, - }); - } - - return ( - - ); + return ; } export default SettingsPage; diff --git a/frontend/src/pages/Settings/utils.ts b/frontend/src/pages/Settings/utils.ts new file mode 100644 index 0000000000..8c965b0040 --- /dev/null +++ b/frontend/src/pages/Settings/utils.ts @@ -0,0 +1,17 @@ +import { RouteTabProps } from 'components/RouteTab/types'; +import { TFunction } from 'i18next'; + +import { commonRoutes, organizationSettings } from './config'; + +export const getRoutes = ( + isCurrentOrgSettings: boolean, + t: TFunction, +): RouteTabProps['routes'] => { + let common = commonRoutes(t); + + if (isCurrentOrgSettings) { + common = [...common, ...organizationSettings(t)]; + } + + return common; +}; diff --git a/frontend/src/utils/permission/index.ts b/frontend/src/utils/permission/index.ts index db2a7eb049..7beb10c385 100644 --- a/frontend/src/utils/permission/index.ts +++ b/frontend/src/utils/permission/index.ts @@ -74,6 +74,8 @@ export const routePermission: Record = { LOGS: ['ADMIN', 'EDITOR', 'VIEWER'], LOGS_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'], LIST_LICENSES: ['ADMIN'], + LOGS_INDEX_FIELDS: ['ADMIN', 'EDITOR', 'VIEWER'], + LOGS_PIPELINE: ['ADMIN', 'EDITOR', 'VIEWER'], TRACE_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'], PIPELINES: ['ADMIN', 'EDITOR', 'VIEWER'], };