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

likyh 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 c86e2be3 feat(config-ui): add global connections store (#3848)
c86e2be3 is described below

commit c86e2be31787279cfb33440d4d4c2a39d81b726b
Author: 青湛 <[email protected]>
AuthorDate: Mon Dec 5 11:12:56 2022 +0800

    feat(config-ui): add global connections store (#3848)
    
    * feat(config-ui): add global connections store
    
    * feat(config-ui): add loading flag for use-connections
---
 config-ui/src/index.d.ts                           |   2 +
 .../src/{index.d.ts => store/connections/api.ts}   |  20 ++-
 .../src/{index.d.ts => store/connections/index.ts} |   6 +-
 .../src/{index.d.ts => store/connections/types.ts} |  24 +++-
 config-ui/src/store/connections/use-connections.ts | 155 +++++++++++++++++++++
 config-ui/src/{index.d.ts => store/index.ts}       |   5 +-
 6 files changed, 198 insertions(+), 14 deletions(-)

diff --git a/config-ui/src/index.d.ts b/config-ui/src/index.d.ts
index bfdcc83e..b24a60d7 100644
--- a/config-ui/src/index.d.ts
+++ b/config-ui/src/index.d.ts
@@ -16,6 +16,8 @@
  *
  */
 
+type ID = string | number
+
 declare module '*.svg' {
   const content: any
   export default content
diff --git a/config-ui/src/index.d.ts b/config-ui/src/store/connections/api.ts
similarity index 65%
copy from config-ui/src/index.d.ts
copy to config-ui/src/store/connections/api.ts
index bfdcc83e..0b4c71da 100644
--- a/config-ui/src/index.d.ts
+++ b/config-ui/src/store/connections/api.ts
@@ -16,7 +16,21 @@
  *
  */
 
-declare module '*.svg' {
-  const content: any
-  export default content
+import request from '@/components/utils/request'
+
+type TestConnectionPayload = {
+  endpoint: string
+  proxy: string
+  token?: string
+  username?: string
+  password?: string
 }
+
+export const getConnection = (plugin: string) =>
+  request(`/plugins/${plugin}/connections`)
+
+export const testConnection = (plugin: string, data: TestConnectionPayload) =>
+  request(`/plugins/${plugin}/test`, {
+    method: 'post',
+    data
+  })
diff --git a/config-ui/src/index.d.ts b/config-ui/src/store/connections/index.ts
similarity index 91%
copy from config-ui/src/index.d.ts
copy to config-ui/src/store/connections/index.ts
index bfdcc83e..63e0a341 100644
--- a/config-ui/src/index.d.ts
+++ b/config-ui/src/store/connections/index.ts
@@ -16,7 +16,5 @@
  *
  */
 
-declare module '*.svg' {
-  const content: any
-  export default content
-}
+export * from './use-connections'
+export * from './types'
diff --git a/config-ui/src/index.d.ts b/config-ui/src/store/connections/types.ts
similarity index 67%
copy from config-ui/src/index.d.ts
copy to config-ui/src/store/connections/types.ts
index bfdcc83e..9d976439 100644
--- a/config-ui/src/index.d.ts
+++ b/config-ui/src/store/connections/types.ts
@@ -16,7 +16,25 @@
  *
  */
 
-declare module '*.svg' {
-  const content: any
-  export default content
+export enum ConnectionStatusEnum {
+  ONLINE = 'online',
+  OFFLINE = 'offline',
+  WAITING = 'waiting',
+  TESTING = 'testing',
+  NULL = 'null'
+}
+
+export type ConnectionItemType = {
+  unique: string
+  status: ConnectionStatusEnum
+  plugin: string
+  id: ID
+  name: string
+  icon: string
+  entities: string[]
+  endpoint: string
+  proxy: string
+  token?: string
+  username?: string
+  password?: string
 }
diff --git a/config-ui/src/store/connections/use-connections.ts 
b/config-ui/src/store/connections/use-connections.ts
new file mode 100644
index 00000000..dad82d49
--- /dev/null
+++ b/config-ui/src/store/connections/use-connections.ts
@@ -0,0 +1,155 @@
+/*
+ * 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 { useState, useEffect, useCallback, useMemo } from 'react'
+
+import { Plugins } from '@/registry'
+
+import type { ConnectionItemType } from './types'
+import { ConnectionStatusEnum } from './types'
+import { getConnection, testConnection } from './api'
+
+export const useConnections = (plugin?: string | string[]) => {
+  const [loading, setLoading] = useState(false)
+  const [connections, setConnections] = useState<ConnectionItemType[]>([])
+
+  const allConnections = useMemo(
+    () =>
+      Plugins.filter((p) => p.type === 'integration').filter((p) => {
+        if (!plugin) return true
+        return Array.isArray(plugin) ? plugin.includes(p.id) : p.id === plugin
+      }),
+    [plugin]
+  )
+
+  const handleRefresh = useCallback(async () => {
+    setLoading(true)
+
+    try {
+      const res = await Promise.all(
+        allConnections.map((cs) => getConnection(cs.id))
+      )
+
+      const resWithPlugin = res.map((cs, i) =>
+        cs.map((it: any) => {
+          const { id, icon, availableDataDomains } = allConnections[i] as any
+
+          return {
+            ...it,
+            plugin: id,
+            icon: `/${icon}`,
+            entities: availableDataDomains
+          }
+        })
+      )
+
+      setConnections(
+        resWithPlugin.flat().map((it) => ({
+          unique: `${it.plugin}-${it.id}`,
+          status: ConnectionStatusEnum.NULL,
+          plugin: it.plugin,
+          id: it.id,
+          name: it.name,
+          icon: it.icon,
+          entities: it.entities,
+          endpoint: it.endpoint,
+          proxy: it.proxy,
+          token: it.token,
+          username: it.username,
+          password: it.password
+        }))
+      )
+    } finally {
+      setLoading(false)
+    }
+  }, [allConnections])
+
+  useEffect(() => {
+    handleRefresh()
+  }, [])
+
+  const handleTest = useCallback(
+    async (selectedConnections: ConnectionItemType[]) => {
+      const uniqueList = selectedConnections.map((cs) => cs.unique)
+
+      const initConnections = connections.map((cs) =>
+        uniqueList.includes(cs.unique) &&
+        cs.status === ConnectionStatusEnum.NULL
+          ? {
+              ...cs,
+              status: ConnectionStatusEnum.WAITING
+            }
+          : cs
+      )
+
+      setConnections(initConnections)
+
+      const [updatedConnection] = await Promise.all(
+        initConnections
+          .filter((cs) => cs.status === ConnectionStatusEnum.WAITING)
+          .map(async (cs) => {
+            setConnections(
+              initConnections.map((it) =>
+                it.unique === cs.unique
+                  ? { ...it, status: ConnectionStatusEnum.TESTING }
+                  : it
+              )
+            )
+            const { plugin, endpoint, proxy, token, username, password } = cs
+            let status
+
+            try {
+              const res = await testConnection(plugin, {
+                endpoint,
+                proxy,
+                token,
+                username,
+                password
+              })
+              status = res.success
+                ? ConnectionStatusEnum.ONLINE
+                : ConnectionStatusEnum.OFFLINE
+            } catch {
+              status = ConnectionStatusEnum.OFFLINE
+            }
+
+            return { ...cs, status }
+          })
+      )
+
+      if (updatedConnection) {
+        setConnections((connections) =>
+          connections.map((cs) =>
+            cs.unique === updatedConnection.unique ? updatedConnection : cs
+          )
+        )
+      }
+    },
+    [connections]
+  )
+
+  return useMemo(
+    () => ({
+      loading,
+      connections,
+      onRefresh: handleRefresh,
+      onTest: handleTest
+    }),
+    [loading, connections]
+  )
+}
diff --git a/config-ui/src/index.d.ts b/config-ui/src/store/index.ts
similarity index 91%
copy from config-ui/src/index.d.ts
copy to config-ui/src/store/index.ts
index bfdcc83e..839be970 100644
--- a/config-ui/src/index.d.ts
+++ b/config-ui/src/store/index.ts
@@ -16,7 +16,4 @@
  *
  */
 
-declare module '*.svg' {
-  const content: any
-  export default content
-}
+export * from './connections'

Reply via email to