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 775ad569c refactor(config-ui): the plugin config (#3955)
775ad569c is described below

commit 775ad569c910760ca77304a34576aa526377de7a
Author: 青湛 <[email protected]>
AuthorDate: Fri Dec 16 11:14:24 2022 +0800

    refactor(config-ui): the plugin config (#3955)
    
    * refactor(config-ui): the plugin config
    
    * refactor(config-ui): use new plugin to replace old
    
    * refactor(config-ui): the connection home page
---
 config-ui/src/App.js                               |  26 ++--
 config-ui/src/layouts/base/use-menu.ts             |  22 +--
 config-ui/src/pages/blueprint/detail/use-detail.ts |   8 +-
 config-ui/src/pages/connection/home/index.tsx      |  75 +++++++++
 .../delete-modal.jsx => connection/home/styled.ts} |  74 +++++----
 .../src/{plugins => pages/connection}/index.ts     |   4 +-
 .../{connections => connection/webhook}/index.ts   |   0
 .../connections/incoming-webhook/add-modal.jsx     | 161 --------------------
 .../pages/connections/incoming-webhook/index.jsx   | 163 --------------------
 .../pages/connections/incoming-webhook/styled.js   | 169 ---------------------
 .../incoming-webhook/view-or-edit-modal.jsx        | 137 -----------------
 config-ui/src/pages/index.ts                       |   2 +-
 config-ui/src/plugins/common/index.ts              |   1 -
 .../connections/index.ts => plugins/config.ts}     |  14 +-
 config-ui/src/plugins/github/assets/icon.svg       |  19 +++
 .../plugins/{common/types.ts => github/config.ts}  |  30 +++-
 config-ui/src/plugins/github/index.ts              |   1 +
 config-ui/src/plugins/gitlab/assets/icon.svg       |  19 +++
 .../plugins/{common/types.ts => gitlab/config.ts}  |  20 ++-
 config-ui/src/plugins/gitlab/index.ts              |   1 +
 config-ui/src/plugins/index.ts                     |   2 +
 config-ui/src/plugins/jenkins/assets/icon.svg      |  22 +++
 .../plugins/{common/types.ts => jenkins/config.ts} |  20 ++-
 config-ui/src/plugins/jenkins/index.ts             |   1 +
 config-ui/src/plugins/jira/assets/icon.svg         |  20 +++
 .../plugins/{common/types.ts => jira/config.ts}    |  22 ++-
 config-ui/src/plugins/jira/index.ts                |   1 +
 config-ui/src/plugins/{common => }/types.ts        |   5 +
 config-ui/src/plugins/webook/assets/icon.svg       |   5 +
 .../plugins/{common/types.ts => webook/config.ts}  |  17 ++-
 config-ui/src/plugins/webook/index.ts              |   1 +
 .../src/store/connections/use-context-value.ts     |  16 +-
 32 files changed, 354 insertions(+), 724 deletions(-)

diff --git a/config-ui/src/App.js b/config-ui/src/App.js
index 2cf626341..91c2b9128 100644
--- a/config-ui/src/App.js
+++ b/config-ui/src/App.js
@@ -28,9 +28,10 @@ import { BaseLayout } from '@/layouts'
 import {
   ProjectHomePage,
   ProjectDetailPage,
+  ConnectionHomePage,
+  WebHookConnectionPage,
   CreateBlueprintPage,
-  BlueprintDetailPage,
-  WebHookConnectionPage
+  BlueprintDetailPage
 } from '@/pages'
 import Integration from '@/pages/configure/integration/index'
 import ManageIntegration from '@/pages/configure/integration/manage'
