Compare commits
11 Commits
v0.82.0
...
react-rout
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
923377d559 | ||
|
|
842b6e543f | ||
|
|
23de62329c | ||
|
|
2a805ed1dc | ||
|
|
3c9dc6aa43 | ||
|
|
5812521db9 | ||
|
|
152a0ae958 | ||
|
|
542c3c4752 | ||
|
|
70636ad2f3 | ||
|
|
be9b7039b7 | ||
|
|
6b463a9912 |
@@ -79,7 +79,6 @@
|
|||||||
"eventemitter3": "5.0.1",
|
"eventemitter3": "5.0.1",
|
||||||
"file-loader": "6.1.1",
|
"file-loader": "6.1.1",
|
||||||
"fontfaceobserver": "2.3.0",
|
"fontfaceobserver": "2.3.0",
|
||||||
"history": "4.10.1",
|
|
||||||
"html-webpack-plugin": "5.5.0",
|
"html-webpack-plugin": "5.5.0",
|
||||||
"http-proxy-middleware": "3.0.3",
|
"http-proxy-middleware": "3.0.3",
|
||||||
"i18next": "^21.6.12",
|
"i18next": "^21.6.12",
|
||||||
@@ -115,8 +114,7 @@
|
|||||||
"react-markdown": "8.0.7",
|
"react-markdown": "8.0.7",
|
||||||
"react-query": "3.39.3",
|
"react-query": "3.39.3",
|
||||||
"react-redux": "^7.2.2",
|
"react-redux": "^7.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router": "7.5.1",
|
||||||
"react-router-dom-v5-compat": "6.27.0",
|
|
||||||
"react-syntax-highlighter": "15.5.0",
|
"react-syntax-highlighter": "15.5.0",
|
||||||
"react-use": "^17.3.2",
|
"react-use": "^17.3.2",
|
||||||
"react-virtuoso": "4.0.3",
|
"react-virtuoso": "4.0.3",
|
||||||
@@ -186,7 +184,7 @@
|
|||||||
"@types/react-lottie": "1.2.10",
|
"@types/react-lottie": "1.2.10",
|
||||||
"@types/react-redux": "^7.1.11",
|
"@types/react-redux": "^7.1.11",
|
||||||
"@types/react-resizable": "3.0.3",
|
"@types/react-resizable": "3.0.3",
|
||||||
"@types/react-router-dom": "^5.1.6",
|
"@types/react-router": "^5.1.20",
|
||||||
"@types/react-syntax-highlighter": "15.5.7",
|
"@types/react-syntax-highlighter": "15.5.7",
|
||||||
"@types/redux-mock-store": "1.0.4",
|
"@types/redux-mock-store": "1.0.4",
|
||||||
"@types/styled-components": "^5.1.4",
|
"@types/styled-components": "^5.1.4",
|
||||||
|
|||||||
@@ -5,15 +5,17 @@ import { FeatureKeys } from 'constants/features';
|
|||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
||||||
import history from 'lib/history';
|
import { useGlobalEventListener } from 'hooks/useGlobalEventListener';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { isEmpty } from 'lodash-es';
|
import { isEmpty } from 'lodash-es';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { ReactChild, useCallback, useEffect, useMemo, useState } from 'react';
|
import { ReactChild, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { matchPath, useLocation } from 'react-router-dom';
|
import { matchPath, useLocation } from 'react-router';
|
||||||
import { LicensePlatform, LicenseState } from 'types/api/licensesV3/getActive';
|
import { LicensePlatform, LicenseState } from 'types/api/licensesV3/getActive';
|
||||||
import { Organization } from 'types/api/user/getOrganization';
|
import { Organization } from 'types/api/user/getOrganization';
|
||||||
import { USER_ROLES } from 'types/roles';
|
import { USER_ROLES } from 'types/roles';
|
||||||
|
import { safeNavigateNoSameURLMemo } from 'utils/navigate';
|
||||||
import { routePermission } from 'utils/permission';
|
import { routePermission } from 'utils/permission';
|
||||||
|
|
||||||
import routes, {
|
import routes, {
|
||||||
@@ -26,6 +28,10 @@ import routes, {
|
|||||||
|
|
||||||
function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
const { safeNavigate: unsafeNavigate } = useSafeNavigate({
|
||||||
|
preventSameUrlNavigation: false,
|
||||||
|
});
|
||||||
const { pathname } = location;
|
const { pathname } = location;
|
||||||
const {
|
const {
|
||||||
org,
|
org,
|
||||||
@@ -44,9 +50,13 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
() =>
|
() =>
|
||||||
new Map(
|
new Map(
|
||||||
[...routes, LIST_LICENSES, SUPPORT_ROUTE].map((e) => {
|
[...routes, LIST_LICENSES, SUPPORT_ROUTE].map((e) => {
|
||||||
const currentPath = matchPath(pathname, {
|
const currentPath = matchPath(
|
||||||
path: e.path,
|
{
|
||||||
});
|
// Temp: Hard type cast
|
||||||
|
path: e.path as string,
|
||||||
|
},
|
||||||
|
pathname,
|
||||||
|
);
|
||||||
return [currentPath === null ? null : 'current', e];
|
return [currentPath === null ? null : 'current', e];
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@@ -101,7 +111,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
// if the current route is allowed to be overriden by org onboarding then only do the same
|
// if the current route is allowed to be overriden by org onboarding then only do the same
|
||||||
!ROUTES_NOT_TO_BE_OVERRIDEN.includes(pathname)
|
!ROUTES_NOT_TO_BE_OVERRIDEN.includes(pathname)
|
||||||
) {
|
) {
|
||||||
history.push(ROUTES.ONBOARDING);
|
safeNavigateNoSameURLMemo(ROUTES.ONBOARDING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
@@ -114,31 +124,37 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
pathname,
|
pathname,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const navigateToWorkSpaceBlocked = (route: any): void => {
|
const safeNavigateToWorkSpaceBlocked = useCallback(
|
||||||
const { path } = route;
|
(route: any): void => {
|
||||||
|
const { path } = route;
|
||||||
|
|
||||||
const isRouteEnabledForWorkspaceBlockedState =
|
const isRouteEnabledForWorkspaceBlockedState =
|
||||||
isAdmin &&
|
isAdmin &&
|
||||||
(path === ROUTES.ORG_SETTINGS ||
|
(path === ROUTES.ORG_SETTINGS ||
|
||||||
path === ROUTES.BILLING ||
|
path === ROUTES.BILLING ||
|
||||||
path === ROUTES.MY_SETTINGS);
|
path === ROUTES.MY_SETTINGS);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
path &&
|
path &&
|
||||||
path !== ROUTES.WORKSPACE_LOCKED &&
|
path !== ROUTES.WORKSPACE_LOCKED &&
|
||||||
!isRouteEnabledForWorkspaceBlockedState
|
!isRouteEnabledForWorkspaceBlockedState
|
||||||
) {
|
) {
|
||||||
history.push(ROUTES.WORKSPACE_LOCKED);
|
safeNavigateNoSameURLMemo(ROUTES.WORKSPACE_LOCKED);
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
[isAdmin],
|
||||||
|
);
|
||||||
|
|
||||||
const navigateToWorkSpaceAccessRestricted = (route: any): void => {
|
const safeNavigateToWorkSpaceAccessRestricted = useCallback(
|
||||||
const { path } = route;
|
(route: any): void => {
|
||||||
|
const { path } = route;
|
||||||
|
|
||||||
if (path && path !== ROUTES.WORKSPACE_ACCESS_RESTRICTED) {
|
if (path && path !== ROUTES.WORKSPACE_ACCESS_RESTRICTED) {
|
||||||
history.push(ROUTES.WORKSPACE_ACCESS_RESTRICTED);
|
safeNavigateNoSameURLMemo(ROUTES.WORKSPACE_ACCESS_RESTRICTED);
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isFetchingActiveLicenseV3 && activeLicenseV3) {
|
if (!isFetchingActiveLicenseV3 && activeLicenseV3) {
|
||||||
@@ -157,10 +173,16 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
platform === LicensePlatform.CLOUD &&
|
platform === LicensePlatform.CLOUD &&
|
||||||
currentRoute
|
currentRoute
|
||||||
) {
|
) {
|
||||||
navigateToWorkSpaceAccessRestricted(currentRoute);
|
safeNavigateToWorkSpaceAccessRestricted(currentRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isFetchingActiveLicenseV3, activeLicenseV3, mapRoutes, pathname]);
|
}, [
|
||||||
|
isFetchingActiveLicenseV3,
|
||||||
|
activeLicenseV3,
|
||||||
|
mapRoutes,
|
||||||
|
pathname,
|
||||||
|
safeNavigateToWorkSpaceAccessRestricted,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isFetchingActiveLicenseV3) {
|
if (!isFetchingActiveLicenseV3) {
|
||||||
@@ -172,7 +194,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
currentRoute &&
|
currentRoute &&
|
||||||
activeLicenseV3?.platform === LicensePlatform.CLOUD
|
activeLicenseV3?.platform === LicensePlatform.CLOUD
|
||||||
) {
|
) {
|
||||||
navigateToWorkSpaceBlocked(currentRoute);
|
safeNavigateToWorkSpaceBlocked(currentRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
@@ -182,15 +204,16 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
activeLicenseV3?.platform,
|
activeLicenseV3?.platform,
|
||||||
mapRoutes,
|
mapRoutes,
|
||||||
pathname,
|
pathname,
|
||||||
|
safeNavigateToWorkSpaceBlocked,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const navigateToWorkSpaceSuspended = (route: any): void => {
|
const safeNavigateToWorkSpaceSuspended = useCallback((route: any): void => {
|
||||||
const { path } = route;
|
const { path } = route;
|
||||||
|
|
||||||
if (path && path !== ROUTES.WORKSPACE_SUSPENDED) {
|
if (path && path !== ROUTES.WORKSPACE_SUSPENDED) {
|
||||||
history.push(ROUTES.WORKSPACE_SUSPENDED);
|
safeNavigateNoSameURLMemo(ROUTES.WORKSPACE_SUSPENDED);
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isFetchingActiveLicenseV3 && activeLicenseV3) {
|
if (!isFetchingActiveLicenseV3 && activeLicenseV3) {
|
||||||
@@ -203,10 +226,16 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
currentRoute &&
|
currentRoute &&
|
||||||
activeLicenseV3.platform === LicensePlatform.CLOUD
|
activeLicenseV3.platform === LicensePlatform.CLOUD
|
||||||
) {
|
) {
|
||||||
navigateToWorkSpaceSuspended(currentRoute);
|
safeNavigateToWorkSpaceSuspended(currentRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isFetchingActiveLicenseV3, activeLicenseV3, mapRoutes, pathname]);
|
}, [
|
||||||
|
isFetchingActiveLicenseV3,
|
||||||
|
activeLicenseV3,
|
||||||
|
mapRoutes,
|
||||||
|
pathname,
|
||||||
|
safeNavigateToWorkSpaceSuspended,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (org && org.length > 0 && org[0].id !== undefined) {
|
if (org && org.length > 0 && org[0].id !== undefined) {
|
||||||
@@ -220,13 +249,13 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
currentRoute?.path === ROUTES.GET_STARTED &&
|
currentRoute?.path === ROUTES.GET_STARTED &&
|
||||||
featureFlags?.find((e) => e.name === FeatureKeys.ONBOARDING_V3)?.active
|
featureFlags?.find((e) => e.name === FeatureKeys.ONBOARDING_V3)?.active
|
||||||
) {
|
) {
|
||||||
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
safeNavigateNoSameURLMemo(ROUTES.GET_STARTED_WITH_CLOUD);
|
||||||
}
|
}
|
||||||
}, [currentRoute, featureFlags]);
|
}, [currentRoute, featureFlags]);
|
||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if it is an old route navigate to the new route
|
// if it is an old route safeNavigate to the new route
|
||||||
if (isOldRoute) {
|
if (isOldRoute) {
|
||||||
const redirectUrl = oldNewRoutesMapping[pathname];
|
const redirectUrl = oldNewRoutesMapping[pathname];
|
||||||
|
|
||||||
@@ -234,7 +263,8 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
...location,
|
...location,
|
||||||
pathname: redirectUrl,
|
pathname: redirectUrl,
|
||||||
};
|
};
|
||||||
history.replace(newLocation);
|
|
||||||
|
safeNavigateNoSameURLMemo(newLocation, { replace: true });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if the current route
|
// if the current route
|
||||||
@@ -244,21 +274,21 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
if (isLoggedInState) {
|
if (isLoggedInState) {
|
||||||
const route = routePermission[key];
|
const route = routePermission[key];
|
||||||
if (route && route.find((e) => e === user.role) === undefined) {
|
if (route && route.find((e) => e === user.role) === undefined) {
|
||||||
history.push(ROUTES.UN_AUTHORIZED);
|
safeNavigateNoSameURLMemo(ROUTES.UN_AUTHORIZED);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, pathname);
|
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, pathname);
|
||||||
history.push(ROUTES.LOGIN);
|
safeNavigateNoSameURLMemo(ROUTES.LOGIN);
|
||||||
}
|
}
|
||||||
} else if (isLoggedInState) {
|
} else if (isLoggedInState) {
|
||||||
const fromPathname = getLocalStorageApi(
|
const fromPathname = getLocalStorageApi(
|
||||||
LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT,
|
LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT,
|
||||||
);
|
);
|
||||||
if (fromPathname) {
|
if (fromPathname) {
|
||||||
history.push(fromPathname);
|
safeNavigateNoSameURLMemo(fromPathname);
|
||||||
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, '');
|
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, '');
|
||||||
} else if (pathname !== ROUTES.SOMETHING_WENT_WRONG) {
|
} else if (pathname !== ROUTES.SOMETHING_WENT_WRONG) {
|
||||||
history.push(ROUTES.HOME);
|
safeNavigateNoSameURLMemo(ROUTES.HOME);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// do nothing as the unauthenticated routes are LOGIN and SIGNUP and the LOGIN container takes care of routing to signup if
|
// do nothing as the unauthenticated routes are LOGIN and SIGNUP and the LOGIN container takes care of routing to signup if
|
||||||
@@ -269,17 +299,45 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
|
|||||||
LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT,
|
LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT,
|
||||||
);
|
);
|
||||||
if (fromPathname) {
|
if (fromPathname) {
|
||||||
history.push(fromPathname);
|
safeNavigateNoSameURLMemo(fromPathname);
|
||||||
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, '');
|
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, '');
|
||||||
} else {
|
} else {
|
||||||
history.push(ROUTES.HOME);
|
safeNavigateNoSameURLMemo(ROUTES.HOME);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, pathname);
|
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, pathname);
|
||||||
history.push(ROUTES.LOGIN);
|
safeNavigateNoSameURLMemo(ROUTES.LOGIN);
|
||||||
}
|
}
|
||||||
}, [isLoggedInState, pathname, user, isOldRoute, currentRoute, location]);
|
}, [isLoggedInState, pathname, user, isOldRoute, currentRoute, location]);
|
||||||
|
|
||||||
|
// global event listener for NAVIGATE event
|
||||||
|
// This will provide access to useNavigation hook from outside of components
|
||||||
|
useGlobalEventListener(
|
||||||
|
'SAFE_NAVIGATE',
|
||||||
|
(event: CustomEvent) => {
|
||||||
|
const { to, options } = event.detail;
|
||||||
|
if (to) {
|
||||||
|
safeNavigate(to, options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
passive: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
useGlobalEventListener(
|
||||||
|
'UNSAFE_NAVIGATE',
|
||||||
|
(event: CustomEvent) => {
|
||||||
|
const { to, options } = event.detail;
|
||||||
|
if (to) {
|
||||||
|
unsafeNavigate(to, options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
passive: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// NOTE: disabling this rule as there is no need to have div
|
// NOTE: disabling this rule as there is no need to have div
|
||||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
|||||||
import { LICENSE_PLAN_KEY } from 'hooks/useLicense';
|
import { LICENSE_PLAN_KEY } from 'hooks/useLicense';
|
||||||
import { NotificationProvider } from 'hooks/useNotifications';
|
import { NotificationProvider } from 'hooks/useNotifications';
|
||||||
import { ResourceProvider } from 'hooks/useResourceAttribute';
|
import { ResourceProvider } from 'hooks/useResourceAttribute';
|
||||||
import history from 'lib/history';
|
|
||||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||||
import posthog from 'posthog-js';
|
import posthog from 'posthog-js';
|
||||||
import AlertRuleProvider from 'providers/Alert';
|
import AlertRuleProvider from 'providers/Alert';
|
||||||
@@ -24,9 +23,9 @@ import { IUser } from 'providers/App/types';
|
|||||||
import { DashboardProvider } from 'providers/Dashboard/Dashboard';
|
import { DashboardProvider } from 'providers/Dashboard/Dashboard';
|
||||||
import { QueryBuilderProvider } from 'providers/QueryBuilder';
|
import { QueryBuilderProvider } from 'providers/QueryBuilder';
|
||||||
import { Suspense, useCallback, useEffect, useState } from 'react';
|
import { Suspense, useCallback, useEffect, useState } from 'react';
|
||||||
import { Route, Router, Switch } from 'react-router-dom';
|
import { BrowserRouter, Route, Routes } from 'react-router';
|
||||||
import { CompatRouter } from 'react-router-dom-v5-compat';
|
|
||||||
import { extractDomain } from 'utils/app';
|
import { extractDomain } from 'utils/app';
|
||||||
|
import { safeNavigateNoSameURLMemo } from 'utils/navigate';
|
||||||
|
|
||||||
import { Home } from './pageComponents';
|
import { Home } from './pageComponents';
|
||||||
import PrivateRoute from './Private';
|
import PrivateRoute from './Private';
|
||||||
@@ -316,7 +315,7 @@ function App(): JSX.Element {
|
|||||||
// this needs to be on top of data missing error because if there is an error, data will never be loaded and it will
|
// this needs to be on top of data missing error because if there is an error, data will never be loaded and it will
|
||||||
// move to indefinitive loading
|
// move to indefinitive loading
|
||||||
if (userFetchError && pathname !== ROUTES.SOMETHING_WENT_WRONG) {
|
if (userFetchError && pathname !== ROUTES.SOMETHING_WENT_WRONG) {
|
||||||
history.replace(ROUTES.SOMETHING_WENT_WRONG);
|
safeNavigateNoSameURLMemo(ROUTES.SOMETHING_WENT_WRONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if all of the data is not set then return a spinner, this is required because there is some gap between loading states and data setting
|
// if all of the data is not set then return a spinner, this is required because there is some gap between loading states and data setting
|
||||||
@@ -328,40 +327,33 @@ function App(): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||||
<ConfigProvider theme={themeConfig}>
|
<ConfigProvider theme={themeConfig}>
|
||||||
<Router history={history}>
|
<BrowserRouter>
|
||||||
<CompatRouter>
|
<NotificationProvider>
|
||||||
<NotificationProvider>
|
<PrivateRoute>
|
||||||
<PrivateRoute>
|
<ResourceProvider>
|
||||||
<ResourceProvider>
|
<QueryBuilderProvider>
|
||||||
<QueryBuilderProvider>
|
<DashboardProvider>
|
||||||
<DashboardProvider>
|
<KeyboardHotkeysProvider>
|
||||||
<KeyboardHotkeysProvider>
|
<AlertRuleProvider>
|
||||||
<AlertRuleProvider>
|
<AppLayout>
|
||||||
<AppLayout>
|
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
|
||||||
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
|
<Routes>
|
||||||
<Switch>
|
{routes.map(({ path, element }) => (
|
||||||
{routes.map(({ path, component, exact }) => (
|
<Route key={`${path}`} path={path} element={element} />
|
||||||
<Route
|
))}
|
||||||
key={`${path}`}
|
<Route path="/" element={<Home />} />
|
||||||
exact={exact}
|
<Route path="*" element={<NotFound />} />
|
||||||
path={path}
|
</Routes>
|
||||||
component={component}
|
</Suspense>
|
||||||
/>
|
</AppLayout>
|
||||||
))}
|
</AlertRuleProvider>
|
||||||
<Route exact path="/" component={Home} />
|
</KeyboardHotkeysProvider>
|
||||||
<Route path="*" component={NotFound} />
|
</DashboardProvider>
|
||||||
</Switch>
|
</QueryBuilderProvider>
|
||||||
</Suspense>
|
</ResourceProvider>
|
||||||
</AppLayout>
|
</PrivateRoute>
|
||||||
</AlertRuleProvider>
|
</NotificationProvider>
|
||||||
</KeyboardHotkeysProvider>
|
</BrowserRouter>
|
||||||
</DashboardProvider>
|
|
||||||
</QueryBuilderProvider>
|
|
||||||
</ResourceProvider>
|
|
||||||
</PrivateRoute>
|
|
||||||
</NotificationProvider>
|
|
||||||
</CompatRouter>
|
|
||||||
</Router>
|
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</Sentry.ErrorBoundary>
|
</Sentry.ErrorBoundary>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import MessagingQueues from 'pages/MessagingQueues';
|
import MessagingQueues from 'pages/MessagingQueues';
|
||||||
import { RouteProps } from 'react-router-dom';
|
import { RouteProps } from 'react-router';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AlertHistory,
|
AlertHistory,
|
||||||
@@ -65,443 +65,383 @@ import {
|
|||||||
|
|
||||||
const routes: AppRoutes[] = [
|
const routes: AppRoutes[] = [
|
||||||
{
|
{
|
||||||
component: SignupPage,
|
|
||||||
path: ROUTES.SIGN_UP,
|
path: ROUTES.SIGN_UP,
|
||||||
exact: true,
|
element: <SignupPage />,
|
||||||
isPrivate: false,
|
isPrivate: false,
|
||||||
key: 'SIGN_UP',
|
key: 'SIGN_UP',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.GET_STARTED,
|
path: ROUTES.GET_STARTED,
|
||||||
exact: false,
|
// exact: false
|
||||||
component: Onboarding,
|
element: <Onboarding />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'GET_STARTED',
|
key: 'GET_STARTED',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.GET_STARTED_WITH_CLOUD,
|
path: ROUTES.GET_STARTED_WITH_CLOUD,
|
||||||
exact: false,
|
// exact: false
|
||||||
component: OnboardingV2,
|
element: <OnboardingV2 />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'GET_STARTED_WITH_CLOUD',
|
key: 'GET_STARTED_WITH_CLOUD',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.HOME,
|
path: ROUTES.HOME,
|
||||||
exact: true,
|
element: <Home />,
|
||||||
component: Home,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'HOME',
|
key: 'HOME',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ONBOARDING,
|
path: ROUTES.ONBOARDING,
|
||||||
exact: false,
|
// exact: false
|
||||||
component: OrgOnboarding,
|
element: <OrgOnboarding />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ONBOARDING',
|
key: 'ONBOARDING',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: LogsIndexToFields,
|
|
||||||
path: ROUTES.LOGS_INDEX_FIELDS,
|
path: ROUTES.LOGS_INDEX_FIELDS,
|
||||||
exact: true,
|
element: <LogsIndexToFields />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'LOGS_INDEX_FIELDS',
|
key: 'LOGS_INDEX_FIELDS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: ServicesTablePage,
|
|
||||||
path: ROUTES.APPLICATION,
|
path: ROUTES.APPLICATION,
|
||||||
exact: true,
|
element: <ServicesTablePage />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'APPLICATION',
|
key: 'APPLICATION',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.SERVICE_METRICS,
|
path: ROUTES.SERVICE_METRICS,
|
||||||
exact: true,
|
element: <ServiceMetricsPage />,
|
||||||
component: ServiceMetricsPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'SERVICE_METRICS',
|
key: 'SERVICE_METRICS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.SERVICE_TOP_LEVEL_OPERATIONS,
|
path: ROUTES.SERVICE_TOP_LEVEL_OPERATIONS,
|
||||||
exact: true,
|
element: <ServiceTopLevelOperationsPage />,
|
||||||
component: ServiceTopLevelOperationsPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'SERVICE_TOP_LEVEL_OPERATIONS',
|
key: 'SERVICE_TOP_LEVEL_OPERATIONS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.SERVICE_MAP,
|
path: ROUTES.SERVICE_MAP,
|
||||||
component: ServiceMapPage,
|
element: <ServiceMapPage />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
exact: true,
|
|
||||||
key: 'SERVICE_MAP',
|
key: 'SERVICE_MAP',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.LOGS_SAVE_VIEWS,
|
path: ROUTES.LOGS_SAVE_VIEWS,
|
||||||
component: LogsSaveViews,
|
element: <LogsSaveViews />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
exact: true,
|
|
||||||
key: 'LOGS_SAVE_VIEWS',
|
key: 'LOGS_SAVE_VIEWS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.TRACE_DETAIL,
|
path: ROUTES.TRACE_DETAIL,
|
||||||
exact: true,
|
element: <TraceDetail />,
|
||||||
component: TraceDetail,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'TRACE_DETAIL',
|
key: 'TRACE_DETAIL',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.SETTINGS,
|
path: ROUTES.SETTINGS,
|
||||||
exact: true,
|
element: <SettingsPage />,
|
||||||
component: SettingsPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'SETTINGS',
|
key: 'SETTINGS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.USAGE_EXPLORER,
|
path: ROUTES.USAGE_EXPLORER,
|
||||||
exact: true,
|
element: <UsageExplorerPage />,
|
||||||
component: UsageExplorerPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'USAGE_EXPLORER',
|
key: 'USAGE_EXPLORER',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ALL_DASHBOARD,
|
path: ROUTES.ALL_DASHBOARD,
|
||||||
exact: true,
|
element: <DashboardPage />,
|
||||||
component: DashboardPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ALL_DASHBOARD',
|
key: 'ALL_DASHBOARD',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.DASHBOARD,
|
path: ROUTES.DASHBOARD,
|
||||||
exact: true,
|
element: <NewDashboardPage />,
|
||||||
component: NewDashboardPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'DASHBOARD',
|
key: 'DASHBOARD',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.DASHBOARD_WIDGET,
|
path: ROUTES.DASHBOARD_WIDGET,
|
||||||
exact: true,
|
element: <DashboardWidget />,
|
||||||
component: DashboardWidget,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'DASHBOARD_WIDGET',
|
key: 'DASHBOARD_WIDGET',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.EDIT_ALERTS,
|
path: ROUTES.EDIT_ALERTS,
|
||||||
exact: true,
|
element: <EditRulesPage />,
|
||||||
component: EditRulesPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'EDIT_ALERTS',
|
key: 'EDIT_ALERTS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.LIST_ALL_ALERT,
|
path: ROUTES.LIST_ALL_ALERT,
|
||||||
exact: true,
|
element: <ListAllALertsPage />,
|
||||||
component: ListAllALertsPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'LIST_ALL_ALERT',
|
key: 'LIST_ALL_ALERT',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ALERTS_NEW,
|
path: ROUTES.ALERTS_NEW,
|
||||||
exact: true,
|
element: <CreateNewAlerts />,
|
||||||
component: CreateNewAlerts,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ALERTS_NEW',
|
key: 'ALERTS_NEW',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ALERT_HISTORY,
|
path: ROUTES.ALERT_HISTORY,
|
||||||
exact: true,
|
element: <AlertHistory />,
|
||||||
component: AlertHistory,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ALERT_HISTORY',
|
key: 'ALERT_HISTORY',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ALERT_OVERVIEW,
|
path: ROUTES.ALERT_OVERVIEW,
|
||||||
exact: true,
|
element: <AlertOverview />,
|
||||||
component: AlertOverview,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ALERT_OVERVIEW',
|
key: 'ALERT_OVERVIEW',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.TRACE,
|
path: ROUTES.TRACE,
|
||||||
exact: true,
|
element: <TraceFilter />,
|
||||||
component: TraceFilter,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'TRACE',
|
key: 'TRACE',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.TRACES_EXPLORER,
|
path: ROUTES.TRACES_EXPLORER,
|
||||||
exact: true,
|
element: <TracesExplorer />,
|
||||||
component: TracesExplorer,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'TRACES_EXPLORER',
|
key: 'TRACES_EXPLORER',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.TRACES_SAVE_VIEWS,
|
path: ROUTES.TRACES_SAVE_VIEWS,
|
||||||
exact: true,
|
element: <TracesSaveViews />,
|
||||||
component: TracesSaveViews,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'TRACES_SAVE_VIEWS',
|
key: 'TRACES_SAVE_VIEWS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.TRACES_FUNNELS,
|
path: ROUTES.TRACES_FUNNELS,
|
||||||
exact: true,
|
element: <TracesFunnels />,
|
||||||
component: TracesFunnels,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'TRACES_FUNNELS',
|
key: 'TRACES_FUNNELS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.TRACES_FUNNELS_DETAIL,
|
path: ROUTES.TRACES_FUNNELS_DETAIL,
|
||||||
exact: true,
|
element: <TracesFunnelDetails />,
|
||||||
component: TracesFunnelDetails,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'TRACES_FUNNELS_DETAIL',
|
key: 'TRACES_FUNNELS_DETAIL',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.CHANNELS_NEW,
|
path: ROUTES.CHANNELS_NEW,
|
||||||
exact: true,
|
element: <CreateAlertChannelAlerts />,
|
||||||
component: CreateAlertChannelAlerts,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'CHANNELS_NEW',
|
key: 'CHANNELS_NEW',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.CHANNELS_EDIT,
|
path: ROUTES.CHANNELS_EDIT,
|
||||||
exact: true,
|
element: <EditAlertChannelsAlerts />,
|
||||||
component: EditAlertChannelsAlerts,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'CHANNELS_EDIT',
|
key: 'CHANNELS_EDIT',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ALL_CHANNELS,
|
path: ROUTES.ALL_CHANNELS,
|
||||||
exact: true,
|
element: <AllAlertChannels />,
|
||||||
component: AllAlertChannels,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ALL_CHANNELS',
|
key: 'ALL_CHANNELS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ALL_ERROR,
|
path: ROUTES.ALL_ERROR,
|
||||||
exact: true,
|
element: <AllErrors />,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
component: AllErrors,
|
|
||||||
key: 'ALL_ERROR',
|
key: 'ALL_ERROR',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ERROR_DETAIL,
|
path: ROUTES.ERROR_DETAIL,
|
||||||
exact: true,
|
element: <ErrorDetails />,
|
||||||
component: ErrorDetails,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ERROR_DETAIL',
|
key: 'ERROR_DETAIL',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.VERSION,
|
path: ROUTES.VERSION,
|
||||||
exact: true,
|
element: <StatusPage />,
|
||||||
component: StatusPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'VERSION',
|
key: 'VERSION',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.ORG_SETTINGS,
|
path: ROUTES.ORG_SETTINGS,
|
||||||
exact: true,
|
element: <OrganizationSettings />,
|
||||||
component: OrganizationSettings,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'ORG_SETTINGS',
|
key: 'ORG_SETTINGS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.INGESTION_SETTINGS,
|
path: ROUTES.INGESTION_SETTINGS,
|
||||||
exact: true,
|
element: <IngestionSettings />,
|
||||||
component: IngestionSettings,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'INGESTION_SETTINGS',
|
key: 'INGESTION_SETTINGS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.API_KEYS,
|
path: ROUTES.API_KEYS,
|
||||||
exact: true,
|
element: <APIKeys />,
|
||||||
component: APIKeys,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'API_KEYS',
|
key: 'API_KEYS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.MY_SETTINGS,
|
path: ROUTES.MY_SETTINGS,
|
||||||
exact: true,
|
element: <MySettings />,
|
||||||
component: MySettings,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'MY_SETTINGS',
|
key: 'MY_SETTINGS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.CUSTOM_DOMAIN_SETTINGS,
|
path: ROUTES.CUSTOM_DOMAIN_SETTINGS,
|
||||||
exact: true,
|
element: <CustomDomainSettings />,
|
||||||
component: CustomDomainSettings,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'CUSTOM_DOMAIN_SETTINGS',
|
key: 'CUSTOM_DOMAIN_SETTINGS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.LOGS,
|
path: ROUTES.LOGS,
|
||||||
exact: true,
|
element: <Logs />,
|
||||||
component: Logs,
|
|
||||||
key: 'LOGS',
|
key: 'LOGS',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.LOGS_EXPLORER,
|
path: ROUTES.LOGS_EXPLORER,
|
||||||
exact: true,
|
element: <LogsExplorer />,
|
||||||
component: LogsExplorer,
|
|
||||||
key: 'LOGS_EXPLORER',
|
key: 'LOGS_EXPLORER',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.OLD_LOGS_EXPLORER,
|
path: ROUTES.OLD_LOGS_EXPLORER,
|
||||||
exact: true,
|
element: <OldLogsExplorer />,
|
||||||
component: OldLogsExplorer,
|
|
||||||
key: 'OLD_LOGS_EXPLORER',
|
key: 'OLD_LOGS_EXPLORER',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.LIVE_LOGS,
|
path: ROUTES.LIVE_LOGS,
|
||||||
exact: true,
|
element: <LiveLogs />,
|
||||||
component: LiveLogs,
|
|
||||||
key: 'LIVE_LOGS',
|
key: 'LIVE_LOGS',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.LOGS_PIPELINES,
|
path: ROUTES.LOGS_PIPELINES,
|
||||||
exact: true,
|
element: <PipelinePage />,
|
||||||
component: PipelinePage,
|
|
||||||
key: 'LOGS_PIPELINES',
|
key: 'LOGS_PIPELINES',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.LOGIN,
|
path: ROUTES.LOGIN,
|
||||||
exact: true,
|
element: <Login />,
|
||||||
component: Login,
|
|
||||||
isPrivate: false,
|
isPrivate: false,
|
||||||
key: 'LOGIN',
|
key: 'LOGIN',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.UN_AUTHORIZED,
|
path: ROUTES.UN_AUTHORIZED,
|
||||||
exact: true,
|
element: <UnAuthorized />,
|
||||||
component: UnAuthorized,
|
|
||||||
key: 'UN_AUTHORIZED',
|
key: 'UN_AUTHORIZED',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.PASSWORD_RESET,
|
path: ROUTES.PASSWORD_RESET,
|
||||||
exact: true,
|
element: <PasswordReset />,
|
||||||
component: PasswordReset,
|
|
||||||
key: 'PASSWORD_RESET',
|
key: 'PASSWORD_RESET',
|
||||||
isPrivate: false,
|
isPrivate: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.SOMETHING_WENT_WRONG,
|
path: ROUTES.SOMETHING_WENT_WRONG,
|
||||||
exact: true,
|
element: <SomethingWentWrong />,
|
||||||
component: SomethingWentWrong,
|
|
||||||
key: 'SOMETHING_WENT_WRONG',
|
key: 'SOMETHING_WENT_WRONG',
|
||||||
isPrivate: false,
|
isPrivate: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.BILLING,
|
path: ROUTES.BILLING,
|
||||||
exact: true,
|
element: <BillingPage />,
|
||||||
component: BillingPage,
|
|
||||||
key: 'BILLING',
|
key: 'BILLING',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.WORKSPACE_LOCKED,
|
path: ROUTES.WORKSPACE_LOCKED,
|
||||||
exact: true,
|
element: <WorkspaceBlocked />,
|
||||||
component: WorkspaceBlocked,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'WORKSPACE_LOCKED',
|
key: 'WORKSPACE_LOCKED',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.WORKSPACE_SUSPENDED,
|
path: ROUTES.WORKSPACE_SUSPENDED,
|
||||||
exact: true,
|
element: <WorkspaceSuspended />,
|
||||||
component: WorkspaceSuspended,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'WORKSPACE_SUSPENDED',
|
key: 'WORKSPACE_SUSPENDED',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.WORKSPACE_ACCESS_RESTRICTED,
|
path: ROUTES.WORKSPACE_ACCESS_RESTRICTED,
|
||||||
exact: true,
|
element: <WorkspaceAccessRestricted />,
|
||||||
component: WorkspaceAccessRestricted,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'WORKSPACE_ACCESS_RESTRICTED',
|
key: 'WORKSPACE_ACCESS_RESTRICTED',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.SHORTCUTS,
|
path: ROUTES.SHORTCUTS,
|
||||||
exact: true,
|
element: <ShortcutsPage />,
|
||||||
component: ShortcutsPage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'SHORTCUTS',
|
key: 'SHORTCUTS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.INTEGRATIONS,
|
path: ROUTES.INTEGRATIONS,
|
||||||
exact: true,
|
element: <InstalledIntegrations />,
|
||||||
component: InstalledIntegrations,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'INTEGRATIONS',
|
key: 'INTEGRATIONS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.MESSAGING_QUEUES_KAFKA,
|
path: ROUTES.MESSAGING_QUEUES_KAFKA,
|
||||||
exact: true,
|
element: <MessagingQueues />,
|
||||||
component: MessagingQueues,
|
|
||||||
key: 'MESSAGING_QUEUES_KAFKA',
|
key: 'MESSAGING_QUEUES_KAFKA',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.MESSAGING_QUEUES_CELERY_TASK,
|
path: ROUTES.MESSAGING_QUEUES_CELERY_TASK,
|
||||||
exact: true,
|
element: <MessagingQueues />,
|
||||||
component: MessagingQueues,
|
|
||||||
key: 'MESSAGING_QUEUES_CELERY_TASK',
|
key: 'MESSAGING_QUEUES_CELERY_TASK',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.MESSAGING_QUEUES_OVERVIEW,
|
path: ROUTES.MESSAGING_QUEUES_OVERVIEW,
|
||||||
exact: true,
|
element: <MessagingQueues />,
|
||||||
component: MessagingQueues,
|
|
||||||
key: 'MESSAGING_QUEUES_OVERVIEW',
|
key: 'MESSAGING_QUEUES_OVERVIEW',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL,
|
path: ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL,
|
||||||
exact: true,
|
element: <MessagingQueues />,
|
||||||
component: MessagingQueues,
|
|
||||||
key: 'MESSAGING_QUEUES_KAFKA_DETAIL',
|
key: 'MESSAGING_QUEUES_KAFKA_DETAIL',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
|
path: ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
|
||||||
exact: true,
|
element: <InfrastructureMonitoring />,
|
||||||
component: InfrastructureMonitoring,
|
|
||||||
key: 'INFRASTRUCTURE_MONITORING_HOSTS',
|
key: 'INFRASTRUCTURE_MONITORING_HOSTS',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.INFRASTRUCTURE_MONITORING_KUBERNETES,
|
path: ROUTES.INFRASTRUCTURE_MONITORING_KUBERNETES,
|
||||||
exact: true,
|
element: <InfrastructureMonitoring />,
|
||||||
component: InfrastructureMonitoring,
|
|
||||||
key: 'INFRASTRUCTURE_MONITORING_KUBERNETES',
|
key: 'INFRASTRUCTURE_MONITORING_KUBERNETES',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.METRICS_EXPLORER,
|
path: ROUTES.METRICS_EXPLORER,
|
||||||
exact: true,
|
element: <MetricsExplorer />,
|
||||||
component: MetricsExplorer,
|
|
||||||
key: 'METRICS_EXPLORER',
|
key: 'METRICS_EXPLORER',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.METRICS_EXPLORER_EXPLORER,
|
path: ROUTES.METRICS_EXPLORER_EXPLORER,
|
||||||
exact: true,
|
element: <MetricsExplorer />,
|
||||||
component: MetricsExplorer,
|
|
||||||
key: 'METRICS_EXPLORER_EXPLORER',
|
key: 'METRICS_EXPLORER_EXPLORER',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.METRICS_EXPLORER_VIEWS,
|
path: ROUTES.METRICS_EXPLORER_VIEWS,
|
||||||
exact: true,
|
element: <MetricsExplorer />,
|
||||||
component: MetricsExplorer,
|
|
||||||
key: 'METRICS_EXPLORER_VIEWS',
|
key: 'METRICS_EXPLORER_VIEWS',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ROUTES.API_MONITORING,
|
path: ROUTES.API_MONITORING,
|
||||||
exact: true,
|
element: <ApiMonitoring />,
|
||||||
component: ApiMonitoring,
|
|
||||||
key: 'API_MONITORING',
|
key: 'API_MONITORING',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
},
|
},
|
||||||
@@ -509,16 +449,14 @@ const routes: AppRoutes[] = [
|
|||||||
|
|
||||||
export const SUPPORT_ROUTE: AppRoutes = {
|
export const SUPPORT_ROUTE: AppRoutes = {
|
||||||
path: ROUTES.SUPPORT,
|
path: ROUTES.SUPPORT,
|
||||||
exact: true,
|
element: <SupportPage />,
|
||||||
component: SupportPage,
|
|
||||||
key: 'SUPPORT',
|
key: 'SUPPORT',
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LIST_LICENSES: AppRoutes = {
|
export const LIST_LICENSES: AppRoutes = {
|
||||||
path: ROUTES.LIST_LICENSES,
|
path: ROUTES.LIST_LICENSES,
|
||||||
exact: true,
|
element: <LicensePage />,
|
||||||
component: LicensePage,
|
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
key: 'LIST_LICENSES',
|
key: 'LIST_LICENSES',
|
||||||
};
|
};
|
||||||
@@ -549,9 +487,8 @@ export const ROUTES_NOT_TO_BE_OVERRIDEN: string[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export interface AppRoutes {
|
export interface AppRoutes {
|
||||||
component: RouteProps['component'];
|
element: RouteProps['element'];
|
||||||
path: RouteProps['path'];
|
path: RouteProps['path'];
|
||||||
exact: RouteProps['exact'];
|
|
||||||
isPrivate: boolean;
|
isPrivate: boolean;
|
||||||
key: keyof typeof ROUTES;
|
key: keyof typeof ROUTES;
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import deleteLocalStorageKey from 'api/browser/localstorage/remove';
|
import deleteLocalStorageKey from 'api/browser/localstorage/remove';
|
||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import history from 'lib/history';
|
import { safeNavigateNoSameURLMemo } from 'utils/navigate';
|
||||||
|
|
||||||
export const Logout = (): void => {
|
export const Logout = (): void => {
|
||||||
deleteLocalStorageKey(LOCALSTORAGE.AUTH_TOKEN);
|
deleteLocalStorageKey(LOCALSTORAGE.AUTH_TOKEN);
|
||||||
@@ -23,5 +23,5 @@ export const Logout = (): void => {
|
|||||||
window.Intercom('shutdown');
|
window.Intercom('shutdown');
|
||||||
}
|
}
|
||||||
|
|
||||||
history.push(ROUTES.LOGIN);
|
safeNavigateNoSameURLMemo(ROUTES.LOGIN);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ import {
|
|||||||
import { useCeleryFilterOptions } from 'components/CeleryTask/useCeleryFilterOptions';
|
import { useCeleryFilterOptions } from 'components/CeleryTask/useCeleryFilterOptions';
|
||||||
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
|
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
interface SelectOptionConfig {
|
interface SelectOptionConfig {
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
@@ -27,7 +28,7 @@ function FilterSelect({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -55,7 +56,13 @@ function FilterSelect({
|
|||||||
}
|
}
|
||||||
onChange={(value): void => {
|
onChange={(value): void => {
|
||||||
handleSearch('');
|
handleSearch('');
|
||||||
setQueryParamsFromOptions(value, urlQuery, history, location, queryParam);
|
setQueryParamsFromOptions(
|
||||||
|
value,
|
||||||
|
urlQuery,
|
||||||
|
safeNavigate,
|
||||||
|
location,
|
||||||
|
queryParam,
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import './CeleryTaskConfigOptions.styles.scss';
|
|||||||
import { Select, Spin, Typography } from 'antd';
|
import { Select, Spin, Typography } from 'antd';
|
||||||
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
|
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getValuesFromQueryParams,
|
getValuesFromQueryParams,
|
||||||
@@ -16,7 +17,7 @@ function CeleryTaskConfigOptions(): JSX.Element {
|
|||||||
const { handleSearch, isFetching, options } = useCeleryFilterOptions(
|
const { handleSearch, isFetching, options } = useCeleryFilterOptions(
|
||||||
'celery.task_name',
|
'celery.task_name',
|
||||||
);
|
);
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
@@ -52,7 +53,7 @@ function CeleryTaskConfigOptions(): JSX.Element {
|
|||||||
setQueryParamsFromOptions(
|
setQueryParamsFromOptions(
|
||||||
value,
|
value,
|
||||||
urlQuery,
|
urlQuery,
|
||||||
history,
|
safeNavigate,
|
||||||
location,
|
location,
|
||||||
QueryParams.taskName,
|
QueryParams.taskName,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import { ViewMenuAction } from 'container/GridCardLayout/config';
|
|||||||
import GridCard from 'container/GridCardLayout/GridCard';
|
import GridCard from 'container/GridCardLayout/GridCard';
|
||||||
import { Card } from 'container/GridCardLayout/styles';
|
import { Card } from 'container/GridCardLayout/styles';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { isEmpty } from 'lodash-es';
|
import { isEmpty } from 'lodash-es';
|
||||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
@@ -49,7 +50,7 @@ function CeleryTaskBar({
|
|||||||
queryEnabled: boolean;
|
queryEnabled: boolean;
|
||||||
checkIfDataExists?: (isDataAvailable: boolean) => void;
|
checkIfDataExists?: (isDataAvailable: boolean) => void;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
@@ -67,13 +68,13 @@ function CeleryTaskBar({
|
|||||||
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
||||||
history.push(generatedUrl);
|
safeNavigate(generatedUrl);
|
||||||
|
|
||||||
if (startTimestamp !== endTimestamp) {
|
if (startTimestamp !== endTimestamp) {
|
||||||
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch, history, pathname, urlQuery],
|
[dispatch, pathname, urlQuery, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const [barState, setBarState] = useState<CeleryTaskState>(CeleryTaskState.All);
|
const [barState, setBarState] = useState<CeleryTaskState>(CeleryTaskState.All);
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import { ViewMenuAction } from 'container/GridCardLayout/config';
|
|||||||
import GridCard from 'container/GridCardLayout/GridCard';
|
import GridCard from 'container/GridCardLayout/GridCard';
|
||||||
import { Card } from 'container/GridCardLayout/styles';
|
import { Card } from 'container/GridCardLayout/styles';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
@@ -53,7 +54,7 @@ function CeleryTaskGraph({
|
|||||||
checkIfDataExists?: (isDataAvailable: boolean) => void;
|
checkIfDataExists?: (isDataAvailable: boolean) => void;
|
||||||
analyticsEvent?: string;
|
analyticsEvent?: string;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
@@ -82,13 +83,13 @@ function CeleryTaskGraph({
|
|||||||
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
||||||
history.push(generatedUrl);
|
safeNavigate(generatedUrl);
|
||||||
|
|
||||||
if (startTimestamp !== endTimestamp) {
|
if (startTimestamp !== endTimestamp) {
|
||||||
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch, history, pathname, urlQuery],
|
[dispatch, pathname, urlQuery, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ import { Card } from 'container/GridCardLayout/styles';
|
|||||||
import { Button } from 'container/MetricsApplication/Tabs/styles';
|
import { Button } from 'container/MetricsApplication/Tabs/styles';
|
||||||
import { useGraphClickHandler } from 'container/MetricsApplication/Tabs/util';
|
import { useGraphClickHandler } from 'container/MetricsApplication/Tabs/util';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
@@ -47,7 +48,7 @@ function CeleryTaskLatencyGraph({
|
|||||||
queryEnabled: boolean;
|
queryEnabled: boolean;
|
||||||
checkIfDataExists?: (isDataAvailable: boolean) => void;
|
checkIfDataExists?: (isDataAvailable: boolean) => void;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
@@ -79,13 +80,13 @@ function CeleryTaskLatencyGraph({
|
|||||||
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
||||||
history.push(generatedUrl);
|
safeNavigate(generatedUrl);
|
||||||
|
|
||||||
if (startTimestamp !== endTimestamp) {
|
if (startTimestamp !== endTimestamp) {
|
||||||
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch, history, pathname, urlQuery],
|
[dispatch, pathname, urlQuery, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFilters = useMemo(
|
const selectedFilters = useMemo(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import { History, Location } from 'history';
|
|
||||||
import getRenderer from 'lib/uPlotLib/utils/getRenderer';
|
import getRenderer from 'lib/uPlotLib/utils/getRenderer';
|
||||||
|
import type { Location, NavigateFunction } from 'react-router';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
@@ -17,13 +17,13 @@ export function getValuesFromQueryParams(
|
|||||||
export function setQueryParamsFromOptions(
|
export function setQueryParamsFromOptions(
|
||||||
value: string[],
|
value: string[],
|
||||||
urlQuery: URLSearchParams,
|
urlQuery: URLSearchParams,
|
||||||
history: History<unknown>,
|
safeNavigate: NavigateFunction,
|
||||||
location: Location<unknown>,
|
location: Location<unknown>,
|
||||||
queryParams: QueryParams,
|
queryParams: QueryParams,
|
||||||
): void {
|
): void {
|
||||||
urlQuery.set(queryParams, value.join(','));
|
urlQuery.set(queryParams, value.join(','));
|
||||||
const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
|
||||||
history.replace(generatedUrl);
|
safeNavigate(generatedUrl, { replace: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFiltersFromQueryParams(
|
export function getFiltersFromQueryParams(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { useNotifications } from 'hooks/useNotifications';
|
|||||||
import { CreditCard, X } from 'lucide-react';
|
import { CreditCard, X } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useMutation } from 'react-query';
|
import { useMutation } from 'react-query';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
import { CheckoutSuccessPayloadProps } from 'types/api/billing/checkout';
|
import { CheckoutSuccessPayloadProps } from 'types/api/billing/checkout';
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { popupContainer } from 'utils/selectPopupContainer';
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import CustomTimePickerPopoverContent from './CustomTimePickerPopoverContent';
|
import CustomTimePickerPopoverContent from './CustomTimePickerPopoverContent';
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
import { Clock, PenLine } from 'lucide-react';
|
import { Clock, PenLine } from 'lucide-react';
|
||||||
import { useTimezone } from 'providers/Timezone';
|
import { useTimezone } from 'providers/Timezone';
|
||||||
import { Dispatch, SetStateAction, useMemo } from 'react';
|
import { Dispatch, SetStateAction, useMemo } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
import RangePickerModal from './RangePickerModal';
|
import RangePickerModal from './RangePickerModal';
|
||||||
import TimezonePicker from './TimezonePicker';
|
import TimezonePicker from './TimezonePicker';
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ function ExplorerCard({
|
|||||||
showSearch
|
showSearch
|
||||||
placeholder="Select a view"
|
placeholder="Select a view"
|
||||||
dropdownStyle={DropDownOverlay}
|
dropdownStyle={DropDownOverlay}
|
||||||
dropdownMatchSelectWidth={false}
|
popupMatchSelectWidth={false}
|
||||||
optionLabelProp="value"
|
optionLabelProp="value"
|
||||||
value={viewName || undefined}
|
value={viewName || undefined}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { CreditCard, HelpCircle, X } from 'lucide-react';
|
|||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useMutation } from 'react-query';
|
import { useMutation } from 'react-query';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
import { CheckoutSuccessPayloadProps } from 'types/api/billing/checkout';
|
import { CheckoutSuccessPayloadProps } from 'types/api/billing/checkout';
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { ComponentType, lazy, LazyExoticComponent } from 'react';
|
import { ComponentType, lazy, LazyExoticComponent } from 'react';
|
||||||
import { lazyRetry } from 'utils/lazyWithRetries';
|
import { lazyRetry } from 'utils/lazyWithRetries';
|
||||||
|
|
||||||
function Loadable(importPath: {
|
|
||||||
(): LoadableProps;
|
|
||||||
}): LazyExoticComponent<LazyComponent> {
|
|
||||||
return lazy(() => lazyRetry(() => importPath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
type LazyComponent = ComponentType<Record<string, unknown>>;
|
type LazyComponent = ComponentType<Record<string, unknown>>;
|
||||||
|
|
||||||
type LoadableProps = Promise<{
|
type LoadableProps = Promise<{
|
||||||
default: LazyComponent;
|
default: LazyComponent;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
function Loadable(importPath: {
|
||||||
|
(): LoadableProps;
|
||||||
|
}): LazyExoticComponent<LazyComponent> {
|
||||||
|
return lazy(() => lazyRetry(() => importPath()));
|
||||||
|
}
|
||||||
|
|
||||||
export default Loadable;
|
export default Loadable;
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ import {
|
|||||||
import { OnboardingStatusResponse } from 'api/messagingQueues/onboarding/getOnboardingStatus';
|
import { OnboardingStatusResponse } from 'api/messagingQueues/onboarding/getOnboardingStatus';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { History } from 'history';
|
|
||||||
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { Bolt, Check, OctagonAlert, X } from 'lucide-react';
|
import { Bolt, Check, OctagonAlert, X } from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
KAFKA_SETUP_DOC_LINK,
|
KAFKA_SETUP_DOC_LINK,
|
||||||
MessagingQueueHealthCheckService,
|
MessagingQueueHealthCheckService,
|
||||||
} from 'pages/MessagingQueues/MessagingQueuesUtils';
|
} from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||||
import { ReactNode, useEffect, useState } from 'react';
|
import { ReactNode, useEffect, useState } from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import type { NavigateFunction } from 'react-router';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
interface AttributeCheckListProps {
|
interface AttributeCheckListProps {
|
||||||
@@ -46,7 +46,7 @@ export enum AttributesFilters {
|
|||||||
function ErrorTitleAndKey({
|
function ErrorTitleAndKey({
|
||||||
title,
|
title,
|
||||||
parentTitle,
|
parentTitle,
|
||||||
history,
|
safeNavigate,
|
||||||
isCloudUserVal,
|
isCloudUserVal,
|
||||||
errorMsg,
|
errorMsg,
|
||||||
isLeaf,
|
isLeaf,
|
||||||
@@ -54,7 +54,7 @@ function ErrorTitleAndKey({
|
|||||||
title: string;
|
title: string;
|
||||||
parentTitle: string;
|
parentTitle: string;
|
||||||
isCloudUserVal: boolean;
|
isCloudUserVal: boolean;
|
||||||
history: History<unknown>;
|
safeNavigate: NavigateFunction;
|
||||||
errorMsg?: string;
|
errorMsg?: string;
|
||||||
isLeaf?: boolean;
|
isLeaf?: boolean;
|
||||||
}): TreeDataNode {
|
}): TreeDataNode {
|
||||||
@@ -76,7 +76,7 @@ function ErrorTitleAndKey({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isCloudUserVal && !!link) {
|
if (isCloudUserVal && !!link) {
|
||||||
history.push(link);
|
safeNavigate(link);
|
||||||
} else {
|
} else {
|
||||||
window.open(KAFKA_SETUP_DOC_LINK, '_blank');
|
window.open(KAFKA_SETUP_DOC_LINK, '_blank');
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ function generateTreeDataNodes(
|
|||||||
response: OnboardingStatusResponse['data'],
|
response: OnboardingStatusResponse['data'],
|
||||||
parentTitle: string,
|
parentTitle: string,
|
||||||
isCloudUserVal: boolean,
|
isCloudUserVal: boolean,
|
||||||
history: History<unknown>,
|
safeNavigate: NavigateFunction,
|
||||||
): TreeDataNode[] {
|
): TreeDataNode[] {
|
||||||
return response
|
return response
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
@@ -159,7 +159,7 @@ function generateTreeDataNodes(
|
|||||||
title: item.attribute,
|
title: item.attribute,
|
||||||
errorMsg: item.error_message || '',
|
errorMsg: item.error_message || '',
|
||||||
parentTitle,
|
parentTitle,
|
||||||
history,
|
safeNavigate,
|
||||||
isCloudUserVal,
|
isCloudUserVal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ function AttributeCheckList({
|
|||||||
setFilter(value);
|
setFilter(value);
|
||||||
};
|
};
|
||||||
const { isCloudUser: isCloudUserVal } = useGetTenantLicense();
|
const { isCloudUser: isCloudUserVal } = useGetTenantLicense();
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filteredData = onboardingStatusResponses.map((response) => {
|
const filteredData = onboardingStatusResponses.map((response) => {
|
||||||
@@ -192,7 +192,7 @@ function AttributeCheckList({
|
|||||||
errorMsg: response.errorMsg,
|
errorMsg: response.errorMsg,
|
||||||
isLeaf: true,
|
isLeaf: true,
|
||||||
parentTitle: response.title,
|
parentTitle: response.title,
|
||||||
history,
|
safeNavigate,
|
||||||
isCloudUserVal,
|
isCloudUserVal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ function AttributeCheckList({
|
|||||||
filteredData,
|
filteredData,
|
||||||
response.title,
|
response.title,
|
||||||
isCloudUserVal,
|
isCloudUserVal,
|
||||||
history,
|
safeNavigate,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
export const Button = styled(Link)`
|
export const Button = styled(Link)`
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Tabs, TabsProps } from 'antd';
|
import { Tabs, TabsProps } from 'antd';
|
||||||
|
import { safeNavigateNoSameURLMemo } from 'utils/navigate';
|
||||||
|
|
||||||
import { RouteTabProps } from './types';
|
import { RouteTabProps } from './types';
|
||||||
|
|
||||||
@@ -6,7 +7,6 @@ function RouteTab({
|
|||||||
routes,
|
routes,
|
||||||
activeKey,
|
activeKey,
|
||||||
onChangeHandler,
|
onChangeHandler,
|
||||||
history,
|
|
||||||
...rest
|
...rest
|
||||||
}: RouteTabProps & TabsProps): JSX.Element {
|
}: RouteTabProps & TabsProps): JSX.Element {
|
||||||
const onChange = (activeRoute: string): void => {
|
const onChange = (activeRoute: string): void => {
|
||||||
@@ -17,7 +17,7 @@ function RouteTab({
|
|||||||
const selectedRoute = routes.find((e) => e.key === activeRoute);
|
const selectedRoute = routes.find((e) => e.key === activeRoute);
|
||||||
|
|
||||||
if (selectedRoute) {
|
if (selectedRoute) {
|
||||||
history.push(selectedRoute.route);
|
safeNavigateNoSameURLMemo(selectedRoute.route);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { TabsProps } from 'antd';
|
import { TabsProps } from 'antd';
|
||||||
import { History } from 'history';
|
// import type { NavigateFunction } from 'react-router';
|
||||||
|
|
||||||
export type TabRoutes = {
|
export type TabRoutes = {
|
||||||
name: React.ReactNode;
|
name: React.ReactNode;
|
||||||
@@ -12,5 +12,5 @@ export interface RouteTabProps {
|
|||||||
routes: TabRoutes[];
|
routes: TabRoutes[];
|
||||||
activeKey: TabsProps['activeKey'];
|
activeKey: TabsProps['activeKey'];
|
||||||
onChangeHandler?: (key: string) => void;
|
onChangeHandler?: (key: string) => void;
|
||||||
history: History<unknown>;
|
// safeNavigate: NavigateFunction;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import ROUTES from 'constants/routes';
|
|||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { DraftingCompass } from 'lucide-react';
|
import { DraftingCompass } from 'lucide-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import './TopContributorsCard.styles.scss';
|
|||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { ArrowRight } from 'lucide-react';
|
import { ArrowRight } from 'lucide-react';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
import TopContributorsContent from './TopContributorsContent';
|
import TopContributorsContent from './TopContributorsContent';
|
||||||
import { TopContributorsCardProps } from './types';
|
import { TopContributorsCardProps } from './types';
|
||||||
@@ -17,6 +17,7 @@ function TopContributorsCard({
|
|||||||
totalCurrentTriggers,
|
totalCurrentTriggers,
|
||||||
}: TopContributorsCardProps): JSX.Element {
|
}: TopContributorsCardProps): JSX.Element {
|
||||||
const { search } = useLocation();
|
const { search } = useLocation();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const searchParams = useMemo(() => new URLSearchParams(search), [search]);
|
const searchParams = useMemo(() => new URLSearchParams(search), [search]);
|
||||||
|
|
||||||
const viewAllTopContributorsParam = searchParams.get('viewAllTopContributors');
|
const viewAllTopContributorsParam = searchParams.get('viewAllTopContributors');
|
||||||
@@ -43,7 +44,7 @@ function TopContributorsCard({
|
|||||||
|
|
||||||
return newState;
|
return newState;
|
||||||
});
|
});
|
||||||
history.push({ search: searchParams.toString() });
|
safeNavigate({ search: searchParams.toString() });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import Uplot from 'components/Uplot';
|
|||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { useResizeObserver } from 'hooks/useDimensions';
|
import { useResizeObserver } from 'hooks/useDimensions';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import history from 'lib/history';
|
|
||||||
import heatmapPlugin from 'lib/uPlotLib/plugins/heatmapPlugin';
|
import heatmapPlugin from 'lib/uPlotLib/plugins/heatmapPlugin';
|
||||||
import timelinePlugin from 'lib/uPlotLib/plugins/timelinePlugin';
|
import timelinePlugin from 'lib/uPlotLib/plugins/timelinePlugin';
|
||||||
import { uPlotXAxisValuesFormat } from 'lib/uPlotLib/utils/constants';
|
import { uPlotXAxisValuesFormat } from 'lib/uPlotLib/utils/constants';
|
||||||
@@ -28,6 +28,8 @@ function HorizontalTimelineGraph({
|
|||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
data: AlertRuleTimelineGraphResponse[];
|
data: AlertRuleTimelineGraphResponse[];
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const transformedData: AlignedData = useMemo(() => {
|
const transformedData: AlignedData = useMemo(() => {
|
||||||
if (!data?.length) {
|
if (!data?.length) {
|
||||||
return [[], []];
|
return [[], []];
|
||||||
@@ -102,7 +104,7 @@ function HorizontalTimelineGraph({
|
|||||||
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
|
|
||||||
history.push({
|
safeNavigate({
|
||||||
search: urlQuery.toString(),
|
search: urlQuery.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -131,6 +133,7 @@ function HorizontalTimelineGraph({
|
|||||||
urlQuery,
|
urlQuery,
|
||||||
dispatch,
|
dispatch,
|
||||||
timezone.value,
|
timezone.value,
|
||||||
|
safeNavigate,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return <Uplot data={transformedData} options={options} />;
|
return <Uplot data={transformedData} options={options} />;
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import './TabsAndFilters.styles.scss';
|
|||||||
|
|
||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { TimelineFilter, TimelineTab } from 'container/AlertHistory/types';
|
import { TimelineFilter, TimelineTab } from 'container/AlertHistory/types';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { Info } from 'lucide-react';
|
import { Info } from 'lucide-react';
|
||||||
import Tabs2 from 'periscope/components/Tabs2';
|
import Tabs2 from 'periscope/components/Tabs2';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
function ComingSoon(): JSX.Element {
|
function ComingSoon(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
@@ -41,6 +41,8 @@ function TimelineTabs(): JSX.Element {
|
|||||||
|
|
||||||
function TimelineFilters(): JSX.Element {
|
function TimelineFilters(): JSX.Element {
|
||||||
const { search } = useLocation();
|
const { search } = useLocation();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const searchParams = useMemo(() => new URLSearchParams(search), [search]);
|
const searchParams = useMemo(() => new URLSearchParams(search), [search]);
|
||||||
|
|
||||||
const initialSelectedTab = useMemo(
|
const initialSelectedTab = useMemo(
|
||||||
@@ -50,7 +52,7 @@ function TimelineFilters(): JSX.Element {
|
|||||||
|
|
||||||
const handleFilter = (value: TimelineFilter): void => {
|
const handleFilter = (value: TimelineFilter): void => {
|
||||||
searchParams.set('timelineFilter', value);
|
searchParams.set('timelineFilter', value);
|
||||||
history.push({ search: searchParams.toString() });
|
safeNavigate({ search: searchParams.toString() });
|
||||||
};
|
};
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import { ResizeTable } from 'components/ResizeTable';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import useComponentPermission from 'hooks/useComponentPermission';
|
import useComponentPermission from 'hooks/useComponentPermission';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { generatePath } from 'react-router-dom';
|
import { generatePath } from 'react-router';
|
||||||
import { Channels, PayloadProps } from 'types/api/channels/getAll';
|
import { Channels, PayloadProps } from 'types/api/channels/getAll';
|
||||||
|
|
||||||
import Delete from './Delete';
|
import Delete from './Delete';
|
||||||
@@ -17,17 +17,22 @@ import Delete from './Delete';
|
|||||||
function AlertChannels({ allChannels }: AlertChannelsProps): JSX.Element {
|
function AlertChannels({ allChannels }: AlertChannelsProps): JSX.Element {
|
||||||
const { t } = useTranslation(['channels']);
|
const { t } = useTranslation(['channels']);
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const [channels, setChannels] = useState<Channels[]>(allChannels);
|
const [channels, setChannels] = useState<Channels[]>(allChannels);
|
||||||
const { user } = useAppContext();
|
const { user } = useAppContext();
|
||||||
const [action] = useComponentPermission(['new_alert_action'], user.role);
|
const [action] = useComponentPermission(['new_alert_action'], user.role);
|
||||||
|
|
||||||
const onClickEditHandler = useCallback((id: string) => {
|
const onClickEditHandler = useCallback(
|
||||||
history.replace(
|
(id: string) => {
|
||||||
generatePath(ROUTES.CHANNELS_EDIT, {
|
safeNavigate(
|
||||||
id,
|
generatePath(ROUTES.CHANNELS_EDIT, {
|
||||||
}),
|
id,
|
||||||
);
|
}),
|
||||||
}, []);
|
{ replace: true },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[safeNavigate],
|
||||||
|
);
|
||||||
|
|
||||||
const columns: ColumnsType<Channels> = [
|
const columns: ColumnsType<Channels> = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import TextToolTip from 'components/TextToolTip';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import useComponentPermission from 'hooks/useComponentPermission';
|
import useComponentPermission from 'hooks/useComponentPermission';
|
||||||
import useFetch from 'hooks/useFetch';
|
import useFetch from 'hooks/useFetch';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { isUndefined } from 'lodash-es';
|
import { isUndefined } from 'lodash-es';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
@@ -21,13 +21,14 @@ const { Paragraph } = Typography;
|
|||||||
function AlertChannels(): JSX.Element {
|
function AlertChannels(): JSX.Element {
|
||||||
const { t } = useTranslation(['channels']);
|
const { t } = useTranslation(['channels']);
|
||||||
const { user } = useAppContext();
|
const { user } = useAppContext();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const [addNewChannelPermission] = useComponentPermission(
|
const [addNewChannelPermission] = useComponentPermission(
|
||||||
['add_new_channel'],
|
['add_new_channel'],
|
||||||
user.role,
|
user.role,
|
||||||
);
|
);
|
||||||
const onToggleHandler = useCallback(() => {
|
const onToggleHandler = useCallback(() => {
|
||||||
history.push(ROUTES.CHANNELS_NEW);
|
safeNavigate(ROUTES.CHANNELS_NEW);
|
||||||
}, []);
|
}, [safeNavigate]);
|
||||||
|
|
||||||
const { loading, payload, error, errorMessage } = useFetch(getAll);
|
const { loading, payload, error, errorMessage } = useFetch(getAll);
|
||||||
|
|
||||||
|
|||||||
@@ -21,17 +21,17 @@ import ROUTES from 'constants/routes';
|
|||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||||
import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils';
|
import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { TimestampInput } from 'hooks/useTimezoneFormatter/useTimezoneFormatter';
|
import { TimestampInput } from 'hooks/useTimezoneFormatter/useTimezoneFormatter';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import createQueryParams from 'lib/createQueryParams';
|
import createQueryParams from 'lib/createQueryParams';
|
||||||
import history from 'lib/history';
|
|
||||||
import { isUndefined } from 'lodash-es';
|
import { isUndefined } from 'lodash-es';
|
||||||
import { useTimezone } from 'providers/Timezone';
|
import { useTimezone } from 'providers/Timezone';
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQueries } from 'react-query';
|
import { useQueries } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
import { Exception, PayloadProps } from 'types/api/errors/getAll';
|
import { Exception, PayloadProps } from 'types/api/errors/getAll';
|
||||||
@@ -66,6 +66,7 @@ function AllErrors(): JSX.Element {
|
|||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
);
|
);
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const params = useUrlQuery();
|
const params = useUrlQuery();
|
||||||
const { t } = useTranslation(['common']);
|
const { t } = useTranslation(['common']);
|
||||||
const {
|
const {
|
||||||
@@ -202,7 +203,9 @@ function AllErrors(): JSX.Element {
|
|||||||
queryParams.serviceName = serviceFilterValue;
|
queryParams.serviceName = serviceFilterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
history.replace(`${pathname}?${createQueryParams(queryParams)}`);
|
safeNavigate(`${pathname}?${createQueryParams(queryParams)}`, {
|
||||||
|
replace: true,
|
||||||
|
});
|
||||||
confirm();
|
confirm();
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
@@ -213,6 +216,7 @@ function AllErrors(): JSX.Element {
|
|||||||
getUpdatedServiceName,
|
getUpdatedServiceName,
|
||||||
pathname,
|
pathname,
|
||||||
updatedOrder,
|
updatedOrder,
|
||||||
|
safeNavigate,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -414,7 +418,7 @@ function AllErrors(): JSX.Element {
|
|||||||
serviceName: getFilterString(params.get(urlKey.serviceName)),
|
serviceName: getFilterString(params.get(urlKey.serviceName)),
|
||||||
exceptionType: getFilterString(params.get(urlKey.exceptionType)),
|
exceptionType: getFilterString(params.get(urlKey.exceptionType)),
|
||||||
});
|
});
|
||||||
history.replace(
|
safeNavigate(
|
||||||
`${pathname}?${createQueryParams({
|
`${pathname}?${createQueryParams({
|
||||||
order: updatedOrder,
|
order: updatedOrder,
|
||||||
offset: (current - 1) * pageSize,
|
offset: (current - 1) * pageSize,
|
||||||
@@ -423,10 +427,11 @@ function AllErrors(): JSX.Element {
|
|||||||
exceptionType,
|
exceptionType,
|
||||||
serviceName,
|
serviceName,
|
||||||
})}`,
|
})}`,
|
||||||
|
{ replace: true },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[pathname],
|
[pathname, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const logEventCalledRef = useRef(false);
|
const logEventCalledRef = useRef(false);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import dayjs from 'dayjs';
|
|||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { isNull } from 'lodash-es';
|
import { isNull } from 'lodash-es';
|
||||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||||
import { INTEGRATION_TYPES } from 'pages/Integrations/utils';
|
import { INTEGRATION_TYPES } from 'pages/Integrations/utils';
|
||||||
@@ -42,7 +42,7 @@ import { Helmet } from 'react-helmet-async';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useMutation, useQueries } from 'react-query';
|
import { useMutation, useQueries } from 'react-query';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { Dispatch } from 'redux';
|
import { Dispatch } from 'redux';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import {
|
import {
|
||||||
@@ -121,6 +121,7 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const { t } = useTranslation(['titles']);
|
const { t } = useTranslation(['titles']);
|
||||||
@@ -319,9 +320,9 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
|
|
||||||
const handleUpgrade = useCallback((): void => {
|
const handleUpgrade = useCallback((): void => {
|
||||||
if (user.role === USER_ROLES.ADMIN) {
|
if (user.role === USER_ROLES.ADMIN) {
|
||||||
history.push(ROUTES.BILLING);
|
safeNavigate(ROUTES.BILLING);
|
||||||
}
|
}
|
||||||
}, [user.role]);
|
}, [user.role, safeNavigate]);
|
||||||
|
|
||||||
const handleFailedPayment = useCallback((): void => {
|
const handleFailedPayment = useCallback((): void => {
|
||||||
manageCreditCard({
|
manageCreditCard({
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import './Header.styles.scss';
|
|||||||
import Breadcrumb from 'antd/es/breadcrumb';
|
import Breadcrumb from 'antd/es/breadcrumb';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { Blocks, LifeBuoy } from 'lucide-react';
|
import { Blocks, LifeBuoy } from 'lucide-react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
function Header(): JSX.Element {
|
function Header(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import { Button, Select, Skeleton } from 'antd';
|
|||||||
import { SelectProps } from 'antd/lib';
|
import { SelectProps } from 'antd/lib';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { useAwsAccounts } from 'hooks/integration/aws/useAwsAccounts';
|
import { useAwsAccounts } from 'hooks/integration/aws/useAwsAccounts';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { Check, ChevronDown } from 'lucide-react';
|
import { Check, ChevronDown } from 'lucide-react';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom-v5-compat';
|
|
||||||
|
|
||||||
import { CloudAccount } from '../../ServicesSection/types';
|
import { CloudAccount } from '../../ServicesSection/types';
|
||||||
import AccountSettingsModal from './AccountSettingsModal';
|
import AccountSettingsModal from './AccountSettingsModal';
|
||||||
@@ -140,7 +140,7 @@ function AccountActionsRenderer({
|
|||||||
|
|
||||||
function AccountActions(): JSX.Element {
|
function AccountActions(): JSX.Element {
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
const navigate = useNavigate();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const { data: accounts, isLoading } = useAwsAccounts();
|
const { data: accounts, isLoading } = useAwsAccounts();
|
||||||
|
|
||||||
const initialAccount = useMemo(
|
const initialAccount = useMemo(
|
||||||
@@ -162,7 +162,7 @@ function AccountActions(): JSX.Element {
|
|||||||
setActiveAccount(initialAccount);
|
setActiveAccount(initialAccount);
|
||||||
const latestUrlQuery = new URLSearchParams(window.location.search);
|
const latestUrlQuery = new URLSearchParams(window.location.search);
|
||||||
latestUrlQuery.set('cloudAccountId', initialAccount.cloud_account_id);
|
latestUrlQuery.set('cloudAccountId', initialAccount.cloud_account_id);
|
||||||
navigate({ search: latestUrlQuery.toString() });
|
safeNavigate({ search: latestUrlQuery.toString() });
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [initialAccount]);
|
}, [initialAccount]);
|
||||||
@@ -216,7 +216,7 @@ function AccountActions(): JSX.Element {
|
|||||||
if (accounts) {
|
if (accounts) {
|
||||||
setActiveAccount(getAccountById(accounts, value));
|
setActiveAccount(getAccountById(accounts, value));
|
||||||
urlQuery.set('cloudAccountId', value);
|
urlQuery.set('cloudAccountId', value);
|
||||||
navigate({ search: urlQuery.toString() });
|
safeNavigate({ search: urlQuery.toString() });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onIntegrationModalOpen={startAccountConnectionAttempt}
|
onIntegrationModalOpen={startAccountConnectionAttempt}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import {
|
|||||||
getRegionPreviewText,
|
getRegionPreviewText,
|
||||||
useAccountSettingsModal,
|
useAccountSettingsModal,
|
||||||
} from 'hooks/integration/aws/useAccountSettingsModal';
|
} from 'hooks/integration/aws/useAccountSettingsModal';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import history from 'lib/history';
|
|
||||||
import { Dispatch, SetStateAction, useCallback } from 'react';
|
import { Dispatch, SetStateAction, useCallback } from 'react';
|
||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
|
|
||||||
@@ -45,12 +45,13 @@ function AccountSettingsModal({
|
|||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const handleRemoveIntegrationAccountSuccess = (): void => {
|
const handleRemoveIntegrationAccountSuccess = (): void => {
|
||||||
queryClient.invalidateQueries([REACT_QUERY_KEY.AWS_ACCOUNTS]);
|
queryClient.invalidateQueries([REACT_QUERY_KEY.AWS_ACCOUNTS]);
|
||||||
urlQuery.delete('cloudAccountId');
|
urlQuery.delete('cloudAccountId');
|
||||||
handleClose();
|
handleClose();
|
||||||
history.replace({ search: urlQuery.toString() });
|
safeNavigate({ search: urlQuery.toString() });
|
||||||
|
|
||||||
logEvent('AWS Integration: Account removed', {
|
logEvent('AWS Integration: Account removed', {
|
||||||
id: account?.id,
|
id: account?.id,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
import { ServiceData } from './types';
|
import { ServiceData } from './types';
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { useGetAccountServices } from 'hooks/integration/aws/useGetAccountServices';
|
import { useGetAccountServices } from 'hooks/integration/aws/useGetAccountServices';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { useCallback, useEffect, useMemo } from 'react';
|
import { useCallback, useEffect, useMemo } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom-v5-compat';
|
|
||||||
|
|
||||||
import ServiceItem from './ServiceItem';
|
import ServiceItem from './ServiceItem';
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ function ServicesList({
|
|||||||
filter,
|
filter,
|
||||||
}: ServicesListProps): JSX.Element {
|
}: ServicesListProps): JSX.Element {
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
const navigate = useNavigate();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const { data: services = [], isLoading } = useGetAccountServices(
|
const { data: services = [], isLoading } = useGetAccountServices(
|
||||||
cloudAccountId,
|
cloudAccountId,
|
||||||
);
|
);
|
||||||
@@ -26,9 +26,9 @@ function ServicesList({
|
|||||||
(serviceId: string): void => {
|
(serviceId: string): void => {
|
||||||
const latestUrlQuery = new URLSearchParams(window.location.search);
|
const latestUrlQuery = new URLSearchParams(window.location.search);
|
||||||
latestUrlQuery.set('service', serviceId);
|
latestUrlQuery.set('service', serviceId);
|
||||||
navigate({ search: latestUrlQuery.toString() });
|
safeNavigate({ search: latestUrlQuery.toString() });
|
||||||
},
|
},
|
||||||
[navigate],
|
[safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const filteredServices = useMemo(() => {
|
const filteredServices = useMemo(() => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
function LinkContainer({ children, href }: LinkContainerProps): JSX.Element {
|
function LinkContainer({ children, href }: LinkContainerProps): JSX.Element {
|
||||||
const isInternalLink = href.startsWith('/');
|
const isInternalLink = href.startsWith('/');
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import logEvent from 'api/common/logEvent';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import FormAlertChannels from 'container/FormAlertChannels';
|
import FormAlertChannels from 'container/FormAlertChannels';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@@ -86,6 +86,7 @@ function CreateAlertChannels({
|
|||||||
const [savingState, setSavingState] = useState<boolean>(false);
|
const [savingState, setSavingState] = useState<boolean>(false);
|
||||||
const [testingState, setTestingState] = useState<boolean>(false);
|
const [testingState, setTestingState] = useState<boolean>(false);
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const [type, setType] = useState<ChannelType>(preType);
|
const [type, setType] = useState<ChannelType>(preType);
|
||||||
const onTypeChangeHandler = useCallback(
|
const onTypeChangeHandler = useCallback(
|
||||||
@@ -143,7 +144,7 @@ function CreateAlertChannels({
|
|||||||
message: 'Success',
|
message: 'Success',
|
||||||
description: t('channel_creation_done'),
|
description: t('channel_creation_done'),
|
||||||
});
|
});
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_creation_done') };
|
return { status: 'success', statusMessage: t('channel_creation_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -163,7 +164,7 @@ function CreateAlertChannels({
|
|||||||
} finally {
|
} finally {
|
||||||
setSavingState(false);
|
setSavingState(false);
|
||||||
}
|
}
|
||||||
}, [prepareSlackRequest, t, notifications]);
|
}, [prepareSlackRequest, t, notifications, safeNavigate]);
|
||||||
|
|
||||||
const prepareWebhookRequest = useCallback(() => {
|
const prepareWebhookRequest = useCallback(() => {
|
||||||
// initial api request without auth params
|
// initial api request without auth params
|
||||||
@@ -210,7 +211,7 @@ function CreateAlertChannels({
|
|||||||
message: 'Success',
|
message: 'Success',
|
||||||
description: t('channel_creation_done'),
|
description: t('channel_creation_done'),
|
||||||
});
|
});
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_creation_done') };
|
return { status: 'success', statusMessage: t('channel_creation_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -230,7 +231,7 @@ function CreateAlertChannels({
|
|||||||
} finally {
|
} finally {
|
||||||
setSavingState(false);
|
setSavingState(false);
|
||||||
}
|
}
|
||||||
}, [prepareWebhookRequest, t, notifications]);
|
}, [prepareWebhookRequest, t, notifications, safeNavigate]);
|
||||||
|
|
||||||
const preparePagerRequest = useCallback(() => {
|
const preparePagerRequest = useCallback(() => {
|
||||||
const validationError = ValidatePagerChannel(selectedConfig as PagerChannel);
|
const validationError = ValidatePagerChannel(selectedConfig as PagerChannel);
|
||||||
@@ -271,7 +272,7 @@ function CreateAlertChannels({
|
|||||||
message: 'Success',
|
message: 'Success',
|
||||||
description: t('channel_creation_done'),
|
description: t('channel_creation_done'),
|
||||||
});
|
});
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_creation_done') };
|
return { status: 'success', statusMessage: t('channel_creation_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -297,7 +298,7 @@ function CreateAlertChannels({
|
|||||||
} finally {
|
} finally {
|
||||||
setSavingState(false);
|
setSavingState(false);
|
||||||
}
|
}
|
||||||
}, [t, notifications, preparePagerRequest]);
|
}, [t, notifications, preparePagerRequest, safeNavigate]);
|
||||||
|
|
||||||
const prepareOpsgenieRequest = useCallback(
|
const prepareOpsgenieRequest = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -322,7 +323,7 @@ function CreateAlertChannels({
|
|||||||
message: 'Success',
|
message: 'Success',
|
||||||
description: t('channel_creation_done'),
|
description: t('channel_creation_done'),
|
||||||
});
|
});
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_creation_done') };
|
return { status: 'success', statusMessage: t('channel_creation_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -342,7 +343,7 @@ function CreateAlertChannels({
|
|||||||
} finally {
|
} finally {
|
||||||
setSavingState(false);
|
setSavingState(false);
|
||||||
}
|
}
|
||||||
}, [prepareOpsgenieRequest, t, notifications]);
|
}, [prepareOpsgenieRequest, t, notifications, safeNavigate]);
|
||||||
|
|
||||||
const prepareEmailRequest = useCallback(
|
const prepareEmailRequest = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -365,7 +366,7 @@ function CreateAlertChannels({
|
|||||||
message: 'Success',
|
message: 'Success',
|
||||||
description: t('channel_creation_done'),
|
description: t('channel_creation_done'),
|
||||||
});
|
});
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_creation_done') };
|
return { status: 'success', statusMessage: t('channel_creation_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -385,7 +386,7 @@ function CreateAlertChannels({
|
|||||||
} finally {
|
} finally {
|
||||||
setSavingState(false);
|
setSavingState(false);
|
||||||
}
|
}
|
||||||
}, [prepareEmailRequest, t, notifications]);
|
}, [prepareEmailRequest, t, notifications, safeNavigate]);
|
||||||
|
|
||||||
const prepareMsTeamsRequest = useCallback(
|
const prepareMsTeamsRequest = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -409,7 +410,7 @@ function CreateAlertChannels({
|
|||||||
message: 'Success',
|
message: 'Success',
|
||||||
description: t('channel_creation_done'),
|
description: t('channel_creation_done'),
|
||||||
});
|
});
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_creation_done') };
|
return { status: 'success', statusMessage: t('channel_creation_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -429,7 +430,7 @@ function CreateAlertChannels({
|
|||||||
} finally {
|
} finally {
|
||||||
setSavingState(false);
|
setSavingState(false);
|
||||||
}
|
}
|
||||||
}, [prepareMsTeamsRequest, t, notifications]);
|
}, [prepareMsTeamsRequest, t, notifications, safeNavigate]);
|
||||||
|
|
||||||
const onSaveHandler = useCallback(
|
const onSaveHandler = useCallback(
|
||||||
async (value: ChannelType) => {
|
async (value: ChannelType) => {
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { ENTITY_VERSION_V4 } from 'constants/app';
|
|||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import FormAlertRules, { AlertDetectionTypes } from 'container/FormAlertRules';
|
import FormAlertRules, { AlertDetectionTypes } from 'container/FormAlertRules';
|
||||||
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
|
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
||||||
import { AlertDef } from 'types/api/alerts/def';
|
import { AlertDef } from 'types/api/alerts/def';
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ function CreateRules(): JSX.Element {
|
|||||||
const [initValues, setInitValues] = useState<AlertDef | null>(null);
|
const [initValues, setInitValues] = useState<AlertDef | null>(null);
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const queryParams = new URLSearchParams(location.search);
|
const queryParams = new URLSearchParams(location.search);
|
||||||
const alertTypeFromURL = queryParams.get(QueryParams.ruleType);
|
const alertTypeFromURL = queryParams.get(QueryParams.ruleType);
|
||||||
const version = queryParams.get('version');
|
const version = queryParams.get('version');
|
||||||
@@ -96,7 +97,7 @@ function CreateRules(): JSX.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const generatedUrl = `${location.pathname}?${queryParams.toString()}`;
|
const generatedUrl = `${location.pathname}?${queryParams.toString()}`;
|
||||||
history.replace(generatedUrl);
|
safeNavigate(generatedUrl, { replace: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import {
|
|||||||
} from 'container/CreateAlertChannels/config';
|
} from 'container/CreateAlertChannels/config';
|
||||||
import FormAlertChannels from 'container/FormAlertChannels';
|
import FormAlertChannels from 'container/FormAlertChannels';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
function EditAlertChannels({
|
function EditAlertChannels({
|
||||||
initialValue,
|
initialValue,
|
||||||
@@ -52,7 +52,9 @@ function EditAlertChannels({
|
|||||||
const [savingState, setSavingState] = useState<boolean>(false);
|
const [savingState, setSavingState] = useState<boolean>(false);
|
||||||
const [testingState, setTestingState] = useState<boolean>(false);
|
const [testingState, setTestingState] = useState<boolean>(false);
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
const { id } = useParams<{ id: string }>();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const { id } = useParams() as { id: string };
|
||||||
|
|
||||||
const [type, setType] = useState<ChannelType>(
|
const [type, setType] = useState<ChannelType>(
|
||||||
initialValue?.type ? (initialValue.type as ChannelType) : ChannelType.Slack,
|
initialValue?.type ? (initialValue.type as ChannelType) : ChannelType.Slack,
|
||||||
@@ -101,7 +103,7 @@ function EditAlertChannels({
|
|||||||
description: t('channel_edit_done'),
|
description: t('channel_edit_done'),
|
||||||
});
|
});
|
||||||
|
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_edit_done') };
|
return { status: 'success', statusMessage: t('channel_edit_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -113,7 +115,7 @@ function EditAlertChannels({
|
|||||||
status: 'failed',
|
status: 'failed',
|
||||||
statusMessage: response.error || t('channel_edit_failed'),
|
statusMessage: response.error || t('channel_edit_failed'),
|
||||||
};
|
};
|
||||||
}, [prepareSlackRequest, t, notifications, selectedConfig]);
|
}, [prepareSlackRequest, t, notifications, selectedConfig, safeNavigate]);
|
||||||
|
|
||||||
const prepareWebhookRequest = useCallback(() => {
|
const prepareWebhookRequest = useCallback(() => {
|
||||||
const { name, username, password } = selectedConfig;
|
const { name, username, password } = selectedConfig;
|
||||||
@@ -158,7 +160,7 @@ function EditAlertChannels({
|
|||||||
description: t('channel_edit_done'),
|
description: t('channel_edit_done'),
|
||||||
});
|
});
|
||||||
|
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_edit_done') };
|
return { status: 'success', statusMessage: t('channel_edit_done') };
|
||||||
}
|
}
|
||||||
showError(response.error || t('channel_edit_failed'));
|
showError(response.error || t('channel_edit_failed'));
|
||||||
@@ -168,7 +170,7 @@ function EditAlertChannels({
|
|||||||
status: 'failed',
|
status: 'failed',
|
||||||
statusMessage: response.error || t('channel_edit_failed'),
|
statusMessage: response.error || t('channel_edit_failed'),
|
||||||
};
|
};
|
||||||
}, [prepareWebhookRequest, t, notifications, selectedConfig]);
|
}, [prepareWebhookRequest, t, notifications, selectedConfig, safeNavigate]);
|
||||||
|
|
||||||
const prepareEmailRequest = useCallback(
|
const prepareEmailRequest = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -191,7 +193,7 @@ function EditAlertChannels({
|
|||||||
message: 'Success',
|
message: 'Success',
|
||||||
description: t('channel_edit_done'),
|
description: t('channel_edit_done'),
|
||||||
});
|
});
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_edit_done') };
|
return { status: 'success', statusMessage: t('channel_edit_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -204,7 +206,7 @@ function EditAlertChannels({
|
|||||||
status: 'failed',
|
status: 'failed',
|
||||||
statusMessage: response.error || t('channel_edit_failed'),
|
statusMessage: response.error || t('channel_edit_failed'),
|
||||||
};
|
};
|
||||||
}, [prepareEmailRequest, t, notifications]);
|
}, [prepareEmailRequest, t, notifications, safeNavigate]);
|
||||||
|
|
||||||
const preparePagerRequest = useCallback(
|
const preparePagerRequest = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -245,7 +247,7 @@ function EditAlertChannels({
|
|||||||
description: t('channel_edit_done'),
|
description: t('channel_edit_done'),
|
||||||
});
|
});
|
||||||
|
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_edit_done') };
|
return { status: 'success', statusMessage: t('channel_edit_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -258,7 +260,7 @@ function EditAlertChannels({
|
|||||||
status: 'failed',
|
status: 'failed',
|
||||||
statusMessage: response.error || t('channel_edit_failed'),
|
statusMessage: response.error || t('channel_edit_failed'),
|
||||||
};
|
};
|
||||||
}, [preparePagerRequest, notifications, selectedConfig, t]);
|
}, [preparePagerRequest, notifications, selectedConfig, t, safeNavigate]);
|
||||||
|
|
||||||
const prepareOpsgenieRequest = useCallback(
|
const prepareOpsgenieRequest = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -293,7 +295,7 @@ function EditAlertChannels({
|
|||||||
description: t('channel_edit_done'),
|
description: t('channel_edit_done'),
|
||||||
});
|
});
|
||||||
|
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_edit_done') };
|
return { status: 'success', statusMessage: t('channel_edit_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -306,7 +308,7 @@ function EditAlertChannels({
|
|||||||
status: 'failed',
|
status: 'failed',
|
||||||
statusMessage: response.error || t('channel_edit_failed'),
|
statusMessage: response.error || t('channel_edit_failed'),
|
||||||
};
|
};
|
||||||
}, [prepareOpsgenieRequest, t, notifications, selectedConfig]);
|
}, [prepareOpsgenieRequest, t, notifications, selectedConfig, safeNavigate]);
|
||||||
|
|
||||||
const prepareMsTeamsRequest = useCallback(
|
const prepareMsTeamsRequest = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -340,7 +342,7 @@ function EditAlertChannels({
|
|||||||
description: t('channel_edit_done'),
|
description: t('channel_edit_done'),
|
||||||
});
|
});
|
||||||
|
|
||||||
history.replace(ROUTES.ALL_CHANNELS);
|
safeNavigate(ROUTES.ALL_CHANNELS, { replace: true });
|
||||||
return { status: 'success', statusMessage: t('channel_edit_done') };
|
return { status: 'success', statusMessage: t('channel_edit_done') };
|
||||||
}
|
}
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@@ -353,7 +355,7 @@ function EditAlertChannels({
|
|||||||
status: 'failed',
|
status: 'failed',
|
||||||
statusMessage: response.error || t('channel_edit_failed'),
|
statusMessage: response.error || t('channel_edit_failed'),
|
||||||
};
|
};
|
||||||
}, [prepareMsTeamsRequest, t, notifications, selectedConfig]);
|
}, [prepareMsTeamsRequest, t, notifications, selectedConfig, safeNavigate]);
|
||||||
|
|
||||||
const onSaveHandler = useCallback(
|
const onSaveHandler = useCallback(
|
||||||
async (value: ChannelType) => {
|
async (value: ChannelType) => {
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ import { ResizeTable } from 'components/ResizeTable';
|
|||||||
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
||||||
import { getNanoSeconds } from 'container/AllError/utils';
|
import { getNanoSeconds } from 'container/AllError/utils';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import createQueryParams from 'lib/createQueryParams';
|
import createQueryParams from 'lib/createQueryParams';
|
||||||
import history from 'lib/history';
|
|
||||||
import { isUndefined } from 'lodash-es';
|
import { isUndefined } from 'lodash-es';
|
||||||
import { urlKey } from 'pages/ErrorDetails/utils';
|
import { urlKey } from 'pages/ErrorDetails/utils';
|
||||||
import { useTimezone } from 'providers/Timezone';
|
import { useTimezone } from 'providers/Timezone';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { PayloadProps as GetByErrorTypeAndServicePayload } from 'types/api/errors/getByErrorTypeAndService';
|
import { PayloadProps as GetByErrorTypeAndServicePayload } from 'types/api/errors/getByErrorTypeAndService';
|
||||||
|
|
||||||
import { keyToExclude } from './config';
|
import { keyToExclude } from './config';
|
||||||
@@ -77,6 +77,7 @@ function ErrorDetails(props: ErrorDetailsProps): JSX.Element {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const onClickErrorIdHandler = async (
|
const onClickErrorIdHandler = async (
|
||||||
id: string,
|
id: string,
|
||||||
@@ -96,7 +97,9 @@ function ErrorDetails(props: ErrorDetailsProps): JSX.Element {
|
|||||||
errorId: id,
|
errorId: id,
|
||||||
};
|
};
|
||||||
|
|
||||||
history.replace(`${pathname}?${createQueryParams(queryParams)}`);
|
safeNavigate(`${pathname}?${createQueryParams(queryParams)}`, {
|
||||||
|
replace: true,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error({
|
notifications.error({
|
||||||
message: t('something_went_wrong'),
|
message: t('something_went_wrong'),
|
||||||
@@ -118,7 +121,7 @@ function ErrorDetails(props: ErrorDetailsProps): JSX.Element {
|
|||||||
traceId: errorDetail.traceID,
|
traceId: errorDetail.traceID,
|
||||||
exceptionId: errorDetail?.errorId,
|
exceptionId: errorDetail?.errorId,
|
||||||
});
|
});
|
||||||
history.push(`/trace/${errorDetail.traceID}?spanId=${errorDetail.spanID}`);
|
safeNavigate(`/trace/${errorDetail.traceID}?spanId=${errorDetail.spanID}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const logEventCalledRef = useRef(false);
|
const logEventCalledRef = useRef(false);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
|
|||||||
import useErrorNotification from 'hooks/useErrorNotification';
|
import useErrorNotification from 'hooks/useErrorNotification';
|
||||||
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
|
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
|
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
|
||||||
import { cloneDeep, isEqual, omit } from 'lodash-es';
|
import { cloneDeep, isEqual, omit } from 'lodash-es';
|
||||||
import {
|
import {
|
||||||
@@ -60,7 +61,6 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
@@ -96,7 +96,7 @@ function ExplorerOptions({
|
|||||||
const [newViewName, setNewViewName] = useState<string>('');
|
const [newViewName, setNewViewName] = useState<string>('');
|
||||||
const [color, setColor] = useState(Color.BG_SIENNA_500);
|
const [color, setColor] = useState(Color.BG_SIENNA_500);
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const ref = useRef<RefSelectProps>(null);
|
const ref = useRef<RefSelectProps>(null);
|
||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
const isLogsExplorer = sourcepage === DataSource.LOGS;
|
const isLogsExplorer = sourcepage === DataSource.LOGS;
|
||||||
@@ -181,13 +181,13 @@ function ExplorerOptions({
|
|||||||
|
|
||||||
const stringifiedQuery = handleConditionalQueryModification();
|
const stringifiedQuery = handleConditionalQueryModification();
|
||||||
|
|
||||||
history.push(
|
safeNavigate(
|
||||||
`${ROUTES.ALERTS_NEW}?${QueryParams.compositeQuery}=${encodeURIComponent(
|
`${ROUTES.ALERTS_NEW}?${QueryParams.compositeQuery}=${encodeURIComponent(
|
||||||
stringifiedQuery,
|
stringifiedQuery,
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [handleConditionalQueryModification, history]);
|
}, [handleConditionalQueryModification, safeNavigate]);
|
||||||
|
|
||||||
const onCancel = (value: boolean) => (): void => {
|
const onCancel = (value: boolean) => (): void => {
|
||||||
onModalToggle(value);
|
onModalToggle(value);
|
||||||
@@ -461,7 +461,7 @@ function ExplorerOptions({
|
|||||||
: defaultLogsSelectedColumns,
|
: defaultLogsSelectedColumns,
|
||||||
});
|
});
|
||||||
|
|
||||||
history.replace(DATASOURCE_VS_ROUTES[sourcepage]);
|
safeNavigate(DATASOURCE_VS_ROUTES[sourcepage], { replace: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
const isQueryUpdated = isStagedQueryUpdated(
|
const isQueryUpdated = isStagedQueryUpdated(
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
SlackChannel,
|
SlackChannel,
|
||||||
WebhookChannel,
|
WebhookChannel,
|
||||||
} from 'container/CreateAlertChannels/config';
|
} from 'container/CreateAlertChannels/config';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { Dispatch, ReactElement, SetStateAction } from 'react';
|
import { Dispatch, ReactElement, SetStateAction } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@@ -35,6 +35,7 @@ function FormAlertChannels({
|
|||||||
editing = false,
|
editing = false,
|
||||||
}: FormAlertChannelsProps): JSX.Element {
|
}: FormAlertChannelsProps): JSX.Element {
|
||||||
const { t } = useTranslation('channels');
|
const { t } = useTranslation('channels');
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const renderSettings = (): ReactElement | null => {
|
const renderSettings = (): ReactElement | null => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -147,7 +148,7 @@ function FormAlertChannels({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
history.replace(ROUTES.SETTINGS);
|
safeNavigate(ROUTES.SETTINGS);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('button_return')}
|
{t('button_return')}
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ import {
|
|||||||
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { useResizeObserver } from 'hooks/useDimensions';
|
import { useResizeObserver } from 'hooks/useDimensions';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import GetMinMax from 'lib/getMinMax';
|
import GetMinMax from 'lib/getMinMax';
|
||||||
import getTimeString from 'lib/getTimeString';
|
import getTimeString from 'lib/getTimeString';
|
||||||
import history from 'lib/history';
|
|
||||||
import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
|
import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
|
||||||
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
|
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
@@ -29,7 +29,7 @@ import { useTimezone } from 'providers/Timezone';
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { AlertDef } from 'types/api/alerts/def';
|
import { AlertDef } from 'types/api/alerts/def';
|
||||||
@@ -85,6 +85,7 @@ function ChartPreview({
|
|||||||
>((state) => state.globalTime);
|
>((state) => state.globalTime);
|
||||||
|
|
||||||
const { featureFlags } = useAppContext();
|
const { featureFlags } = useAppContext();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const handleBackNavigation = (): void => {
|
const handleBackNavigation = (): void => {
|
||||||
const searchParams = new URLSearchParams(window.location.search);
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
@@ -200,9 +201,9 @@ function ChartPreview({
|
|||||||
urlQuery.set(QueryParams.startTime, minTime.toString());
|
urlQuery.set(QueryParams.startTime, minTime.toString());
|
||||||
urlQuery.set(QueryParams.endTime, maxTime.toString());
|
urlQuery.set(QueryParams.endTime, maxTime.toString());
|
||||||
const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
|
||||||
history.push(generatedUrl);
|
safeNavigate(generatedUrl);
|
||||||
},
|
},
|
||||||
[dispatch, location.pathname, urlQuery],
|
[dispatch, location.pathname, urlQuery, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { timezone } = useTimezone();
|
const { timezone } = useTimezone();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -2,15 +2,16 @@
|
|||||||
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||||
import './FullScreenHeader.styles.scss';
|
import './FullScreenHeader.styles.scss';
|
||||||
|
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
|
|
||||||
export default function FullScreenHeader({
|
export default function FullScreenHeader({
|
||||||
overrideRoute,
|
overrideRoute,
|
||||||
}: {
|
}: {
|
||||||
overrideRoute?: string;
|
overrideRoute?: string;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const handleLogoClick = (): void => {
|
const handleLogoClick = (): void => {
|
||||||
history.push(overrideRoute || '/');
|
safeNavigate(overrideRoute || '/');
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="full-screen-header-container">
|
<div className="full-screen-header-container">
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import GetMinMax from 'lib/getMinMax';
|
|||||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import { FullScreen, FullScreenHandle } from 'react-full-screen';
|
import { FullScreen, FullScreenHandle } from 'react-full-screen';
|
||||||
import { ItemCallback, Layout } from 'react-grid-layout';
|
import { ItemCallback, Layout } from 'react-grid-layout';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { Dashboard, Widgets } from 'types/api/dashboard/getAll';
|
import { Dashboard, Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { ROLES, USER_ROLES } from 'types/roles';
|
import { ROLES, USER_ROLES } from 'types/roles';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { getYAxisFormattedValue } from 'components/Graph/yAxisConfig';
|
|||||||
import ValueGraph from 'components/ValueGraph';
|
import ValueGraph from 'components/ValueGraph';
|
||||||
import { generateGridTitle } from 'container/GridPanelSwitch/utils';
|
import { generateGridTitle } from 'container/GridPanelSwitch/utils';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
import { TitleContainer, ValueContainer } from './styles';
|
import { TitleContainer, ValueContainer } from './styles';
|
||||||
import { GridValueComponentProps } from './types';
|
import { GridValueComponentProps } from './types';
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import getAll from 'api/alerts/getAll';
|
|||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
||||||
import { ArrowRight, ArrowUpRight, Plus } from 'lucide-react';
|
import { ArrowRight, ArrowUpRight, Plus } from 'lucide-react';
|
||||||
import Card from 'periscope/components/Card/Card';
|
import Card from 'periscope/components/Card/Card';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router';
|
||||||
import { GettableAlert } from 'types/api/alerts/get';
|
import { GettableAlert } from 'types/api/alerts/get';
|
||||||
import { USER_ROLES } from 'types/roles';
|
import { USER_ROLES } from 'types/roles';
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ export default function AlertRules({
|
|||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
// Fetch Alerts
|
// Fetch Alerts
|
||||||
const { data: alerts, isError, isLoading } = useQuery('allAlerts', {
|
const { data: alerts, isError, isLoading } = useQuery('allAlerts', {
|
||||||
@@ -131,7 +132,7 @@ export default function AlertRules({
|
|||||||
|
|
||||||
params.set(QueryParams.ruleId, record.id.toString());
|
params.set(QueryParams.ruleId, record.id.toString());
|
||||||
|
|
||||||
history.push(`${ROUTES.ALERT_OVERVIEW}?${params.toString()}`);
|
safeNavigate(`${ROUTES.ALERT_OVERVIEW}?${params.toString()}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderAlertRules = (): JSX.Element => (
|
const renderAlertRules = (): JSX.Element => (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { ArrowRight, ArrowUpRight, Plus } from 'lucide-react';
|
|||||||
import Card from 'periscope/components/Card/Card';
|
import Card from 'periscope/components/Card/Card';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
import { USER_ROLES } from 'types/roles';
|
import { USER_ROLES } from 'types/roles';
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Button, Skeleton, Tag, Typography } from 'antd';
|
|||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useGetDeploymentsData } from 'hooks/CustomDomain/useGetDeploymentsData';
|
import { useGetDeploymentsData } from 'hooks/CustomDomain/useGetDeploymentsData';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { Globe, Link2 } from 'lucide-react';
|
import { Globe, Link2 } from 'lucide-react';
|
||||||
import Card from 'periscope/components/Card/Card';
|
import Card from 'periscope/components/Card/Card';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
@@ -20,6 +20,7 @@ function DataSourceInfo({
|
|||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { activeLicenseV3 } = useAppContext();
|
const { activeLicenseV3 } = useAppContext();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const notSendingData = !dataSentToSigNoz;
|
const notSendingData = !dataSentToSigNoz;
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ function DataSourceInfo({
|
|||||||
activeLicenseV3 &&
|
activeLicenseV3 &&
|
||||||
activeLicenseV3.platform === LicensePlatform.CLOUD
|
activeLicenseV3.platform === LicensePlatform.CLOUD
|
||||||
) {
|
) {
|
||||||
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
safeNavigate(ROUTES.GET_STARTED_WITH_CLOUD);
|
||||||
} else {
|
} else {
|
||||||
window?.open(
|
window?.open(
|
||||||
DOCS_LINKS.ADD_DATA_SOURCE,
|
DOCS_LINKS.ADD_DATA_SOURCE,
|
||||||
@@ -108,7 +109,7 @@ function DataSourceInfo({
|
|||||||
activeLicenseV3 &&
|
activeLicenseV3 &&
|
||||||
activeLicenseV3.platform === LicensePlatform.CLOUD
|
activeLicenseV3.platform === LicensePlatform.CLOUD
|
||||||
) {
|
) {
|
||||||
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
safeNavigate(ROUTES.GET_STARTED_WITH_CLOUD);
|
||||||
} else {
|
} else {
|
||||||
window?.open(
|
window?.open(
|
||||||
DOCS_LINKS.ADD_DATA_SOURCE,
|
DOCS_LINKS.ADD_DATA_SOURCE,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { getHostListsQuery } from 'container/InfraMonitoringHosts/utils';
|
|||||||
import { useGetHostList } from 'hooks/infraMonitoring/useGetHostList';
|
import { useGetHostList } from 'hooks/infraMonitoring/useGetHostList';
|
||||||
import { useGetK8sPodsList } from 'hooks/infraMonitoring/useGetK8sPodsList';
|
import { useGetK8sPodsList } from 'hooks/infraMonitoring/useGetK8sPodsList';
|
||||||
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import cloneDeep from 'lodash-es/cloneDeep';
|
import cloneDeep from 'lodash-es/cloneDeep';
|
||||||
import { CompassIcon, DotIcon, HomeIcon, Plus, Wrench } from 'lucide-react';
|
import { CompassIcon, DotIcon, HomeIcon, Plus, Wrench } from 'lucide-react';
|
||||||
import { AnimatePresence } from 'motion/react';
|
import { AnimatePresence } from 'motion/react';
|
||||||
@@ -45,6 +45,7 @@ const homeInterval = 30 * 60 * 1000;
|
|||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
export default function Home(): JSX.Element {
|
export default function Home(): JSX.Element {
|
||||||
const { user } = useAppContext();
|
const { user } = useAppContext();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const [startTime, setStartTime] = useState<number | null>(null);
|
const [startTime, setStartTime] = useState<number | null>(null);
|
||||||
const [endTime, setEndTime] = useState<number | null>(null);
|
const [endTime, setEndTime] = useState<number | null>(null);
|
||||||
@@ -382,14 +383,14 @@ export default function Home(): JSX.Element {
|
|||||||
logEvent('Homepage: Ingestion Active Explore clicked', {
|
logEvent('Homepage: Ingestion Active Explore clicked', {
|
||||||
source: 'Logs',
|
source: 'Logs',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.LOGS_EXPLORER);
|
safeNavigate(ROUTES.LOGS_EXPLORER);
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e): void => {
|
onKeyDown={(e): void => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
logEvent('Homepage: Ingestion Active Explore clicked', {
|
logEvent('Homepage: Ingestion Active Explore clicked', {
|
||||||
source: 'Logs',
|
source: 'Logs',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.LOGS_EXPLORER);
|
safeNavigate(ROUTES.LOGS_EXPLORER);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -423,14 +424,14 @@ export default function Home(): JSX.Element {
|
|||||||
logEvent('Homepage: Ingestion Active Explore clicked', {
|
logEvent('Homepage: Ingestion Active Explore clicked', {
|
||||||
source: 'Traces',
|
source: 'Traces',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.TRACES_EXPLORER);
|
safeNavigate(ROUTES.TRACES_EXPLORER);
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e): void => {
|
onKeyDown={(e): void => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
logEvent('Homepage: Ingestion Active Explore clicked', {
|
logEvent('Homepage: Ingestion Active Explore clicked', {
|
||||||
source: 'Traces',
|
source: 'Traces',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.TRACES_EXPLORER);
|
safeNavigate(ROUTES.TRACES_EXPLORER);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -464,14 +465,14 @@ export default function Home(): JSX.Element {
|
|||||||
logEvent('Homepage: Ingestion Active Explore clicked', {
|
logEvent('Homepage: Ingestion Active Explore clicked', {
|
||||||
source: 'Metrics',
|
source: 'Metrics',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.INFRASTRUCTURE_MONITORING_HOSTS);
|
safeNavigate(ROUTES.INFRASTRUCTURE_MONITORING_HOSTS);
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e): void => {
|
onKeyDown={(e): void => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
logEvent('Homepage: Ingestion Active Explore clicked', {
|
logEvent('Homepage: Ingestion Active Explore clicked', {
|
||||||
source: 'Metrics',
|
source: 'Metrics',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.INFRASTRUCTURE_MONITORING_HOSTS);
|
safeNavigate(ROUTES.INFRASTRUCTURE_MONITORING_HOSTS);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -518,7 +519,7 @@ export default function Home(): JSX.Element {
|
|||||||
logEvent('Homepage: Explore clicked', {
|
logEvent('Homepage: Explore clicked', {
|
||||||
source: 'Logs',
|
source: 'Logs',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.LOGS_EXPLORER);
|
safeNavigate(ROUTES.LOGS_EXPLORER);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Open Logs Explorer
|
Open Logs Explorer
|
||||||
@@ -532,7 +533,7 @@ export default function Home(): JSX.Element {
|
|||||||
logEvent('Homepage: Explore clicked', {
|
logEvent('Homepage: Explore clicked', {
|
||||||
source: 'Traces',
|
source: 'Traces',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.TRACES_EXPLORER);
|
safeNavigate(ROUTES.TRACES_EXPLORER);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Open Traces Explorer
|
Open Traces Explorer
|
||||||
@@ -573,7 +574,7 @@ export default function Home(): JSX.Element {
|
|||||||
logEvent('Homepage: Explore clicked', {
|
logEvent('Homepage: Explore clicked', {
|
||||||
source: 'Dashboards',
|
source: 'Dashboards',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.ALL_DASHBOARD);
|
safeNavigate(ROUTES.ALL_DASHBOARD);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Create dashboard
|
Create dashboard
|
||||||
@@ -615,7 +616,7 @@ export default function Home(): JSX.Element {
|
|||||||
logEvent('Homepage: Explore clicked', {
|
logEvent('Homepage: Explore clicked', {
|
||||||
source: 'Alerts',
|
source: 'Alerts',
|
||||||
});
|
});
|
||||||
history.push(ROUTES.ALERTS_NEW);
|
safeNavigate(ROUTES.ALERTS_NEW);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Create an alert
|
Create an alert
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import './HomeChecklist.styles.scss';
|
|||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { ArrowRight, ArrowRightToLine, BookOpenText } from 'lucide-react';
|
import { ArrowRight, ArrowRightToLine, BookOpenText } from 'lucide-react';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
@@ -41,6 +41,7 @@ function HomeChecklist({
|
|||||||
const [whatsNextChecklistItems, setWhatsNextChecklistItems] = useState<
|
const [whatsNextChecklistItems, setWhatsNextChecklistItems] = useState<
|
||||||
ChecklistItem[]
|
ChecklistItem[]
|
||||||
>([]);
|
>([]);
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCompletedChecklistItems(checklistItems.filter((item) => item.completed));
|
setCompletedChecklistItems(checklistItems.filter((item) => item.completed));
|
||||||
@@ -92,12 +93,12 @@ function HomeChecklist({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (item.toRoute !== ROUTES.GET_STARTED_WITH_CLOUD) {
|
if (item.toRoute !== ROUTES.GET_STARTED_WITH_CLOUD) {
|
||||||
history.push(item.toRoute || '');
|
safeNavigate(item.toRoute || '');
|
||||||
} else if (
|
} else if (
|
||||||
activeLicenseV3 &&
|
activeLicenseV3 &&
|
||||||
activeLicenseV3.platform === LicensePlatform.CLOUD
|
activeLicenseV3.platform === LicensePlatform.CLOUD
|
||||||
) {
|
) {
|
||||||
history.push(item.toRoute || '');
|
safeNavigate(item.toRoute || '');
|
||||||
} else {
|
} else {
|
||||||
window?.open(
|
window?.open(
|
||||||
item.docsLink || '',
|
item.docsLink || '',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { SOURCEPAGE_VS_ROUTES } from 'pages/SaveView/constants';
|
|||||||
import Card from 'periscope/components/Card/Card';
|
import Card from 'periscope/components/Card/Card';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
import { ViewProps } from 'types/api/saveViews/types';
|
import { ViewProps } from 'types/api/saveViews/types';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import { USER_ROLES } from 'types/roles';
|
import { USER_ROLES } from 'types/roles';
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import useGetTopLevelOperations from 'hooks/useGetTopLevelOperations';
|
|||||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||||
import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils';
|
import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils';
|
||||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import history from 'lib/history';
|
|
||||||
import { ArrowRight, ArrowUpRight } from 'lucide-react';
|
import { ArrowRight, ArrowUpRight } from 'lucide-react';
|
||||||
import Card from 'periscope/components/Card/Card';
|
import Card from 'periscope/components/Card/Card';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
@@ -19,7 +18,7 @@ import { IUser } from 'providers/App/types';
|
|||||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { QueryKey } from 'react-query';
|
import { QueryKey } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import {
|
import {
|
||||||
LicensePlatform,
|
LicensePlatform,
|
||||||
@@ -29,6 +28,7 @@ import { ServicesList } from 'types/api/metrics/getService';
|
|||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
import { Tags } from 'types/reducer/trace';
|
import { Tags } from 'types/reducer/trace';
|
||||||
import { USER_ROLES } from 'types/roles';
|
import { USER_ROLES } from 'types/roles';
|
||||||
|
import { safeNavigateNoSameURLMemo } from 'utils/navigate';
|
||||||
|
|
||||||
import { DOCS_LINKS } from '../constants';
|
import { DOCS_LINKS } from '../constants';
|
||||||
import { columns, TIME_PICKER_OPTIONS } from './constants';
|
import { columns, TIME_PICKER_OPTIONS } from './constants';
|
||||||
@@ -72,7 +72,7 @@ const EmptyState = memo(
|
|||||||
activeLicenseV3 &&
|
activeLicenseV3 &&
|
||||||
activeLicenseV3.platform === LicensePlatform.CLOUD
|
activeLicenseV3.platform === LicensePlatform.CLOUD
|
||||||
) {
|
) {
|
||||||
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
safeNavigateNoSameURLMemo(ROUTES.GET_STARTED_WITH_CLOUD);
|
||||||
} else {
|
} else {
|
||||||
window?.open(
|
window?.open(
|
||||||
DOCS_LINKS.ADD_DATA_SOURCE,
|
DOCS_LINKS.ADD_DATA_SOURCE,
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ import logEvent from 'api/common/logEvent';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useQueryService } from 'hooks/useQueryService';
|
import { useQueryService } from 'hooks/useQueryService';
|
||||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import history from 'lib/history';
|
|
||||||
import { ArrowRight, ArrowUpRight } from 'lucide-react';
|
import { ArrowRight, ArrowUpRight } from 'lucide-react';
|
||||||
import Card from 'periscope/components/Card/Card';
|
import Card from 'periscope/components/Card/Card';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { LicensePlatform } from 'types/api/licensesV3/getActive';
|
import { LicensePlatform } from 'types/api/licensesV3/getActive';
|
||||||
import { ServicesList } from 'types/api/metrics/getService';
|
import { ServicesList } from 'types/api/metrics/getService';
|
||||||
@@ -127,7 +126,7 @@ export default function ServiceTraces({
|
|||||||
activeLicenseV3 &&
|
activeLicenseV3 &&
|
||||||
activeLicenseV3.platform === LicensePlatform.CLOUD
|
activeLicenseV3.platform === LicensePlatform.CLOUD
|
||||||
) {
|
) {
|
||||||
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
safeNavigate(ROUTES.GET_STARTED_WITH_CLOUD);
|
||||||
} else {
|
} else {
|
||||||
window?.open(
|
window?.open(
|
||||||
DOCS_LINKS.ADD_DATA_SOURCE,
|
DOCS_LINKS.ADD_DATA_SOURCE,
|
||||||
@@ -160,7 +159,7 @@ export default function ServiceTraces({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
[user?.role, activeLicenseV3],
|
[user?.role, activeLicenseV3, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderDashboardsList = useCallback(
|
const renderDashboardsList = useCallback(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Button, Divider, Typography } from 'antd';
|
|||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import useComponentPermission from 'hooks/useComponentPermission';
|
import useComponentPermission from 'hooks/useComponentPermission';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
@@ -33,13 +33,14 @@ export function AlertsEmptyState(): JSX.Element {
|
|||||||
['add_new_alert', 'action'],
|
['add_new_alert', 'action'],
|
||||||
user.role,
|
user.role,
|
||||||
);
|
);
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const onClickNewAlertHandler = useCallback(() => {
|
const onClickNewAlertHandler = useCallback(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
history.push(ROUTES.ALERTS_NEW);
|
safeNavigate(ROUTES.ALERTS_NEW);
|
||||||
}, []);
|
}, [safeNavigate]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="alert-list-container">
|
<div className="alert-list-container">
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import useComponentPermission from 'hooks/useComponentPermission';
|
|||||||
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
||||||
import useInterval from 'hooks/useInterval';
|
import useInterval from 'hooks/useInterval';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import history from 'lib/history';
|
|
||||||
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
@@ -61,6 +61,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
|||||||
const filteredData = filterAlerts(allAlertRules, value);
|
const filteredData = filterAlerts(allAlertRules, value);
|
||||||
return filteredData || [];
|
return filteredData || [];
|
||||||
});
|
});
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
// Type asuring
|
// Type asuring
|
||||||
const sortingOrder: 'ascend' | 'descend' | null =
|
const sortingOrder: 'ascend' | 'descend' | null =
|
||||||
@@ -102,7 +103,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
|||||||
logEvent('Alert: New alert button clicked', {
|
logEvent('Alert: New alert button clicked', {
|
||||||
number: allAlertRules?.length,
|
number: allAlertRules?.length,
|
||||||
});
|
});
|
||||||
history.push(ROUTES.ALERTS_NEW);
|
safeNavigate(ROUTES.ALERTS_NEW);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
|||||||
params.set(QueryParams.ruleId, record.id.toString());
|
params.set(QueryParams.ruleId, record.id.toString());
|
||||||
|
|
||||||
setEditLoader(false);
|
setEditLoader(false);
|
||||||
history.push(`${ROUTES.ALERT_OVERVIEW}?${params.toString()}`);
|
safeNavigate(`${ROUTES.ALERT_OVERVIEW}?${params.toString()}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCloneHandler = (
|
const onCloneHandler = (
|
||||||
@@ -146,7 +147,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const clonedAlert = refetchData.payload[refetchData.payload.length - 1];
|
const clonedAlert = refetchData.payload[refetchData.payload.length - 1];
|
||||||
params.set(QueryParams.ruleId, String(clonedAlert.id));
|
params.set(QueryParams.ruleId, String(clonedAlert.id));
|
||||||
history.push(`${ROUTES.EDIT_ALERTS}?${params.toString()}`);
|
safeNavigate(`${ROUTES.EDIT_ALERTS}?${params.toString()}`);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
if (status === 'error') {
|
if (status === 'error') {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ import {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
import { Layout } from 'react-grid-layout';
|
import { Layout } from 'react-grid-layout';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { generatePath } from 'react-router-dom';
|
import { generatePath } from 'react-router';
|
||||||
import { useCopyToClipboard } from 'react-use';
|
import { useCopyToClipboard } from 'react-use';
|
||||||
import {
|
import {
|
||||||
Dashboard,
|
Dashboard,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { ExternalLink, Github, MonitorDot, MoveRight, X } from 'lucide-react';
|
|||||||
// See more: https://github.com/lucide-icons/lucide/issues/94
|
// See more: https://github.com/lucide-icons/lucide/issues/94
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { generatePath } from 'react-router-dom';
|
import { generatePath } from 'react-router';
|
||||||
import { DashboardData } from 'types/api/dashboard/getAll';
|
import { DashboardData } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
function ImportJSON({
|
function ImportJSON({
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { CloseCircleFilled } from '@ant-design/icons';
|
|||||||
import { useMachine } from '@xstate/react';
|
import { useMachine } from '@xstate/react';
|
||||||
import { Button, Select } from 'antd';
|
import { Button, Select } from 'antd';
|
||||||
import { RefSelectProps } from 'antd/lib/select';
|
import { RefSelectProps } from 'antd/lib/select';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { filter, map } from 'lodash-es';
|
import { filter, map } from 'lodash-es';
|
||||||
import {
|
import {
|
||||||
MutableRefObject,
|
MutableRefObject,
|
||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
import { useLocation } from 'react-router';
|
||||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
@@ -41,13 +42,15 @@ function SearchFilter({
|
|||||||
const [selectedValues, setSelectedValues] = useState<string[]>([]);
|
const [selectedValues, setSelectedValues] = useState<string[]>([]);
|
||||||
const [staging, setStaging] = useState<string[] | string[][] | unknown[]>([]);
|
const [staging, setStaging] = useState<string[] | string[][] | unknown[]>([]);
|
||||||
const [queries, setQueries] = useState<IQueryStructure[]>([]);
|
const [queries, setQueries] = useState<IQueryStructure[]>([]);
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
const { pathname, search } = useLocation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const searchQueryString = new URLSearchParams(history.location.search).get(
|
const searchQueryString = new URLSearchParams(search).get('search');
|
||||||
'search',
|
|
||||||
);
|
|
||||||
if (searchQueryString)
|
if (searchQueryString)
|
||||||
setQueries(convertURLQueryStringToQuery(searchQueryString) || []);
|
setQueries(convertURLQueryStringToQuery(searchQueryString) || []);
|
||||||
|
// TODO: SMIT is this a bug no search in deps?
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
filterDashboards(executeSearchQueries(queries, searchData));
|
filterDashboards(executeSearchQueries(queries, searchData));
|
||||||
@@ -56,15 +59,15 @@ function SearchFilter({
|
|||||||
|
|
||||||
const updateURLWithQuery = useCallback(
|
const updateURLWithQuery = useCallback(
|
||||||
(inputQueries?: IQueryStructure[]): void => {
|
(inputQueries?: IQueryStructure[]): void => {
|
||||||
history.push({
|
safeNavigate({
|
||||||
pathname: history.location.pathname,
|
pathname,
|
||||||
search:
|
search:
|
||||||
inputQueries || queries
|
inputQueries || queries
|
||||||
? `?search=${convertQueriesToURLQuery(inputQueries || queries)}`
|
? `?search=${convertQueriesToURLQuery(inputQueries || queries)}`
|
||||||
: '',
|
: '',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[queries],
|
[queries, pathname, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -149,8 +152,8 @@ function SearchFilter({
|
|||||||
|
|
||||||
const clearQueries = (): void => {
|
const clearQueries = (): void => {
|
||||||
setQueries([]);
|
setQueries([]);
|
||||||
history.push({
|
safeNavigate({
|
||||||
pathname: history.location.pathname,
|
pathname,
|
||||||
search: ``,
|
search: ``,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useDeleteDashboard } from 'hooks/dashboard/useDeleteDashboard';
|
import { useDeleteDashboard } from 'hooks/dashboard/useDeleteDashboard';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -36,6 +36,7 @@ export function DeleteButton({
|
|||||||
const isAuthor = user?.email === createdBy;
|
const isAuthor = user?.email === createdBy;
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ export function DeleteButton({
|
|||||||
});
|
});
|
||||||
queryClient.invalidateQueries([REACT_QUERY_KEY.GET_ALL_DASHBOARDS]);
|
queryClient.invalidateQueries([REACT_QUERY_KEY.GET_ALL_DASHBOARDS]);
|
||||||
if (routeToListPage) {
|
if (routeToListPage) {
|
||||||
history.replace(ROUTES.ALL_DASHBOARD);
|
safeNavigate(ROUTES.ALL_DASHBOARD);
|
||||||
}
|
}
|
||||||
destroy();
|
destroy();
|
||||||
},
|
},
|
||||||
@@ -86,6 +87,7 @@ export function DeleteButton({
|
|||||||
t,
|
t,
|
||||||
queryClient,
|
queryClient,
|
||||||
routeToListPage,
|
routeToListPage,
|
||||||
|
safeNavigate,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const getDeleteTooltipContent = (): string => {
|
const getDeleteTooltipContent = (): string => {
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { LockFilled } from '@ant-design/icons';
|
import { LockFilled } from '@ant-design/icons';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
|
|
||||||
import { Data } from '../DashboardsList';
|
import { Data } from '../DashboardsList';
|
||||||
import { TableLinkText } from './styles';
|
import { TableLinkText } from './styles';
|
||||||
|
|
||||||
function Name(name: Data['name'], data: Data): JSX.Element {
|
function Name(name: Data['name'], data: Data): JSX.Element {
|
||||||
const { id: DashboardId, isLocked } = data;
|
const { id: DashboardId, isLocked } = data;
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const getLink = (): string => `${ROUTES.ALL_DASHBOARD}/${DashboardId}`;
|
const getLink = (): string => `${ROUTES.ALL_DASHBOARD}/${DashboardId}`;
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ function Name(name: Data['name'], data: Data): JSX.Element {
|
|||||||
if (event.metaKey || event.ctrlKey) {
|
if (event.metaKey || event.ctrlKey) {
|
||||||
window.open(getLink(), '_blank');
|
window.open(getLink(), '_blank');
|
||||||
} else {
|
} else {
|
||||||
history.push(getLink());
|
safeNavigate(getLink());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import {
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
|
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
|
|
||||||
import { constructCompositeQuery } from '../constants';
|
import { constructCompositeQuery } from '../constants';
|
||||||
|
|
||||||
function BackButton(): JSX.Element {
|
function BackButton(): JSX.Element {
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const { updateAllQueriesOperators } = useQueryBuilder();
|
const { updateAllQueriesOperators } = useQueryBuilder();
|
||||||
|
|
||||||
@@ -40,8 +40,8 @@ function BackButton(): JSX.Element {
|
|||||||
|
|
||||||
const path = `${ROUTES.LOGS_EXPLORER}?${QueryParams.compositeQuery}=${JSONCompositeQuery}`;
|
const path = `${ROUTES.LOGS_EXPLORER}?${QueryParams.compositeQuery}=${JSONCompositeQuery}`;
|
||||||
|
|
||||||
history.push(path);
|
safeNavigate(path);
|
||||||
}, [history, compositeQuery, updateAllQueriesOperators]);
|
}, [safeNavigate, compositeQuery, updateAllQueriesOperators]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button icon={<ArrowLeftOutlined />} onClick={handleBack}>
|
<Button icon={<ArrowLeftOutlined />} onClick={handleBack}>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { prepareQueryRangePayload } from 'lib/dashboard/prepareQueryRangePayload
|
|||||||
import { useEventSource } from 'providers/EventSource';
|
import { useEventSource } from 'providers/EventSource';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { ILog } from 'types/api/logs/log';
|
import { ILog } from 'types/api/logs/log';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/co
|
|||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { Virtuoso } from 'react-virtuoso';
|
import { Virtuoso } from 'react-virtuoso';
|
||||||
import { ILog } from 'types/api/logs/log';
|
import { ILog } from 'types/api/logs/log';
|
||||||
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ import { OPERATORS } from 'constants/queryBuilder';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { FontSize, OptionsQuery } from 'container/OptionsMenu/types';
|
import { FontSize, OptionsQuery } from 'container/OptionsMenu/types';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { fieldSearchFilter } from 'lib/logs/fieldSearch';
|
import { fieldSearchFilter } from 'lib/logs/fieldSearch';
|
||||||
import { removeJSONStringifyQuotes } from 'lib/removeJSONStringifyQuotes';
|
import { removeJSONStringifyQuotes } from 'lib/removeJSONStringifyQuotes';
|
||||||
import { Pin } from 'lucide-react';
|
import { Pin } from 'lucide-react';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { generatePath } from 'react-router-dom';
|
import { generatePath } from 'react-router';
|
||||||
import { Dispatch } from 'redux';
|
import { Dispatch } from 'redux';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import { SET_DETAILED_LOG_DATA } from 'types/actions/logs';
|
import { SET_DETAILED_LOG_DATA } from 'types/actions/logs';
|
||||||
@@ -68,6 +68,7 @@ function TableView({
|
|||||||
const [isfilterInLoading, setIsFilterInLoading] = useState<boolean>(false);
|
const [isfilterInLoading, setIsFilterInLoading] = useState<boolean>(false);
|
||||||
const [isfilterOutLoading, setIsFilterOutLoading] = useState<boolean>(false);
|
const [isfilterOutLoading, setIsFilterOutLoading] = useState<boolean>(false);
|
||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const [pinnedAttributes, setPinnedAttributes] = useState<
|
const [pinnedAttributes, setPinnedAttributes] = useState<
|
||||||
Record<string, boolean>
|
Record<string, boolean>
|
||||||
@@ -170,7 +171,7 @@ function TableView({
|
|||||||
// open the trace in new tab
|
// open the trace in new tab
|
||||||
window.open(route, '_blank');
|
window.open(route, '_blank');
|
||||||
} else {
|
} else {
|
||||||
history.push(route);
|
safeNavigate(route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { isEmpty } from 'lodash-es';
|
|||||||
import { ArrowDownToDot, ArrowUpFromDot, Ellipsis } from 'lucide-react';
|
import { ArrowDownToDot, ArrowUpFromDot, Ellipsis } from 'lucide-react';
|
||||||
import { useTimezone } from 'providers/Timezone';
|
import { useTimezone } from 'providers/Timezone';
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { FORBID_DOM_PURIFY_TAGS } from 'utils/app';
|
import { FORBID_DOM_PURIFY_TAGS } from 'utils/app';
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import LogDetail from 'components/LogDetail';
|
|||||||
import { VIEW_TYPES } from 'components/LogDetail/constants';
|
import { VIEW_TYPES } from 'components/LogDetail/constants';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { getOldLogsOperatorFromNew } from 'hooks/logs/useActiveLog';
|
import { getOldLogsOperatorFromNew } from 'hooks/logs/useActiveLog';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { getGeneratedFilterQueryString } from 'lib/getGeneratedFilterQueryString';
|
import { getGeneratedFilterQueryString } from 'lib/getGeneratedFilterQueryString';
|
||||||
import getStep from 'lib/getStep';
|
import getStep from 'lib/getStep';
|
||||||
import { getIdConditions } from 'pages/Logs/utils';
|
import { getIdConditions } from 'pages/Logs/utils';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { connect, useDispatch, useSelector } from 'react-redux';
|
import { connect, useDispatch, useSelector } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { bindActionCreators, Dispatch } from 'redux';
|
import { bindActionCreators, Dispatch } from 'redux';
|
||||||
import { ThunkDispatch } from 'redux-thunk';
|
import { ThunkDispatch } from 'redux-thunk';
|
||||||
import { getLogs } from 'store/actions/logs/getLogs';
|
import { getLogs } from 'store/actions/logs/getLogs';
|
||||||
@@ -33,7 +33,7 @@ function LogDetailedView({
|
|||||||
getLogs,
|
getLogs,
|
||||||
getLogsAggregate,
|
getLogsAggregate,
|
||||||
}: LogDetailedViewProps): JSX.Element {
|
}: LogDetailedViewProps): JSX.Element {
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const {
|
const {
|
||||||
detailedLog,
|
detailedLog,
|
||||||
searchFilter: { queryString },
|
searchFilter: { queryString },
|
||||||
@@ -66,9 +66,11 @@ function LogDetailedView({
|
|||||||
queryString,
|
queryString,
|
||||||
);
|
);
|
||||||
|
|
||||||
history.replace(`${ROUTES.OLD_LOGS_EXPLORER}?q=${updatedQueryString}`);
|
safeNavigate(`${ROUTES.OLD_LOGS_EXPLORER}?q=${updatedQueryString}`, {
|
||||||
|
replace: true,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[history, queryString],
|
[safeNavigate, queryString],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClickActionItem = useCallback(
|
const handleClickActionItem = useCallback(
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ import afterLogin from 'AppRoutes/utils';
|
|||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { PayloadProps as PrecheckResultType } from 'types/api/user/loginPrecheck';
|
import { PayloadProps as PrecheckResultType } from 'types/api/user/loginPrecheck';
|
||||||
|
import { safeNavigateNoSameURLMemo } from 'utils/navigate';
|
||||||
|
|
||||||
import { FormContainer, FormWrapper, Label, ParentContainer } from './styles';
|
import { FormContainer, FormWrapper, Label, ParentContainer } from './styles';
|
||||||
|
|
||||||
@@ -39,6 +40,7 @@ function Login({
|
|||||||
const { t } = useTranslation(['login']);
|
const { t } = useTranslation(['login']);
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
const { user } = useAppContext();
|
const { user } = useAppContext();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const [precheckResult, setPrecheckResult] = useState<PrecheckResultType>({
|
const [precheckResult, setPrecheckResult] = useState<PrecheckResultType>({
|
||||||
sso: false,
|
sso: false,
|
||||||
@@ -67,7 +69,7 @@ function Login({
|
|||||||
const { setupCompleted } = getUserVersionResponse.data.payload;
|
const { setupCompleted } = getUserVersionResponse.data.payload;
|
||||||
if (!setupCompleted) {
|
if (!setupCompleted) {
|
||||||
// no org account registered yet, re-route user to sign up first
|
// no org account registered yet, re-route user to sign up first
|
||||||
history.push(ROUTES.SIGN_UP);
|
safeNavigateNoSameURLMemo(ROUTES.SIGN_UP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [getUserVersionResponse]);
|
}, [getUserVersionResponse]);
|
||||||
@@ -90,10 +92,10 @@ function Login({
|
|||||||
LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT,
|
LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT,
|
||||||
);
|
);
|
||||||
if (fromPathname) {
|
if (fromPathname) {
|
||||||
history.push(fromPathname);
|
safeNavigateNoSameURLMemo(fromPathname);
|
||||||
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, '');
|
setLocalStorageApi(LOCALSTORAGE.UNAUTHENTICATED_ROUTE_HIT, '');
|
||||||
} else {
|
} else {
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigateNoSameURLMemo(ROUTES.APPLICATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,7 +289,7 @@ function Login({
|
|||||||
{t('prompt_if_admin')}{' '}
|
{t('prompt_if_admin')}{' '}
|
||||||
<Typography.Link
|
<Typography.Link
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
history.push(ROUTES.SIGN_UP);
|
safeNavigate(ROUTES.SIGN_UP);
|
||||||
}}
|
}}
|
||||||
style={{ fontWeight: 700 }}
|
style={{ fontWeight: 700 }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import './LogsError.styles.scss';
|
|||||||
|
|
||||||
import { Typography } from 'antd';
|
import { Typography } from 'antd';
|
||||||
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { ArrowRight } from 'lucide-react';
|
import { ArrowRight } from 'lucide-react';
|
||||||
|
|
||||||
export default function LogsError(): JSX.Element {
|
export default function LogsError(): JSX.Element {
|
||||||
const { isCloudUser: isCloudUserVal } = useGetTenantLicense();
|
const { isCloudUser: isCloudUserVal } = useGetTenantLicense();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const handleContactSupport = (): void => {
|
const handleContactSupport = (): void => {
|
||||||
if (isCloudUserVal) {
|
if (isCloudUserVal) {
|
||||||
history.push('/support');
|
safeNavigate('/support');
|
||||||
} else {
|
} else {
|
||||||
window.open('https://signoz.io/slack', '_blank');
|
window.open('https://signoz.io/slack', '_blank');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import GetMinMax from 'lib/getMinMax';
|
|||||||
import { colors } from 'lib/getRandomColor';
|
import { colors } from 'lib/getRandomColor';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
|
|
||||||
import { LogsExplorerChartProps } from './LogsExplorerChart.interfaces';
|
import { LogsExplorerChartProps } from './LogsExplorerChart.interfaces';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import { getMinMax } from 'container/TopNav/AutoRefresh/config';
|
import { getMinMax } from 'container/TopNav/AutoRefresh/config';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import history from 'lib/history';
|
|
||||||
import { parseQuery } from 'lib/logql';
|
import { parseQuery } from 'lib/logql';
|
||||||
import isEqual from 'lodash-es/isEqual';
|
import isEqual from 'lodash-es/isEqual';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
@@ -24,6 +24,7 @@ export function useSearchParser(): {
|
|||||||
updateQueryString: (arg0: string) => void;
|
updateQueryString: (arg0: string) => void;
|
||||||
} {
|
} {
|
||||||
const dispatch = useDispatch<Dispatch<AppActions>>();
|
const dispatch = useDispatch<Dispatch<AppActions>>();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const {
|
const {
|
||||||
searchFilter: { parsedQuery, queryString },
|
searchFilter: { parsedQuery, queryString },
|
||||||
order,
|
order,
|
||||||
@@ -39,10 +40,16 @@ export function useSearchParser(): {
|
|||||||
|
|
||||||
const updateQueryString = useCallback(
|
const updateQueryString = useCallback(
|
||||||
(updatedQueryString: string) => {
|
(updatedQueryString: string) => {
|
||||||
history.replace({
|
// Defaults to the current URL
|
||||||
pathname: history.location.pathname,
|
safeNavigate(
|
||||||
search: `?${QueryParams.q}=${updatedQueryString}&${QueryParams.order}=${order}`,
|
{
|
||||||
});
|
// No need to prepend '?'
|
||||||
|
search: `${QueryParams.q}=${updatedQueryString}&${QueryParams.order}=${order}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
replace: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const globalTime = getMinMax(selectedTime, minTime, maxTime);
|
const globalTime = getMinMax(selectedTime, minTime, maxTime);
|
||||||
|
|
||||||
@@ -64,7 +71,7 @@ export function useSearchParser(): {
|
|||||||
},
|
},
|
||||||
// need to hide this warning as we don't want to update the query string on every change
|
// need to hide this warning as we don't want to update the query string on every change
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
[dispatch, parsedQuery, selectedTime, queryString],
|
[dispatch, parsedQuery, selectedTime, queryString, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -13,16 +13,16 @@ import {
|
|||||||
import { QueryHistoryState } from 'container/LiveLogs/types';
|
import { QueryHistoryState } from 'container/LiveLogs/types';
|
||||||
import LocalTopNav from 'container/LocalTopNav';
|
import LocalTopNav from 'container/LocalTopNav';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
|
|
||||||
import { LiveButtonStyled } from './styles';
|
import { LiveButtonStyled } from './styles';
|
||||||
|
|
||||||
function LogsTopNav(): JSX.Element {
|
function LogsTopNav(): JSX.Element {
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const { stagedQuery, panelType } = useQueryBuilder();
|
const { stagedQuery, panelType } = useQueryBuilder();
|
||||||
@@ -65,8 +65,9 @@ function LogsTopNav(): JSX.Element {
|
|||||||
|
|
||||||
const path = `${ROUTES.LIVE_LOGS}?${QueryParams.compositeQuery}=${JSONCompositeQuery}`;
|
const path = `${ROUTES.LIVE_LOGS}?${QueryParams.compositeQuery}=${JSONCompositeQuery}`;
|
||||||
|
|
||||||
history.push(path, queryHistoryState);
|
// TODO: SMIT Discuss with reviewer
|
||||||
}, [history, panelType, queryClient, stagedQuery]);
|
safeNavigate(path, { state: queryHistoryState });
|
||||||
|
}, [safeNavigate, panelType, queryClient, stagedQuery]);
|
||||||
|
|
||||||
const liveButton = useMemo(
|
const liveButton = useMemo(
|
||||||
() => (
|
() => (
|
||||||
|
|||||||
@@ -16,10 +16,9 @@ import {
|
|||||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import getStep from 'lib/getStep';
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router';
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
@@ -40,13 +39,17 @@ import {
|
|||||||
} from './util';
|
} from './util';
|
||||||
|
|
||||||
function DBCall(): JSX.Element {
|
function DBCall(): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
|
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
const [selectedTimeStamp, setSelectedTimeStamp] = useState<number>(0);
|
const [selectedTimeStamp, setSelectedTimeStamp] = useState<number>(0);
|
||||||
const { queries } = useResourceAttribute();
|
const { queries } = useResourceAttribute();
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onDragSelect = useCallback(
|
const onDragSelect = useCallback(
|
||||||
@@ -57,13 +60,13 @@ function DBCall(): JSX.Element {
|
|||||||
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
||||||
history.push(generatedUrl);
|
safeNavigate(generatedUrl);
|
||||||
|
|
||||||
if (startTimestamp !== endTimestamp) {
|
if (startTimestamp !== endTimestamp) {
|
||||||
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch, pathname, urlQuery],
|
[dispatch, pathname, urlQuery, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagFilterItems: TagFilterItem[] = useMemo(
|
const tagFilterItems: TagFilterItem[] = useMemo(
|
||||||
@@ -158,7 +161,6 @@ function DBCall(): JSX.Element {
|
|||||||
servicename,
|
servicename,
|
||||||
isDBCall: true,
|
isDBCall: true,
|
||||||
});
|
});
|
||||||
const { safeNavigate } = useSafeNavigate();
|
|
||||||
|
|
||||||
const onGraphClickHandler = useGraphClickHandler(setSelectedTimeStamp);
|
const onGraphClickHandler = useGraphClickHandler(setSelectedTimeStamp);
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,9 @@ import {
|
|||||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import getStep from 'lib/getStep';
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router';
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
@@ -43,10 +42,14 @@ import {
|
|||||||
function External(): JSX.Element {
|
function External(): JSX.Element {
|
||||||
const [selectedTimeStamp, setSelectedTimeStamp] = useState<number>(0);
|
const [selectedTimeStamp, setSelectedTimeStamp] = useState<number>(0);
|
||||||
|
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
|
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
const { queries } = useResourceAttribute();
|
const { queries } = useResourceAttribute();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
@@ -60,13 +63,13 @@ function External(): JSX.Element {
|
|||||||
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
||||||
history.push(generatedUrl);
|
safeNavigate(generatedUrl);
|
||||||
|
|
||||||
if (startTimestamp !== endTimestamp) {
|
if (startTimestamp !== endTimestamp) {
|
||||||
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch, pathname, urlQuery],
|
[dispatch, pathname, urlQuery, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagFilterItems = useMemo(
|
const tagFilterItems = useMemo(
|
||||||
@@ -221,8 +224,6 @@ function External(): JSX.Element {
|
|||||||
isExternalCall: true,
|
isExternalCall: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { safeNavigate } = useSafeNavigate();
|
|
||||||
|
|
||||||
const onGraphClickHandler = useGraphClickHandler(setSelectedTimeStamp);
|
const onGraphClickHandler = useGraphClickHandler(setSelectedTimeStamp);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -16,14 +16,13 @@ import {
|
|||||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import getStep from 'lib/getStep';
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
|
||||||
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||||
import { defaultTo } from 'lodash-es';
|
import { defaultTo } from 'lodash-es';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
@@ -58,7 +57,10 @@ import {
|
|||||||
} from './util';
|
} from './util';
|
||||||
|
|
||||||
function Application(): JSX.Element {
|
function Application(): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
|
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
@@ -69,6 +71,7 @@ function Application(): JSX.Element {
|
|||||||
const { search, pathname } = useLocation();
|
const { search, pathname } = useLocation();
|
||||||
const { queries } = useResourceAttribute();
|
const { queries } = useResourceAttribute();
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const { featureFlags } = useAppContext();
|
const { featureFlags } = useAppContext();
|
||||||
const isSpanMetricEnabled =
|
const isSpanMetricEnabled =
|
||||||
@@ -208,13 +211,13 @@ function Application(): JSX.Element {
|
|||||||
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
|
||||||
history.push(generatedUrl);
|
safeNavigate(generatedUrl);
|
||||||
|
|
||||||
if (startTimestamp !== endTimestamp) {
|
if (startTimestamp !== endTimestamp) {
|
||||||
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch, pathname, urlQuery],
|
[dispatch, pathname, urlQuery, safeNavigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -253,7 +256,7 @@ function Application(): JSX.Element {
|
|||||||
queryString,
|
queryString,
|
||||||
);
|
);
|
||||||
|
|
||||||
history.push(newPath);
|
safeNavigate(newPath);
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
[stepInterval],
|
[stepInterval],
|
||||||
@@ -295,7 +298,6 @@ function Application(): JSX.Element {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
const { safeNavigate } = useSafeNavigate();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
|
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
|
||||||
import { apDexMetricsQueryBuilderQueries } from 'container/MetricsApplication/MetricsPageQueries/OverviewQueries';
|
import { apDexMetricsQueryBuilderQueries } from 'container/MetricsApplication/MetricsPageQueries/OverviewQueries';
|
||||||
import { ReactNode, useMemo } from 'react';
|
import { ReactNode, useMemo } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
@@ -32,7 +32,10 @@ function ApDexMetrics({
|
|||||||
topLevelOperationsRoute,
|
topLevelOperationsRoute,
|
||||||
handleGraphClick,
|
handleGraphClick,
|
||||||
}: ApDexMetricsProps): JSX.Element {
|
}: ApDexMetricsProps): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
|
|
||||||
const apDexMetricsWidget = useMemo(
|
const apDexMetricsWidget = useMemo(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { useGetMetricMeta } from 'hooks/apDex/useGetMetricMeta';
|
import { useGetMetricMeta } from 'hooks/apDex/useGetMetricMeta';
|
||||||
import useErrorNotification from 'hooks/useErrorNotification';
|
import useErrorNotification from 'hooks/useErrorNotification';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
import { IServiceName } from '../../types';
|
import { IServiceName } from '../../types';
|
||||||
import ApDexMetrics from './ApDexMetrics';
|
import ApDexMetrics from './ApDexMetrics';
|
||||||
@@ -15,7 +15,10 @@ function ApDexMetricsApplication({
|
|||||||
thresholdValue,
|
thresholdValue,
|
||||||
topLevelOperationsRoute,
|
topLevelOperationsRoute,
|
||||||
}: ApDexDataSwitcherProps): JSX.Element {
|
}: ApDexDataSwitcherProps): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
|
|
||||||
const { data, isLoading, error } = useGetMetricMeta(metricMeta, servicename);
|
const { data, isLoading, error } = useGetMetricMeta(metricMeta, servicename);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { GraphTitle } from 'container/MetricsApplication/constant';
|
|||||||
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
|
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
|
||||||
import { apDexTracesQueryBuilderQueries } from 'container/MetricsApplication/MetricsPageQueries/OverviewQueries';
|
import { apDexTracesQueryBuilderQueries } from 'container/MetricsApplication/MetricsPageQueries/OverviewQueries';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
@@ -21,7 +21,10 @@ function ApDexTraces({
|
|||||||
tagFilterItems,
|
tagFilterItems,
|
||||||
thresholdValue,
|
thresholdValue,
|
||||||
}: ApDexDataSwitcherProps): JSX.Element {
|
}: ApDexDataSwitcherProps): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
|
|
||||||
const apDexTracesWidget = useMemo(
|
const apDexTracesWidget = useMemo(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Card, GraphContainer } from 'container/MetricsApplication/styles';
|
|||||||
import { useGetApDexSettings } from 'hooks/apDex/useGetApDexSettings';
|
import { useGetApDexSettings } from 'hooks/apDex/useGetApDexSettings';
|
||||||
import useErrorNotification from 'hooks/useErrorNotification';
|
import useErrorNotification from 'hooks/useErrorNotification';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
import { IServiceName } from '../../types';
|
import { IServiceName } from '../../types';
|
||||||
import ApDexMetricsApplication from './ApDexMetricsApplication';
|
import ApDexMetricsApplication from './ApDexMetricsApplication';
|
||||||
@@ -15,7 +15,10 @@ function ApDexApplication({
|
|||||||
topLevelOperationsRoute,
|
topLevelOperationsRoute,
|
||||||
tagFilterItems,
|
tagFilterItems,
|
||||||
}: ApDexApplicationProps): JSX.Element {
|
}: ApDexApplicationProps): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
|
|
||||||
const { data, isLoading, error, isRefetching } = useGetApDexSettings(
|
const { data, isLoading, error, isRefetching } = useGetApDexSettings(
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
|||||||
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
@@ -38,7 +38,10 @@ function ServiceOverview({
|
|||||||
topLevelOperationsIsLoading,
|
topLevelOperationsIsLoading,
|
||||||
stepInterval,
|
stepInterval,
|
||||||
}: ServiceOverviewProps): JSX.Element {
|
}: ServiceOverviewProps): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
|
|
||||||
const { featureFlags } = useAppContext();
|
const { featureFlags } = useAppContext();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { PayloadProps } from 'types/api/metrics/getTopOperations';
|
import { PayloadProps } from 'types/api/metrics/getTopOperations';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
@@ -15,9 +15,10 @@ function TopOperation(): JSX.Element {
|
|||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
);
|
);
|
||||||
const { servicename: encodedServiceName } = useParams<{
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const { servicename: encodedServiceName } = (useParams() as unknown) as {
|
||||||
servicename?: string;
|
servicename?: string;
|
||||||
}>();
|
};
|
||||||
const servicename = decodeURIComponent(encodedServiceName || '');
|
const servicename = decodeURIComponent(encodedServiceName || '');
|
||||||
|
|
||||||
const { queries } = useResourceAttribute();
|
const { queries } = useResourceAttribute();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute
|
|||||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||||
import { ReactNode, useMemo } from 'react';
|
import { ReactNode, useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
@@ -24,7 +24,10 @@ import ColumnWithLink from './TableRenderer/ColumnWithLink';
|
|||||||
import { getTableColumnRenderer } from './TableRenderer/TableColumnRenderer';
|
import { getTableColumnRenderer } from './TableRenderer/TableColumnRenderer';
|
||||||
|
|
||||||
function TopOperationMetrics(): JSX.Element {
|
function TopOperationMetrics(): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
|
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute
|
|||||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
@@ -31,7 +31,10 @@ function TopOperationsTable({
|
|||||||
isLoading,
|
isLoading,
|
||||||
}: TopOperationsTableProps): JSX.Element {
|
}: TopOperationsTableProps): JSX.Element {
|
||||||
const searchInput = useRef<InputRef>(null);
|
const searchInput = useRef<InputRef>(null);
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
servicename: encodedServiceName,
|
||||||
|
} = (useParams() as unknown) as IServiceName;
|
||||||
const { safeNavigate } = useSafeNavigate();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
const { minTime, maxTime } = useSelector<AppState, GlobalReducer>(
|
const { minTime, maxTime } = useSelector<AppState, GlobalReducer>(
|
||||||
@@ -45,7 +48,8 @@ function TopOperationsTable({
|
|||||||
|
|
||||||
const apmToTraceQuery = useGetAPMToTracesQueries({ servicename });
|
const apmToTraceQuery = useGetAPMToTracesQueries({ servicename });
|
||||||
|
|
||||||
const params = useParams<{ servicename: string }>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const params = (useParams() as unknown) as { servicename: string };
|
||||||
|
|
||||||
const handleOnClick = (operation: string): void => {
|
const handleOnClick = (operation: string): void => {
|
||||||
const { servicename: encodedServiceName } = params;
|
const { servicename: encodedServiceName } = params;
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import { QueryParams } from 'constants/query';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import history from 'lib/history';
|
|
||||||
import { Bell, Grid } from 'lucide-react';
|
import { Bell, Grid } from 'lucide-react';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { generatePath } from 'react-router-dom';
|
import { generatePath } from 'react-router';
|
||||||
|
|
||||||
import { DashboardsAndAlertsPopoverProps } from './types';
|
import { DashboardsAndAlertsPopoverProps } from './types';
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ function DashboardsAndAlertsPopover({
|
|||||||
key={alert.alert_id}
|
key={alert.alert_id}
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
params.set(QueryParams.ruleId, alert.alert_id);
|
params.set(QueryParams.ruleId, alert.alert_id);
|
||||||
history.push(`${ROUTES.ALERT_OVERVIEW}?${params.toString()}`);
|
safeNavigate(`${ROUTES.ALERT_OVERVIEW}?${params.toString()}`);
|
||||||
}}
|
}}
|
||||||
className="dashboards-popover-content-item"
|
className="dashboards-popover-content-item"
|
||||||
>
|
>
|
||||||
@@ -37,7 +36,7 @@ function DashboardsAndAlertsPopover({
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}, [alerts, params]);
|
}, [alerts, params, safeNavigate]);
|
||||||
|
|
||||||
const uniqueDashboards = useMemo(
|
const uniqueDashboards = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import { Card, Modal } from 'antd';
|
|||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import createQueryParams from 'lib/createQueryParams';
|
import createQueryParams from 'lib/createQueryParams';
|
||||||
import history from 'lib/history';
|
|
||||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
|
import { useLocation } from 'react-router';
|
||||||
import { LogsAggregatorOperator } from 'types/common/queryBuilder';
|
import { LogsAggregatorOperator } from 'types/common/queryBuilder';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
@@ -16,7 +17,8 @@ import { Text } from './styles';
|
|||||||
|
|
||||||
function DashboardGraphSlider(): JSX.Element {
|
function DashboardGraphSlider(): JSX.Element {
|
||||||
const { handleToggleDashboardSlider, isDashboardSliderOpen } = useDashboard();
|
const { handleToggleDashboardSlider, isDashboardSliderOpen } = useDashboard();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
const location = useLocation();
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
const onClickHandler = (name: PANEL_TYPES) => (): void => {
|
const onClickHandler = (name: PANEL_TYPES) => (): void => {
|
||||||
const id = uuid();
|
const id = uuid();
|
||||||
@@ -56,13 +58,11 @@ function DashboardGraphSlider(): JSX.Element {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
if (name === PANEL_TYPES.LIST) {
|
if (name === PANEL_TYPES.LIST) {
|
||||||
history.push(
|
safeNavigate(
|
||||||
`${history.location.pathname}/new?${createQueryParams(queryParamsLog)}`,
|
`${location.pathname}/new?${createQueryParams(queryParamsLog)}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
history.push(
|
safeNavigate(`${location.pathname}/new?${createQueryParams(queryParams)}`);
|
||||||
`${history.location.pathname}/new?${createQueryParams(queryParams)}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import { getNonIntegrationDashboardById } from 'mocks-server/__mockdata__/dashbo
|
|||||||
import { server } from 'mocks-server/server';
|
import { server } from 'mocks-server/server';
|
||||||
import { rest } from 'msw';
|
import { rest } from 'msw';
|
||||||
import { DashboardProvider } from 'providers/Dashboard/Dashboard';
|
import { DashboardProvider } from 'providers/Dashboard/Dashboard';
|
||||||
import { MemoryRouter, useLocation } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import { useLocation } from 'react-router-dom-v5-compat';
|
||||||
import { fireEvent, render, screen, waitFor } from 'tests/test-utils';
|
import { fireEvent, render, screen, waitFor } from 'tests/test-utils';
|
||||||
|
|
||||||
import DashboardDescription from '..';
|
import DashboardDescription from '..';
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { CompassOutlined } from '@ant-design/icons';
|
import { CompassOutlined } from '@ant-design/icons';
|
||||||
import { Badge, Button } from 'antd';
|
import { Badge, Button } from 'antd';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
import { buttonText, RIBBON_STYLES } from './config';
|
import { buttonText, RIBBON_STYLES } from './config';
|
||||||
|
|
||||||
function NewExplorerCTA(): JSX.Element | null {
|
function NewExplorerCTA(): JSX.Element | null {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const isTraceOrLogsExplorerPage = useMemo(
|
const isTraceOrLogsExplorerPage = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@@ -21,15 +22,15 @@ function NewExplorerCTA(): JSX.Element | null {
|
|||||||
|
|
||||||
const onClickHandler = useCallback((): void => {
|
const onClickHandler = useCallback((): void => {
|
||||||
if (location.pathname === ROUTES.LOGS_EXPLORER) {
|
if (location.pathname === ROUTES.LOGS_EXPLORER) {
|
||||||
history.push(ROUTES.OLD_LOGS_EXPLORER);
|
safeNavigate(ROUTES.OLD_LOGS_EXPLORER);
|
||||||
} else if (location.pathname === ROUTES.TRACE) {
|
} else if (location.pathname === ROUTES.TRACE) {
|
||||||
history.push(ROUTES.TRACES_EXPLORER);
|
safeNavigate(ROUTES.TRACES_EXPLORER);
|
||||||
} else if (location.pathname === ROUTES.OLD_LOGS_EXPLORER) {
|
} else if (location.pathname === ROUTES.OLD_LOGS_EXPLORER) {
|
||||||
history.push(ROUTES.LOGS_EXPLORER);
|
safeNavigate(ROUTES.LOGS_EXPLORER);
|
||||||
} else if (location.pathname === ROUTES.TRACES_EXPLORER) {
|
} else if (location.pathname === ROUTES.TRACES_EXPLORER) {
|
||||||
history.push(ROUTES.TRACE);
|
safeNavigate(ROUTES.TRACE);
|
||||||
}
|
}
|
||||||
}, [location.pathname]);
|
}, [location.pathname, safeNavigate]);
|
||||||
|
|
||||||
const button = useMemo(
|
const button = useMemo(
|
||||||
() => (
|
() => (
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
import { UseQueryResult } from 'react-query';
|
import { UseQueryResult } from 'react-query';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { SuccessResponse } from 'types/api';
|
import { SuccessResponse } from 'types/api';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { QueryBuilderProvider } from 'providers/QueryBuilder';
|
import { QueryBuilderProvider } from 'providers/QueryBuilder';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom-v5-compat';
|
||||||
import { render } from 'tests/test-utils';
|
import { render } from 'tests/test-utils';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import {
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { generatePath, useParams } from 'react-router-dom';
|
import { generatePath, useParams } from 'react-router';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { ColumnUnit, Dashboard, Widgets } from 'types/api/dashboard/getAll';
|
import { ColumnUnit, Dashboard, Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { IField } from 'types/api/logs/fields';
|
import { IField } from 'types/api/logs/fields';
|
||||||
@@ -101,7 +101,8 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
|
|
||||||
const query = useUrlQuery();
|
const query = useUrlQuery();
|
||||||
|
|
||||||
const { dashboardId } = useParams<DashboardWidgetPageParams>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const { dashboardId } = (useParams() as unknown) as DashboardWidgetPageParams;
|
||||||
|
|
||||||
const [isNewDashboard, setIsNewDashboard] = useState<boolean>(false);
|
const [isNewDashboard, setIsNewDashboard] = useState<boolean>(false);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Typography } from 'antd';
|
|||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { ArrowUpRight } from 'lucide-react';
|
import { ArrowUpRight } from 'lucide-react';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import DOCLINKS from 'utils/docLinks';
|
import DOCLINKS from 'utils/docLinks';
|
||||||
@@ -15,6 +15,7 @@ export default function NoLogs({
|
|||||||
dataSource: DataSource;
|
dataSource: DataSource;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { isCloudUser: isCloudUserVal } = useGetTenantLicense();
|
const { isCloudUser: isCloudUserVal } = useGetTenantLicense();
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const handleLinkClick = (
|
const handleLinkClick = (
|
||||||
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
|
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
|
||||||
@@ -28,7 +29,7 @@ export default function NoLogs({
|
|||||||
} else if (dataSource === DataSource.LOGS) {
|
} else if (dataSource === DataSource.LOGS) {
|
||||||
logEvent('Logs Explorer: Navigate to onboarding', {});
|
logEvent('Logs Explorer: Navigate to onboarding', {});
|
||||||
}
|
}
|
||||||
history.push(
|
safeNavigate(
|
||||||
dataSource === 'traces'
|
dataSource === 'traces'
|
||||||
? ROUTES.GET_STARTED_APPLICATION_MONITORING
|
? ROUTES.GET_STARTED_APPLICATION_MONITORING
|
||||||
: ROUTES.GET_STARTED_LOGS_MANAGEMENT,
|
: ROUTES.GET_STARTED_LOGS_MANAGEMENT,
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ import ROUTES from 'constants/routes';
|
|||||||
import FullScreenHeader from 'container/FullScreenHeader/FullScreenHeader';
|
import FullScreenHeader from 'container/FullScreenHeader/FullScreenHeader';
|
||||||
import InviteUserModal from 'container/OrganizationSettings/InviteUserModal/InviteUserModal';
|
import InviteUserModal from 'container/OrganizationSettings/InviteUserModal/InviteUserModal';
|
||||||
import { InviteMemberFormValues } from 'container/OrganizationSettings/PendingInvitesContainer';
|
import { InviteMemberFormValues } from 'container/OrganizationSettings/PendingInvitesContainer';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { UserPlus } from 'lucide-react';
|
import { UserPlus } from 'lucide-react';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
|
import { useLocation } from 'react-router';
|
||||||
import { useEffectOnce } from 'react-use';
|
import { useEffectOnce } from 'react-use';
|
||||||
|
|
||||||
import ModuleStepsContainer from './common/ModuleStepsContainer/ModuleStepsContainer';
|
import ModuleStepsContainer from './common/ModuleStepsContainer/ModuleStepsContainer';
|
||||||
@@ -105,8 +106,9 @@ export default function Onboarding(): JSX.Element {
|
|||||||
const [selectedModuleSteps, setSelectedModuleSteps] = useState(APM_STEPS);
|
const [selectedModuleSteps, setSelectedModuleSteps] = useState(APM_STEPS);
|
||||||
const [activeStep, setActiveStep] = useState(1);
|
const [activeStep, setActiveStep] = useState(1);
|
||||||
const [current, setCurrent] = useState(0);
|
const [current, setCurrent] = useState(0);
|
||||||
const { location } = history;
|
const location = useLocation();
|
||||||
const { t } = useTranslation(['onboarding']);
|
const { t } = useTranslation(['onboarding']);
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const { featureFlags } = useAppContext();
|
const { featureFlags } = useAppContext();
|
||||||
const isOnboardingV3Enabled = featureFlags?.find(
|
const isOnboardingV3Enabled = featureFlags?.find(
|
||||||
@@ -254,7 +256,7 @@ export default function Onboarding(): JSX.Element {
|
|||||||
|
|
||||||
const handleNext = (): void => {
|
const handleNext = (): void => {
|
||||||
if (activeStep <= 3) {
|
if (activeStep <= 3) {
|
||||||
history.push(moduleRouteMap[selectedModule.id as ModulesMap]);
|
safeNavigate(moduleRouteMap[selectedModule.id as ModulesMap]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -319,7 +321,7 @@ export default function Onboarding(): JSX.Element {
|
|||||||
<div
|
<div
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
logEvent('Onboarding V2: Skip Button Clicked', {});
|
logEvent('Onboarding V2: Skip Button Clicked', {});
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigate(ROUTES.APPLICATION);
|
||||||
}}
|
}}
|
||||||
className="skip-to-console"
|
className="skip-to-console"
|
||||||
>
|
>
|
||||||
@@ -393,9 +395,9 @@ export default function Onboarding(): JSX.Element {
|
|||||||
resetProgress();
|
resetProgress();
|
||||||
|
|
||||||
if (isOnboardingV3Enabled) {
|
if (isOnboardingV3Enabled) {
|
||||||
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
safeNavigate(ROUTES.GET_STARTED_WITH_CLOUD);
|
||||||
} else {
|
} else {
|
||||||
history.push(ROUTES.GET_STARTED);
|
safeNavigate(ROUTES.GET_STARTED);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
selectedModule={selectedModule}
|
selectedModule={selectedModule}
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ import {
|
|||||||
messagingQueueKakfaSupportedDataSources,
|
messagingQueueKakfaSupportedDataSources,
|
||||||
} from 'container/OnboardingContainer/utils/dataSourceUtils';
|
} from 'container/OnboardingContainer/utils/dataSourceUtils';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { Blocks, Check } from 'lucide-react';
|
import { Blocks, Check } from 'lucide-react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { popupContainer } from 'utils/selectPopupContainer';
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
export interface DataSourceType {
|
export interface DataSourceType {
|
||||||
@@ -37,7 +37,7 @@ export interface DataSourceType {
|
|||||||
export default function DataSource(): JSX.Element {
|
export default function DataSource(): JSX.Element {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const { t } = useTranslation(['common']);
|
const { t } = useTranslation(['common']);
|
||||||
const history = useHistory();
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const getStartedSource = useUrlQuery().get(QueryParams.getStartedSource);
|
const getStartedSource = useUrlQuery().get(QueryParams.getStartedSource);
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ export default function DataSource(): JSX.Element {
|
|||||||
dataSource: selectedDataSource?.name,
|
dataSource: selectedDataSource?.name,
|
||||||
framework: selectedFramework,
|
framework: selectedFramework,
|
||||||
});
|
});
|
||||||
history.push(ROUTES.INTEGRATIONS);
|
safeNavigate(ROUTES.INTEGRATIONS);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import ROUTES from 'constants/routes';
|
|||||||
import { stepsMap } from 'container/OnboardingContainer/constants/stepsConfig';
|
import { stepsMap } from 'container/OnboardingContainer/constants/stepsConfig';
|
||||||
import { DataSourceType } from 'container/OnboardingContainer/Steps/DataSource/DataSource';
|
import { DataSourceType } from 'container/OnboardingContainer/Steps/DataSource/DataSource';
|
||||||
import { hasFrameworks } from 'container/OnboardingContainer/utils/dataSourceUtils';
|
import { hasFrameworks } from 'container/OnboardingContainer/utils/dataSourceUtils';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { isEmpty, isNull } from 'lodash-es';
|
import { isEmpty, isNull } from 'lodash-es';
|
||||||
import { UserPlus } from 'lucide-react';
|
import { UserPlus } from 'lucide-react';
|
||||||
import { SetStateAction, useState } from 'react';
|
import { SetStateAction, useState } from 'react';
|
||||||
@@ -83,6 +83,8 @@ export default function ModuleStepsContainer({
|
|||||||
const [metaData, setMetaData] = useState<MetaDataProps[]>(defaultMetaData);
|
const [metaData, setMetaData] = useState<MetaDataProps[]>(defaultMetaData);
|
||||||
const lastStepIndex = selectedModuleSteps.length - 1;
|
const lastStepIndex = selectedModuleSteps.length - 1;
|
||||||
|
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
const isValidForm = (): boolean => {
|
const isValidForm = (): boolean => {
|
||||||
const { id: selectedModuleID } = selectedModule;
|
const { id: selectedModuleID } = selectedModule;
|
||||||
@@ -153,15 +155,15 @@ export default function ModuleStepsContainer({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (selectedModule.id === ModulesMap.APM) {
|
if (selectedModule.id === ModulesMap.APM) {
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigate(ROUTES.APPLICATION);
|
||||||
} else if (selectedModule.id === ModulesMap.LogsManagement) {
|
} else if (selectedModule.id === ModulesMap.LogsManagement) {
|
||||||
history.push(ROUTES.LOGS_EXPLORER);
|
safeNavigate(ROUTES.LOGS_EXPLORER);
|
||||||
} else if (selectedModule.id === ModulesMap.InfrastructureMonitoring) {
|
} else if (selectedModule.id === ModulesMap.InfrastructureMonitoring) {
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigate(ROUTES.APPLICATION);
|
||||||
} else if (selectedModule.id === ModulesMap.AwsMonitoring) {
|
} else if (selectedModule.id === ModulesMap.AwsMonitoring) {
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigate(ROUTES.APPLICATION);
|
||||||
} else {
|
} else {
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigate(ROUTES.APPLICATION);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -380,7 +382,7 @@ export default function ModuleStepsContainer({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleLogoClick = (): void => {
|
const handleLogoClick = (): void => {
|
||||||
history.push('/home');
|
safeNavigate('/home');
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { FeatureKeys } from 'constants/features';
|
|||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { InviteTeamMembersProps } from 'container/OrganizationSettings/PendingInvitesContainer';
|
import { InviteTeamMembersProps } from 'container/OrganizationSettings/PendingInvitesContainer';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useMutation, useQuery } from 'react-query';
|
import { useMutation, useQuery } from 'react-query';
|
||||||
@@ -72,6 +72,7 @@ function OnboardingQuestionaire(): JSX.Element {
|
|||||||
const [signozDetails, setSignozDetails] = useState<SignozDetails>(
|
const [signozDetails, setSignozDetails] = useState<SignozDetails>(
|
||||||
INITIAL_SIGNOZ_DETAILS,
|
INITIAL_SIGNOZ_DETAILS,
|
||||||
);
|
);
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const [
|
const [
|
||||||
optimiseSignozDetails,
|
optimiseSignozDetails,
|
||||||
@@ -122,9 +123,9 @@ function OnboardingQuestionaire(): JSX.Element {
|
|||||||
logEvent('Org Onboarding: Redirecting to Get Started', {});
|
logEvent('Org Onboarding: Redirecting to Get Started', {});
|
||||||
|
|
||||||
if (isOnboardingV3Enabled) {
|
if (isOnboardingV3Enabled) {
|
||||||
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
safeNavigate(ROUTES.GET_STARTED_WITH_CLOUD);
|
||||||
} else {
|
} else {
|
||||||
history.push(ROUTES.GET_STARTED);
|
safeNavigate(ROUTES.GET_STARTED);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import logEvent from 'api/common/logEvent';
|
|||||||
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
|
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
||||||
import history from 'lib/history';
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||||
import { isEmpty } from 'lodash-es';
|
import { isEmpty } from 'lodash-es';
|
||||||
import { CheckIcon, Goal, UserPlus, X } from 'lucide-react';
|
import { CheckIcon, Goal, UserPlus, X } from 'lucide-react';
|
||||||
import { useAppContext } from 'providers/App/App';
|
import { useAppContext } from 'providers/App/App';
|
||||||
@@ -120,6 +120,7 @@ function OnboardingAddDataSource(): JSX.Element {
|
|||||||
const question2Ref = useRef<HTMLDivElement | null>(null);
|
const question2Ref = useRef<HTMLDivElement | null>(null);
|
||||||
const question3Ref = useRef<HTMLDivElement | null>(null);
|
const question3Ref = useRef<HTMLDivElement | null>(null);
|
||||||
const configureProdRef = useRef<HTMLDivElement | null>(null);
|
const configureProdRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const { safeNavigate } = useSafeNavigate();
|
||||||
|
|
||||||
const [showConfigureProduct, setShowConfigureProduct] = useState<boolean>(
|
const [showConfigureProduct, setShowConfigureProduct] = useState<boolean>(
|
||||||
false,
|
false,
|
||||||
@@ -417,22 +418,22 @@ function OnboardingAddDataSource(): JSX.Element {
|
|||||||
} else if (step === 3) {
|
} else if (step === 3) {
|
||||||
switch (selectedDataSource?.module) {
|
switch (selectedDataSource?.module) {
|
||||||
case 'apm':
|
case 'apm':
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigate(ROUTES.APPLICATION);
|
||||||
break;
|
break;
|
||||||
case 'logs':
|
case 'logs':
|
||||||
history.push(ROUTES.LOGS);
|
safeNavigate(ROUTES.LOGS);
|
||||||
break;
|
break;
|
||||||
case 'metrics':
|
case 'metrics':
|
||||||
history.push(ROUTES.ALL_DASHBOARD);
|
safeNavigate(ROUTES.ALL_DASHBOARD);
|
||||||
break;
|
break;
|
||||||
case 'infra-monitoring-hosts':
|
case 'infra-monitoring-hosts':
|
||||||
history.push(ROUTES.INFRASTRUCTURE_MONITORING_HOSTS);
|
safeNavigate(ROUTES.INFRASTRUCTURE_MONITORING_HOSTS);
|
||||||
break;
|
break;
|
||||||
case 'infra-monitoring-k8s':
|
case 'infra-monitoring-k8s':
|
||||||
history.push(ROUTES.INFRASTRUCTURE_MONITORING_KUBERNETES);
|
safeNavigate(ROUTES.INFRASTRUCTURE_MONITORING_KUBERNETES);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
history.push(ROUTES.APPLICATION);
|
safeNavigate(ROUTES.APPLICATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -590,7 +591,7 @@ function OnboardingAddDataSource(): JSX.Element {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
history.push(ROUTES.HOME);
|
safeNavigate(ROUTES.HOME);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Typography.Text>Get Started (2/4)</Typography.Text>
|
<Typography.Text>Get Started (2/4)</Typography.Text>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { useAppContext } from 'providers/App/App';
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
import { useCopyToClipboard } from 'react-use';
|
import { useCopyToClipboard } from 'react-use';
|
||||||
import { PayloadProps } from 'types/api/user/getPendingInvites';
|
import { PayloadProps } from 'types/api/user/getPendingInvites';
|
||||||
import { ROLES } from 'types/roles';
|
import { ROLES } from 'types/roles';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
|
|||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { generateColor } from 'lib/uPlotLib/utils/generateColor';
|
import { generateColor } from 'lib/uPlotLib/utils/generateColor';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router';
|
||||||
import { TraceDetailFlamegraphURLProps } from 'types/api/trace/getTraceFlamegraph';
|
import { TraceDetailFlamegraphURLProps } from 'types/api/trace/getTraceFlamegraph';
|
||||||
import { Span } from 'types/api/trace/getTraceV2';
|
import { Span } from 'types/api/trace/getTraceV2';
|
||||||
|
|
||||||
@@ -34,7 +34,10 @@ function TraceFlamegraph(props: ITraceFlamegraphProps): JSX.Element {
|
|||||||
traceFlamegraphStatsWidth,
|
traceFlamegraphStatsWidth,
|
||||||
selectedSpan,
|
selectedSpan,
|
||||||
} = props;
|
} = props;
|
||||||
const { id: traceId } = useParams<TraceDetailFlamegraphURLProps>();
|
// Temp: Hard type casting for string | undefined
|
||||||
|
const {
|
||||||
|
id: traceId,
|
||||||
|
} = (useParams() as unknown) as TraceDetailFlamegraphURLProps;
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
const [firstSpanAtFetchLevel, setFirstSpanAtFetchLevel] = useState<string>(
|
const [firstSpanAtFetchLevel, setFirstSpanAtFetchLevel] = useState<string>(
|
||||||
urlQuery.get('spanId') || '',
|
urlQuery.get('spanId') || '',
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user