This is an automated email from the ASF dual-hosted git repository.

mintsweet pushed a commit to branch refactor-redux
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git

commit db5612b2245bf6eecfd9a09bfaa093d3b7aadcfc
Author: mintsweet <[email protected]>
AuthorDate: Mon Sep 9 15:50:21 2024 +1200

    refactor: adjust redux dir and structure
---
 config-ui/src/{routes/app/app.tsx => App.tsx}      | 25 ++++--
 config-ui/src/api/index.ts                         |  2 +-
 config-ui/src/app/routrer.tsx                      |  5 +-
 config-ui/src/app/store.ts                         |  4 +-
 config-ui/src/features/connections/slice.ts        | 90 +++++++++++-----------
 config-ui/src/features/onboard/slice.ts            | 12 ++-
 config-ui/src/features/{ => version}/index.ts      |  2 +-
 config-ui/src/features/version/slice.ts            | 63 +++++++++++++++
 .../plugins/components/connection-form/index.tsx   |  2 +-
 .../register/webhook/components/create-dialog.tsx  |  2 +-
 .../register/webhook/components/delete-dialog.tsx  |  2 +-
 .../register/webhook/components/edit-dialog.tsx    |  2 +-
 .../webhook/components/selector-dialog.tsx         |  2 +-
 .../register/webhook/components/view-dialog.tsx    |  2 +-
 config-ui/src/routes/app/index.ts                  | 20 -----
 config-ui/src/routes/app/loader.ts                 | 46 -----------
 .../components/add-connection-dialog/index.tsx     |  2 +-
 .../blueprint/detail/configuration-panel.tsx       |  2 +-
 config-ui/src/routes/blueprint/home/index.tsx      |  2 +-
 config-ui/src/routes/connection/connection.tsx     |  2 +-
 config-ui/src/routes/index.ts                      |  1 -
 config-ui/src/routes/layout/layout.tsx             | 14 +---
 config-ui/src/routes/project/home/index.tsx        |  2 +-
 23 files changed, 156 insertions(+), 150 deletions(-)

diff --git a/config-ui/src/routes/app/app.tsx b/config-ui/src/App.tsx
similarity index 52%
rename from config-ui/src/routes/app/app.tsx
rename to config-ui/src/App.tsx
index 51c3ce0c7..28343144e 100644
--- a/config-ui/src/routes/app/app.tsx
+++ b/config-ui/src/App.tsx
@@ -17,31 +17,40 @@
  */
 
 import { useEffect } from 'react';
-import { useNavigate, useLoaderData, Outlet } from 'react-router-dom';
+import { useNavigate, Outlet } from 'react-router-dom';
 
 import { PageLoading } from '@/components';
