Repository: provectus/kafka-ui
Issue: Redirect the user to the wizard page if no clusters present upon app startup
Labels: type/enhancement
scope/frontend
status/accepted
area/wizard

If:
1. there are no clusters configured
2. dynamic config is ON
then redirect the user to the wizard page initially

Issue comments:

Pull request review comments:
```suggestion
    if (appInfo.hasDynamicConfig && clusters.isSuccess &&  clusters.data.length === 0) {
```
why non exact?
understood
done 
we use custom `render` method. Pls check other components
@David-DB88 why we use `getNonExactPath` here?
removed it 
replaced with custom render 
```suggestion
const mockedNavigate = jest.fn();
```
done

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Dashboard/Dashboard.tsx b/kafka-ui-react-app/src/components/Dashboard/Dashboard.tsx
index 46c35d50794..7eab4c1d2ff 100644
--- a/kafka-ui-react-app/src/components/Dashboard/Dashboard.tsx
+++ b/kafka-ui-react-app/src/components/Dashboard/Dashboard.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
 import PageHeading from 'components/common/PageHeading/PageHeading';
 import * as Metrics from 'components/common/Metrics';
 import { Tag } from 'components/common/Tag/Tag.styled';
@@ -11,6 +11,7 @@ import useBoolean from 'lib/hooks/useBoolean';
 import { Button } from 'components/common/Button/Button';
 import { clusterNewConfigPath } from 'lib/paths';
 import { GlobalSettingsContext } from 'components/contexts/GlobalSettingsContext';
+import { useNavigate } from 'react-router-dom';
 
 import * as S from './Dashboard.styled';
 import ClusterName from './ClusterName';
@@ -20,7 +21,7 @@ const Dashboard: React.FC = () => {
   const clusters = useClusters();
   const { value: showOfflineOnly, toggle } = useBoolean(false);
   const appInfo = React.useContext(GlobalSettingsContext);
-
+  const navigate = useNavigate();
   const config = React.useMemo(() => {
     const clusterList = clusters.data || [];
     const offlineClusters = clusterList.filter(
@@ -55,6 +56,12 @@ const Dashboard: React.FC = () => {
     return initialColumns;
   }, []);
 
+  useEffect(() => {
+    if (appInfo.hasDynamicConfig && !clusters.data) {
+      navigate(clusterNewConfigPath);
+    }
+  }, [clusters, appInfo.hasDynamicConfig]);
+
   return (
     <>
       <PageHeading text="Dashboard" />
diff --git a/kafka-ui-react-app/src/components/Dashboard/__test__/Dashboard.spec.tsx b/kafka-ui-react-app/src/components/Dashboard/__test__/Dashboard.spec.tsx
new file mode 100644
index 00000000000..e9141e980e4
--- /dev/null
+++ b/kafka-ui-react-app/src/components/Dashboard/__test__/Dashboard.spec.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import { useClusters } from 'lib/hooks/api/clusters';
+import Dashboard from 'components/Dashboard/Dashboard';
+import { Cluster, ServerStatus } from 'generated-sources';
+import { render } from 'lib/testHelpers';
+
+interface DataType {
+  data: Cluster[] | undefined;
+}
+jest.mock('lib/hooks/api/clusters');
+const mockedNavigate = jest.fn();
+jest.mock('react-router-dom', () => ({
+  ...jest.requireActual('react-router-dom'),
+  useNavigate: () => mockedNavigate,
+}));
+describe('Dashboard component', () => {
+  const renderComponent = (hasDynamicConfig: boolean, data: DataType) => {
+    const useClustersMock = useClusters as jest.Mock;
+    useClustersMock.mockReturnValue(data);
+    render(<Dashboard />, {
+      globalSettings: { hasDynamicConfig },
+    });
+  };
+  it('redirects to new cluster configuration page if there are no clusters and dynamic config is enabled', async () => {
+    await renderComponent(true, { data: undefined });
+
+    expect(mockedNavigate).toHaveBeenCalled();
+  });
+
+  it('should not navigate to new cluster config page when there are clusters', async () => {
+    await renderComponent(true, {
+      data: [{ name: 'Cluster 1', status: ServerStatus.ONLINE }],
+    });
+
+    expect(mockedNavigate).not.toHaveBeenCalled();
+  });
+
+  it('should not navigate to new cluster config page when there are no clusters and hasDynamicConfig is false', async () => {
+    await renderComponent(false, {
+      data: [],
+    });
+
+    expect(mockedNavigate).not.toHaveBeenCalled();
+  });
+});
diff --git a/kafka-ui-react-app/src/components/contexts/GlobalSettingsContext.tsx b/kafka-ui-react-app/src/components/contexts/GlobalSettingsContext.tsx
index 4de05307b11..563fb175f32 100644
--- a/kafka-ui-react-app/src/components/contexts/GlobalSettingsContext.tsx
+++ b/kafka-ui-react-app/src/components/contexts/GlobalSettingsContext.tsx
@@ -2,7 +2,7 @@ import { useAppInfo } from 'lib/hooks/api/appConfig';
 import React from 'react';
 import { ApplicationInfoEnabledFeaturesEnum } from 'generated-sources';
 
-interface GlobalSettingsContextProps {
+export interface GlobalSettingsContextProps {
   hasDynamicConfig: boolean;
 }
 


Test patch:
diff --git a/kafka-ui-react-app/src/lib/testHelpers.tsx b/kafka-ui-react-app/src/lib/testHelpers.tsx
index 508904d1466..42539a0aac9 100644
--- a/kafka-ui-react-app/src/lib/testHelpers.tsx
+++ b/kafka-ui-react-app/src/lib/testHelpers.tsx
@@ -26,7 +26,10 @@ import {
 } from '@tanstack/react-query';
 import { ConfirmContextProvider } from 'components/contexts/ConfirmContext';
 import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
-import { GlobalSettingsContext } from 'components/contexts/GlobalSettingsContext';
+import {
+  GlobalSettingsContext,
+  GlobalSettingsContextProps,
+} from 'components/contexts/GlobalSettingsContext';
 import { UserInfoRolesAccessContext } from 'components/contexts/UserInfoRolesAccessContext';
 
 import { RolesType, modifyRolesData } from './permissions';
@@ -35,6 +38,7 @@ interface CustomRenderOptions extends Omit<RenderOptions, 'wrapper'> {
   preloadedState?: Partial<RootState>;
   store?: Store<Partial<RootState>, AnyAction>;
   initialEntries?: MemoryRouterProps['initialEntries'];
+  globalSettings?: GlobalSettingsContextProps;
   userInfo?: {
     roles?: RolesType;
     rbacFlag: boolean;
@@ -110,6 +114,7 @@ const customRender = (
       preloadedState,
     }),
     initialEntries,
+    globalSettings = { hasDynamicConfig: false },
     userInfo,
     ...renderOptions
   }: CustomRenderOptions = {}
@@ -119,7 +124,7 @@ const customRender = (
     children,
   }) => (
     <TestQueryClientProvider>
-      <GlobalSettingsContext.Provider value={{ hasDynamicConfig: false }}>
+      <GlobalSettingsContext.Provider value={globalSettings}>
         <ThemeProvider theme={theme}>
           <TestUserInfoProvider data={userInfo}>
             <ConfirmContextProvider>