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

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

commit 59afd9cf04156be272fa8369b0cd64bcfe08c066
Author: mintsweet <[email protected]>
AuthorDate: Fri Oct 20 21:18:22 2023 +1300

    fix(config-ui): missed some code for refactor redux connections
---
 config-ui/src/App.tsx                              | 18 ++++++++++-
 config-ui/src/features/connections/slice.ts        | 36 ++++++++++++++++++++--
 config-ui/src/pages/connection/detail/index.tsx    |  8 +++--
 .../plugins/components/connection-form/index.tsx   |  5 ++-
 config-ui/src/routes/layout/layout.tsx             | 10 +-----
 5 files changed, 61 insertions(+), 16 deletions(-)

diff --git a/config-ui/src/App.tsx b/config-ui/src/App.tsx
index 11757250e..433c7a16f 100644
--- a/config-ui/src/App.tsx
+++ b/config-ui/src/App.tsx
@@ -16,8 +16,11 @@
  *
  */
 
+import { useEffect } from 'react';
 import { createBrowserRouter, Navigate, RouterProvider, json } from 
'react-router-dom';
 
+import { useAppDispatch, useAppSelector } from '@/app/hook';
+import { init, selectStatus } from '@/features';
 import { PageLoading } from '@/components';
 import {
   ConnectionHomePage,
@@ -100,4 +103,17 @@ const router = createBrowserRouter([
   },
 ]);
 
-export const App = () => <RouterProvider router={router} 
fallbackElement={<PageLoading />} />;
+export const App = () => {
+  const dispatch = useAppDispatch();
+  const status = useAppSelector(selectStatus);
+
+  useEffect(() => {
+    dispatch(init());
+  }, []);
+
+  if (['idle', 'loading'].includes(status)) {
+    return <PageLoading />;
+  }
+
+  return <RouterProvider router={router} fallbackElement={<PageLoading />} />;
+};
diff --git a/config-ui/src/features/connections/slice.ts 
b/config-ui/src/features/connections/slice.ts
index 66b534d1f..f0494f929 100644
--- a/config-ui/src/features/connections/slice.ts
+++ b/config-ui/src/features/connections/slice.ts
@@ -20,7 +20,6 @@ import { createSlice, createAsyncThunk } from 
'@reduxjs/toolkit';
 import { flatten } from 'lodash';
 
 import API from '@/api';
-import type { ConnectionForm } from '@/api/connection/types';
 import { RootState } from '@/app/store';
 import { PluginConfig } from '@/plugins';
 import { IConnection, IConnectionStatus } from '@/types';