-import { init } from '@/features';
-import { request as requestOnboard, selectStatus } from '@/features/onboard';
+import { request as requestVersion, selectVersionStatus, selectVersionError } 
from '@/features/version';
+import { request as requestConnections, selectConnectionsStatus, 
selectConnectionsError } from '@/features/connections';
+import { request as requestOnboard, selectOnboardStatus, selectOnboardError } 
from '@/features/onboard';
 import { useAppDispatch, useAppSelector } from '@/hooks';
 import { setUpRequestInterceptor } from '@/utils';
 
 export const App = () => {
   const navigate = useNavigate();
 
-  const { version, plugins } = useLoaderData() as { version: string; plugins: 
string[] };
-
   const dispatch = useAppDispatch();
-  const status = useAppSelector(selectStatus);
+  const versionStatus = useAppSelector(selectVersionStatus);
+  const versionError = useAppSelector(selectVersionError);
+  const connectionsStatus = useAppSelector(selectConnectionsStatus);
+  const connectionsError = useAppSelector(selectConnectionsError);
+  const onboardStatus = useAppSelector(selectOnboardStatus);
+  const onboardError = useAppSelector(selectOnboardError);
 
   useEffect(() => {
     setUpRequestInterceptor(navigate);
-    dispatch(init({ version, plugins }));
+    dispatch(requestVersion());
+    dispatch(requestConnections());
     dispatch(requestOnboard());
   }, []);
 
-  if (status === 'loading') {
+  if (versionStatus === 'loading' || connectionsStatus === 'loading' || 
onboardStatus === 'loading') {
     return <PageLoading />;
   }
 
+  if (versionStatus === 'failed' || connectionsStatus === 'failed' || 
onboardStatus === 'failed') {
+    throw (versionError as any).message || (connectionsError as any).message 
|| (onboardError as any).message;
+  }
+
   return <Outlet />;
 };
diff --git a/config-ui/src/api/index.ts b/config-ui/src/api/index.ts
index f211e5640..b358e1eee 100644
--- a/config-ui/src/api/index.ts
+++ b/config-ui/src/api/index.ts
@@ -31,7 +31,7 @@ import * as task from './task';
 
 const migrate = () => request('/proceed-db-migration');
 const ping = () => request('/ping');
-const version = (signal?: AbortSignal): Promise<{ version: string }> => 
request('/version', { signal });
+const version = (): Promise<{ version: string }> => request('/version');
 
 export const API = {
   apiKey,
diff --git a/config-ui/src/app/routrer.tsx b/config-ui/src/app/routrer.tsx
index 1c90a7a35..e40c83084 100644
--- a/config-ui/src/app/routrer.tsx
+++ b/config-ui/src/app/routrer.tsx
@@ -19,8 +19,6 @@
 import { createBrowserRouter, Navigate } from 'react-router-dom';
 
 import {
-  App,
-  appLoader,
   DBMigrate,
   Onboard,
   Error,
@@ -41,13 +39,14 @@ import {
   NotFound,
 } from '@/routes';
 
+import { App } from '../App';
+
 const PATH_PREFIX = import.meta.env.DEVLAKE_PATH_PREFIX ?? '/';
 
 export const router = createBrowserRouter([
   {
     path: PATH_PREFIX,
     element: <App />,
-    loader: appLoader,
     errorElement: <Error />,
     children: [
       {
diff --git a/config-ui/src/app/store.ts b/config-ui/src/app/store.ts
index 8fec5046c..f95900a46 100644
--- a/config-ui/src/app/store.ts
+++ b/config-ui/src/app/store.ts
@@ -18,11 +18,13 @@
 
 import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit';
 
-import { connectionsSlice } from '@/features';
+import { versionSlice } from '@/features/version';
+import { connectionsSlice } from '@/features/connections';
 import { onboardSlice } from '@/features/onboard';
 
 export const store = configureStore({
   reducer: {
+    version: versionSlice.reducer,
     connections: connectionsSlice.reducer,
     onboard: onboardSlice.reducer,
   },
diff --git a/config-ui/src/features/connections/slice.ts 
b/config-ui/src/features/connections/slice.ts
index e4006fae1..8e2309bc0 100644
--- a/config-ui/src/features/connections/slice.ts
+++ b/config-ui/src/features/connections/slice.ts
@@ -17,59 +17,67 @@
  */
 
 import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
-import { flatten } from 'lodash';
+import { intersection, flatten } from 'lodash';
 
 import API from '@/api';
 import { RootState } from '@/app/store';
 import { IConnection, IConnectionStatus, IWebhook, IStatus } from '@/types';
+import { getRegisterPlugins } from '@/plugins';
 
 import { transformConnection, transformWebhook } from './utils';
 
 const initialState: {
   status: IStatus;
-  error: any;
-  version: string;
+  error?: unknown;
   plugins: string[];
   connections: IConnection[];
   webhooks: IWebhook[];
 } = {
   status: 'idle',
-  error: null,
-  version: '',
   plugins: [],
   connections: [],
   webhooks: [],
 };
 
-export const init = createAsyncThunk(
-  'connections/init',
-  async ({ version, plugins }: { version: string; plugins: string[] }) => {
-    const connections = await Promise.all(
-      plugins
-        .filter((plugin) => plugin !== 'webhook')
-        .map(async (plugin) => {
-          const connections = await API.connection.list(plugin);
-          return connections.map((connection) => transformConnection(plugin, 
connection));
-        }),
-    );
-
-    const webhooks = await Promise.all(
-      plugins
-        .filter((plugin) => plugin === 'webhook')
-        .map(async () => {
-          const webhooks = await API.plugin.webhook.list();
-          return webhooks.map((webhook) => transformWebhook(webhook));
-        }),
-    );
-
-    return {
-      version,
-      plugins,
-      connections: flatten(connections),
-      webhooks: flatten(webhooks),
-    };
-  },
-);
+export const request = createAsyncThunk('connections/request', async () => {
+  let plugins = [];
+  let fePlugins = getRegisterPlugins();
+  const bePlugins = await API.plugin.list();
+
+  try {
+    const envPlugins = 
import.meta.env.DEVLAKE_PLUGINS.split(',').filter(Boolean);
+    fePlugins = fePlugins.filter((plugin) => !envPlugins.length || 
envPlugins.includes(plugin));
+  } catch (err) {}
+
+  plugins = intersection(
+    fePlugins,
+    bePlugins.map((it) => it.plugin),
+  );
+
+  const connections = await Promise.all(
+    plugins
+      .filter((plugin) => plugin !== 'webhook')
+      .map(async (plugin) => {
+        const connections = await API.connection.list(plugin);
+        return connections.map((connection) => transformConnection(plugin, 
connection));
+      }),
+  );
+
+  const webhooks = await Promise.all(
+    plugins
+      .filter((plugin) => plugin === 'webhook')
+      .map(async () => {
+        const webhooks = await API.plugin.webhook.list();
+        return webhooks.map((webhook) => transformWebhook(webhook));
+      }),
+  );
+
+  return {
+    plugins,
+    connections: flatten(connections),
+    webhooks: flatten(webhooks),
+  };
+});
 
 export const addConnection = createAsyncThunk('connections/addConnection', 
async ({ plugin, ...payload }: any) => {
   const connection = await API.connection.create(plugin, payload);
@@ -145,18 +153,16 @@ export const connectionsSlice = createSlice({
   reducers: {},
   extraReducers(builder) {
     builder
-      .addCase(init.pending, (state) => {
+      .addCase(request.pending, (state) => {
         state.status = 'loading';
       })
-      .addCase(init.fulfilled, (state, action) => {
-        state.version = action.payload.version;
+      .addCase(request.fulfilled, (state, action) => {
         state.plugins = action.payload.plugins;
         state.connections = action.payload.connections;
         state.webhooks = action.payload.webhooks;
         state.status = 'success';
       })
-      .addCase(init.rejected, (state, action) => {
-        console.error(action.error.stack);
+      .addCase(request.rejected, (state, action) => {
         state.status = 'failed';
         state.error = action.error;
       })
@@ -208,11 +214,9 @@ export const connectionsSlice = createSlice({
 
 export default connectionsSlice.reducer;
 
-export const selectStatus = (state: RootState) => state.connections.status;
-
-export const selectError = (state: RootState) => state.connections.error;
+export const selectConnectionsStatus = (state: RootState) => 
state.connections.status;
 
-export const selectVersion = (state: RootState) => state.connections.version;
+export const selectConnectionsError = (state: RootState) => 
state.connections.error;
 
 export const selectPlugins = (state: RootState) => state.connections.plugins;
 
diff --git a/config-ui/src/features/onboard/slice.ts 
b/config-ui/src/features/onboard/slice.ts
index 1ddebf576..87d771eb6 100644
--- a/config-ui/src/features/onboard/slice.ts
+++ b/config-ui/src/features/onboard/slice.ts
@@ -61,10 +61,10 @@ export const done = createAsyncThunk('onboard/done', async 
(_, { getState }) =>
   return {};
 });
 
-const initialState: { status: IStatus; data: DataType } = {
+const initialState: { status: IStatus; error?: unknown; data: DataType } = {
   status: 'idle',
   data: {
-    initial: false,
+    initial: true,
     step: 0,
     records: [],
     projectName: '',
@@ -105,6 +105,10 @@ export const onboardSlice = createSlice({
           done: action.payload?.done ?? false,
         };
       })
+      .addCase(request.rejected, (state, action) => {
+        state.status = 'failed';
+        state.error = action.error;
+      })
       .addCase(update.fulfilled, (state, action) => {
         state.data = {
           ...state.data,
@@ -121,7 +125,9 @@ export default onboardSlice.reducer;
 
 export const { previous, changeProjectName, changePlugin, changeRecords } = 
onboardSlice.actions;
 
-export const selectStatus = (state: RootState) => state.onboard.status;
+export const selectOnboardStatus = (state: RootState) => state.onboard.status;
+
+export const selectOnboardError = (state: RootState) => state.onboard.error;
 
 export const selectOnboard = (state: RootState) => state.onboard.data;
 
diff --git a/config-ui/src/features/index.ts 
b/config-ui/src/features/version/index.ts
similarity index 96%
rename from config-ui/src/features/index.ts
rename to config-ui/src/features/version/index.ts
index 4e6e8a4de..513ab48a7 100644
--- a/config-ui/src/features/index.ts
+++ b/config-ui/src/features/version/index.ts
@@ -16,4 +16,4 @@
  *
  */
 
-export * from './connections';
+export * from './slice';
diff --git a/config-ui/src/features/version/slice.ts 
b/config-ui/src/features/version/slice.ts
new file mode 100644
index 000000000..873d9a46e
--- /dev/null
+++ b/config-ui/src/features/version/slice.ts
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
+
+import API from '@/api';
+import { RootState } from '@/app/store';
+import type { IStatus } from '@/types';
+
+export const request = createAsyncThunk('version/request', async () => {
+  const res = await API.version();
+  return res;
+});
+
+const initialState: {
+  status: IStatus;
+  error?: unknown;
+  version: string;
+} = {
+  status: 'idle',
+  version: '',
+};
+
+export const versionSlice = createSlice({
+  name: 'version',
+  initialState,
+  reducers: {},
+  extraReducers: (builder) => {
+    builder
+      .addCase(request.pending, (state) => {
+        state.status = 'loading';
+      })
+      .addCase(request.fulfilled, (state, action) => {
+        state.status = 'success';
+        state.version = action.payload.version;
+      })
+      .addCase(request.rejected, (state, action) => {
+        state.status = 'failed';
+        state.error = action.error;
+      });
+  },
+});
+
+export const selectVersionStatus = (state: RootState) => state.version.status;
+
+export const selectVersionError = (state: RootState) => state.version.error;
+
+export const selectVersion = (state: RootState) => state.version.version;
diff --git a/config-ui/src/plugins/components/connection-form/index.tsx 
b/config-ui/src/plugins/components/connection-form/index.tsx
index a0b60b0f7..6facde761 100644
--- a/config-ui/src/plugins/components/connection-form/index.tsx
+++ b/config-ui/src/plugins/components/connection-form/index.tsx
@@ -23,7 +23,7 @@ import { Flex, Alert, Button } from 'antd';
 import API from '@/api';
 import { useAppDispatch, useAppSelector } from '@/hooks';
 import { ExternalLink } from '@/components';
-import { addConnection, updateConnection } from '@/features';
+import { addConnection, updateConnection } from '@/features/connections';
 import { selectConnection } from '@/features/connections';
 import { getPluginConfig } from '@/plugins';
 import { operator } from '@/utils';
diff --git 
a/config-ui/src/plugins/register/webhook/components/create-dialog.tsx 
b/config-ui/src/plugins/register/webhook/components/create-dialog.tsx
index 0e2579346..54ec50acf 100644
--- a/config-ui/src/plugins/register/webhook/components/create-dialog.tsx
+++ b/config-ui/src/plugins/register/webhook/components/create-dialog.tsx
@@ -22,7 +22,7 @@ import { Modal, Input } from 'antd';
 
 import { useAppDispatch } from '@/hooks';
 import { Block, CopyText, ExternalLink } from '@/components';
-import { addWebhook } from '@/features';
+import { addWebhook } from '@/features/connections';
 import { operator } from '@/utils';
 
 import { transformURI } from './utils';
diff --git 
a/config-ui/src/plugins/register/webhook/components/delete-dialog.tsx 
b/config-ui/src/plugins/register/webhook/components/delete-dialog.tsx
index 8b05c3cd4..ce244d97a 100644
--- a/config-ui/src/plugins/register/webhook/components/delete-dialog.tsx
+++ b/config-ui/src/plugins/register/webhook/components/delete-dialog.tsx
@@ -21,7 +21,7 @@ import { Modal } from 'antd';
 
 import { useAppDispatch } from '@/hooks';
 import { Message } from '@/components';
-import { removeWebhook } from '@/features';
+import { removeWebhook } from '@/features/connections';
 import { operator } from '@/utils';
 
 interface Props {
diff --git a/config-ui/src/plugins/register/webhook/components/edit-dialog.tsx 
b/config-ui/src/plugins/register/webhook/components/edit-dialog.tsx
index eec2dd129..44ced0e3e 100644
--- a/config-ui/src/plugins/register/webhook/components/edit-dialog.tsx
+++ b/config-ui/src/plugins/register/webhook/components/edit-dialog.tsx
@@ -21,7 +21,7 @@ import { Modal, Input } from 'antd';
 
 import { useAppDispatch, useAppSelector } from '@/hooks';
 import { Block } from '@/components';
-import { updateWebhook, selectWebhook } from '@/features';
+import { updateWebhook, selectWebhook } from '@/features/connections';
 import { operator } from '@/utils';
 
 interface Props {
diff --git 
a/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx 
b/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx
index f63a94124..4c0c49511 100644
--- a/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx
+++ b/config-ui/src/plugins/register/webhook/components/selector-dialog.tsx
@@ -22,7 +22,7 @@ import MillerColumnsSelect from 'miller-columns-select';
 
 import { useAppSelector } from '@/hooks';
 import { Block, Loading } from '@/components';
-import { selectWebhooks } from '@/features';
+import { selectWebhooks } from '@/features/connections';
 import { IWebhook } from '@/types';
 
 import * as S from '../styled';
diff --git a/config-ui/src/plugins/register/webhook/components/view-dialog.tsx 
b/config-ui/src/plugins/register/webhook/components/view-dialog.tsx
index e1d45aede..95750c0a0 100644
--- a/config-ui/src/plugins/register/webhook/components/view-dialog.tsx
+++ b/config-ui/src/plugins/register/webhook/components/view-dialog.tsx
@@ -21,7 +21,7 @@ import { Modal, Button } from 'antd';
 
 import { useAppDispatch, useAppSelector } from '@/hooks';
 import { Block, CopyText, ExternalLink, Message } from '@/components';
-import { selectWebhook, renewWebhookApiKey } from '@/features';
+import { selectWebhook, renewWebhookApiKey } from '@/features/connections';
 import { IWebhook } from '@/types';
 import { operator } from '@/utils';
 
diff --git a/config-ui/src/routes/app/index.ts 
b/config-ui/src/routes/app/index.ts
deleted file mode 100644
index 57d773fc3..000000000
--- a/config-ui/src/routes/app/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-export * from './app';
-export * from './loader';
diff --git a/config-ui/src/routes/app/loader.ts 
b/config-ui/src/routes/app/loader.ts
deleted file mode 100644
index dad6d1267..000000000
--- a/config-ui/src/routes/app/loader.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import { intersection } from 'lodash';
-
-import API from '@/api';
-import { getRegisterPlugins } from '@/plugins';
-
-type Props = {
-  request: Request;
-};
-
-export const appLoader = async ({ request }: Props) => {
-  let fePlugins = getRegisterPlugins();
-  const bePlugins = await API.plugin.list();
-
-  try {
-    const envPlugins = 
import.meta.env.DEVLAKE_PLUGINS.split(',').filter(Boolean);
-    fePlugins = fePlugins.filter((plugin) => !envPlugins.length || 
envPlugins.includes(plugin));
-  } catch (err) {}
-
-  const res = await API.version(request.signal);
-
-  return {
-    version: res.version,
-    plugins: intersection(
-      fePlugins,
-      bePlugins.map((it) => it.plugin),
-    ),
-  };
-};
diff --git 
a/config-ui/src/routes/blueprint/detail/components/add-connection-dialog/index.tsx
 
b/config-ui/src/routes/blueprint/detail/components/add-connection-dialog/index.tsx
index a82659b4b..938df24bc 100644
--- 
a/config-ui/src/routes/blueprint/detail/components/add-connection-dialog/index.tsx
+++ 
b/config-ui/src/routes/blueprint/detail/components/add-connection-dialog/index.tsx
@@ -24,7 +24,7 @@ import styled from 'styled-components';
 
 import { PATHS } from '@/config';
 import { Block } from '@/components';
-import { selectAllConnections } from '@/features';
+import { selectAllConnections } from '@/features/connections';
 import { useAppSelector } from '@/hooks';
 import { PluginName, DataScopeSelect } from '@/plugins';
 import { IConnection } from '@/types';
diff --git a/config-ui/src/routes/blueprint/detail/configuration-panel.tsx 
b/config-ui/src/routes/blueprint/detail/configuration-panel.tsx
index a73b10743..2262545f0 100644
--- a/config-ui/src/routes/blueprint/detail/configuration-panel.tsx
+++ b/config-ui/src/routes/blueprint/detail/configuration-panel.tsx
@@ -24,7 +24,7 @@ import { Flex, Table, Button } from 'antd';
 import API from '@/api';
 import { NoData } from '@/components';
 import { getCron, PATHS } from '@/config';
-import { ConnectionName } from '@/features';
+import { ConnectionName } from '@/features/connections';
 import { getPluginConfig } from '@/plugins';
 import { IBlueprint, IBPMode } from '@/types';
 import { formatTime, operator } from '@/utils';
diff --git a/config-ui/src/routes/blueprint/home/index.tsx 
b/config-ui/src/routes/blueprint/home/index.tsx
index ae2a624b2..f8a860a04 100644
--- a/config-ui/src/routes/blueprint/home/index.tsx
+++ b/config-ui/src/routes/blueprint/home/index.tsx
@@ -25,7 +25,7 @@ import dayjs from 'dayjs';
 import API from '@/api';
 import { PageHeader, Block, TextTooltip, IconButton } from '@/components';
 import { getCronOptions, cronPresets, getCron, PATHS } from '@/config';
-import { ConnectionName } from '@/features';
+import { ConnectionName } from '@/features/connections';
 import { useRefreshData } from '@/hooks';
 import { IBlueprint, IBPMode } from '@/types';
 import { formatTime, operator } from '@/utils';
diff --git a/config-ui/src/routes/connection/connection.tsx 
b/config-ui/src/routes/connection/connection.tsx
index ef7431914..8092e4a88 100644
--- a/config-ui/src/routes/connection/connection.tsx
+++ b/config-ui/src/routes/connection/connection.tsx
@@ -26,7 +26,7 @@ import API from '@/api';
 import { PageHeader, Message, IconButton } from '@/components';
 import { PATHS } from '@/config';
 import { useAppSelector } from '@/hooks';
-import { selectConnection } from '@/features';
+import { selectConnection } from '@/features/connections';
 import { useRefreshData } from '@/hooks';
 import {
   ConnectionStatus,
diff --git a/config-ui/src/routes/index.ts b/config-ui/src/routes/index.ts
index fcb2cfec6..025a0792f 100644
--- a/config-ui/src/routes/index.ts
+++ b/config-ui/src/routes/index.ts
@@ -17,7 +17,6 @@
  */
 
 export * from './api-keys';
-export * from './app';
 export * from './blueprint';
 export * from './connection';
 export * from './db-migrate';
diff --git a/config-ui/src/routes/layout/layout.tsx 
b/config-ui/src/routes/layout/layout.tsx
index a67036a5c..9e5b519f2 100644
--- a/config-ui/src/routes/layout/layout.tsx
+++ b/config-ui/src/routes/layout/layout.tsx
@@ -21,9 +21,9 @@ import { Outlet, useNavigate, useLocation, Navigate } from 
'react-router-dom';
 import { Helmet } from 'react-helmet';
 import { Layout as AntdLayout, Menu, Divider } from 'antd';
 
-import { PageLoading, Logo, ExternalLink } from '@/components';
-import { selectError, selectStatus, selectVersion } from 
'@/features/connections';
+import { Logo, ExternalLink } from '@/components';
 import { selectOnboard } from '@/features/onboard';
+import { selectVersion } from '@/features/version';
 import { OnboardCard } from '@/routes/onboard/components';
 import { useAppSelector } from '@/hooks';
 
@@ -41,8 +41,6 @@ export const Layout = () => {
   const { pathname } = useLocation();
 
   const { initial } = useAppSelector(selectOnboard);
-  const status = useAppSelector(selectStatus);
-  const error = useAppSelector(selectError);
   const version = useAppSelector(selectVersion);
 
   useEffect(() => {
@@ -71,14 +69,6 @@ export const Layout = () => {
     return curMenuItem?.label ?? '';
   }, [pathname]);
 
-  if (['idle', 'loading'].includes(status)) {
-    return <PageLoading />;
-  }
-
-  if (status === 'failed') {
-    throw error.message;
-  }
-
   if (!initial) {
     return <Navigate to="/onboard" />;
   }
diff --git a/config-ui/src/routes/project/home/index.tsx 
b/config-ui/src/routes/project/home/index.tsx
index 0c52c1860..a84dd6506 100644
--- a/config-ui/src/routes/project/home/index.tsx
+++ b/config-ui/src/routes/project/home/index.tsx
@@ -24,7 +24,7 @@ import { Flex, Table, Button, Modal, Input } from 'antd';
 import API from '@/api';
 import { PageHeader, Block, IconButton } from '@/components';
 import { getCron, PATHS } from '@/config';
-import { ConnectionName } from '@/features';
+import { ConnectionName } from '@/features/connections';
 import { useRefreshData } from '@/hooks';
 import { OnboardTour } from '@/routes/onboard/components';
 import { formatTime, operator } from '@/utils';

Reply via email to