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 279743826 feat(config-ui): add bp upgrade error (#3966)
279743826 is described below

commit 2797438268b3c4d3585e27e35a9ae8db652935c2
Author: 青湛 <[email protected]>
AuthorDate: Wed Dec 21 11:11:14 2022 +0800

    feat(config-ui): add bp upgrade error (#3966)
    
    * fix(config-ui): missed some fields on jira
    
    * feat(config-ui): add bp upgrade error
---
 config-ui/src/error/components/bp-upgrade/api.ts   |  53 +++++++
 .../src/error/components/bp-upgrade/index.tsx      |  53 +++++++
 .../error/components/bp-upgrade/use-bp-upgrade.ts  | 174 +++++++++++++++++++++
 config-ui/src/error/components/index.ts            |   1 +
 config-ui/src/error/error-boundary.tsx             |   5 +-
 config-ui/src/error/types.ts                       |   3 +-
 config-ui/src/pages/blueprint/detail/use-detail.ts |  10 ++
 .../jira/components/miller-columns/index.tsx       |   7 +-
 .../miller-columns/use-miller-columns.ts           |   1 -
 9 files changed, 302 insertions(+), 5 deletions(-)

diff --git a/config-ui/src/error/components/bp-upgrade/api.ts 
b/config-ui/src/error/components/bp-upgrade/api.ts
new file mode 100644
index 000000000..8c4fce6ab
--- /dev/null
+++ b/config-ui/src/error/components/bp-upgrade/api.ts
@@ -0,0 +1,53 @@
+/*
+ * 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 request from '@/components/utils/request'
+
+export const getBlueprint = (id: ID) => request(`/blueprints/${id}`)
+
+export const updateBlueprint = (id: ID, payload: any) =>
+  request(`/blueprints/${id}`, {
+    method: 'patch',
+    data: payload
+  })
+
+export const createTransformation = (plugin: string, payload: any) =>
+  request(`/plugins/${plugin}/transformation_rules`, {
+    method: 'post',
+    data: payload
+  })
+
+export const getGitHub = (prefix: string, owner: string, repo: string) =>
+  request(`${prefix}/repos/${owner}/${repo}`)
+
+export const getGitLab = (prefix: string, id: ID) =>
+  request(`${prefix}/projects/${id}`)
+
+export const getJIRA = (prefix: string, id: ID) =>
+  request(`${prefix}/agile/1.0/board/${id}`)
+
+export const updateDataScope = (
+  plugin: string,
+  connectionId: ID,
+  repoId: ID,
+  payload: any
+) =>
+  request(`/plugins/${plugin}/connections/${connectionId}/scopes/${repoId}`, {
+    method: 'patch',
+    data: payload
+  })
diff --git a/config-ui/src/error/components/bp-upgrade/index.tsx 
b/config-ui/src/error/components/bp-upgrade/index.tsx
new file mode 100644
index 000000000..07df5ae75
--- /dev/null
+++ b/config-ui/src/error/components/bp-upgrade/index.tsx
@@ -0,0 +1,53 @@
+/*
+ * 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 from 'react'
+import { Icon, ButtonGroup, Button, Colors, Intent } from '@blueprintjs/core'
+
+import { Card } from '@/components'
+
+import type { UseBPUpgradeProps } from './use-bp-upgrade'
+import { useBPUpgrade } from './use-bp-upgrade'
+
+interface Props extends Pick<UseBPUpgradeProps, 'onResetError'> {}
+
+export const BPUpgrade = ({ ...props }: Props) => {
+  const bpId = window.location.pathname.split('/').pop()
+  const { processing, onSubmit } = useBPUpgrade({ id: bpId, ...props })
+
+  return (
+    <Card>
+      <h2>
+        <Icon icon='outdated' color={Colors.ORANGE5} size={20} />
+        <span>Current Blueprint Need to Upgrade</span>
+      </h2>
+      <p>
+        If you have already started, please wait for database migrations to
+        complete, do <strong>NOT</strong> close your browser at this time.
+      </p>
+      <ButtonGroup>
+        <Button
+          loading={processing}
+          text='Proceed to Upgrade'
+          intent={Intent.PRIMARY}
+          onClick={onSubmit}
+        />
+      </ButtonGroup>
+    </Card>
+  )
+}
diff --git a/config-ui/src/error/components/bp-upgrade/use-bp-upgrade.ts 
b/config-ui/src/error/components/bp-upgrade/use-bp-upgrade.ts
new file mode 100644
index 000000000..42edde849
--- /dev/null
+++ b/config-ui/src/error/components/bp-upgrade/use-bp-upgrade.ts
@@ -0,0 +1,174 @@
+/*
+ * 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 { operator } from '@/utils'
+
+import * as API from './api'
+
+export interface UseBPUpgradeProps {
+  id?: ID
+  onResetError: () => void
+}
+
+export const useBPUpgrade = ({ id, onResetError }: UseBPUpgradeProps) => {
+  const [processing, setProcessing] = useState(false)
+
+  const getScopeId = (plugin: string, scope: any) => {
+    switch (plugin) {
+      case 'github':
+        return scope.githubId
+      case 'gitlab':
+        return scope.gitlabId
+      case 'jira':
+        return scope.boardId
+    }
+  }
+
+  const getScopeDetail = async (
+    plugin: string,
+    connectionId: ID,
+    options: any
+  ) => {
+    const prefix = `/plugins/${plugin}/connections/${connectionId}/proxy/rest`
+
+    if (plugin === 'github') {
+      const res = await API.getGitHub(prefix, options.owner, options.repo)
+      return {
+        connectionId,
+        githubId: res.id,
+        name: `${res.owner.login}/${it.name}`,
+        ownerId: res.owner.id,
+        language: res.language,
+        description: res.description,
+        cloneUrl: res.clone_url,
+        HTMLUrl: res.html_url
+      }
+    }
+
+    if (plugin === 'gitlab') {
+      const res = await API.getGitLab(prefix, options.projectId)
+      return {
+        connectionId,
+        gitlabId: res.id,
+        name: res.path_with_namespace,
+        pathWithNamespace: res.path_with_namespace,
+        creatorId: res.creator_id,
+        defaultBranch: res.default_branch,
+        description: res.description,
+        openIssuesCount: res.open_issues_count,
+        starCount: res.star_count,
+        visibility: res.visibility,
+        webUrl: res.web_url,
+        httpUrlToRepo: res.http_url_to_repo
+      }
+    }
+
+    if (plugin === 'jira') {
+      const res = await API.getJIRA(prefix, options.boardId)
+      return {
+        connectionId,
+        boardId: res.id,
+        name: res.name,
+        self: res.self,
+        type: res.type,
+        projectId: res?.location?.projectId
+      }
+    }
+  }
+
+  const upgradeScope = async (plugin: string, connectionId: ID, scope: any) => 
{
+    // create transfromation template
+    const transfromationRule = await API.createTransformation(plugin, {
+      ...scope.transformation,
+      name: `upgrade-${plugin}-${connectionId}-${new Date().getTime()}`
+    })
+
+    // get data scope detail
+    const scopeDetail = await getScopeDetail(
+      plugin,
+      connectionId,
+      scope.options
+    )
+
+    // put data scope
+    const res = await API.updateDataScope(
+      plugin,
+      connectionId,
+      getScopeId(plugin, scopeDetail),
+      {
+        ...scopeDetail,
+        transformationRuleId: transfromationRule.id
+      }
+    )
+
+    return {
+      id: res.id,
+      entities: scope.entities
+    }
+  }
+
+  const upgradeConnection = async (connection: any) => {
+    const { plugin, connectionId } = connection
+
+    const scope = await Promise.all(
+      connection.scope.map((sc: any) => upgradeScope(plugin, connectionId, sc))
+    )
+    return {
+      plugin,
+      connectionId,
+      scope
+    }
+  }
+
+  const handleUpgrade = async () => {
+    if (!id) return
+
+    const bp = await API.getBlueprint(id)
+    const connections = await Promise.all(
+      bp.settings.connections.map((cs: any) => upgradeConnection(cs))
+    )
+
+    await API.updateBlueprint(id, {
+      ...bp,
+      settings: {
+        version: '2.0.0',
+        connections
+      }
+    })
+  }
+
+  const handleSubmit = async () => {
+    const [success] = await operator(handleUpgrade, {
+      setOperating: setProcessing
+    })
+
+    if (success) {
+      onResetError()
+    }
+  }
+
+  return useMemo(
+    () => ({
+      processing,
+      onSubmit: handleSubmit
+    }),
+    [processing]
+  )
+}
diff --git a/config-ui/src/error/components/index.ts 
b/config-ui/src/error/components/index.ts
index 6fd9487cb..b30b105e8 100644
--- a/config-ui/src/error/components/index.ts
+++ b/config-ui/src/error/components/index.ts
@@ -18,3 +18,4 @@
 export * from './db-migrate'
 export * from './offline'
 export * from './default'
+export * from './bp-upgrade'
diff --git a/config-ui/src/error/error-boundary.tsx 
b/config-ui/src/error/error-boundary.tsx
index 27afe1a08..1e6e3aa35 100644
--- a/config-ui/src/error/error-boundary.tsx
+++ b/config-ui/src/error/error-boundary.tsx
@@ -20,7 +20,7 @@ import React from 'react'
 import { Logo } from '@/components'
 
 import { Error } from './types'
-import { DBMigrate, Offline, Default } from './components'
+import { DBMigrate, Offline, Default, BPUpgrade } from './components'
 
 import * as S from './styled'
 
@@ -70,6 +70,9 @@ export class ErrorBoundary extends React.Component<Props, 
State> {
           {error === Error.API_OFFLINE && (
             <Offline onResetError={this.handleResetError} />
           )}
+          {error === Error.BP_NEED_TO_UPGRADE && (
+            <BPUpgrade onResetError={this.handleResetError} />
+          )}
           {!Object.keys(Error).includes(error) && (
             <Default error={error} onResetError={this.handleResetError} />
           )}
diff --git a/config-ui/src/error/types.ts b/config-ui/src/error/types.ts
index 66a83f2c4..b481b40e2 100644
--- a/config-ui/src/error/types.ts
+++ b/config-ui/src/error/types.ts
@@ -18,5 +18,6 @@
 
 export enum Error {
   API_OFFLINE = 'API_OFFLINE',
-  DB_NEED_MIGRATE = 'DB_NEED_MIGRATE'
+  DB_NEED_MIGRATE = 'DB_NEED_MIGRATE',
+  BP_NEED_TO_UPGRADE = 'BP_NEED_TO_UPGRADE'
 }
diff --git a/config-ui/src/pages/blueprint/detail/use-detail.ts 
b/config-ui/src/pages/blueprint/detail/use-detail.ts
index 986f4d644..78189e1c7 100644
--- a/config-ui/src/pages/blueprint/detail/use-detail.ts
+++ b/config-ui/src/pages/blueprint/detail/use-detail.ts
@@ -18,6 +18,7 @@
 
 import { useState, useEffect, useMemo } from 'react'
 
+import { Error } from '@/error'
 import { operator } from '@/utils'
 import { PluginConfig } from '@/plugins'
 
@@ -33,6 +34,7 @@ export const useDetail = ({ id }: UseDetailProps) => {
   const [saving, setSaving] = useState(false)
   const [blueprint, setBlueprint] = useState<BlueprintType>()
   const [connections, setConnections] = useState<ConnectionItemType[]>([])
+  const [, setError] = useState()
 
   const transformConnection = (connections: any) => {
     return connections
@@ -55,6 +57,14 @@ export const useDetail = ({ id }: UseDetailProps) => {
     setLoading(true)
     try {
       const res = await API.getBlueprint(id)
+
+      // need to upgrade 2.0.0
+      if (res.settings.version === '1.0.0') {
+        setError(() => {
+          throw Error.BP_NEED_TO_UPGRADE
+        })
+      }
+
       setBlueprint(res)
       setConnections(transformConnection(res.settings?.connections || []))
     } finally {
diff --git a/config-ui/src/plugins/jira/components/miller-columns/index.tsx 
b/config-ui/src/plugins/jira/components/miller-columns/index.tsx
index dac096603..ee68c37ac 100644
--- a/config-ui/src/plugins/jira/components/miller-columns/index.tsx
+++ b/config-ui/src/plugins/jira/components/miller-columns/index.tsx
@@ -52,8 +52,11 @@ export const MillerColumns = ({
         .filter((it) => seletedIds.includes(it.id))
         .map((it) => ({
           connectionId,
-          boardId: it.id,
-          name: it.name
+          boardId: it.boardId,
+          name: it.name,
+          self: it.self,
+          type: it.type,
+          projectId: it.projectId
         }))
     )
   }, [seletedIds])
diff --git 
a/config-ui/src/plugins/jira/components/miller-columns/use-miller-columns.ts 
b/config-ui/src/plugins/jira/components/miller-columns/use-miller-columns.ts
index 94b2164e2..5dd8803f5 100644
--- a/config-ui/src/plugins/jira/components/miller-columns/use-miller-columns.ts
+++ b/config-ui/src/plugins/jira/components/miller-columns/use-miller-columns.ts
@@ -43,7 +43,6 @@ export const useMillerColumns = ({ connectionId }: 
UseMillerColumnsProps) => {
       parentId: null,
       id: it.id,
       title: it.name,
-      connectionId,
       boardId: it.id,
       name: it.name,
       self: it.self,

Reply via email to