import { CheckCircleTwoTone, WarningOutlined } from '@ant-design/icons'; import { MenuProps } from 'antd'; import getLocalStorageKey from 'api/browser/localstorage/get'; import { IS_SIDEBAR_COLLAPSED } from 'constants/app'; import { FeatureKeys } from 'constants/features'; import ROUTES from 'constants/routes'; import useLicense, { LICENSE_PLAN_KEY } from 'hooks/useLicense'; import history from 'lib/history'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import { useLocation } from 'react-router-dom'; import { sideBarCollapse } from 'store/actions/app'; import { AppState } from 'store/reducers'; import AppReducer from 'types/reducer/app'; import { routeConfig, styles } from './config'; import { getQueryString } from './helper'; import defaultMenuItems from './menuItems'; import { MenuItem, SecondaryMenuItemKey } from './sideNav.types'; import { getActiveMenuKeyFromPath } from './sideNav.utils'; import Slack from './Slack'; import { MenuLabelContainer, RedDot, Sider, StyledPrimaryMenu, StyledSecondaryMenu, StyledText, } from './styles'; function SideNav(): JSX.Element { const dispatch = useDispatch(); const [collapsed, setCollapsed] = useState( getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true', ); const { role, currentVersion, latestVersion, isCurrentVersionError, featureResponse, } = useSelector((state) => state.app); const { data } = useLicense(); const isOnBasicPlan = data?.payload?.licenses?.some( (license) => license.isCurrent && license.planKey === LICENSE_PLAN_KEY.BASIC_PLAN, ) || data?.payload?.licenses === null; const { hostname } = window.location; const menuItems = useMemo( () => defaultMenuItems.filter((item) => { const isOnboardingEnabled = featureResponse.data?.find( (feature) => feature.name === FeatureKeys.ONBOARDING, )?.active || false; if (role !== 'ADMIN' || isOnBasicPlan) { return item.key !== ROUTES.BILLING; } if ( !isOnboardingEnabled || !(hostname && hostname.endsWith('signoz.cloud')) ) { return item.key !== ROUTES.GET_STARTED; } return true; }), [featureResponse.data, isOnBasicPlan, hostname, role], ); const { pathname, search } = useLocation(); const { t } = useTranslation(''); const onCollapse = useCallback(() => { setCollapsed((collapsed) => !collapsed); }, []); useLayoutEffect(() => { dispatch(sideBarCollapse(collapsed)); }, [collapsed, dispatch]); const onClickHandler = useCallback( (key: string) => { const params = new URLSearchParams(search); const availableParams = routeConfig[key]; const queryString = getQueryString(availableParams || [], params); if (pathname !== key) { history.push(`${key}?${queryString.join('&')}`); } }, [pathname, search], ); const onClickMenuHandler: MenuProps['onClick'] = (e) => { onClickHandler(e.key); }; const onClickSlackHandler = (): void => { window.open('https://signoz.io/slack', '_blank'); }; const onClickVersionHandler = (): void => { history.push(ROUTES.VERSION); }; const checkVersionState = (): boolean => { const versionCore = currentVersion?.split('-')[0]; if (versionCore) { return versionCore !== latestVersion; } return false; }; const isNotCurrentVersion = checkVersionState(); const secondaryMenuItems: MenuItem[] = [ { key: SecondaryMenuItemKey.Version, icon: isNotCurrentVersion ? ( ) : ( ), label: ( {!isCurrentVersionError ? currentVersion : t('n_a')} {isNotCurrentVersion && } ), onClick: onClickVersionHandler, }, { key: SecondaryMenuItemKey.Slack, icon: , label: Support, onClick: onClickSlackHandler, }, ]; const activeMenuKey = useMemo(() => getActiveMenuKeyFromPath(pathname), [ pathname, ]); return ( ); } export default SideNav;