@@ -29,8 +28,10 @@ import { transformConnection } from './utils';
 
 const initialState: {
   connections: IConnection[];
+  status: 'idle' | 'loading' | 'success' | 'failed';
 } = {
   connections: [],
+  status: 'idle',
 };
 
 export const init = createAsyncThunk('connections/init', async () => {
@@ -77,7 +78,21 @@ export const addConnection = 
createAsyncThunk('connections/addConnection', async
   return transformConnection(plugin, connection);
 });
 
-export const updateConnection = 
createAsyncThunk('connections/updateConnection', async (payload: 
ConnectionForm) => {});
+export const updateConnection = createAsyncThunk(
+  'connections/updateConnection',
+  async ({ plugin, connectionId, ...payload }: any) => {
+    const connection = await API.connection.update(plugin, connectionId, 
payload);
+    return transformConnection(plugin, connection);
+  },
+);
+
+export const removeConnection = createAsyncThunk(
+  'connections/removeConnection',
+  async ({ plugin, connectionId }: any) => {
+    await API.connection.remove(plugin, connectionId);
+    return `${plugin}-${connectionId}`;
+  },
+);
 
 export const slice = createSlice({
   name: 'connections',
@@ -85,8 +100,12 @@ export const slice = createSlice({
   reducers: {},
   extraReducers(builder) {
     builder
+      .addCase(init.pending, (state) => {
+        state.status = 'loading';
+      })
       .addCase(init.fulfilled, (state, action) => {
         state.connections = action.payload;
+        state.status = 'success';
       })
       .addCase(fetchConnections.fulfilled, (state, action) => {
         state.connections = 
state.connections.concat(action.payload.connections);
@@ -94,6 +113,17 @@ export const slice = createSlice({
       .addCase(addConnection.fulfilled, (state, action) => {
         state.connections.push(action.payload);
       })
+      .addCase(updateConnection.fulfilled, (state, action) => {
+        state.connections = state.connections.map((cs) => {
+          if (cs.unique === action.payload.unique) {
+            return action.payload;
+          }
+          return cs;
+        });
+      })
+      .addCase(removeConnection.fulfilled, (state, action) => {
+        state.connections = state.connections.filter((cs) => cs.unique !== 
action.payload);
+      })
       .addCase(testConnection.pending, (state, action) => {
         const existingConnection = state.connections.find((cs) => cs.unique 
=== action.meta.arg.unique);
         if (existingConnection) {
@@ -113,6 +143,8 @@ export const {} = slice.actions;
 
 export default slice.reducer;
 
+export const selectStatus = (state: RootState) => state.connections.status;
+
 export const selectAllConnections = (state: RootState) => 
state.connections.connections;
 
 export const selectConnections = (state: RootState, plugin: string) =>
diff --git a/config-ui/src/pages/connection/detail/index.tsx 
b/config-ui/src/pages/connection/detail/index.tsx
index 2ce5e207e..e040c82ca 100644
--- a/config-ui/src/pages/connection/detail/index.tsx
+++ b/config-ui/src/pages/connection/detail/index.tsx
@@ -21,9 +21,9 @@ import { useParams, useNavigate, Link } from 
'react-router-dom';
 import { Button, Intent } from '@blueprintjs/core';
 
 import API from '@/api';
-import { useAppSelector } from '@/app/hook';
+import { useAppDispatch, useAppSelector } from '@/app/hook';
 import { PageHeader, Buttons, Dialog, IconButton, Table, Message, toast } from 
'@/components';
-import { selectConnection } from '@/features';
+import { selectConnection, removeConnection } from '@/features';
 import { useTips, useRefreshData } from '@/hooks';
 import ClearImg from '@/images/icons/clear.svg';
 import {
@@ -64,7 +64,9 @@ export const ConnectionDetailPage = () => {
   const { plugin, id } = useParams() as { plugin: string; id: string };
   const connectionId = +id;
 
+  const dispatch = useAppDispatch();
   const connection = useAppSelector((state) => selectConnection(state, 
`${plugin}-${connectionId}`)) as IConnection;
+
   const navigate = useNavigate();
   const { setTips } = useTips();
   const { ready, data } = useRefreshData(
@@ -102,7 +104,7 @@ export const ConnectionDetailPage = () => {
     const [, res] = await operator(
       async () => {
         try {
-          await API.connection.remove(plugin, connectionId);
+          await dispatch(removeConnection({ plugin, connectionId }));
           return { status: 'success' };
         } catch (err: any) {
           const { status, data } = err.response;
diff --git a/config-ui/src/plugins/components/connection-form/index.tsx 
b/config-ui/src/plugins/components/connection-form/index.tsx
index cb7ffa549..1a6d93a65 100644
--- a/config-ui/src/plugins/components/connection-form/index.tsx
+++ b/config-ui/src/plugins/components/connection-form/index.tsx
@@ -23,6 +23,7 @@ import { pick } from 'lodash';
 import API from '@/api';
 import { useAppDispatch, useAppSelector } from '@/app/hook';
 import { ExternalLink, Buttons } from '@/components';
+import { addConnection, updateConnection } from '@/features';
 import { selectConnection } from '@/features/connections';
 import { PluginConfig, PluginConfigType } from '@/plugins';
 import { operator } from '@/utils';
@@ -82,7 +83,9 @@ export const ConnectionForm = ({ plugin, connectionId, 
onSuccess }: Props) => {
   const handleSave = async () => {
     const [success, res] = await operator(
       () =>
-        !connectionId ? API.connection.create(plugin, values) : 
API.connection.update(plugin, connectionId, values),
+        !connectionId
+          ? dispatch(addConnection({ plugin, ...values })).unwrap()
+          : dispatch(updateConnection({ plugin, connectionId, ...values 
})).unwrap(),
       {
         setOperating,
         formatMessage: () => (!connectionId ? 'Create a New Connection 
Successful.' : 'Update Connection Successful.'),
diff --git a/config-ui/src/routes/layout/layout.tsx 
b/config-ui/src/routes/layout/layout.tsx
index cc5b4b260..de136ae4d 100644
--- a/config-ui/src/routes/layout/layout.tsx
+++ b/config-ui/src/routes/layout/layout.tsx
@@ -16,14 +16,12 @@
  *
  */
 
-import { useEffect, useRef } from 'react';
+import { useRef } from 'react';
 import { useLoaderData, Outlet, useNavigate, useLocation } from 
'react-router-dom';
 import { CSSTransition } from 'react-transition-group';
 import { Menu, MenuItem, Navbar, Alignment } from '@blueprintjs/core';
 
-import { useAppDispatch } from '@/app/hook';
 import { Logo, ExternalLink, IconButton } from '@/components';
-import { init } from '@/features';
 import { DOC_URL } from '@/release';
 import { TipsContextProvider, TipsContextConsumer } from '@/store';
 
@@ -41,12 +39,6 @@ import './tips-transition.css';
 export const Layout = () => {
   const { version } = useLoaderData() as Awaited<ReturnType<typeof loader>>;
 
-  const dispatch = useAppDispatch();
-
-  useEffect(() => {
-    dispatch(init());
-  }, []);
-
   const navigate = useNavigate();
   const { pathname } = useLocation();
 

Reply via email to