2024-01-05 11:15:31 +05:30
|
|
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
|
|
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
|
|
|
|
import './SideNav.styles.scss';
|
|
|
|
|
|
2024-04-02 19:43:03 +05:30
|
|
|
import { Color } from '@signozhq/design-tokens';
|
2025-04-02 01:12:42 +05:30
|
|
|
import { Button, Tooltip } from 'antd';
|
2024-07-16 14:18:59 +05:30
|
|
|
import logEvent from 'api/common/logEvent';
|
2024-01-05 11:15:31 +05:30
|
|
|
import cx from 'classnames';
|
2023-09-12 19:20:14 +05:30
|
|
|
import { FeatureKeys } from 'constants/features';
|
2021-09-23 15:43:43 +05:30
|
|
|
import ROUTES from 'constants/routes';
|
2024-02-06 14:17:27 +05:30
|
|
|
import { GlobalShortcuts } from 'constants/shortcuts/globalShortcuts';
|
|
|
|
|
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
|
2024-01-05 11:15:31 +05:30
|
|
|
import useComponentPermission from 'hooks/useComponentPermission';
|
2025-03-05 21:50:29 +05:30
|
|
|
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
2025-05-24 19:14:29 +05:30
|
|
|
import { StatusCodes } from 'http-status-codes';
|
2021-09-28 18:50:10 +05:30
|
|
|
import history from 'lib/history';
|
2024-01-05 11:15:31 +05:30
|
|
|
import {
|
|
|
|
|
AlertTriangle,
|
|
|
|
|
CheckSquare,
|
2024-12-05 12:47:18 +05:30
|
|
|
PackagePlus,
|
2024-01-05 11:15:31 +05:30
|
|
|
UserCircle,
|
|
|
|
|
} from 'lucide-react';
|
2024-12-20 14:00:02 +05:30
|
|
|
import { useAppContext } from 'providers/App/App';
|
2024-02-17 14:59:49 +05:30
|
|
|
import { MouseEvent, useCallback, useEffect, useMemo, useState } from 'react';
|
2022-04-05 18:21:25 +05:30
|
|
|
import { useTranslation } from 'react-i18next';
|
2024-02-12 00:23:19 +05:30
|
|
|
import { useSelector } from 'react-redux';
|
2022-05-03 15:27:09 +05:30
|
|
|
import { useLocation } from 'react-router-dom';
|
2021-09-28 18:50:10 +05:30
|
|
|
import { AppState } from 'store/reducers';
|
|
|
|
|
import AppReducer from 'types/reducer/app';
|
2023-10-26 18:39:04 +05:30
|
|
|
import { USER_ROLES } from 'types/roles';
|
2025-03-05 21:50:29 +05:30
|
|
|
import { checkVersionState } from 'utils/app';
|
2021-09-23 15:43:43 +05:30
|
|
|
|
2024-01-05 11:15:31 +05:30
|
|
|
import { routeConfig } from './config';
|
2023-04-20 18:14:32 +05:30
|
|
|
import { getQueryString } from './helper';
|
2024-01-05 11:15:31 +05:30
|
|
|
import defaultMenuItems, {
|
|
|
|
|
helpSupportMenuItem,
|
|
|
|
|
inviteMemberMenuItem,
|
|
|
|
|
manageLicenseMenuItem,
|
2024-02-12 19:53:35 +05:30
|
|
|
shortcutMenuItem,
|
2024-01-05 11:15:31 +05:30
|
|
|
slackSupportMenuItem,
|
|
|
|
|
trySignozCloudMenuItem,
|
|
|
|
|
} from './menuItems';
|
|
|
|
|
import NavItem from './NavItem/NavItem';
|
2024-02-17 14:59:49 +05:30
|
|
|
import { SecondaryMenuItemKey, SidebarItem } from './sideNav.types';
|
2023-09-06 13:00:20 +05:30
|
|
|
import { getActiveMenuKeyFromPath } from './sideNav.utils';
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2024-02-12 00:23:19 +05:30
|
|
|
interface UserManagementMenuItems {
|
|
|
|
|
key: string;
|
|
|
|
|
label: string;
|
|
|
|
|
icon: JSX.Element;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 14:00:02 +05:30
|
|
|
function SideNav(): JSX.Element {
|
2023-10-26 18:39:04 +05:30
|
|
|
const [menuItems, setMenuItems] = useState(defaultMenuItems);
|
2024-01-05 11:15:31 +05:30
|
|
|
const { pathname, search } = useLocation();
|
2024-12-20 14:00:02 +05:30
|
|
|
const { currentVersion, latestVersion, isCurrentVersionError } = useSelector<
|
|
|
|
|
AppState,
|
|
|
|
|
AppReducer
|
|
|
|
|
>((state) => state.app);
|
|
|
|
|
|
2025-05-24 19:14:29 +05:30
|
|
|
const {
|
|
|
|
|
user,
|
|
|
|
|
featureFlags,
|
|
|
|
|
trialInfo,
|
|
|
|
|
activeLicense,
|
|
|
|
|
activeLicenseFetchError,
|
|
|
|
|
} = useAppContext();
|
2023-09-12 19:20:14 +05:30
|
|
|
|
2025-03-02 13:05:22 +05:30
|
|
|
const isOnboardingV3Enabled = featureFlags?.find(
|
|
|
|
|
(flag) => flag.name === FeatureKeys.ONBOARDING_V3,
|
|
|
|
|
)?.active;
|
|
|
|
|
|
2024-01-31 14:25:27 +05:30
|
|
|
const [licenseTag, setLicenseTag] = useState('');
|
|
|
|
|
|
2024-01-05 11:15:31 +05:30
|
|
|
const userSettingsMenuItem = {
|
|
|
|
|
key: ROUTES.MY_SETTINGS,
|
2025-05-14 23:53:41 +05:30
|
|
|
label: user?.displayName || 'User',
|
2024-01-05 11:15:31 +05:30
|
|
|
icon: <UserCircle size={16} />,
|
|
|
|
|
};
|
|
|
|
|
|
2024-02-12 00:23:19 +05:30
|
|
|
const [userManagementMenuItems, setUserManagementMenuItems] = useState<
|
|
|
|
|
UserManagementMenuItems[]
|
2025-04-02 01:12:42 +05:30
|
|
|
>([]);
|
2024-01-05 11:15:31 +05:30
|
|
|
|
|
|
|
|
const onClickSlackHandler = (): void => {
|
|
|
|
|
window.open('https://signoz.io/slack', '_blank');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const isLatestVersion = checkVersionState(currentVersion, latestVersion);
|
|
|
|
|
|
2024-12-20 14:00:02 +05:30
|
|
|
const [inviteMembers] = useComponentPermission(['invite_members'], user.role);
|
2023-10-16 23:57:44 +05:30
|
|
|
|
2024-02-06 14:17:27 +05:30
|
|
|
const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys();
|
|
|
|
|
|
2025-03-05 21:50:29 +05:30
|
|
|
const {
|
2025-04-02 01:12:42 +05:30
|
|
|
isCloudUser,
|
|
|
|
|
isEnterpriseSelfHostedUser,
|
|
|
|
|
isCommunityUser,
|
|
|
|
|
isCommunityEnterpriseUser,
|
2025-03-05 21:50:29 +05:30
|
|
|
} = useGetTenantLicense();
|
2024-04-09 12:05:39 +05:30
|
|
|
|
2022-04-05 18:21:25 +05:30
|
|
|
const { t } = useTranslation('');
|
2022-03-22 21:56:12 +05:30
|
|
|
|
2025-05-24 19:14:29 +05:30
|
|
|
const licenseStatus: string = activeLicense?.status || '';
|
2024-06-25 10:56:52 +05:30
|
|
|
|
2025-03-17 19:27:45 +05:30
|
|
|
const isWorkspaceBlocked = trialInfo?.workSpaceBlock || false;
|
2025-01-08 11:16:41 +05:30
|
|
|
|
2025-05-24 19:14:29 +05:30
|
|
|
const isLicenseActive = licenseStatus === 'VALID';
|
2024-01-05 11:15:31 +05:30
|
|
|
|
|
|
|
|
const onClickSignozCloud = (): void => {
|
|
|
|
|
window.open(
|
|
|
|
|
'https://signoz.io/oss-to-cloud/?utm_source=product_navbar&utm_medium=frontend&utm_campaign=oss_users',
|
|
|
|
|
'_blank',
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2024-02-17 14:59:49 +05:30
|
|
|
const isCtrlMetaKey = (e: MouseEvent): boolean => e.ctrlKey || e.metaKey;
|
|
|
|
|
|
|
|
|
|
const openInNewTab = (path: string): void => {
|
|
|
|
|
window.open(path, '_blank');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onClickShortcuts = (e: MouseEvent): void => {
|
2024-07-16 14:18:59 +05:30
|
|
|
// eslint-disable-next-line sonarjs/no-duplicate-string
|
|
|
|
|
logEvent('Sidebar: Menu clicked', {
|
|
|
|
|
menuRoute: '/shortcuts',
|
|
|
|
|
menuLabel: 'Keyboard Shortcuts',
|
|
|
|
|
});
|
2024-02-17 14:59:49 +05:30
|
|
|
if (isCtrlMetaKey(e)) {
|
|
|
|
|
openInNewTab('/shortcuts');
|
|
|
|
|
} else {
|
|
|
|
|
history.push(`/shortcuts`);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onClickGetStarted = (event: MouseEvent): void => {
|
2024-07-16 14:18:59 +05:30
|
|
|
logEvent('Sidebar: Menu clicked', {
|
|
|
|
|
menuRoute: '/get-started',
|
|
|
|
|
menuLabel: 'Get Started',
|
|
|
|
|
});
|
2025-03-02 13:05:22 +05:30
|
|
|
|
|
|
|
|
const onboaringRoute = isOnboardingV3Enabled
|
|
|
|
|
? ROUTES.GET_STARTED_WITH_CLOUD
|
|
|
|
|
: ROUTES.GET_STARTED;
|
|
|
|
|
|
2024-02-17 14:59:49 +05:30
|
|
|
if (isCtrlMetaKey(event)) {
|
2025-03-02 13:05:22 +05:30
|
|
|
openInNewTab(onboaringRoute);
|
2024-02-17 14:59:49 +05:30
|
|
|
} else {
|
2025-03-02 13:05:22 +05:30
|
|
|
history.push(onboaringRoute);
|
2024-02-17 14:59:49 +05:30
|
|
|
}
|
2024-02-12 19:53:35 +05:30
|
|
|
};
|
|
|
|
|
|
2024-12-20 14:00:02 +05:30
|
|
|
const onClickVersionHandler = useCallback((event: MouseEvent): void => {
|
2024-02-17 14:59:49 +05:30
|
|
|
if (isCtrlMetaKey(event)) {
|
|
|
|
|
openInNewTab(ROUTES.VERSION);
|
|
|
|
|
} else {
|
|
|
|
|
history.push(ROUTES.VERSION);
|
|
|
|
|
}
|
2024-12-20 14:00:02 +05:30
|
|
|
}, []);
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2021-10-20 09:24:55 +05:30
|
|
|
const onClickHandler = useCallback(
|
2024-02-17 14:59:49 +05:30
|
|
|
(key: string, event: MouseEvent | null) => {
|
2023-04-20 18:14:32 +05:30
|
|
|
const params = new URLSearchParams(search);
|
2023-08-02 11:22:24 +05:30
|
|
|
const availableParams = routeConfig[key];
|
2023-04-20 18:14:32 +05:30
|
|
|
|
2023-06-08 10:49:33 +03:00
|
|
|
const queryString = getQueryString(availableParams || [], params);
|
2023-04-20 18:14:32 +05:30
|
|
|
|
2023-08-02 11:22:24 +05:30
|
|
|
if (pathname !== key) {
|
2024-02-17 14:59:49 +05:30
|
|
|
if (event && isCtrlMetaKey(event)) {
|
|
|
|
|
openInNewTab(`${key}?${queryString.join('&')}`);
|
|
|
|
|
} else {
|
2024-06-07 14:49:34 +05:30
|
|
|
history.push(`${key}?${queryString.join('&')}`, {
|
|
|
|
|
from: pathname,
|
|
|
|
|
});
|
2024-02-17 14:59:49 +05:30
|
|
|
}
|
2021-10-20 09:24:55 +05:30
|
|
|
}
|
|
|
|
|
},
|
2023-04-20 18:14:32 +05:30
|
|
|
[pathname, search],
|
2021-10-20 09:24:55 +05:30
|
|
|
);
|
2021-09-23 15:43:43 +05:30
|
|
|
|
2024-01-05 11:15:31 +05:30
|
|
|
const activeMenuKey = useMemo(() => getActiveMenuKeyFromPath(pathname), [
|
|
|
|
|
pathname,
|
|
|
|
|
]);
|
2023-06-08 10:49:33 +03:00
|
|
|
|
2024-02-17 14:59:49 +05:30
|
|
|
const handleUserManagentMenuItemClick = (
|
|
|
|
|
key: string,
|
|
|
|
|
event: MouseEvent,
|
|
|
|
|
): void => {
|
2024-01-05 11:15:31 +05:30
|
|
|
switch (key) {
|
|
|
|
|
case SecondaryMenuItemKey.Slack:
|
|
|
|
|
onClickSlackHandler();
|
|
|
|
|
break;
|
|
|
|
|
case SecondaryMenuItemKey.Version:
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickVersionHandler(event);
|
2024-01-05 11:15:31 +05:30
|
|
|
break;
|
|
|
|
|
default:
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickHandler(key, event);
|
2024-01-05 11:15:31 +05:30
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
};
|
2023-03-03 12:09:24 +01:00
|
|
|
|
2024-01-31 14:25:27 +05:30
|
|
|
useEffect(() => {
|
2025-04-02 01:12:42 +05:30
|
|
|
if (isCloudUser) {
|
2024-12-20 14:00:02 +05:30
|
|
|
setLicenseTag('Cloud');
|
2025-04-02 01:12:42 +05:30
|
|
|
} else if (isEnterpriseSelfHostedUser) {
|
2024-12-20 14:00:02 +05:30
|
|
|
setLicenseTag('Enterprise');
|
2025-04-02 01:12:42 +05:30
|
|
|
} else if (isCommunityEnterpriseUser) {
|
|
|
|
|
setLicenseTag('Enterprise');
|
|
|
|
|
} else if (isCommunityUser) {
|
|
|
|
|
setLicenseTag('Community');
|
2024-04-01 12:40:15 +05:30
|
|
|
}
|
2025-04-02 01:12:42 +05:30
|
|
|
}, [
|
|
|
|
|
isCloudUser,
|
|
|
|
|
isEnterpriseSelfHostedUser,
|
|
|
|
|
isCommunityEnterpriseUser,
|
|
|
|
|
isCommunityUser,
|
|
|
|
|
]);
|
2024-04-01 12:40:15 +05:30
|
|
|
|
2024-02-01 04:04:19 +05:30
|
|
|
const [isCurrentOrgSettings] = useComponentPermission(
|
|
|
|
|
['current_org_settings'],
|
2024-12-20 14:00:02 +05:30
|
|
|
user.role,
|
2024-02-01 04:04:19 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const settingsRoute = isCurrentOrgSettings
|
|
|
|
|
? ROUTES.ORG_SETTINGS
|
|
|
|
|
: ROUTES.SETTINGS;
|
|
|
|
|
|
2024-02-17 14:59:49 +05:30
|
|
|
const handleMenuItemClick = (event: MouseEvent, item: SidebarItem): void => {
|
|
|
|
|
if (item.key === ROUTES.SETTINGS) {
|
|
|
|
|
if (isCtrlMetaKey(event)) {
|
|
|
|
|
openInNewTab(settingsRoute);
|
|
|
|
|
} else {
|
|
|
|
|
history.push(settingsRoute);
|
|
|
|
|
}
|
|
|
|
|
} else if (item) {
|
|
|
|
|
onClickHandler(item?.key as string, event);
|
|
|
|
|
}
|
2024-07-16 14:18:59 +05:30
|
|
|
logEvent('Sidebar: Menu clicked', {
|
2024-07-18 13:54:05 +05:30
|
|
|
menuRoute: item?.key,
|
|
|
|
|
menuLabel: item?.label,
|
2024-07-16 14:18:59 +05:30
|
|
|
});
|
2024-02-17 14:59:49 +05:30
|
|
|
};
|
|
|
|
|
|
2024-02-12 19:53:35 +05:30
|
|
|
useEffect(() => {
|
|
|
|
|
registerShortcut(GlobalShortcuts.NavigateToServices, () =>
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickHandler(ROUTES.APPLICATION, null),
|
2024-02-12 19:53:35 +05:30
|
|
|
);
|
|
|
|
|
registerShortcut(GlobalShortcuts.NavigateToTraces, () =>
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickHandler(ROUTES.TRACE, null),
|
2024-02-12 19:53:35 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
|
|
registerShortcut(GlobalShortcuts.NavigateToLogs, () =>
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickHandler(ROUTES.LOGS, null),
|
2024-02-12 19:53:35 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
|
|
registerShortcut(GlobalShortcuts.NavigateToDashboards, () =>
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickHandler(ROUTES.ALL_DASHBOARD, null),
|
2024-02-12 19:53:35 +05:30
|
|
|
);
|
|
|
|
|
|
2024-08-29 16:36:56 +05:30
|
|
|
registerShortcut(GlobalShortcuts.NavigateToMessagingQueues, () =>
|
2025-01-29 17:32:01 +05:30
|
|
|
onClickHandler(ROUTES.MESSAGING_QUEUES_OVERVIEW, null),
|
2024-08-29 16:36:56 +05:30
|
|
|
);
|
|
|
|
|
|
2024-02-12 19:53:35 +05:30
|
|
|
registerShortcut(GlobalShortcuts.NavigateToAlerts, () =>
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickHandler(ROUTES.LIST_ALL_ALERT, null),
|
2024-02-12 19:53:35 +05:30
|
|
|
);
|
|
|
|
|
registerShortcut(GlobalShortcuts.NavigateToExceptions, () =>
|
2024-02-17 14:59:49 +05:30
|
|
|
onClickHandler(ROUTES.ALL_ERROR, null),
|
2024-02-12 19:53:35 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return (): void => {
|
|
|
|
|
deregisterShortcut(GlobalShortcuts.NavigateToServices);
|
|
|
|
|
deregisterShortcut(GlobalShortcuts.NavigateToTraces);
|
|
|
|
|
deregisterShortcut(GlobalShortcuts.NavigateToLogs);
|
|
|
|
|
deregisterShortcut(GlobalShortcuts.NavigateToDashboards);
|
|
|
|
|
deregisterShortcut(GlobalShortcuts.NavigateToAlerts);
|
|
|
|
|
deregisterShortcut(GlobalShortcuts.NavigateToExceptions);
|
2024-08-29 16:36:56 +05:30
|
|
|
deregisterShortcut(GlobalShortcuts.NavigateToMessagingQueues);
|
2024-02-12 19:53:35 +05:30
|
|
|
};
|
2024-09-27 12:08:25 +05:30
|
|
|
}, [deregisterShortcut, onClickHandler, registerShortcut]);
|
2024-02-12 19:53:35 +05:30
|
|
|
|
2024-12-20 14:00:02 +05:30
|
|
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
let updatedMenuItems = defaultMenuItems;
|
|
|
|
|
let updatedUserManagementItems: UserManagementMenuItems[] = [
|
|
|
|
|
manageLicenseMenuItem,
|
|
|
|
|
];
|
2025-03-30 03:10:43 +05:30
|
|
|
|
2025-04-02 01:12:42 +05:30
|
|
|
if (isCloudUser || isEnterpriseSelfHostedUser) {
|
2024-12-20 14:00:02 +05:30
|
|
|
const isOnboardingEnabled =
|
|
|
|
|
featureFlags?.find((feature) => feature.name === FeatureKeys.ONBOARDING)
|
|
|
|
|
?.active || false;
|
2025-03-02 13:05:22 +05:30
|
|
|
|
2024-12-20 14:00:02 +05:30
|
|
|
if (!isOnboardingEnabled) {
|
|
|
|
|
updatedMenuItems = updatedMenuItems.filter(
|
|
|
|
|
(item) =>
|
2025-03-02 13:05:22 +05:30
|
|
|
item.key !== ROUTES.GET_STARTED &&
|
|
|
|
|
item.key !== ROUTES.ONBOARDING &&
|
|
|
|
|
item.key !== ROUTES.GET_STARTED_WITH_CLOUD,
|
2024-12-20 14:00:02 +05:30
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const isOnBasicPlan =
|
2025-05-24 19:14:29 +05:30
|
|
|
activeLicenseFetchError &&
|
|
|
|
|
[StatusCodes.NOT_FOUND, StatusCodes.NOT_IMPLEMENTED].includes(
|
|
|
|
|
activeLicenseFetchError?.getHttpStatusCode(),
|
|
|
|
|
);
|
2024-12-20 14:00:02 +05:30
|
|
|
|
|
|
|
|
if (user.role !== USER_ROLES.ADMIN || isOnBasicPlan) {
|
|
|
|
|
updatedMenuItems = updatedMenuItems.filter(
|
|
|
|
|
(item) => item.key !== ROUTES.BILLING,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updatedUserManagementItems = [helpSupportMenuItem];
|
2025-04-02 01:12:42 +05:30
|
|
|
|
|
|
|
|
// Show manage license menu item for EE cloud users with a active license
|
|
|
|
|
if (isEnterpriseSelfHostedUser) {
|
|
|
|
|
updatedUserManagementItems.push(manageLicenseMenuItem);
|
|
|
|
|
}
|
2024-12-20 14:00:02 +05:30
|
|
|
} else {
|
|
|
|
|
updatedMenuItems = updatedMenuItems.filter(
|
|
|
|
|
(item) => item.key !== ROUTES.INTEGRATIONS && item.key !== ROUTES.BILLING,
|
|
|
|
|
);
|
|
|
|
|
const versionMenuItem = {
|
|
|
|
|
key: SecondaryMenuItemKey.Version,
|
|
|
|
|
label: !isCurrentVersionError ? currentVersion : t('n_a'),
|
|
|
|
|
icon: !isLatestVersion ? (
|
|
|
|
|
<AlertTriangle color={Color.BG_CHERRY_600} size={16} />
|
|
|
|
|
) : (
|
|
|
|
|
<CheckSquare color={Color.BG_FOREST_500} size={16} />
|
|
|
|
|
),
|
|
|
|
|
onClick: onClickVersionHandler,
|
|
|
|
|
};
|
|
|
|
|
|
2025-04-02 01:12:42 +05:30
|
|
|
updatedUserManagementItems = [versionMenuItem, slackSupportMenuItem];
|
|
|
|
|
|
|
|
|
|
if (isCommunityEnterpriseUser) {
|
|
|
|
|
updatedUserManagementItems.push(manageLicenseMenuItem);
|
|
|
|
|
}
|
2024-12-20 14:00:02 +05:30
|
|
|
}
|
|
|
|
|
setMenuItems(updatedMenuItems);
|
|
|
|
|
setUserManagementMenuItems(updatedUserManagementItems);
|
|
|
|
|
}, [
|
2025-04-02 01:12:42 +05:30
|
|
|
isCommunityEnterpriseUser,
|
2024-12-20 14:00:02 +05:30
|
|
|
currentVersion,
|
|
|
|
|
featureFlags,
|
2025-04-02 01:12:42 +05:30
|
|
|
isCloudUser,
|
|
|
|
|
isEnterpriseSelfHostedUser,
|
2024-12-20 14:00:02 +05:30
|
|
|
isCurrentVersionError,
|
|
|
|
|
isLatestVersion,
|
|
|
|
|
onClickVersionHandler,
|
|
|
|
|
t,
|
|
|
|
|
user.role,
|
2025-05-24 19:14:29 +05:30
|
|
|
activeLicenseFetchError,
|
2024-12-20 14:00:02 +05:30
|
|
|
]);
|
|
|
|
|
|
2021-08-27 12:13:32 +05:30
|
|
|
return (
|
2024-09-27 12:08:25 +05:30
|
|
|
<div className={cx('sidenav-container')}>
|
|
|
|
|
<div className={cx('sideNav')}>
|
2024-04-02 19:43:03 +05:30
|
|
|
<div className="brand">
|
|
|
|
|
<div className="brand-company-meta">
|
|
|
|
|
<div
|
|
|
|
|
className="brand-logo"
|
|
|
|
|
// eslint-disable-next-line react/no-unknown-property
|
|
|
|
|
onClick={(event: MouseEvent): void => {
|
|
|
|
|
// Current home page
|
2025-03-16 19:41:08 +05:30
|
|
|
onClickHandler(ROUTES.HOME, event);
|
2024-04-02 19:43:03 +05:30
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img src="/Logos/signoz-brand-logo.svg" alt="SigNoz" />
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2024-04-02 19:43:03 +05:30
|
|
|
<span className="brand-logo-name nav-item-label"> SigNoz </span>
|
|
|
|
|
</div>
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2024-04-02 19:43:03 +05:30
|
|
|
{licenseTag && (
|
2025-04-02 01:12:42 +05:30
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
// eslint-disable-next-line no-nested-ternary
|
|
|
|
|
isCommunityUser
|
|
|
|
|
? 'You are running the community version of SigNoz. You have to install the Enterprise edition in order enable Enterprise features.'
|
|
|
|
|
: isCommunityEnterpriseUser
|
|
|
|
|
? 'You do not have an active license present. Add an active license to enable Enterprise features.'
|
|
|
|
|
: ''
|
|
|
|
|
}
|
|
|
|
|
placement="bottomRight"
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
className={cx(
|
|
|
|
|
'license tag nav-item-label',
|
|
|
|
|
isCommunityEnterpriseUser && 'community-enterprise-user',
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
{licenseTag}
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
2024-04-02 19:43:03 +05:30
|
|
|
)}
|
|
|
|
|
</div>
|
2024-04-02 12:38:10 +05:30
|
|
|
</div>
|
2024-02-12 19:53:35 +05:30
|
|
|
|
2025-04-02 01:12:42 +05:30
|
|
|
{isCloudUser && user?.role !== USER_ROLES.VIEWER && (
|
2024-04-02 19:43:03 +05:30
|
|
|
<div className="get-started-nav-items">
|
|
|
|
|
<Button
|
|
|
|
|
className="get-started-btn"
|
2025-01-08 11:16:41 +05:30
|
|
|
disabled={isWorkspaceBlocked}
|
2024-04-02 19:43:03 +05:30
|
|
|
onClick={(event: MouseEvent): void => {
|
2025-01-08 11:16:41 +05:30
|
|
|
if (isWorkspaceBlocked) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-04-02 19:43:03 +05:30
|
|
|
onClickGetStarted(event);
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-12-05 12:47:18 +05:30
|
|
|
<PackagePlus size={16} />
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2024-12-05 12:47:18 +05:30
|
|
|
<div className="license tag nav-item-label"> New source </div>
|
2024-04-02 19:43:03 +05:30
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2025-04-02 01:12:42 +05:30
|
|
|
<div className={cx(`nav-wrapper`, isCloudUser && 'nav-wrapper-cloud')}>
|
2024-04-02 19:43:03 +05:30
|
|
|
<div className="primary-nav-items">
|
|
|
|
|
{menuItems.map((item, index) => (
|
2024-04-02 12:38:10 +05:30
|
|
|
<NavItem
|
2024-04-02 19:43:03 +05:30
|
|
|
key={item.key || index}
|
2024-04-02 12:38:10 +05:30
|
|
|
item={item}
|
2024-04-02 19:43:03 +05:30
|
|
|
isActive={activeMenuKey === item.key}
|
2025-01-08 11:16:41 +05:30
|
|
|
isDisabled={
|
|
|
|
|
isWorkspaceBlocked &&
|
|
|
|
|
item.key !== ROUTES.BILLING &&
|
|
|
|
|
item.key !== ROUTES.SETTINGS
|
|
|
|
|
}
|
2024-04-02 19:43:03 +05:30
|
|
|
onClick={(event): void => {
|
|
|
|
|
handleMenuItemClick(event, item);
|
2024-04-02 12:38:10 +05:30
|
|
|
}}
|
|
|
|
|
/>
|
2024-04-02 19:43:03 +05:30
|
|
|
))}
|
|
|
|
|
</div>
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2024-04-02 19:43:03 +05:30
|
|
|
<div className="secondary-nav-items">
|
2024-04-02 12:38:10 +05:30
|
|
|
<NavItem
|
2024-04-02 19:43:03 +05:30
|
|
|
key="keyboardShortcuts"
|
|
|
|
|
item={shortcutMenuItem}
|
2025-01-08 11:16:41 +05:30
|
|
|
isDisabled={isWorkspaceBlocked}
|
2024-04-02 19:43:03 +05:30
|
|
|
isActive={false}
|
|
|
|
|
onClick={onClickShortcuts}
|
2024-04-02 12:38:10 +05:30
|
|
|
/>
|
2024-01-05 11:15:31 +05:30
|
|
|
|
2025-05-24 19:14:29 +05:30
|
|
|
{!isLicenseActive && (
|
2024-04-02 19:43:03 +05:30
|
|
|
<NavItem
|
|
|
|
|
key="trySignozCloud"
|
|
|
|
|
item={trySignozCloudMenuItem}
|
|
|
|
|
isActive={false}
|
2025-01-08 11:16:41 +05:30
|
|
|
isDisabled={isWorkspaceBlocked}
|
2024-04-02 19:43:03 +05:30
|
|
|
onClick={onClickSignozCloud}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2024-04-02 12:38:10 +05:30
|
|
|
|
2024-04-02 19:43:03 +05:30
|
|
|
{userManagementMenuItems.map(
|
|
|
|
|
(item, index): JSX.Element => (
|
|
|
|
|
<NavItem
|
|
|
|
|
key={item?.key || index}
|
|
|
|
|
item={item}
|
|
|
|
|
isActive={activeMenuKey === item?.key}
|
2025-01-08 11:16:41 +05:30
|
|
|
isDisabled={isWorkspaceBlocked}
|
2024-04-02 19:43:03 +05:30
|
|
|
onClick={(event: MouseEvent): void => {
|
|
|
|
|
handleUserManagentMenuItemClick(item?.key as string, event);
|
2024-07-16 14:18:59 +05:30
|
|
|
logEvent('Sidebar: Menu clicked', {
|
2024-07-18 13:54:05 +05:30
|
|
|
menuRoute: item?.key,
|
|
|
|
|
menuLabel: item?.label,
|
2024-07-16 14:18:59 +05:30
|
|
|
});
|
2024-04-02 19:43:03 +05:30
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
),
|
2024-04-02 12:38:10 +05:30
|
|
|
)}
|
2024-04-02 19:43:03 +05:30
|
|
|
|
|
|
|
|
{inviteMembers && (
|
|
|
|
|
<NavItem
|
|
|
|
|
key={inviteMemberMenuItem.key}
|
|
|
|
|
item={inviteMemberMenuItem}
|
|
|
|
|
isActive={activeMenuKey === inviteMemberMenuItem?.key}
|
2025-01-08 11:16:41 +05:30
|
|
|
isDisabled={false}
|
2024-04-02 19:43:03 +05:30
|
|
|
onClick={(event: React.MouseEvent): void => {
|
|
|
|
|
if (isCtrlMetaKey(event)) {
|
|
|
|
|
openInNewTab(`${inviteMemberMenuItem.key}`);
|
|
|
|
|
} else {
|
|
|
|
|
history.push(`${inviteMemberMenuItem.key}`);
|
|
|
|
|
}
|
2024-07-16 14:18:59 +05:30
|
|
|
logEvent('Sidebar: Menu clicked', {
|
2024-07-18 13:54:05 +05:30
|
|
|
menuRoute: inviteMemberMenuItem?.key,
|
|
|
|
|
menuLabel: inviteMemberMenuItem?.label,
|
2024-07-16 14:18:59 +05:30
|
|
|
});
|
2024-04-02 19:43:03 +05:30
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{user && (
|
|
|
|
|
<NavItem
|
|
|
|
|
key={ROUTES.MY_SETTINGS}
|
|
|
|
|
item={userSettingsMenuItem}
|
|
|
|
|
isActive={activeMenuKey === userSettingsMenuItem?.key}
|
2025-01-08 11:16:41 +05:30
|
|
|
isDisabled={false}
|
2024-04-02 19:43:03 +05:30
|
|
|
onClick={(event: MouseEvent): void => {
|
|
|
|
|
handleUserManagentMenuItemClick(
|
|
|
|
|
userSettingsMenuItem?.key as string,
|
|
|
|
|
event,
|
|
|
|
|
);
|
2024-07-16 14:18:59 +05:30
|
|
|
logEvent('Sidebar: Menu clicked', {
|
2024-07-18 13:54:05 +05:30
|
|
|
menuRoute: userSettingsMenuItem?.key,
|
2024-07-16 14:18:59 +05:30
|
|
|
menuLabel: 'User',
|
|
|
|
|
});
|
2024-04-02 19:43:03 +05:30
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2024-04-02 12:38:10 +05:30
|
|
|
</div>
|
2024-01-05 11:15:31 +05:30
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2021-08-27 12:13:32 +05:30
|
|
|
);
|
2022-03-22 12:10:31 +05:30
|
|
|
}
|
2021-08-27 12:13:32 +05:30
|
|
|
|
2022-05-03 15:27:09 +05:30
|
|
|
export default SideNav;
|