@@ -54,24 +55,31 @@ function App() {
           path='/projects/:pname/create-blueprint'
           component={() => <CreateBlueprintPage from='project' />}
         />
-        <Route exact path='/integrations' component={() => <Integration />} />
         <Route
-          path='/integrations/:providerId'
+          exact
+          path='/connections'
+          component={() => <ConnectionHomePage />}
+        />
+        <Route
+          exact
+          path='/connections/webhook'
+          component={() => <WebHookConnectionPage />}
+        />
+        <Route
+          exact
+          path='/connections/:providerId'
           component={() => <ManageIntegration />}
         />
         <Route
+          exact
           path='/connections/add/:providerId'
           component={() => <AddConnection />}
         />
         <Route
+          exact
           path='/connections/configure/:providerId/:connectionId'
           component={() => <ConfigureConnection />}
         />
-        <Route
-          exact
-          path='/connections/incoming-webhook'
-          component={() => <WebHookConnectionPage />}
-        />
         <Route exact path='/blueprints' component={() => <Blueprints />} />
         <Route
           exact
diff --git a/config-ui/src/layouts/base/use-menu.ts 
b/config-ui/src/layouts/base/use-menu.ts
index be448e4db..fef4a2b8c 100644
--- a/config-ui/src/layouts/base/use-menu.ts
+++ b/config-ui/src/layouts/base/use-menu.ts
@@ -19,7 +19,7 @@
 import { useMemo } from 'react'
 import { IconName } from '@blueprintjs/core'
 
-import { Plugins } from '@/registry'
+import { PluginConfig, PluginType } from '@/plugins'
 
 export type MenuItemType = {
   key: string
@@ -54,15 +54,17 @@ export const useMenu = () => {
           key: 'connection',
           title: 'Connections',
           icon: 'data-connection',
-          path: '/integrations',
-          children: Plugins.filter((p) => p.type === 'integration').map(
-            (it) => ({
-              key: it.id,
-              title: it.name,
-              iconUrl: `/${it.icon}`,
-              path: `/integrations/${it.id}`
-            })
-          )
+          path: '/connections',
+          children: PluginConfig.filter((p) =>
+            [PluginType.Connection, PluginType.Incoming_Connection].includes(
+              p.type
+            )
+          ).map((it) => ({
+            key: it.plugin,
+            title: it.name,
+            iconUrl: it.icon,
+            path: `/connections/${it.plugin}`
+          }))
         },
         {
           key: 'blueprint',
diff --git a/config-ui/src/pages/blueprint/detail/use-detail.ts 
b/config-ui/src/pages/blueprint/detail/use-detail.ts
index d3bfe1335..4b41d123f 100644
--- a/config-ui/src/pages/blueprint/detail/use-detail.ts
+++ b/config-ui/src/pages/blueprint/detail/use-detail.ts
@@ -19,7 +19,7 @@
 import { useState, useEffect, useMemo } from 'react'
 
 import { operator } from '@/utils'
-import { Plugins } from '@/registry'
+import { PluginConfig } from '@/plugins'
 
 import type { BlueprintType, ConnectionItemType } from './types'
 import * as API from './api'
@@ -37,10 +37,10 @@ export const useDetail = ({ id }: UseDetailProps) => {
   const transformConnection = (connections: any) => {
     return connections
       .map((cs: any) => {
-        const plugin = Plugins.find((plugin) => plugin.id === cs.plugin) as any
+        const plugin = PluginConfig.find((p) => p.plugin === cs.plugin)
         if (!plugin) return null
         return {
-          icon: `/${plugin.icon}`,
+          icon: plugin.icon,
           name: plugin.name,
           connectionId: cs.connectionId,
           entities: cs.scopes[0].entities,
@@ -67,7 +67,7 @@ export const useDetail = ({ id }: UseDetailProps) => {
   }, [])
 
   const handleUpdate = async (payload: any) => {
-    const [success, res] = await operator(
+    const [success] = await operator(
       () =>
         API.updateBlueprint(id, {
           ...blueprint,
diff --git a/config-ui/src/pages/connection/home/index.tsx 
b/config-ui/src/pages/connection/home/index.tsx
new file mode 100644
index 000000000..66249af4e
--- /dev/null
+++ b/config-ui/src/pages/connection/home/index.tsx
@@ -0,0 +1,75 @@
+/*
+ * 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 React, { useMemo } from 'react'
+import { useHistory } from 'react-router-dom'
+
+import { PluginConfig, PluginType, Plugins } from '@/plugins'
+
+import * as S from './styled'
+
+export const ConnectionHomePage = () => {
+  const history = useHistory()
+
+  const [connections, webhook] = useMemo(
+    () => [
+      PluginConfig.filter((p) => p.type === PluginType.Connection),
+      PluginConfig.filter((p) => p.plugin === Plugins.Webhook)
+    ],
+    []
+  )
+
+  return (
+    <S.Wrapper>
+      <div className='block'>
+        <h2>Data Connections</h2>
+        <p> connections are available for data collection.</p>
+        <ul>
+          {connections.map((cs) => (
+            <li
+              key={cs.plugin}
+              onClick={() => history.push(`/connections/${cs.plugin}`)}
+            >
+              <img src={cs.icon} alt='' />
+              <span>{cs.name}</span>
+            </li>
+          ))}
+        </ul>
+      </div>
+      <div className='block'>
+        <h2>Webhooks</h2>
+        <p>
+          You can use webhooks to import deployments and incidents from the
+          unsupported data integrations to calculate DORA metrics, etc. Please
+          note: webhooks cannot be created or managed in Blueprints.
+        </p>
+        <ul>
+          {webhook.map((cs) => (
+            <li
+              key={cs.plugin}
+              onClick={() => history.push(`/connections/${cs.plugin}`)}
+            >
+              <img src={cs.icon} alt='' />
+              <span>{cs.name}</span>
+            </li>
+          ))}
+        </ul>
+      </div>
+    </S.Wrapper>
+  )
+}
diff --git a/config-ui/src/pages/connections/incoming-webhook/delete-modal.jsx 
b/config-ui/src/pages/connection/home/styled.ts
similarity index 51%
rename from config-ui/src/pages/connections/incoming-webhook/delete-modal.jsx
rename to config-ui/src/pages/connection/home/styled.ts
index a4e97d784..5aad62de9 100644
--- a/config-ui/src/pages/connections/incoming-webhook/delete-modal.jsx
+++ b/config-ui/src/pages/connection/home/styled.ts
@@ -16,34 +16,54 @@
  *
  */
 
-import React from 'react'
-import { Dialog, Button, Intent } from '@blueprintjs/core'
+import styled from 'styled-components'
 
-import * as S from './styled'
+export const Wrapper = styled.div`
+  .block + .block {
+    margin-top: 48px;
+  }
+
+  h2 {
+    margin: 0 0 4px;
+  }
 
-export const DeleteModal = ({ record, onSubmit, onCancel }) => {
-  const handleSubmit = () => {
-    onSubmit(record.id)
-    onCancel()
+  p {
+    margin: 0 0 16px;
   }
 
-  return (
-    <Dialog
-      isOpen={true}
-      title='Delete this Incoming Webhook?'
-      onClose={onCancel}
-    >
-      <S.FormWrapper>
-        <div className='message'>
-          <p>This Incoming Webhook cannot be recovered once it’s deleted.</p>
-        </div>
-        <div className='btns'>
-          <Button onClick={onCancel}>Cancel</Button>
-          <Button intent={Intent.PRIMARY} onClick={handleSubmit}>
-            Confirm
-          </Button>
-        </div>
-      </S.FormWrapper>
-    </Dialog>
-  )
-}
+  ul {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+    display: flex;
+    align-items: center;
+  }
+
+  li {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 8px 16px;
+    border: 2px solid transparent;
+    cursor: pointer;
+    transition: all 0.2s linear;
+
+    &:hover {
+      background-color: #eeeeee;
+      border-color: #7497f7;
+      box-shadow: 0 2px 2px 0 rgb(0 0 0 / 16%), 0 0 2px 0 rgb(0 0 0 / 12%);
+    }
+
+    img {
+      width: 50px;
+    }
+
+    span {
+      margin-top: 4px;
+    }
+  }
+
+  li + li {
+    margin-left: 24px;
+  }
+`
diff --git a/config-ui/src/plugins/index.ts 
b/config-ui/src/pages/connection/index.ts
similarity index 94%
copy from config-ui/src/plugins/index.ts
copy to config-ui/src/pages/connection/index.ts
index c784ec481..af1444500 100644
--- a/config-ui/src/plugins/index.ts
+++ b/config-ui/src/pages/connection/index.ts
@@ -16,5 +16,5 @@
  *
  */
 
-export * from './common'
-export * from './webook'
+export * from './home'
+export * from './webhook'
diff --git a/config-ui/src/pages/connections/index.ts 
b/config-ui/src/pages/connection/webhook/index.ts
similarity index 100%
copy from config-ui/src/pages/connections/index.ts
copy to config-ui/src/pages/connection/webhook/index.ts
diff --git a/config-ui/src/pages/connections/incoming-webhook/add-modal.jsx 
b/config-ui/src/pages/connections/incoming-webhook/add-modal.jsx
deleted file mode 100644
index 943976f26..000000000
--- a/config-ui/src/pages/connections/incoming-webhook/add-modal.jsx
+++ /dev/null
@@ -1,161 +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 React, { useState } from 'react'
-import { Dialog, Button, Toaster, Position, Intent } from '@blueprintjs/core'
-import { CopyToClipboard } from 'react-copy-to-clipboard'
-
-import { ReactComponent as Vector } from '@/images/icons/vector.svg'
-import { ReactComponent as CopyIcon } from '@/images/icons/copy.svg'
-
-import * as S from './styled'
-
-const CopyToaster = Toaster.create({
-  position: Position.TOP_RIGHT
-})
-
-const postUrlPrefix = `${window.location.origin}/api`
-
-export const AddModal = ({ onSubmit, onCancel }) => {
-  const [step, setStep] = useState(1)
-  const [name, setName] = useState('')
-  const [error, setError] = useState('')
-  const [record, setRecord] = useState({})
-
-  const handleInputChange = (e) => {
-    setName(e.target.value)
-    setError('')
-  }
-
-  const handleSubmit = async () => {
-    if (!name) {
-      setError('Name is required')
-      return
-    }
-
-    const res = await onSubmit({ name })
-
-    setStep(2)
-    setRecord({
-      postIssuesEndpoint: `${postUrlPrefix}${res.postIssuesEndpoint}`,
-      closeIssuesEndpoint: `${postUrlPrefix}${res.closeIssuesEndpoint}`,
-      postDeploymentsCurl: `curl 
${postUrlPrefix}${res.postPipelineDeployTaskEndpoint} -X 'POST' -d "{
-  \\"commit_sha\\":\\"the sha of deployment commit\\",
-  \\"repo_url\\":\\"the repo URL of the deployment commit\\",
-  \\"start_time\\":\\"Optional, eg. 2020-01-01T12:00:00+00:00\\"
-}"`
-    })
-  }
-
-  return (
-    <Dialog
-      isOpen={true}
-      title='Add a New Incoming Webhook'
-      style={{ width: 640 }}
-      onClose={onCancel}
-    >
-      <S.FormWrapper>
-        {step === 1 && (
-          <>
-            <div className='form'>
-              <h2>Incoming Webhook Name *</h2>
-              <p>
-                Give your Incoming Webhook a unique name to help you identify 
it
-                in the future.
-              </p>
-              <input
-                type='text'
-                placeholder='Your Incoming Webhook Name'
-                className={error ? 'has-error' : ''}
-                value={name || ''}
-                onChange={handleInputChange}
-              />
-              {error && <p className='error'>{error}</p>}
-            </div>
-            <div className='btns'>
-              <Button onClick={onCancel}>Cancel</Button>
-              <Button intent={Intent.PRIMARY} onClick={handleSubmit}>
-                Generate POST URL
-              </Button>
-            </div>
-          </>
-        )}
-        {step === 2 && (
-          <>
-            <div className='tips'>
-              <Vector width={20} height={20} />
-              <span>POST URL Generated!</span>
-            </div>
-            <div className='url'>
-              <h2>POST URL</h2>
-              <p>
-                Copy the following URLs to your issue tracking tool for
-                Incidents and CI tool for Deployments by making a POST to
-                DevLake.
-              </p>
-              <h3>Incident</h3>
-              <p>POST to register an incident</p>
-              <div className='block'>
-                <span>{record.postIssuesEndpoint}</span>
-                <CopyToClipboard
-                  text={record.postIssuesEndpoint}
-                  onCopy={() =>
-                    CopyToaster.show({
-                      message: 'Copy successfully.',
-                      intent: Intent.SUCCESS
-                    })
-                  }
-                >
-                  <CopyIcon width={16} height={16} />
-                </CopyToClipboard>
-              </div>
-              <p>POST to close a registered incident</p>
-              <div className='block'>
-                <span>{record.closeIssuesEndpoint}</span>
-                <CopyToClipboard
-                  text={record.closeIssuesEndpoint}
-                  onCopy={() =>
-                    CopyToaster.show({
-                      message: 'Copy successfully.',
-                      intent: Intent.SUCCESS
-                    })
-                  }
-                >
-                  <CopyIcon width={16} height={16} />
-                </CopyToClipboard>
-              </div>
-              <h3>Deployment</h3>
-              <p>POST to register a deployment</p>
-              <div className='block'>
-                <span>{record.postDeploymentsCurl}</span>
-                <CopyToClipboard text={record.postDeploymentsCurl}>
-                  <CopyIcon width={16} height={16} />
-                </CopyToClipboard>
-              </div>
-            </div>
-            <div className='btns'>
-              <Button intent={Intent.PRIMARY} onClick={onCancel}>
-                Done
-              </Button>
-            </div>
-          </>
-        )}
-      </S.FormWrapper>
-    </Dialog>
-  )
-}
diff --git a/config-ui/src/pages/connections/incoming-webhook/index.jsx 
b/config-ui/src/pages/connections/incoming-webhook/index.jsx
deleted file mode 100644
index 6226480c2..000000000
--- a/config-ui/src/pages/connections/incoming-webhook/index.jsx
+++ /dev/null
@@ -1,163 +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 React, { useState } from 'react'
-import { Link } from 'react-router-dom'
-import { Icon, Button, Intent } from '@blueprintjs/core'
-
-import { useWebhookManager } from '@/hooks/useWebhookManager'
-import { ReactComponent as WebHookProviderIcon } from 
'@/images/integrations/incoming-webhook.svg'
-import { ReactComponent as EditIcon } from '@/images/icons/setting-con.svg'
-import { ReactComponent as DeleteIcon } from '@/images/icons/delete.svg'
-
-import { AddModal } from './add-modal'
-import { ViewOrEditModal } from './view-or-edit-modal'
-import { DeleteModal } from './delete-modal'
-import * as S from './styled'
-
-const postUrlPrefix = `${window.location.origin}/api`
-
-export const IncomingWebhook = () => {
-  // defined the form modal is add | edit | delete
-  const [modalType, setModalType] = useState()
-  // defined the edit or delete record
-  const [record, setRecord] = useState()
-
-  const { loading, data, operating, onCreate, onUpdate, onDelete } =
-    useWebhookManager()
-
-  const handleShowModal = (mt, r) => {
-    setModalType(mt)
-    setRecord((existingRecord) =>
-      r
-        ? {
-            ...r,
-            postIssuesEndpoint: `${postUrlPrefix}${r.postIssuesEndpoint}`,
-            closeIssuesEndpoint: `${postUrlPrefix}${r.closeIssuesEndpoint}`,
-            postDeploymentsCurl: `curl 
${postUrlPrefix}${r.postPipelineDeployTaskEndpoint} -X 'POST' -d "{
-  \\"commit_sha\\":\\"the sha of deployment commit\\",
-  \\"repo_url\\":\\"the repo URL of the deployment commit\\",
-  \\"start_time\\":\\"Optional, eg. 2020-01-01T12:00:00+00:00\\"
-}"`
-          }
-        : existingRecord
-    )
-  }
-
-  const handleHideModal = () => {
-    setModalType()
-    setRecord()
-  }
-
-  return (
-    <>
-      <div className='main'>
-        <div className='headlineContainer'>
-          <div
-            style={{
-              display: 'flex',
-              alignItems: 'center',
-              justifyContent: 'space-between',
-              marginBottom: 12
-            }}
-          >
-            <div style={{ display: 'flex', alignItems: 'center' }}>
-              <WebHookProviderIcon
-                className='providerIconSvg'
-                width='30'
-                height='30'
-              />
-              <h1 style={{ margin: '0 0 0 8px' }}>Incoming Webhook</h1>
-            </div>
-            <Link style={{ color: '#777777' }} to='/integrations'>
-              <Icon icon='undo' size={16} /> Go Back
-            </Link>
-          </div>
-          <div className='page-description'>
-            Use Webhooks to define Incidents and Deployments for your CI tools
-            if they are not listed in Data Sources.
-          </div>
-        </div>
-        <div className='manageProvider'>
-          <S.Container>
-            <span>
-              <Button
-                intent='primary'
-                text='Add Incoming Webhook'
-                loading={operating}
-                onClick={() => handleShowModal('add')}
-              />
-            </span>
-            <S.Wrapper>
-              <S.Grid className='title'>
-                <li>ID</li>
-                <li>Incoming Webhook Name</li>
-                <li />
-              </S.Grid>
-              {loading ? (
-                <div>Loading</div>
-              ) : (
-                data.map((it) => (
-                  <S.Grid key={it.id}>
-                    <li>{it.id}</li>
-                    <li>{it.name}</li>
-                    <li>
-                      <Button
-                        loading={operating}
-                        intent={Intent.PRIMARY}
-                        minimal
-                        small
-                        icon={<EditIcon width={18} height={18} />}
-                        onClick={() => handleShowModal('edit', it)}
-                      />
-                      <Button
-                        loading={operating}
-                        intent={Intent.PRIMARY}
-                        minimal
-                        small
-                        icon={<DeleteIcon width={18} height={18} />}
-                        onClick={() => handleShowModal('delete', it)}
-                      />
-                    </li>
-                  </S.Grid>
-                ))
-              )}
-            </S.Wrapper>
-          </S.Container>
-        </div>
-      </div>
-      {modalType === 'add' && (
-        <AddModal onSubmit={onCreate} onCancel={handleHideModal} />
-      )}
-      {modalType === 'edit' && (
-        <ViewOrEditModal
-          record={record}
-          onSubmit={onUpdate}
-          onCancel={handleHideModal}
-        />
-      )}
-      {modalType === 'delete' && (
-        <DeleteModal
-          record={record}
-          onSubmit={onDelete}
-          onCancel={handleHideModal}
-        />
-      )}
-    </>
-  )
-}
diff --git a/config-ui/src/pages/connections/incoming-webhook/styled.js 
b/config-ui/src/pages/connections/incoming-webhook/styled.js
deleted file mode 100644
index 91e4d47f3..000000000
--- a/config-ui/src/pages/connections/incoming-webhook/styled.js
+++ /dev/null
@@ -1,169 +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 styled from '@emotion/styled'
-
-export const Container = styled.div`
-  margin-top: 48px;
-`
-
-export const Wrapper = styled.div`
-  margin-top: 12px;
-  background: #ffffff;
-  box-shadow: 0px 2.4px 4.8px -0.8px rgba(0, 0, 0, 0.1),
-    0px 1.6px 8px rgba(0, 0, 0, 0.07);
-  border-radius: 4px;
-`
-
-export const Grid = styled.ul`
-  margin: 0;
-  padding: 0;
-  list-style: none;
-  display: flex;
-  align-items: center;
-  padding: 0 16px;
-  width: 100%;
-  height: 48px;
-  font-size: 14px;
-  color: #292b3f;
-  border-top: 1px solid #bdcefb;
-  box-sizing: border-box;
-
-  &.title {
-    font-size: 16px;
-    font-weight: 600;
-  }
-
-  &:first-child {
-    border-top: 0;
-  }
-
-  li {
-    flex: auto;
-
-    &:first-child {
-      flex: 0 0 200px;
-    }
-
-    &:last-child {
-      flex: 0 0 60px;
-      display: flex;
-      justify-content: space-around;
-
-      & > svg {
-        cursor: pointer;
-      }
-    }
-  }
-`
-
-export const FormWrapper = styled.div`
-  padding: 24px;
-  font-size: 14px;
-  color: #292b3f;
-
-  h2 {
-    margin: 0;
-    font-size: 16px;
-    font-weight: 600;
-  }
-
-  h3 {
-    margin: 16px 0 0;
-    font-size: 14px;
-    font-weight: 600;
-  }
-
-  p {
-    margin: 8px 0;
-    font-size: 12px;
-    color: #94959f;
-  }
-
-  .message {
-    margin-bottom: 24px;
-
-    p {
-      font-size: 14px;
-    }
-  }
-
-  .form {
-    input {
-      padding: 7px 12px;
-      width: 100%;
-      height: 32px;
-      background-color: #ffffff;
-      border: 1px solid #dbe4fd;
-      border-radius: 4px;
-      outline: none;
-      box-sizing: border-box;
-
-      &.has-error {
-        border: 1px solid red;
-      }
-    }
-
-    .error {
-      color: red;
-    }
-  }
-
-  .tips {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-weight: 600;
-    font-size: 16px;
-
-    span {
-      margin-left: 4px;
-    }
-  }
-
-  .url {
-    margin-top: 24px;
-
-    .block {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      padding: 10px;
-      background-color: #f0f4fe;
-
-      & > span {
-        flex: 1 0;
-      }
-
-      & > svg {
-        cursor: pointer;
-      }
-    }
-  }
-
-  .btns {
-    display: flex;
-    align-items: center;
-    justify-content: flex-end;
-    margin-top: 24px;
-
-    .bp3-button + .bp3-button {
-      margin-left: 8px;
-    }
-  }
-`
diff --git 
a/config-ui/src/pages/connections/incoming-webhook/view-or-edit-modal.jsx 
b/config-ui/src/pages/connections/incoming-webhook/view-or-edit-modal.jsx
deleted file mode 100644
index 32ede9ce4..000000000
--- a/config-ui/src/pages/connections/incoming-webhook/view-or-edit-modal.jsx
+++ /dev/null
@@ -1,137 +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 React, { useState, useEffect } from 'react'
-import { Dialog, Button, Toaster, Position, Intent } from '@blueprintjs/core'
-import { CopyToClipboard } from 'react-copy-to-clipboard'
-
-import { ReactComponent as CopyIcon } from '@/images/icons/copy.svg'
-import * as S from './styled'
-
-const CopyToaster = Toaster.create({
-  position: Position.TOP_RIGHT
-})
-
-export const ViewOrEditModal = ({ record, onSubmit, onCancel }) => {
-  const [name, setName] = useState('')
-  const [error, setError] = useState('')
-
-  useEffect(() => {
-    setName(record?.name)
-  }, [record])
-
-  const handleCancel = () => {
-    setName('')
-    setError('')
-    onCancel()
-  }
-
-  const handleInputChange = (e) => {
-    setName(e.target.value)
-    setError('')
-  }
-
-  const handleSubmit = () => {
-    if (!name) {
-      setError('Name is required')
-      return
-    }
-
-    onSubmit(record.id, { name })
-    handleCancel()
-  }
-
-  return (
-    <Dialog
-      isOpen={true}
-      title='View or Edit Incoming Webhook'
-      style={{ width: 640 }}
-      onClose={handleCancel}
-    >
-      <S.FormWrapper>
-        <div className='form'>
-          <h2>Incoming Webhook Name *</h2>
-          <p>
-            Give your Incoming Webhook a unique name to help you identify it in
-            the future.
-          </p>
-          <input
-            type='text'
-            placeholder='Your Incoming Webhook Name'
-            className={error ? 'has-error' : ''}
-            value={name || ''}
-            onChange={handleInputChange}
-          />
-          {error && <p className='error'>{error}</p>}
-        </div>
-        <div className='url'>
-          <h2>POST URL</h2>
-          <p>
-            Copy the following URLs to your issue tracking tool for Incidents
-            and CI tool for Deployments by making a POST to DevLake.
-          </p>
-          <h3>Incident</h3>
-          <p>POST to register an incident </p>
-          <div className='block'>
-            <span>{record.postIssuesEndpoint}</span>
-            <CopyToClipboard
-              text={record.postIssuesEndpoint}
-              onCopy={() =>
-                CopyToaster.show({
-                  message: 'Copy successfully.',
-                  intent: Intent.SUCCESS
-                })
-              }
-            >
-              <CopyIcon width={16} height={16} />
-            </CopyToClipboard>
-          </div>
-          <p>POST to close a registered incident</p>
-          <div className='block'>
-            <span>{record.closeIssuesEndpoint}</span>
-            <CopyToClipboard
-              text={record.closeIssuesEndpoint}
-              onCopy={() =>
-                CopyToaster.show({
-                  message: 'Copy successfully.',
-                  intent: Intent.SUCCESS
-                })
-              }
-            >
-              <CopyIcon width={16} height={16} />
-            </CopyToClipboard>
-          </div>
-          <h3>Deployment</h3>
-          <p>POST to register a deployment</p>
-          <div className='block'>
-            <span>{record.postDeploymentsCurl}</span>
-            <CopyToClipboard text={record.postDeploymentsCurl}>
-              <CopyIcon width={16} height={16} />
-            </CopyToClipboard>
-          </div>
-        </div>
-        <div className='btns'>
-          <Button onClick={onCancel}>Cancel</Button>
-          <Button intent={Intent.PRIMARY} onClick={handleSubmit}>
-            Save
-          </Button>
-        </div>
-      </S.FormWrapper>
-    </Dialog>
-  )
-}
diff --git a/config-ui/src/pages/index.ts b/config-ui/src/pages/index.ts
index 89e794d51..923f761e8 100644
--- a/config-ui/src/pages/index.ts
+++ b/config-ui/src/pages/index.ts
@@ -17,5 +17,5 @@
  */
 
 export * from './project'
+export * from './connection'
 export * from './blueprint'
-export * from './connections'
diff --git a/config-ui/src/plugins/common/index.ts 
b/config-ui/src/plugins/common/index.ts
index 26381231f..35b8a014e 100644
--- a/config-ui/src/plugins/common/index.ts
+++ b/config-ui/src/plugins/common/index.ts
@@ -16,7 +16,6 @@
  *
  */
 
-export * from './types'
 export * from './data-scope-list'
 export * from './data-scope'
 export * from './transformation'
diff --git a/config-ui/src/pages/connections/index.ts 
b/config-ui/src/plugins/config.ts
similarity index 69%
rename from config-ui/src/pages/connections/index.ts
rename to config-ui/src/plugins/config.ts
index 66ed7d6f5..b60313c02 100644
--- a/config-ui/src/pages/connections/index.ts
+++ b/config-ui/src/plugins/config.ts
@@ -16,6 +16,16 @@
  *
  */
 
-import { WebHookConnection } from '@/plugins'
+import { GitHubConfig } from '@/plugins/github'
+import { JIRAConfig } from '@/plugins/jira'
+import { GitLabConfig } from '@/plugins/gitlab'
+import { JenkinsConfig } from '@/plugins/jenkins'
+import { WebhookConfig } from '@/plugins/webook'
 
-export const WebHookConnectionPage = WebHookConnection
+export const PluginConfig = [
+  GitHubConfig,
+  JIRAConfig,
+  GitLabConfig,
+  JenkinsConfig,
+  WebhookConfig
+]
diff --git a/config-ui/src/plugins/github/assets/icon.svg 
b/config-ui/src/plugins/github/assets/icon.svg
new file mode 100644
index 000000000..67375bbfd
--- /dev/null
+++ b/config-ui/src/plugins/github/assets/icon.svg
@@ -0,0 +1,19 @@
+<!--
+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.
+-->
+<svg width="100" height="100" viewBox="0 0 36 36" fill="none" 
xmlns="http://www.w3.org/2000/svg";>
+    <path d="M18 3C9.7125 3 3 9.7125 3 18C2.9983 21.1489 3.98822 24.2184 
5.82933 26.773C7.67043 29.3276 10.2692 31.2376 13.257 32.232C14.007 32.3625 
14.2875 31.9125 14.2875 31.518C14.2875 31.1625 14.268 29.982 14.268 28.725C10.5 
29.4195 9.525 27.807 9.225 26.9625C9.0555 26.5305 8.325 25.2 7.6875 
24.843C7.1625 24.5625 6.4125 23.868 7.668 23.85C8.85 23.8305 9.693 24.9375 
9.975 25.3875C11.325 27.6555 13.482 27.018 14.343 26.625C14.475 25.65 14.868 
24.9945 15.3 24.6195C11.9625 24.2445 8.475  [...]
+</svg>
\ No newline at end of file
diff --git a/config-ui/src/plugins/common/types.ts 
b/config-ui/src/plugins/github/config.ts
similarity index 58%
copy from config-ui/src/plugins/common/types.ts
copy to config-ui/src/plugins/github/config.ts
index b4a97122c..1c3a7ca65 100644
--- a/config-ui/src/plugins/common/types.ts
+++ b/config-ui/src/plugins/github/config.ts
@@ -16,10 +16,28 @@
  *
  */
 
-export enum Plugins {
-  GitHub = 'github',
-  JIRA = 'jira',
-  GitLab = 'gitlab',
-  Jenkins = 'jenkins',
-  Webhook = 'webhook'
+import { PluginType } from '@/plugins'
+
+import Icon from './assets/icon.svg'
+
+export const GitHubConfig = {
+  plugin: 'github',
+  name: 'GitHub',
+  type: PluginType.Connection,
+  icon: Icon,
+  entities: ['CODE', 'TICKET', 'CODEREVIEW', 'CROSS', 'CICD'],
+  transformation: {
+    issueSeverity: '',
+    issueComponent: '',
+    issuePriority: '',
+    issueTypeRequirement: '',
+    issueTypeBug: '',
+    issueTypeIncident: '',
+    prType: '',
+    prComponent: '',
+    prBodyClosePattern: '',
+    productionPattern: '',
+    deploymentPattern: '',
+    refdiff: null
+  }
 }
diff --git a/config-ui/src/plugins/github/index.ts 
b/config-ui/src/plugins/github/index.ts
index 412fedc6e..fd85e9b6f 100644
--- a/config-ui/src/plugins/github/index.ts
+++ b/config-ui/src/plugins/github/index.ts
@@ -16,5 +16,6 @@
  *
  */
 
+export * from './config'
 export * from './data-scope'
 export * from './transformation'
diff --git a/config-ui/src/plugins/gitlab/assets/icon.svg 
b/config-ui/src/plugins/gitlab/assets/icon.svg
new file mode 100644
index 000000000..0943bd442
--- /dev/null
+++ b/config-ui/src/plugins/gitlab/assets/icon.svg
@@ -0,0 +1,19 @@
+<!--
+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.
+-->
+<svg width="100" height="100" viewBox="0 0 36 36" fill="none" 
xmlns="http://www.w3.org/2000/svg";>
+<path d="M8.80197 4.12524L12 15.0002H24L27.198 4.12524C27.2339 4.00187 27.3085 
3.8933 27.4108 3.81551C27.5131 3.73772 27.6377 3.69483 27.7662 3.69315C27.8947 
3.69147 28.0203 3.73109 28.1246 3.80618C28.2289 3.88126 28.3063 3.98785 28.3455 
4.11024L33.588 20.4962C33.6352 20.6437 33.6356 20.8022 33.5891 20.9499C33.5426 
21.0976 33.4516 21.2273 33.3285 21.3212L18 33.0002L2.66997 21.3212C2.5471 
21.2272 2.45635 21.0974 2.41016 20.9497C2.36397 20.8019 2.3646 20.6436 2.41197 
20.4962L7.65447 4.1102 [...]
+</svg>
diff --git a/config-ui/src/plugins/common/types.ts 
b/config-ui/src/plugins/gitlab/config.ts
similarity index 70%
copy from config-ui/src/plugins/common/types.ts
copy to config-ui/src/plugins/gitlab/config.ts
index b4a97122c..e310c43bd 100644
--- a/config-ui/src/plugins/common/types.ts
+++ b/config-ui/src/plugins/gitlab/config.ts
@@ -16,10 +16,18 @@
  *
  */
 
-export enum Plugins {
-  GitHub = 'github',
-  JIRA = 'jira',
-  GitLab = 'gitlab',
-  Jenkins = 'jenkins',
-  Webhook = 'webhook'
+import { PluginType } from '@/plugins'
+
+import Icon from './assets/icon.svg'
+
+export const GitLabConfig = {
+  plugin: 'gitlab',
+  name: 'GitLab',
+  type: PluginType.Connection,
+  icon: Icon,
+  entities: ['CODE', 'TICKET', 'CODEREVIEW', 'CROSS', 'CICD'],
+  transformation: {
+    productionPattern: '',
+    deploymentPattern: ''
+  }
 }
diff --git a/config-ui/src/plugins/gitlab/index.ts 
b/config-ui/src/plugins/gitlab/index.ts
index 412fedc6e..fd85e9b6f 100644
--- a/config-ui/src/plugins/gitlab/index.ts
+++ b/config-ui/src/plugins/gitlab/index.ts
@@ -16,5 +16,6 @@
  *
  */
 
+export * from './config'
 export * from './data-scope'
 export * from './transformation'
diff --git a/config-ui/src/plugins/index.ts b/config-ui/src/plugins/index.ts
index c784ec481..d91981c4d 100644
--- a/config-ui/src/plugins/index.ts
+++ b/config-ui/src/plugins/index.ts
@@ -16,5 +16,7 @@
  *
  */
 
+export * from './types'
+export * from './config'
 export * from './common'
 export * from './webook'
diff --git a/config-ui/src/plugins/jenkins/assets/icon.svg 
b/config-ui/src/plugins/jenkins/assets/icon.svg
new file mode 100644
index 000000000..94ad53162
--- /dev/null
+++ b/config-ui/src/plugins/jenkins/assets/icon.svg
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+<svg width="100" height="100" viewBox="0 0 36 36" fill="none" 
xmlns="http://www.w3.org/2000/svg";>
+<path d="M25.2912 2.67189C23.4918 1.74972 21.1902 1 18.4387 1C5.88829 1 
5.42346 9.33694 5.42346 9.33694C5.42346 9.33694 3.3992 10.0417 2.79942 
13.2055C2.43206 15.1248 2.91188 16.4968 3.34672 17.284C2.92688 17.7338 2.57451 
18.2662 2.30461 18.8659C1.66734 20.2829 1.5174 21.9548 1.89226 23.5817C2.26712 
25.2086 3.11431 26.6256 4.28388 27.5702C5.54341 28.5899 7.08785 28.9572 8.51232 
28.5899C8.5873 28.5749 8.65477 28.5524 8.72974 28.5299C11.4288 32.6159 15.5372 
35 20.0131 35C27.8927 35 34.3103 [...]
+<path d="M22.0673 25.2461C23.7317 25.6809 24.9313 25.591 24.9313 
25.591L24.9613 23.8666C24.9613 23.8666 24.0691 23.8891 22.4047 23.6942C20.7403 
23.4992 19.1359 22.9744 19.1359 22.9744C19.1359 22.9744 19.8557 24.6763 22.0598 
25.2536L22.0673 25.2461Z" fill="#7497F7"/>
+<path d="M21.4376 27.0079C18.5961 26.3557 16.4369 22.9669 16.4369 
22.9669C16.4369 22.9669 15.7322 27.4203 20.7478 29.0172C24.4215 30.1868 26.1758 
26.8805 26.1758 26.8805C26.1758 26.8805 24.279 27.6602 21.4376 27.0079Z" 
fill="#7497F7"/>
+<path d="M19.3308 10.2816C19.3308 10.2816 19.4433 11.6386 20.8153 
13.183C22.1873 14.7275 22.9295 14.7499 22.5022 15.6646C22.0748 16.5793 20.1705 
17.0966 18.5811 16.9466C15.7547 16.6842 15.6422 15.2373 15.6422 15.2373C15.6422 
15.2373 17.8014 15.4847 18.6261 15.2373C19.4508 14.9899 19.6907 14.2926 19.4508 
13.7078C18.6861 11.871 19.3233 10.2816 19.3233 10.2816H19.3308Z" 
fill="#7497F7"/>
+</svg>
diff --git a/config-ui/src/plugins/common/types.ts 
b/config-ui/src/plugins/jenkins/config.ts
similarity index 73%
copy from config-ui/src/plugins/common/types.ts
copy to config-ui/src/plugins/jenkins/config.ts
index b4a97122c..c1213935a 100644
--- a/config-ui/src/plugins/common/types.ts
+++ b/config-ui/src/plugins/jenkins/config.ts
@@ -16,10 +16,18 @@
  *
  */
 
-export enum Plugins {
-  GitHub = 'github',
-  JIRA = 'jira',
-  GitLab = 'gitlab',
-  Jenkins = 'jenkins',
-  Webhook = 'webhook'
+import { PluginType } from '@/plugins'
+
+import Icon from './assets/icon.svg'
+
+export const JenkinsConfig = {
+  plugin: 'jenkins',
+  name: 'Jenkins',
+  type: PluginType.Connection,
+  icon: Icon,
+  entities: ['CICD'],
+  transformation: {
+    productionPattern: '',
+    deploymentPattern: ''
+  }
 }
diff --git a/config-ui/src/plugins/jenkins/index.ts 
b/config-ui/src/plugins/jenkins/index.ts
index 412fedc6e..fd85e9b6f 100644
--- a/config-ui/src/plugins/jenkins/index.ts
+++ b/config-ui/src/plugins/jenkins/index.ts
@@ -16,5 +16,6 @@
  *
  */
 
+export * from './config'
 export * from './data-scope'
 export * from './transformation'
diff --git a/config-ui/src/plugins/jira/assets/icon.svg 
b/config-ui/src/plugins/jira/assets/icon.svg
new file mode 100644
index 000000000..a3e68b3fd
--- /dev/null
+++ b/config-ui/src/plugins/jira/assets/icon.svg
@@ -0,0 +1,20 @@
+<!--
+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.
+-->
+<svg width="100" height="100" viewBox="0 0 36 36" fill="none" 
xmlns="http://www.w3.org/2000/svg";>
+    <path d="M16.5952 12.2857L10.881 18L18.0873 25.2064C21.0714 28.1905 
21.0714 33.0238 18.0873 36L3.35714 21.2698C1.54762 19.4603 1.54762 16.5317 
3.35714 14.7302L13.8095 4.26984C13.4762 7.11905 14.4048 10.0952 16.5952 
12.2778V12.2857Z" fill="#7497F7" />
+    <path d="M19.5714 23.7143L25.2857 18L18.0794 10.7937C15.0952 7.80952 
15.0952 2.97619 18.0794 0L32.8095 14.7302C34.6191 16.5397 34.6191 19.4683 
32.8095 21.2698L22.3571 31.7222C22.6905 28.873 21.7619 25.8968 19.5714 
23.7143Z" fill="#7497F7" />
+</svg>
\ No newline at end of file
diff --git a/config-ui/src/plugins/common/types.ts 
b/config-ui/src/plugins/jira/config.ts
similarity index 70%
copy from config-ui/src/plugins/common/types.ts
copy to config-ui/src/plugins/jira/config.ts
index b4a97122c..205998296 100644
--- a/config-ui/src/plugins/common/types.ts
+++ b/config-ui/src/plugins/jira/config.ts
@@ -16,10 +16,20 @@
  *
  */
 
-export enum Plugins {
-  GitHub = 'github',
-  JIRA = 'jira',
-  GitLab = 'gitlab',
-  Jenkins = 'jenkins',
-  Webhook = 'webhook'
+import { PluginType } from '@/plugins'
+
+import Icon from './assets/icon.svg'
+
+export const JIRAConfig = {
+  plugin: 'jira',
+  name: 'JIRA',
+  type: PluginType.Connection,
+  icon: Icon,
+  entities: ['TICKET', 'CROSS'],
+  transformation: {
+    epicKeyField: '',
+    storyPointField: '',
+    remotelinkCommitShaPattern: '',
+    typeMappings: {}
+  }
 }
diff --git a/config-ui/src/plugins/jira/index.ts 
b/config-ui/src/plugins/jira/index.ts
index 412fedc6e..fd85e9b6f 100644
--- a/config-ui/src/plugins/jira/index.ts
+++ b/config-ui/src/plugins/jira/index.ts
@@ -16,5 +16,6 @@
  *
  */
 
+export * from './config'
 export * from './data-scope'
 export * from './transformation'
diff --git a/config-ui/src/plugins/common/types.ts 
b/config-ui/src/plugins/types.ts
similarity index 90%
copy from config-ui/src/plugins/common/types.ts
copy to config-ui/src/plugins/types.ts
index b4a97122c..126cfdb6b 100644
--- a/config-ui/src/plugins/common/types.ts
+++ b/config-ui/src/plugins/types.ts
@@ -23,3 +23,8 @@ export enum Plugins {
   Jenkins = 'jenkins',
   Webhook = 'webhook'
 }
+
+export enum PluginType {
+  Connection = 'connection',
+  Incoming_Connection = 'incoming_connection'
+}
diff --git a/config-ui/src/plugins/webook/assets/icon.svg 
b/config-ui/src/plugins/webook/assets/icon.svg
new file mode 100644
index 000000000..548503935
--- /dev/null
+++ b/config-ui/src/plugins/webook/assets/icon.svg
@@ -0,0 +1,5 @@
+<svg width="100" height="100" viewBox="0 0 58 52" fill="none" 
xmlns="http://www.w3.org/2000/svg";>
+  <path d="M27.2239 21.9899C24.8672 25.8703 22.6083 29.6289 20.3028 
33.3587C19.7113 34.3151 19.4179 35.0951 19.8914 36.3131C21.1971 39.6749 19.3543 
42.947 15.8922 43.8365C12.6319 44.6743 9.44613 42.5714 8.79873 39.1488C8.2243 
36.1184 10.626 33.1474 14.0369 32.6745C14.3226 32.6334 14.6144 32.6289 15.0942 
32.5939L20.2842 24.0791C17.0239 20.9013 15.0771 17.1851 15.5071 12.5811C15.8176 
9.32719 17.1186 6.51426 19.5064 4.20918C21.7027 2.06888 24.5804 0.728584 
27.6616 0.410795C30.7429 0.0930059 [...]
+  <path d="M33.9556 17.3995C35.6153 20.2687 37.3028 23.1774 38.9733 
26.0664C47.4206 23.5074 53.789 28.0856 56.0727 32.9892C58.8331 38.9116 56.9468 
45.9257 51.527 49.5794C45.9643 53.3305 38.9283 52.6889 33.9991 47.8719L37.8664 
44.7017C42.7351 47.7898 46.9921 47.6438 50.153 43.9886C51.4577 42.4671 52.1615 
40.5375 52.1365 38.5507C52.1114 36.564 51.3591 34.652 50.0164 33.1626C46.8166 
29.6396 42.5286 29.5316 37.3463 32.9147C35.1961 29.1789 33.0086 25.4734 30.9267 
21.7117C30.2249 20.4436 29.45 [...]
+  <path d="M37.9269 40.8548H27.7564C26.7815 44.7807 24.6763 47.951 21.0496 
49.9672C18.3007 51.5212 15.0826 52.0823 11.955 51.5531C5.99955 50.6119 1.13243 
45.3616 0.700828 39.4483C0.216445 32.7505 4.9159 26.7978 11.1818 25.4597C11.615 
26.9985 12.0512 28.5524 12.4844 30.0866C6.7401 32.9588 4.74667 36.5776 6.35507 
41.1042C7.77096 45.0864 11.7889 47.2698 16.1623 46.4259C20.6242 45.5638 22.8722 
41.9328 22.599 36.1048C26.828 36.1048 31.0602 36.0622 35.2892 36.126C36.9411 
36.1519 38.2157 35.984 [...]
+</svg>
\ No newline at end of file
diff --git a/config-ui/src/plugins/common/types.ts 
b/config-ui/src/plugins/webook/config.ts
similarity index 77%
rename from config-ui/src/plugins/common/types.ts
rename to config-ui/src/plugins/webook/config.ts
index b4a97122c..83f53ce14 100644
--- a/config-ui/src/plugins/common/types.ts
+++ b/config-ui/src/plugins/webook/config.ts
@@ -16,10 +16,15 @@
  *
  */
 
-export enum Plugins {
-  GitHub = 'github',
-  JIRA = 'jira',
-  GitLab = 'gitlab',
-  Jenkins = 'jenkins',
-  Webhook = 'webhook'
+import { PluginType } from '@/plugins'
+
+import Icon from './assets/icon.svg'
+
+export const WebhookConfig = {
+  plugin: 'webhook',
+  name: 'Webhook',
+  type: PluginType.Incoming_Connection,
+  icon: Icon,
+  entities: [],
+  transformation: {}
 }
diff --git a/config-ui/src/plugins/webook/index.ts 
b/config-ui/src/plugins/webook/index.ts
index 2011e2dd9..43613a2fd 100644
--- a/config-ui/src/plugins/webook/index.ts
+++ b/config-ui/src/plugins/webook/index.ts
@@ -17,6 +17,7 @@
  */
 
 export * from './types'
+export * from './config'
 export * from './connection'
 export * from './create-dialog'
 export * from './delete-dialog'
diff --git a/config-ui/src/store/connections/use-context-value.ts 
b/config-ui/src/store/connections/use-context-value.ts
index 7822b05e0..cb7d9c32e 100644
--- a/config-ui/src/store/connections/use-context-value.ts
+++ b/config-ui/src/store/connections/use-context-value.ts
@@ -18,7 +18,7 @@
 
 import { useState, useEffect, useCallback, useMemo } from 'react'
 
-import { Plugins } from '@/registry'
+import { PluginConfig, PluginType } from '@/plugins'
 
 import type { ConnectionItemType } from './types'
 import { ConnectionStatusEnum } from './types'
@@ -30,8 +30,8 @@ export const useContextValue = (plugins: string[]) => {
 
   const allConnections = useMemo(
     () =>
-      Plugins.filter((p) => p.type === 'integration').filter((p) =>
-        !plugins.length ? true : plugins.includes(p.id)
+      PluginConfig.filter((p) => p.plugin === PluginType.Connection).filter(
+        (p) => (!plugins.length ? true : plugins.includes(p.plugin))
       ),
     [plugins]
   )
@@ -48,18 +48,18 @@ export const useContextValue = (plugins: string[]) => {
     setLoading(true)
 
     const res = await Promise.all(
-      allConnections.map((cs) => getConnection(cs.id))
+      allConnections.map((cs) => getConnection(cs.plugin))
     )
 
     const resWithPlugin = res.map((cs, i) =>
       cs.map((it: any) => {
-        const { id, icon, availableDataDomains } = allConnections[i] as any
+        const { plugin, icon, entities } = allConnections[i]
 
         return {
           ...it,
-          plugin: id,
-          icon: `/${icon}`,
-          entities: availableDataDomains
+          plugin,
+          icon,
+          entities
         }
       })
     )

Reply via email to