This is an automated email from the ASF dual-hosted git repository.
abeizn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 2871530dc fix(config-ui): missed code for refactoring redux
connections (#6298)
2871530dc is described below
commit 2871530dc859eb3242a84256f7a900777e93b5c2
Author: 青湛 <[email protected]>
AuthorDate: Fri Oct 20 21:28:02 2023 +1300
fix(config-ui): missed code for refactoring redux connections (#6298)
---
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();