Merge pull request #3263 from SigNoz/release/v0.25.2

Release/v0.25.2
This commit is contained in:
Ankit Nayan 2023-08-04 00:16:39 +05:30 committed by GitHub
commit ff392ba883
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 228 additions and 112 deletions

View File

@ -137,7 +137,7 @@ services:
condition: on-failure condition: on-failure
query-service: query-service:
image: signoz/query-service:0.25.1 image: signoz/query-service:0.25.2
command: ["-config=/root/config/prometheus.yml"] command: ["-config=/root/config/prometheus.yml"]
# ports: # ports:
# - "6060:6060" # pprof port # - "6060:6060" # pprof port
@ -166,7 +166,7 @@ services:
<<: *clickhouse-depend <<: *clickhouse-depend
frontend: frontend:
image: signoz/frontend:0.25.1 image: signoz/frontend:0.25.2
deploy: deploy:
restart_policy: restart_policy:
condition: on-failure condition: on-failure

View File

@ -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` # 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: query-service:
image: signoz/query-service:${DOCKER_TAG:-0.25.1} image: signoz/query-service:${DOCKER_TAG:-0.25.2}
container_name: query-service container_name: query-service
command: ["-config=/root/config/prometheus.yml"] command: ["-config=/root/config/prometheus.yml"]
# ports: # ports:
@ -181,7 +181,7 @@ services:
<<: *clickhouse-depend <<: *clickhouse-depend
frontend: frontend:
image: signoz/frontend:${DOCKER_TAG:-0.25.1} image: signoz/frontend:${DOCKER_TAG:-0.25.2}
container_name: frontend container_name: frontend
restart: on-failure restart: on-failure
depends_on: depends_on:

View File

@ -6,6 +6,7 @@
"overview_metrics": "Overview Metrics", "overview_metrics": "Overview Metrics",
"dbcall_metrics": "Database Calls", "dbcall_metrics": "Database Calls",
"external_metrics": "External Calls", "external_metrics": "External Calls",
"pipeline": "Pipeline",
"pipelines": "Pipelines", "pipelines": "Pipelines",
"archives": "Archives", "archives": "Archives",
"logs_to_metrics": "Logs To Metrics" "logs_to_metrics": "Logs To Metrics"

View File

@ -13,6 +13,7 @@
"general": "General", "general": "General",
"alert_channels": "Alert Channels", "alert_channels": "Alert Channels",
"all_errors": "All Exceptions", "all_errors": "All Exceptions",
"index_fields": "Index Fields",
"pipelines": "Pipelines" "pipelines": "Pipelines"
} }
} }

View File

@ -6,6 +6,7 @@
"overview_metrics": "Overview Metrics", "overview_metrics": "Overview Metrics",
"dbcall_metrics": "Database Calls", "dbcall_metrics": "Database Calls",
"external_metrics": "External Calls", "external_metrics": "External Calls",
"pipeline": "Pipeline",
"pipelines": "Pipelines", "pipelines": "Pipelines",
"archives": "Archives", "archives": "Archives",
"logs_to_metrics": "Logs To Metrics" "logs_to_metrics": "Logs To Metrics"

View File

@ -13,6 +13,7 @@
"general": "General", "general": "General",
"alert_channels": "Alert Channels", "alert_channels": "Alert Channels",
"all_errors": "All Exceptions", "all_errors": "All Exceptions",
"index_fields": "Index Fields",
"pipelines": "Pipelines" "pipelines": "Pipelines"
} }
} }

View File

@ -133,6 +133,11 @@ export const LicensePage = Loadable(
() => import(/* webpackChunkName: "All Channels" */ 'pages/License'), () => import(/* webpackChunkName: "All Channels" */ 'pages/License'),
); );
export const LogsIndexToFields = Loadable(
() =>
import(/* webpackChunkName: "LogsIndexToFields Page" */ 'pages/LogsSettings'),
);
export const PipelinePage = Loadable( export const PipelinePage = Loadable(
() => import(/* webpackChunkName: "Pipelines" */ 'pages/Pipelines'), () => import(/* webpackChunkName: "Pipelines" */ 'pages/Pipelines'),
); );

View File

@ -17,6 +17,7 @@ import {
Login, Login,
Logs, Logs,
LogsExplorer, LogsExplorer,
LogsIndexToFields,
MySettings, MySettings,
NewDashboardPage, NewDashboardPage,
OrganizationSettings, OrganizationSettings,
@ -44,6 +45,13 @@ const routes: AppRoutes[] = [
isPrivate: false, isPrivate: false,
key: 'SIGN_UP', key: 'SIGN_UP',
}, },
{
component: LogsIndexToFields,
path: ROUTES.LOGS_INDEX_FIELDS,
exact: true,
isPrivate: true,
key: 'LOGS_INDEX_FIELDS',
},
{ {
component: ServicesTablePage, component: ServicesTablePage,
path: ROUTES.APPLICATION, path: ROUTES.APPLICATION,

View File

@ -3,6 +3,7 @@ import { createMemoryHistory } from 'history';
import { Router } from 'react-router-dom'; import { Router } from 'react-router-dom';
import RouteTab from './index'; import RouteTab from './index';
import { RouteTabProps } from './types';
function DummyComponent1(): JSX.Element { function DummyComponent1(): JSX.Element {
return <div>Dummy Component 1</div>; return <div>Dummy Component 1</div>;
@ -11,16 +12,18 @@ function DummyComponent2(): JSX.Element {
return <div>Dummy Component 2</div>; return <div>Dummy Component 2</div>;
} }
const testRoutes = [ const testRoutes: RouteTabProps['routes'] = [
{ {
name: 'Tab1', name: 'Tab1',
route: '/tab1', route: '/tab1',
Component: DummyComponent1, Component: DummyComponent1,
key: 'Tab1',
}, },
{ {
name: 'Tab2', name: 'Tab2',
route: '/tab2', route: '/tab2',
Component: DummyComponent2, Component: DummyComponent2,
key: 'Tab2',
}, },
]; ];

View File

@ -1,5 +1,6 @@
import { Tabs, TabsProps } from 'antd'; import { Tabs, TabsProps } from 'antd';
import { History } from 'history';
import { RouteTabProps } from './types';
function RouteTab({ function RouteTab({
routes, routes,
@ -13,16 +14,16 @@ function RouteTab({
onChangeHandler(); onChangeHandler();
} }
const selectedRoute = routes.find((e) => e.name === activeRoute); const selectedRoute = routes.find((e) => e.key === activeRoute);
if (selectedRoute) { if (selectedRoute) {
history.push(selectedRoute.route); history.push(selectedRoute.route);
} }
}; };
const items = routes.map(({ Component, name, route }) => ({ const items = routes.map(({ Component, name, route, key }) => ({
label: name, label: name,
key: name, key,
tabKey: route, tabKey: route,
children: <Component />, children: <Component />,
})); }));
@ -32,6 +33,7 @@ function RouteTab({
onChange={onChange} onChange={onChange}
destroyInactiveTabPane destroyInactiveTabPane
activeKey={activeKey} activeKey={activeKey}
defaultActiveKey={activeKey}
animated animated
items={items} items={items}
// eslint-disable-next-line react/jsx-props-no-spreading // 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<unknown>;
}
RouteTab.defaultProps = { RouteTab.defaultProps = {
onChangeHandler: undefined, onChangeHandler: undefined,
}; };

View File

@ -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<unknown>;
}

View File

@ -32,6 +32,8 @@ const ROUTES = {
HOME_PAGE: '/', HOME_PAGE: '/',
PASSWORD_RESET: '/password-reset', PASSWORD_RESET: '/password-reset',
LIST_LICENSES: '/licenses', LIST_LICENSES: '/licenses',
LOGS_INDEX_FIELDS: '/logs-explorer/index-fields',
LOGS_PIPELINE: '/logs-explorer/pipeline',
TRACE_EXPLORER: '/trace-explorer', TRACE_EXPLORER: '/trace-explorer',
PIPELINES: '/pipelines', PIPELINES: '/pipelines',
}; };

View File

@ -173,6 +173,7 @@ function GridCardGraph({
allowClone={allowClone} allowClone={allowClone}
allowDelete={allowDelete} allowDelete={allowDelete}
allowEdit={allowEdit} allowEdit={allowEdit}
onClickHandler={onClickHandler}
/> />
)} )}

View File

@ -0,0 +1,7 @@
import { Typography } from 'antd';
function LogsIndexToFields(): JSX.Element {
return <Typography>LogsIndexToFields</Typography>;
}
export default LogsIndexToFields;

View File

@ -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 => <CreateAlertChannels preType="slack" />,
name: t('routes.alert_channels'),
route: ROUTES.ALL_CHANNELS,
key: ROUTES.ALL_CHANNELS,
},
];

View File

@ -1,35 +1,17 @@
/* eslint-disable react/no-unstable-nested-components */
import RouteTab from 'components/RouteTab'; 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 history from 'lib/history';
import { useTranslation } from 'react-i18next'; import { useLocation } from 'react-router-dom';
import { alertsRoutesConfig } from './config';
function SettingsPage(): JSX.Element { function SettingsPage(): JSX.Element {
const pathName = history.location.pathname; const { pathname } = useLocation();
const { t } = useTranslation();
return ( return (
<RouteTab <RouteTab
history={history} history={history}
{...{ routes={alertsRoutesConfig}
routes: [ activeKey={pathname}
{
Component: GeneralSettings,
name: t('routes.general'),
route: ROUTES.SETTINGS,
},
{
Component: (): JSX.Element => <CreateAlertChannels preType="slack" />,
name: t('routes.alert_channels'),
route: ROUTES.ALL_CHANNELS,
},
],
activeKey:
pathName === ROUTES.SETTINGS
? t('routes.general')
: t('routes.alert_channels'),
}}
/> />
); );
} }

View File

@ -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,
},
];

View File

@ -1,33 +1,17 @@
import RouteTab from 'components/RouteTab'; import RouteTab from 'components/RouteTab';
import ROUTES from 'constants/routes';
import AllErrorsContainer from 'container/AllError';
import ResourceAttributesFilter from 'container/ResourceAttributesFilter'; import ResourceAttributesFilter from 'container/ResourceAttributesFilter';
import history from 'lib/history'; import history from 'lib/history';
import { useMemo } from 'react'; import { useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { routes } from './config';
function AllErrors(): JSX.Element { function AllErrors(): JSX.Element {
const { t } = useTranslation(); const { pathname } = useLocation();
const routes = useMemo(
() => [
{
Component: AllErrorsContainer,
name: t('routes.all_errors'),
route: ROUTES.ALL_ERROR,
},
],
[t],
);
return ( return (
<> <>
<ResourceAttributesFilter /> <ResourceAttributesFilter />
<RouteTab <RouteTab routes={routes} activeKey={pathname} history={history} />
routes={routes}
activeKey={t('routes.all_errors')}
history={history}
/>
</> </>
); );
} }

View File

@ -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 <Typography.Link>{label}</Typography.Link>;
return <Typography>{label}</Typography>;
}
export default TabLabel;

View File

@ -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: (
<TabLabel
label={TABS_TITLE(t)[TABS_KEY.LOGS_INDEX_FIELDS]}
routeKey={ROUTES.LOGS_INDEX_FIELDS}
/>
),
route: ROUTES.LOGS_INDEX_FIELDS,
key: ROUTES.LOGS_INDEX_FIELDS,
},
];

View File

@ -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<string, string> => ({
[TABS_KEY.LOGS_INDEX_FIELDS]: t('routes.index_fields'),
[TABS_KEY.LOGS_PIPELINE]: t('routes.pipeline'),
});

View File

@ -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 <RouteTab activeKey={pathname} routes={routes} history={history} />;
}
export default LogsSettings;

View File

@ -0,0 +1 @@
export type TableLabel = { routeKey: string; label: string };

View File

@ -24,6 +24,7 @@ function MetricsApplication(): JSX.Element {
route: `${generatePath(ROUTES.SERVICE_METRICS, { route: `${generatePath(ROUTES.SERVICE_METRICS, {
servicename, servicename,
})}?tab=${MetricsApplicationTab.OVER_METRICS}`, })}?tab=${MetricsApplicationTab.OVER_METRICS}`,
key: MetricsApplicationTab.OVER_METRICS,
}, },
{ {
Component: DBCall, Component: DBCall,
@ -31,6 +32,7 @@ function MetricsApplication(): JSX.Element {
route: `${generatePath(ROUTES.SERVICE_METRICS, { route: `${generatePath(ROUTES.SERVICE_METRICS, {
servicename, servicename,
})}?tab=${MetricsApplicationTab.DB_CALL_METRICS}`, })}?tab=${MetricsApplicationTab.DB_CALL_METRICS}`,
key: MetricsApplicationTab.DB_CALL_METRICS,
}, },
{ {
Component: External, Component: External,
@ -38,6 +40,7 @@ function MetricsApplication(): JSX.Element {
route: `${generatePath(ROUTES.SERVICE_METRICS, { route: `${generatePath(ROUTES.SERVICE_METRICS, {
servicename, servicename,
})}?tab=${MetricsApplicationTab.EXTERNAL_METRICS}`, })}?tab=${MetricsApplicationTab.EXTERNAL_METRICS}`,
key: MetricsApplicationTab.EXTERNAL_METRICS,
}, },
], ],
[servicename], [servicename],

View File

@ -1,6 +1,5 @@
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import { TAB_KEY_VS_LABEL } from './types';
import { getMetricsApplicationKey } from './utils'; import { getMetricsApplicationKey } from './utils';
const useMetricsApplicationTabKey = (): string => { const useMetricsApplicationTabKey = (): string => {
@ -8,7 +7,7 @@ const useMetricsApplicationTabKey = (): string => {
const tab = urlParams.get('tab'); const tab = urlParams.get('tab');
return TAB_KEY_VS_LABEL[getMetricsApplicationKey(tab)]; return getMetricsApplicationKey(tab);
}; };
export default useMetricsApplicationTabKey; export default useMetricsApplicationTabKey;

View File

@ -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,
},
];

View File

@ -1,62 +1,30 @@
import RouteTab from 'components/RouteTab'; 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 useComponentPermission from 'hooks/useComponentPermission';
import history from 'lib/history'; import history from 'lib/history';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app'; import AppReducer from 'types/reducer/app';
import { getRoutes } from './utils';
function SettingsPage(): JSX.Element { function SettingsPage(): JSX.Element {
const pathName = history.location.pathname; const { pathname } = useLocation();
const { t } = useTranslation(['routes']);
const { role } = useSelector<AppState, AppReducer>((state) => state.app); const { role } = useSelector<AppState, AppReducer>((state) => state.app);
const [currentOrgSettings] = useComponentPermission( const [isCurrentOrgSettings] = useComponentPermission(
['current_org_settings'], ['current_org_settings'],
role, role,
); );
const { t } = useTranslation(['routes']);
const getActiveKey = (pathname: string): string => { const routes = useMemo(() => getRoutes(isCurrentOrgSettings, t), [
if (pathname === ROUTES.SETTINGS) { isCurrentOrgSettings,
return t('general'); t,
} ]);
if (pathname === ROUTES.ORG_SETTINGS && currentOrgSettings) {
return t('organization_settings');
}
return t('alert_channels');
};
const common = [ return <RouteTab routes={routes} activeKey={pathname} history={history} />;
{
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 (
<RouteTab
routes={common}
activeKey={getActiveKey(pathName)}
history={history}
/>
);
} }
export default SettingsPage; export default SettingsPage;

View File

@ -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;
};

View File

@ -74,6 +74,8 @@ export const routePermission: Record<keyof typeof ROUTES, ROLES[]> = {
LOGS: ['ADMIN', 'EDITOR', 'VIEWER'], LOGS: ['ADMIN', 'EDITOR', 'VIEWER'],
LOGS_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'], LOGS_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'],
LIST_LICENSES: ['ADMIN'], LIST_LICENSES: ['ADMIN'],
LOGS_INDEX_FIELDS: ['ADMIN', 'EDITOR', 'VIEWER'],
LOGS_PIPELINE: ['ADMIN', 'EDITOR', 'VIEWER'],
TRACE_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'], TRACE_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'],
PIPELINES: ['ADMIN', 'EDITOR', 'VIEWER'], PIPELINES: ['ADMIN', 'EDITOR', 'VIEWER'],
}; };