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,