mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-28 23:52:02 +08:00
181 lines
5.1 KiB
TypeScript
181 lines
5.1 KiB
TypeScript
import { ConfigProvider } from 'antd';
|
|
import getLocalStorageApi from 'api/browser/localstorage/get';
|
|
import setLocalStorageApi from 'api/browser/localstorage/set';
|
|
import NotFound from 'components/NotFound';
|
|
import Spinner from 'components/Spinner';
|
|
import { FeatureKeys } from 'constants/features';
|
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
|
import ROUTES from 'constants/routes';
|
|
import AppLayout from 'container/AppLayout';
|
|
import { useThemeConfig } from 'hooks/useDarkMode';
|
|
import useGetFeatureFlag from 'hooks/useGetFeatureFlag';
|
|
import useLicense, { LICENSE_PLAN_KEY } from 'hooks/useLicense';
|
|
import { NotificationProvider } from 'hooks/useNotifications';
|
|
import { ResourceProvider } from 'hooks/useResourceAttribute';
|
|
import history from 'lib/history';
|
|
import { DashboardProvider } from 'providers/Dashboard/Dashboard';
|
|
import { QueryBuilderProvider } from 'providers/QueryBuilder';
|
|
import { Suspense, useEffect, useState } from 'react';
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
import { Route, Router, Switch } from 'react-router-dom';
|
|
import { Dispatch } from 'redux';
|
|
import { AppState } from 'store/reducers';
|
|
import AppActions from 'types/actions';
|
|
import { UPDATE_FEATURE_FLAG_RESPONSE } from 'types/actions/app';
|
|
import AppReducer, { User } from 'types/reducer/app';
|
|
import { extractDomain, isCloudUser } from 'utils/app';
|
|
import { trackPageView } from 'utils/segmentAnalytics';
|
|
|
|
import PrivateRoute from './Private';
|
|
import defaultRoutes from './routes';
|
|
|
|
function App(): JSX.Element {
|
|
const themeConfig = useThemeConfig();
|
|
const { data } = useLicense();
|
|
const [routes, setRoutes] = useState(defaultRoutes);
|
|
const { role, isLoggedIn: isLoggedInState, user, org } = useSelector<
|
|
AppState,
|
|
AppReducer
|
|
>((state) => state.app);
|
|
|
|
const dispatch = useDispatch<Dispatch<AppActions>>();
|
|
|
|
const { hostname, pathname } = window.location;
|
|
|
|
const isCloudUserVal = isCloudUser();
|
|
|
|
const featureResponse = useGetFeatureFlag((allFlags) => {
|
|
const isOnboardingEnabled =
|
|
allFlags.find((flag) => flag.name === FeatureKeys.ONBOARDING)?.active ||
|
|
false;
|
|
|
|
const isChatSupportEnabled =
|
|
allFlags.find((flag) => flag.name === FeatureKeys.CHAT_SUPPORT)?.active ||
|
|
false;
|
|
|
|
dispatch({
|
|
type: UPDATE_FEATURE_FLAG_RESPONSE,
|
|
payload: {
|
|
featureFlag: allFlags,
|
|
refetch: featureResponse.refetch,
|
|
},
|
|
});
|
|
|
|
if (!isOnboardingEnabled || !isCloudUserVal) {
|
|
const newRoutes = routes.filter(
|
|
(route) => route?.path !== ROUTES.GET_STARTED,
|
|
);
|
|
|
|
setRoutes(newRoutes);
|
|
}
|
|
|
|
if (isLoggedInState && isChatSupportEnabled) {
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
window.Intercom('boot', {
|
|
app_id: process.env.INTERCOM_APP_ID,
|
|
email: user?.email || '',
|
|
name: user?.name || '',
|
|
});
|
|
}
|
|
});
|
|
|
|
const isOnBasicPlan =
|
|
data?.payload?.licenses?.some(
|
|
(license) =>
|
|
license.isCurrent && license.planKey === LICENSE_PLAN_KEY.BASIC_PLAN,
|
|
) || data?.payload?.licenses === null;
|
|
|
|
const enableAnalytics = (user: User): void => {
|
|
const orgName =
|
|
org && Array.isArray(org) && org.length > 0 ? org[0].name : '';
|
|
|
|
const identifyPayload = {
|
|
email: user?.email,
|
|
name: user?.name,
|
|
company_name: orgName,
|
|
role,
|
|
};
|
|
const domain = extractDomain(user?.email);
|
|
|
|
const hostNameParts = hostname.split('.');
|
|
|
|
const groupTraits = {
|
|
name: orgName,
|
|
tenant_id: hostNameParts[0],
|
|
data_region: hostNameParts[1],
|
|
tenant_url: hostname,
|
|
company_domain: domain,
|
|
};
|
|
|
|
window.analytics.identify(user?.email, identifyPayload);
|
|
|
|
window.analytics.group(domain, groupTraits);
|
|
|
|
window.clarity('identify', user.email, user.name);
|
|
};
|
|
|
|
useEffect(() => {
|
|
const isIdentifiedUser = getLocalStorageApi(LOCALSTORAGE.IS_IDENTIFIED_USER);
|
|
|
|
if (
|
|
isLoggedInState &&
|
|
user &&
|
|
user.userId &&
|
|
user.email &&
|
|
!isIdentifiedUser
|
|
) {
|
|
setLocalStorageApi(LOCALSTORAGE.IS_IDENTIFIED_USER, 'true');
|
|
|
|
if (isCloudUserVal) {
|
|
enableAnalytics(user);
|
|
}
|
|
}
|
|
|
|
if (isOnBasicPlan || (isLoggedInState && role && role !== 'ADMIN')) {
|
|
const newRoutes = routes.filter((route) => route?.path !== ROUTES.BILLING);
|
|
setRoutes(newRoutes);
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [isLoggedInState, isOnBasicPlan, user]);
|
|
|
|
useEffect(() => {
|
|
trackPageView(pathname);
|
|
}, [pathname]);
|
|
|
|
return (
|
|
<ConfigProvider theme={themeConfig}>
|
|
<Router history={history}>
|
|
<NotificationProvider>
|
|
<PrivateRoute>
|
|
<ResourceProvider>
|
|
<QueryBuilderProvider>
|
|
<DashboardProvider>
|
|
<AppLayout>
|
|
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
|
|
<Switch>
|
|
{routes.map(({ path, component, exact }) => (
|
|
<Route
|
|
key={`${path}`}
|
|
exact={exact}
|
|
path={path}
|
|
component={component}
|
|
/>
|
|
))}
|
|
|
|
<Route path="*" component={NotFound} />
|
|
</Switch>
|
|
</Suspense>
|
|
</AppLayout>
|
|
</DashboardProvider>
|
|
</QueryBuilderProvider>
|
|
</ResourceProvider>
|
|
</PrivateRoute>
|
|
</NotificationProvider>
|
|
</Router>
|
|
</ConfigProvider>
|
|
);
|
|
}
|
|
|
|
export default App;
|