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

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

commit 06923a212880ee4382d8fb7720be01a684e28530
Author: mintsweet <[email protected]>
AuthorDate: Tue Nov 21 16:28:55 2023 +1300

    feat(config-ui): use new connections page to replace old
---
 config-ui/src/app/routrer.tsx                      |   4 +-
 config-ui/src/pages/connection/home/index.tsx      | 158 ------------------
 config-ui/src/pages/connection/index.ts            |   1 -
 config-ui/src/routes/connection/connections.tsx    | 181 +++++++++++++++++++++
 .../src/{pages => routes}/connection/index.ts      |   3 +-
 .../home => routes/connection}/styled.ts           |  49 ++++--
 6 files changed, 218 insertions(+), 178 deletions(-)

diff --git a/config-ui/src/app/routrer.tsx b/config-ui/src/app/routrer.tsx
index 8ca565965..f3bb7615a 100644
--- a/config-ui/src/app/routrer.tsx
+++ b/config-ui/src/app/routrer.tsx
@@ -19,7 +19,6 @@
 import { createBrowserRouter, Navigate, json } from 'react-router-dom';
 
 import {
-  ConnectionHomePage,
   ConnectionDetailPage,
   ProjectHomePage,
   ProjectDetailPage,
@@ -29,6 +28,7 @@ import {
 } from '@/pages';
 import { Layout, loader as layoutLoader } from '@/routes/layout';
 import { Error, ErrorEnum } from '@/routes/error';
+import { Connections } from '@/routes/connection';
 import { Pipelines, Pipeline } from '@/routes/pipeline';
 import { ApiKeys } from '@/routes/api-keys';
 
@@ -53,7 +53,7 @@ export const router = createBrowserRouter([
       },
       {
         path: 'connections',
-        element: <ConnectionHomePage />,
+        element: <Connections />,
       },
       {
         path: 'connections/:plugin/:id',
diff --git a/config-ui/src/pages/connection/home/index.tsx 
b/config-ui/src/pages/connection/home/index.tsx
deleted file mode 100644
index 75d18ccfd..000000000
--- a/config-ui/src/pages/connection/home/index.tsx
+++ /dev/null
@@ -1,158 +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 { useState, useMemo } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { Tag, Intent } from '@blueprintjs/core';
-
-import { useAppSelector } from '@/app/hook';
-import { Dialog } from '@/components';
-import { selectPlugins, selectAllConnections, selectWebhooks } from 
'@/features/connections';
-import { getPluginConfig, ConnectionList, ConnectionForm } from '@/plugins';
-
-import * as S from './styled';
-
-export const ConnectionHomePage = () => {
-  const [type, setType] = useState<'list' | 'form'>();
-  const [plugin, setPlugin] = useState('');
-
-  const plugins = useAppSelector(selectPlugins);
-  const connections = useAppSelector(selectAllConnections);
-  const webhooks = useAppSelector(selectWebhooks);
-
-  const navigate = useNavigate();
-
-  const pluginConfig = useMemo(() => getPluginConfig(plugin), [plugin]);
-
-  const handleShowListDialog = (plugin: string) => {
-    setType('list');
-    setPlugin(plugin);
-  };
-
-  const handleShowFormDialog = () => {
-    setType('form');
-  };
-
-  const handleHideDialog = () => {
-    setType(undefined);
-    setPlugin('');
-  };
-
-  const handleSuccessAfter = async (plugin: string, id: ID) => {
-    navigate(`/connections/${plugin}/${id}`);
-  };
-
-  return (
-    <S.Wrapper>
-      <div className="block">
-        <h1>Connections</h1>
-        <h5>
-          Create and manage data connections from the following data sources 
or Webhooks to be used in syncing data in
-          your Projects.
-        </h5>
-      </div>
-      {!!plugins.filter((plugin) => plugin !== 'webhook').length && (
-        <div className="block">
-          <h2>Data Connections</h2>
-          <h5>
-            You can create and manage data connections for the following data 
sources and use them in your Projects.
-          </h5>
-          <ul>
-            {plugins
-              .filter((plugin) => plugin !== 'webhook')
-              .map((plugin) => {
-                const pluginConfig = getPluginConfig(plugin);
-                const connectionCount = connections.filter((cs) => cs.plugin 
=== plugin).length;
-                return (
-                  <li key={plugin} onClick={() => 
handleShowListDialog(plugin)}>
-                    {/* <img src={pluginConfig.icon} alt="" /> */}
-                    <span className="name">{pluginConfig.name}</span>
-                    <S.Count>{connectionCount ? `${connectionCount} 
connections` : 'No connection'}</S.Count>
-                    {pluginConfig.isBeta && (
-                      <Tag intent={Intent.WARNING} round>
-                        beta
-                      </Tag>
-                    )}
-                  </li>
-                );
-              })}
-          </ul>
-        </div>
-      )}
-      {plugins.includes('webhook') && (
-        <div className="block">
-          <h2>Webhooks</h2>
-          <h5>
-            You can use webhooks to import deployments and incidents from the 
unsupported data integrations to calculate
-            DORA metrics, etc.
-          </h5>
-          <ul>
-            {plugins
-              .filter((plugin) => plugin === 'webhook')
-              .map((plugin) => {
-                const pluginConfig = getPluginConfig(plugin);
-                const connectionCount = webhooks.length;
-                return (
-                  <li key={plugin} onClick={() => 
handleShowListDialog(plugin)}>
-                    {/* <img src={pluginConfig.icon} alt="" /> */}
-                    <span className="name">{pluginConfig.name}</span>
-                    <S.Count>{connectionCount ? `${connectionCount} 
connections` : 'No connection'}</S.Count>
-                  </li>
-                );
-              })}
-          </ul>
-        </div>
-      )}
-      {type === 'list' && pluginConfig && (
-        <Dialog
-          style={{ width: 820 }}
-          isOpen
-          title={
-            <S.DialogTitle>
-              {/* <img src={pluginConfig.icon} alt="" /> */}
-              <span>Manage Connections: {pluginConfig.name}</span>
-            </S.DialogTitle>
-          }
-          footer={null}
-          onCancel={handleHideDialog}
-        >
-          <ConnectionList plugin={pluginConfig.plugin} 
onCreate={handleShowFormDialog} />
-        </Dialog>
-      )}
-      {type === 'form' && pluginConfig && (
-        <Dialog
-          style={{ width: 820 }}
-          isOpen
-          title={
-            <S.DialogTitle>
-              {/* <img src={pluginConfig.icon} alt="" /> */}
-              <span>Manage Connections: {pluginConfig.name}</span>
-            </S.DialogTitle>
-          }
-          footer={null}
-          onCancel={handleHideDialog}
-        >
-          <ConnectionForm
-            plugin={pluginConfig.plugin}
-            onSuccess={(id) => handleSuccessAfter(pluginConfig.plugin, id)}
-          />
-        </Dialog>
-      )}
-    </S.Wrapper>
-  );
-};
diff --git a/config-ui/src/pages/connection/index.ts 
b/config-ui/src/pages/connection/index.ts
index d5131a681..d30c832b9 100644
--- a/config-ui/src/pages/connection/index.ts
+++ b/config-ui/src/pages/connection/index.ts
@@ -16,5 +16,4 @@
  *
  */
 
-export * from './home';
 export * from './detail';
diff --git a/config-ui/src/routes/connection/connections.tsx 
b/config-ui/src/routes/connection/connections.tsx
new file mode 100644
index 000000000..7aa101030
--- /dev/null
+++ b/config-ui/src/routes/connection/connections.tsx
@@ -0,0 +1,181 @@
+/*
+ * 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, useMemo } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { theme, Badge, Modal } from 'antd';
+import { chunk } from 'lodash';
+
+import { useAppSelector } from '@/app/hook';
+import { selectPlugins, selectAllConnections, selectWebhooks } from 
'@/features/connections';
+import { getPluginConfig, ConnectionList, ConnectionForm } from '@/plugins';
+
+import * as S from './styled';
+
+export const Connections = () => {
+  const [type, setType] = useState<'list' | 'form'>();
+  const [plugin, setPlugin] = useState('');
+
+  const {
+    token: { colorPrimary },
+  } = theme.useToken();
+
+  const pluginConfig = useMemo(() => getPluginConfig(plugin), [plugin]);
+
+  const navigate = useNavigate();
+
+  const plugins = useAppSelector(selectPlugins);
+  const connections = useAppSelector(selectAllConnections);
+  const webhooks = useAppSelector(selectWebhooks);
+
+  const [firstPlugins, secondPlugins] = chunk(
+    plugins.filter((p) => p !== 'webhook'),
+    6,
+  );
+
+  const handleShowListDialog = (plugin: string) => {
+    setType('list');
+    setPlugin(plugin);
+  };
+
+  const handleShowFormDialog = () => {
+    setType('form');
+  };
+
+  const handleHideDialog = () => {
+    setType(undefined);
+    setPlugin('');
+  };
+
+  const handleSuccessAfter = async (plugin: string, id: ID) => {
+    navigate(`/connections/${plugin}/${id}`);
+  };
+
+  return (
+    <S.Wrapper theme={colorPrimary}>
+      <h1>Connections</h1>
+      <h5>
+        Create and manage data connections from the following data sources or 
Webhooks to be used in syncing data in
+        your Projects.
+      </h5>
+      <h2>Data Connections</h2>
+      <h5>You can create and manage data connections for the following data 
sources and use them in your Projects.</h5>
+      <h4>A-N</h4>
+      <ul>
+        {firstPlugins.map((plugin) => {
+          const pluginConfig = getPluginConfig(plugin);
+          const connectionCount = connections.filter((cs) => cs.plugin === 
plugin).length;
+          return (
+            <li key={plugin} onClick={() => handleShowListDialog(plugin)}>
+              <span className="logo">{pluginConfig.icon({ color: colorPrimary 
})}</span>
+              <span className="name">{pluginConfig.name}</span>
+              <span className="count">
+                {connectionCount ? (
+                  <Badge color={colorPrimary} text={`${connectionCount} 
connections`} />
+                ) : (
+                  'No connection'
+                )}
+              </span>
+            </li>
+          );
+        })}
+      </ul>
+      <h4>O-Z</h4>
+      <ul>
+        {secondPlugins.map((plugin) => {
+          const pluginConfig = getPluginConfig(plugin);
+          const connectionCount = connections.filter((cs) => cs.plugin === 
plugin).length;
+          return (
+            <li key={plugin} onClick={() => handleShowListDialog(plugin)}>
+              <span className="logo">{pluginConfig.icon({ color: colorPrimary 
})}</span>
+              <span className="name">{pluginConfig.name}</span>
+              <span className="count">
+                {connectionCount ? (
+                  <Badge color={colorPrimary} text={`${connectionCount} 
connections`} />
+                ) : (
+                  'No connection'
+                )}
+              </span>
+            </li>
+          );
+        })}
+      </ul>
+      <h2>Webhooks</h2>
+      <h5>
+        You can use webhooks to import deployments and incidents from the 
unsupported data integrations to calculate
+        DORA metrics, etc.
+      </h5>
+      <ul>
+        {plugins
+          .filter((plugin) => plugin === 'webhook')
+          .map((plugin) => {
+            const pluginConfig = getPluginConfig(plugin);
+            const connectionCount = webhooks.length;
+            return (
+              <li key={plugin} onClick={() => handleShowListDialog(plugin)}>
+                <span className="logo">{pluginConfig.icon({ color: 
colorPrimary })}</span>
+                <span className="name">{pluginConfig.name}</span>
+                <span className="count">
+                  {connectionCount ? (
+                    <Badge color={colorPrimary} text={`${connectionCount} 
connections`} />
+                  ) : (
+                    'No connection'
+                  )}
+                </span>
+              </li>
+            );
+          })}
+      </ul>
+      {type === 'list' && pluginConfig && (
+        <Modal
+          open
+          width={820}
+          title={
+            <S.ModalTitle>
+              <span className="icon">{pluginConfig.icon({ color: colorPrimary 
})}</span>
+              <span className="name">Manage Connections: 
{pluginConfig.name}</span>
+            </S.ModalTitle>
+          }
+          footer={null}
+          onCancel={handleHideDialog}
+        >
+          <ConnectionList plugin={pluginConfig.plugin} 
onCreate={handleShowFormDialog} />
+        </Modal>
+      )}
+      {type === 'form' && pluginConfig && (
+        <Modal
+          open
+          width={820}
+          title={
+            <S.ModalTitle>
+              <span className="icon">{pluginConfig.icon({ color: colorPrimary 
})}</span>
+              <span className="name">Manage Connections: 
{pluginConfig.name}</span>
+            </S.ModalTitle>
+          }
+          footer={null}
+          onCancel={handleHideDialog}
+        >
+          <ConnectionForm
+            plugin={pluginConfig.plugin}
+            onSuccess={(id) => handleSuccessAfter(pluginConfig.plugin, id)}
+          />
+        </Modal>
+      )}
+    </S.Wrapper>
+  );
+};
diff --git a/config-ui/src/pages/connection/index.ts 
b/config-ui/src/routes/connection/index.ts
similarity index 94%
copy from config-ui/src/pages/connection/index.ts
copy to config-ui/src/routes/connection/index.ts
index d5131a681..4e6e8a4de 100644
--- a/config-ui/src/pages/connection/index.ts
+++ b/config-ui/src/routes/connection/index.ts
@@ -16,5 +16,4 @@
  *
  */
 
-export * from './home';
-export * from './detail';
+export * from './connections';
diff --git a/config-ui/src/pages/connection/home/styled.ts 
b/config-ui/src/routes/connection/styled.ts
similarity index 78%
rename from config-ui/src/pages/connection/home/styled.ts
rename to config-ui/src/routes/connection/styled.ts
index 6c5cf8c0b..42aa8a6fb 100644
--- a/config-ui/src/pages/connection/home/styled.ts
+++ b/config-ui/src/routes/connection/styled.ts
@@ -18,16 +18,30 @@
 
 import styled from 'styled-components';
 
-export const Wrapper = styled.div`
+export const Wrapper = styled.div<{ theme: string }>`
+  h2 {
+    margin-top: 36px;
+  }
+
   h5 {
     margin-top: 12px;
     font-weight: 400;
   }
 
-  .block + .block {
-    margin-top: 36px;
-  }
+  h4 {
+    position: relative;
+    margin-top: 24px;
 
+    &::after {
+      content: '';
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      width: 48px;
+      height: 4px;
+      background-color: ${({ theme }) => theme};
+    }
+  }
   ul {
     display: flex;
     align-items: center;
@@ -53,9 +67,15 @@ export const Wrapper = styled.div`
       background-color: #eeeeee;
     }
 
-    & > img {
+    & > .logo {
       width: 60px;
+      height: 60px;
       margin-bottom: 8px;
+
+      & > svg {
+        width: 100%;
+        height: 100%;
+      }
     }
 
     & > .name {
@@ -75,24 +95,23 @@ export const Wrapper = styled.div`
       }
     }
 
-    & > .bp5-tag {
-      position: absolute;
-      top: 0;
-      right: 0;
+    & > .count {
+      color: #70727f;
     }
   }
 `;
 
-export const Count = styled.span`
-  color: #70727f;
-`;
-
-export const DialogTitle = styled.div`
+export const ModalTitle = styled.div`
   display: flex;
   align-items: center;
 
-  img {
+  .icon {
     margin-right: 8px;
     width: 24px;
+
+    & > svg {
+      width: 100%;
+      height: 100%;
+    }
   }
 `;

Reply via email to