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 c34803873 feat(config-ui): add new pages about transformation (#4052)
c34803873 is described below
commit c3480387346b43dba36a7cd10c22a9d9b6d7b2be
Author: 青湛 <[email protected]>
AuthorDate: Wed Dec 28 19:30:19 2022 +0800
feat(config-ui): add new pages about transformation (#4052)
* refactor(config-ui): adjust the style for plugin transformation
* feat(config-ui): add global transformation store
* feat(config-ui): add new page transformations
* feat(config-ui): add new page transformation detail
* feat(config-ui): add menu and routes for transformation
---
config-ui/src/App.js | 19 ++-
config-ui/src/layouts/base/use-menu.ts | 6 +
config-ui/src/pages/index.ts | 1 +
.../transformation/detail/api.ts} | 27 ++--
.../src/pages/transformation/detail/index.tsx | 119 ++++++++++++++++
.../transformation/detail/styled.ts} | 33 +++--
.../src/pages/transformation/detail/use-detail.ts | 91 ++++++++++++
config-ui/src/pages/transformation/home/index.tsx | 157 +++++++++++++++++++++
.../transformation/home/styled.ts} | 32 +++--
.../src/{store => pages/transformation}/index.ts | 4 +-
.../transformation.tsx => github/styled.ts} | 38 +++--
config-ui/src/plugins/github/transformation.tsx | 6 +-
.../gitlab/{transformation.tsx => styled.ts} | 38 +++--
config-ui/src/plugins/gitlab/transformation.tsx | 5 +-
.../transformation.tsx => jenkins/styled.ts} | 38 +++--
config-ui/src/plugins/jenkins/transformation.tsx | 5 +-
.../{gitlab/transformation.tsx => jira/styled.ts} | 38 +++--
config-ui/src/plugins/jira/transformation.tsx | 5 +-
config-ui/src/store/index.ts | 3 +-
.../index.ts => store/transformations/api.ts} | 10 +-
config-ui/src/store/transformations/context.tsx | 61 ++++++++
config-ui/src/store/{ => transformations}/index.ts | 4 +-
.../index.ts => store/transformations/types.ts} | 11 +-
.../src/store/transformations/use-context-value.ts | 79 +++++++++++
24 files changed, 717 insertions(+), 113 deletions(-)
diff --git a/config-ui/src/App.js b/config-ui/src/App.js
index 9e0d779c2..06999a60d 100644
--- a/config-ui/src/App.js
+++ b/config-ui/src/App.js
@@ -32,7 +32,9 @@ import {
WebHookConnectionPage,
CreateBlueprintPage,
BlueprintHomePage,
- BlueprintDetailPage
+ BlueprintDetailPage,
+ TransformationHomePage,
+ TransformationDetailPage
} from '@/pages'
import ManageIntegration from '@/pages/configure/integration/manage'
import AddConnection from '@/pages/configure/connections/AddConnection'
@@ -94,6 +96,21 @@ function App() {
path='/blueprints/:id'
component={() => <BlueprintDetailPage />}
/>
+ <Route
+ exact
+ path='/transformations'
+ component={() => <TransformationHomePage />}
+ />
+ <Route
+ exact
+ path='/transformations/:plugin/create'
+ component={() => <TransformationDetailPage />}
+ />
+ <Route
+ exact
+ path='/transformations/:plugin/:tid'
+ component={() => <TransformationDetailPage />}
+ />
</Switch>
</BaseLayout>
)
diff --git a/config-ui/src/layouts/base/use-menu.ts
b/config-ui/src/layouts/base/use-menu.ts
index fef4a2b8c..fcc43f9e6 100644
--- a/config-ui/src/layouts/base/use-menu.ts
+++ b/config-ui/src/layouts/base/use-menu.ts
@@ -80,6 +80,12 @@ export const useMenu = () => {
}
]
},
+ {
+ key: 'transformation',
+ title: 'Transformation',
+ icon: 'function',
+ path: '/transformations'
+ },
{
key: 'dashboard',
title: 'Dashboard',
diff --git a/config-ui/src/pages/index.ts b/config-ui/src/pages/index.ts
index 405539b29..752a0091e 100644
--- a/config-ui/src/pages/index.ts
+++ b/config-ui/src/pages/index.ts
@@ -20,3 +20,4 @@ export * from './project'
export * from './connection'
export * from './blueprint'
export * from './pipeline'
+export * from './transformation'
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/pages/transformation/detail/api.ts
similarity index 59%
copy from config-ui/src/plugins/gitlab/transformation.tsx
copy to config-ui/src/pages/transformation/detail/api.ts
index 6f9402e83..44126ee89 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/pages/transformation/detail/api.ts
@@ -16,19 +16,20 @@
*
*/
-import React from 'react'
+import request from '@/components/utils/request'
+import { Plugins } from '@/plugins'
-import { CiCd } from './components'
+export const createTransformation = (plugin: Plugins, payload: any) =>
+ request(`/plugins/${plugin}/transformation_rules`, {
+ method: 'post',
+ data: payload
+ })
-interface Props {
- transformation: any
- setTransformation: React.Dispatch<React.SetStateAction<any>>
-}
+export const getTransformation = (plugin: Plugins, id: ID) =>
+ request(`/plugins/${plugin}/transformation_rules/${id}`)
-export const GitLabTransformation = ({ ...props }: Props) => {
- return (
- <>
- <CiCd {...props} />
- </>
- )
-}
+export const updateTransformation = (plugin: Plugins, id: ID, payload: any) =>
+ request(`/plugins/${plugin}/transformation_rules/${id}`, {
+ method: 'patch',
+ data: payload
+ })
diff --git a/config-ui/src/pages/transformation/detail/index.tsx
b/config-ui/src/pages/transformation/detail/index.tsx
new file mode 100644
index 000000000..4547a6102
--- /dev/null
+++ b/config-ui/src/pages/transformation/detail/index.tsx
@@ -0,0 +1,119 @@
+/*
+ * 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 { useParams, useHistory } from 'react-router-dom'
+import { InputGroup, ButtonGroup, Button, Intent } from '@blueprintjs/core'
+
+import { PageLoading, PageHeader, Card } from '@/components'
+import { Plugins } from '@/plugins'
+import { GitHubTransformation } from '@/plugins/github'
+import { GitLabTransformation } from '@/plugins/gitlab'
+import { JenkinsTransformation } from '@/plugins/jenkins'
+
+import { useDetail } from './use-detail'
+import * as S from './styled'
+
+export const TransformationDetailPage = () => {
+ const { plugin, tid } = useParams<{ plugin: Plugins; tid?: string }>()
+ const history = useHistory()
+
+ const {
+ loading,
+ operating,
+ name,
+ transformation,
+ onChangeName,
+ onChangeTransformation,
+ onSave
+ } = useDetail({ plugin, id: tid })
+
+ if (loading) {
+ return <PageLoading />
+ }
+
+ return (
+ <PageHeader
+ breadcrumbs={[
+ { name: 'Transformations', path: '/transformations' },
+ {
+ name: plugin,
+ path: '/transformations'
+ },
+ {
+ name: 'Create',
+ path: `/transformations/${plugin}/${tid ? tid : 'Create'}`
+ }
+ ]}
+ >
+ <S.Wrapper>
+ <Card className='name card'>
+ <h3>Transformation Name *</h3>
+ <p>
+ Give this set of transformation rules a unique name so that you can
+ identify it in the future.
+ </p>
+ <InputGroup
+ placeholder='Enter Transformation Name'
+ value={name}
+ onChange={(e) => onChangeName(e.target.value)}
+ />
+ </Card>
+ <Card className='card'>
+ {plugin === Plugins.GitHub && (
+ <GitHubTransformation
+ transformation={transformation}
+ setTransformation={onChangeTransformation}
+ />
+ )}
+ {plugin === Plugins.GitLab && (
+ <GitLabTransformation
+ transformation={transformation}
+ setTransformation={onChangeTransformation}
+ />
+ )}
+
+ {plugin === Plugins.Jenkins && (
+ <JenkinsTransformation
+ transformation={transformation}
+ setTransformation={onChangeTransformation}
+ />
+ )}
+ <div className='action'>
+ <ButtonGroup>
+ <Button
+ disabled={operating}
+ outlined
+ text='Cancel'
+ onClick={() => history.push('/transformations')}
+ />
+ <Button
+ disabled={!name}
+ loading={operating}
+ outlined
+ intent={Intent.PRIMARY}
+ text='Save'
+ onClick={onSave}
+ />
+ </ButtonGroup>
+ </div>
+ </Card>
+ </S.Wrapper>
+ </PageHeader>
+ )
+}
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/pages/transformation/detail/styled.ts
similarity index 73%
copy from config-ui/src/plugins/gitlab/transformation.tsx
copy to config-ui/src/pages/transformation/detail/styled.ts
index 6f9402e83..6942ebbae 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/pages/transformation/detail/styled.ts
@@ -16,19 +16,26 @@
*
*/
-import React from 'react'
+import styled from 'styled-components'
-import { CiCd } from './components'
+export const Wrapper = styled.div`
+ .card + .card {
+ margin-top: 32px;
+ }
-interface Props {
- transformation: any
- setTransformation: React.Dispatch<React.SetStateAction<any>>
-}
+ .name {
+ h3 {
+ margin: 0 0 8px;
+ }
-export const GitLabTransformation = ({ ...props }: Props) => {
- return (
- <>
- <CiCd {...props} />
- </>
- )
-}
+ p {
+ margin: 0 0 8px;
+ }
+ }
+
+ .action {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 16px;
+ }
+`
diff --git a/config-ui/src/pages/transformation/detail/use-detail.ts
b/config-ui/src/pages/transformation/detail/use-detail.ts
new file mode 100644
index 000000000..8e8cc1ae2
--- /dev/null
+++ b/config-ui/src/pages/transformation/detail/use-detail.ts
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { useState, useEffect, useMemo } from 'react'
+import { useHistory } from 'react-router-dom'
+
+import { Plugins, PluginConfig } from '@/plugins'
+import { operator } from '@/utils'
+
+import * as API from './api'
+
+interface Props {
+ plugin: Plugins
+ id?: ID
+}
+
+export const useDetail = ({ plugin, id }: Props) => {
+ const [loading, setLoading] = useState(false)
+ const [operating, setOperating] = useState(false)
+ const [name, setName] = useState('')
+ const [transformation, setTransformation] = useState<any>(
+ PluginConfig.find((pc) => pc.plugin === plugin)?.transformation
+ )
+
+ const history = useHistory()
+
+ const getTransformation = async () => {
+ if (!id) return
+ setLoading(true)
+ try {
+ const res = await API.getTransformation(plugin, id)
+ setName(res.name)
+ setTransformation(res)
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ useEffect(() => {
+ getTransformation()
+ }, [])
+
+ const handleSave = async () => {
+ const payload = {
+ ...transformation,
+ name
+ }
+
+ const [success] = await operator(
+ () =>
+ id
+ ? API.updateTransformation(plugin, id, payload)
+ : API.createTransformation(plugin, payload),
+ {
+ setOperating
+ }
+ )
+
+ if (success) {
+ history.push('/transformations')
+ }
+ }
+
+ return useMemo(
+ () => ({
+ loading,
+ operating,
+ name,
+ transformation,
+ onChangeName: setName,
+ onChangeTransformation: setTransformation,
+ onSave: handleSave
+ }),
+ [loading, operating, name, transformation]
+ )
+}
diff --git a/config-ui/src/pages/transformation/home/index.tsx
b/config-ui/src/pages/transformation/home/index.tsx
new file mode 100644
index 000000000..899a83c21
--- /dev/null
+++ b/config-ui/src/pages/transformation/home/index.tsx
@@ -0,0 +1,157 @@
+/*
+ * 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, useMemo } from 'react'
+import { useHistory } from 'react-router-dom'
+import { ButtonGroup, Button, Icon, Intent } from '@blueprintjs/core'
+
+import { PageHeader, Table, ColumnType, Dialog, Selector } from '@/components'
+import type { PluginConfigType } from '@/plugins'
+import { Plugins } from '@/plugins'
+import {
+ TransformationContextProvider,
+ TransformationContextConsumer,
+ TransformationItemType
+} from '@/store'
+
+import * as S from './styled'
+
+export const TransformationHomePage = () => {
+ const [active, setActive] = useState('All')
+ const [isOpen, setIsOpen] = useState(false)
+ const [selectedPlugin, setSelectedPlugin] = useState<PluginConfigType>()
+
+ const history = useHistory()
+
+ const columns = useMemo(
+ () =>
+ [
+ {
+ title: 'Name',
+ dataIndex: 'name',
+ key: 'name'
+ },
+ {
+ title: 'Data Source',
+ dataIndex: 'plugin',
+ key: 'plugin'
+ },
+ {
+ title: '',
+ key: 'action',
+ align: 'center',
+ render: (_, row) =>
+ row.plugin !== Plugins.JIRA && (
+ <Button
+ minimal
+ intent={Intent.PRIMARY}
+ icon='cog'
+ onClick={() =>
+ history.push(`/transformations/${row.plugin}/${row.id}`)
+ }
+ />
+ )
+ }
+ ] as ColumnType<TransformationItemType>,
+ []
+ )
+
+ return (
+ <TransformationContextProvider>
+ <TransformationContextConsumer>
+ {({ plugins, transformations }) => (
+ <PageHeader
+ breadcrumbs={[
+ { name: 'Transformations', path: '/transformations' }
+ ]}
+ >
+ <S.Wrapper>
+ <div className='action'>
+ <ButtonGroup>
+ <Button
+ intent={active === 'All' ? Intent.PRIMARY : Intent.NONE}
+ text='All'
+ onClick={() => setActive('All')}
+ />
+ {plugins.map((p) => (
+ <Button
+ key={p.plugin}
+ intent={
+ active === p.plugin ? Intent.PRIMARY : Intent.NONE
+ }
+ text={p.name}
+ onClick={() => setActive(p.plugin)}
+ />
+ ))}
+ </ButtonGroup>
+ <Button
+ intent={Intent.PRIMARY}
+ text='Create Transfromation'
+ onClick={() => setIsOpen(true)}
+ />
+ </div>
+ <Table
+ columns={columns}
+ dataSource={transformations.filter((ts) =>
+ active === 'All' ? true : ts.plugin === active
+ )}
+ />
+ <Dialog
+ isOpen={isOpen}
+ title='Select a Data Source'
+ okText='Continue'
+ okDisabled={
+ !selectedPlugin || selectedPlugin.plugin === Plugins.JIRA
+ }
+ onOk={() =>
+ history.push(
+ `/transformations/${selectedPlugin?.plugin}/create`
+ )
+ }
+ onCancel={() => setIsOpen(false)}
+ >
+ <S.DialogWrapper>
+ <p>Select from the supported data sources</p>
+ <Selector
+ items={plugins}
+ getKey={(it) => it.plugin}
+ getName={(it) => it.name}
+ selectedItem={selectedPlugin}
+ onChangeItem={(selectedItem) =>
+ setSelectedPlugin(selectedItem)
+ }
+ />
+ {selectedPlugin?.plugin === Plugins.JIRA && (
+ <div className='warning'>
+ <Icon icon='error' />
+ <span>
+ Because Jira transformation is specific to every Jira
+ connection, you can only add a Transformation in
+ Blueprints.
+ </span>
+ </div>
+ )}
+ </S.DialogWrapper>
+ </Dialog>
+ </S.Wrapper>
+ </PageHeader>
+ )}
+ </TransformationContextConsumer>
+ </TransformationContextProvider>
+ )
+}
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/pages/transformation/home/styled.ts
similarity index 66%
copy from config-ui/src/plugins/gitlab/transformation.tsx
copy to config-ui/src/pages/transformation/home/styled.ts
index 6f9402e83..74e40e624 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/pages/transformation/home/styled.ts
@@ -16,19 +16,25 @@
*
*/
-import React from 'react'
+import { Colors } from '@blueprintjs/core'
+import styled from 'styled-components'
-import { CiCd } from './components'
+export const Wrapper = styled.div`
+ .action {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16px;
+ }
+`
-interface Props {
- transformation: any
- setTransformation: React.Dispatch<React.SetStateAction<any>>
-}
+export const DialogWrapper = styled.div`
+ .warning {
+ margin-top: 16px;
-export const GitLabTransformation = ({ ...props }: Props) => {
- return (
- <>
- <CiCd {...props} />
- </>
- )
-}
+ .bp4-icon {
+ color: ${Colors.ORANGE3};
+ margin-right: 4px;
+ }
+ }
+`
diff --git a/config-ui/src/store/index.ts
b/config-ui/src/pages/transformation/index.ts
similarity index 93%
copy from config-ui/src/store/index.ts
copy to config-ui/src/pages/transformation/index.ts
index 6199fc0b7..188478fcd 100644
--- a/config-ui/src/store/index.ts
+++ b/config-ui/src/pages/transformation/index.ts
@@ -16,5 +16,5 @@
*
*/
-export * from './connections'
-export * from './version'
+export * from './home'
+export * from './detail'
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/plugins/github/styled.ts
similarity index 69%
copy from config-ui/src/plugins/gitlab/transformation.tsx
copy to config-ui/src/plugins/github/styled.ts
index 6f9402e83..6da07d584 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/plugins/github/styled.ts
@@ -16,19 +16,31 @@
*
*/
-import React from 'react'
+import styled from 'styled-components'
-import { CiCd } from './components'
+export const TransformationWrapper = styled.div`
+ h3 {
+ margin: 0 0 8px;
-interface Props {
- transformation: any
- setTransformation: React.Dispatch<React.SetStateAction<any>>
-}
+ .bp4-tag {
+ margin-left: 6px;
+ }
+ }
-export const GitLabTransformation = ({ ...props }: Props) => {
- return (
- <>
- <CiCd {...props} />
- </>
- )
-}
+ p {
+ margin: 0 0 8px;
+ }
+
+ .bp4-form-group {
+ display: flex;
+ align-items: center;
+
+ .bp4-label {
+ flex: 0 0 150px;
+ }
+
+ .bp4-form-content {
+ flex: auto;
+ }
+ }
+`
diff --git a/config-ui/src/plugins/github/transformation.tsx
b/config-ui/src/plugins/github/transformation.tsx
index e3c64cf35..e2c5cb60e 100644
--- a/config-ui/src/plugins/github/transformation.tsx
+++ b/config-ui/src/plugins/github/transformation.tsx
@@ -20,6 +20,8 @@ import React from 'react'
import { Divider } from '@/components'
+import * as S from './styled'
+
import {
IssueTracking,
CiCd,
@@ -34,13 +36,13 @@ interface Props {
export const GitHubTransformation = ({ ...props }: Props) => {
return (
- <>
+ <S.TransformationWrapper>
<IssueTracking {...props} />
<Divider />
<CiCd {...props} />
<Divider />
<CodeReview {...props} />
<AdditionalSettings {...props} />
- </>
+ </S.TransformationWrapper>
)
}
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/plugins/gitlab/styled.ts
similarity index 69%
copy from config-ui/src/plugins/gitlab/transformation.tsx
copy to config-ui/src/plugins/gitlab/styled.ts
index 6f9402e83..6da07d584 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/plugins/gitlab/styled.ts
@@ -16,19 +16,31 @@
*
*/
-import React from 'react'
+import styled from 'styled-components'
-import { CiCd } from './components'
+export const TransformationWrapper = styled.div`
+ h3 {
+ margin: 0 0 8px;
-interface Props {
- transformation: any
- setTransformation: React.Dispatch<React.SetStateAction<any>>
-}
+ .bp4-tag {
+ margin-left: 6px;
+ }
+ }
-export const GitLabTransformation = ({ ...props }: Props) => {
- return (
- <>
- <CiCd {...props} />
- </>
- )
-}
+ p {
+ margin: 0 0 8px;
+ }
+
+ .bp4-form-group {
+ display: flex;
+ align-items: center;
+
+ .bp4-label {
+ flex: 0 0 150px;
+ }
+
+ .bp4-form-content {
+ flex: auto;
+ }
+ }
+`
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/plugins/gitlab/transformation.tsx
index 6f9402e83..58a2192be 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/plugins/gitlab/transformation.tsx
@@ -19,6 +19,7 @@
import React from 'react'
import { CiCd } from './components'
+import * as S from './styled'
interface Props {
transformation: any
@@ -27,8 +28,8 @@ interface Props {
export const GitLabTransformation = ({ ...props }: Props) => {
return (
- <>
+ <S.TransformationWrapper>
<CiCd {...props} />
- </>
+ </S.TransformationWrapper>
)
}
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/plugins/jenkins/styled.ts
similarity index 69%
copy from config-ui/src/plugins/gitlab/transformation.tsx
copy to config-ui/src/plugins/jenkins/styled.ts
index 6f9402e83..6da07d584 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/plugins/jenkins/styled.ts
@@ -16,19 +16,31 @@
*
*/
-import React from 'react'
+import styled from 'styled-components'
-import { CiCd } from './components'
+export const TransformationWrapper = styled.div`
+ h3 {
+ margin: 0 0 8px;
-interface Props {
- transformation: any
- setTransformation: React.Dispatch<React.SetStateAction<any>>
-}
+ .bp4-tag {
+ margin-left: 6px;
+ }
+ }
-export const GitLabTransformation = ({ ...props }: Props) => {
- return (
- <>
- <CiCd {...props} />
- </>
- )
-}
+ p {
+ margin: 0 0 8px;
+ }
+
+ .bp4-form-group {
+ display: flex;
+ align-items: center;
+
+ .bp4-label {
+ flex: 0 0 150px;
+ }
+
+ .bp4-form-content {
+ flex: auto;
+ }
+ }
+`
diff --git a/config-ui/src/plugins/jenkins/transformation.tsx
b/config-ui/src/plugins/jenkins/transformation.tsx
index d4b518de7..fc21a3c23 100644
--- a/config-ui/src/plugins/jenkins/transformation.tsx
+++ b/config-ui/src/plugins/jenkins/transformation.tsx
@@ -19,6 +19,7 @@
import React from 'react'
import { CiCd } from './components'
+import * as S from './styled'
interface Props {
transformation: any
@@ -27,8 +28,8 @@ interface Props {
export const JenkinsTransformation = ({ ...props }: Props) => {
return (
- <>
+ <S.TransformationWrapper>
<CiCd {...props} />
- </>
+ </S.TransformationWrapper>
)
}
diff --git a/config-ui/src/plugins/gitlab/transformation.tsx
b/config-ui/src/plugins/jira/styled.ts
similarity index 69%
copy from config-ui/src/plugins/gitlab/transformation.tsx
copy to config-ui/src/plugins/jira/styled.ts
index 6f9402e83..6da07d584 100644
--- a/config-ui/src/plugins/gitlab/transformation.tsx
+++ b/config-ui/src/plugins/jira/styled.ts
@@ -16,19 +16,31 @@
*
*/
-import React from 'react'
+import styled from 'styled-components'
-import { CiCd } from './components'
+export const TransformationWrapper = styled.div`
+ h3 {
+ margin: 0 0 8px;
-interface Props {
- transformation: any
- setTransformation: React.Dispatch<React.SetStateAction<any>>
-}
+ .bp4-tag {
+ margin-left: 6px;
+ }
+ }
-export const GitLabTransformation = ({ ...props }: Props) => {
- return (
- <>
- <CiCd {...props} />
- </>
- )
-}
+ p {
+ margin: 0 0 8px;
+ }
+
+ .bp4-form-group {
+ display: flex;
+ align-items: center;
+
+ .bp4-label {
+ flex: 0 0 150px;
+ }
+
+ .bp4-form-content {
+ flex: auto;
+ }
+ }
+`
diff --git a/config-ui/src/plugins/jira/transformation.tsx
b/config-ui/src/plugins/jira/transformation.tsx
index 81ef46788..28ee7a419 100644
--- a/config-ui/src/plugins/jira/transformation.tsx
+++ b/config-ui/src/plugins/jira/transformation.tsx
@@ -21,6 +21,7 @@ import React from 'react'
import { Divider } from '@/components'
import { IssueTracking, AdditionalSettings } from './components'
+import * as S from './styled'
interface Props {
connectionId: ID
@@ -30,10 +31,10 @@ interface Props {
export const JIRATransformation = ({ ...props }: Props) => {
return (
- <>
+ <S.TransformationWrapper>
<IssueTracking {...props} />
<Divider />
<AdditionalSettings {...props} />
- </>
+ </S.TransformationWrapper>
)
}
diff --git a/config-ui/src/store/index.ts b/config-ui/src/store/index.ts
index 6199fc0b7..04cd72183 100644
--- a/config-ui/src/store/index.ts
+++ b/config-ui/src/store/index.ts
@@ -16,5 +16,6 @@
*
*/
-export * from './connections'
export * from './version'
+export * from './connections'
+export * from './transformations'
diff --git a/config-ui/src/pages/index.ts
b/config-ui/src/store/transformations/api.ts
similarity index 80%
copy from config-ui/src/pages/index.ts
copy to config-ui/src/store/transformations/api.ts
index 405539b29..86d4a44d7 100644
--- a/config-ui/src/pages/index.ts
+++ b/config-ui/src/store/transformations/api.ts
@@ -16,7 +16,9 @@
*
*/
-export * from './project'
-export * from './connection'
-export * from './blueprint'
-export * from './pipeline'
+import request from '@/components/utils/request'
+
+import { Plugins } from '@/plugins'
+
+export const getTransformation = (plugin: Plugins) =>
+ request(`/plugins/${plugin}/transformation_rules`)
diff --git a/config-ui/src/store/transformations/context.tsx
b/config-ui/src/store/transformations/context.tsx
new file mode 100644
index 000000000..1fe494e1c
--- /dev/null
+++ b/config-ui/src/store/transformations/context.tsx
@@ -0,0 +1,61 @@
+/*
+ * 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, { useContext } from 'react'
+
+import { PageLoading } from '@/components'
+import type { PluginConfigType } from '@/plugins'
+import { Plugins } from '@/plugins'
+
+import type { TransformationItemType } from './types'
+import { useContextValue } from './use-context-value'
+
+const TransformationContext = React.createContext<{
+ plugins: PluginConfigType[]
+ transformations: TransformationItemType[]
+}>({
+ plugins: [],
+ transformations: []
+})
+
+interface Props {
+ children?: React.ReactNode
+}
+
+export const TransformationContextProvider = ({ children }: Props) => {
+ const { loading, plugins, transformations } = useContextValue()
+
+ if (loading) {
+ return <PageLoading />
+ }
+
+ return (
+ <TransformationContext.Provider
+ value={{
+ plugins,
+ transformations
+ }}
+ >
+ {children}
+ </TransformationContext.Provider>
+ )
+}
+
+export const TransformationContextConsumer = TransformationContext.Consumer
+
+export const useTransformation = () => useContext(TransformationContext)
diff --git a/config-ui/src/store/index.ts
b/config-ui/src/store/transformations/index.ts
similarity index 93%
copy from config-ui/src/store/index.ts
copy to config-ui/src/store/transformations/index.ts
index 6199fc0b7..5f25db57c 100644
--- a/config-ui/src/store/index.ts
+++ b/config-ui/src/store/transformations/index.ts
@@ -16,5 +16,5 @@
*
*/
-export * from './connections'
-export * from './version'
+export * from './types'
+export * from './context'
diff --git a/config-ui/src/pages/index.ts
b/config-ui/src/store/transformations/types.ts
similarity index 87%
copy from config-ui/src/pages/index.ts
copy to config-ui/src/store/transformations/types.ts
index 405539b29..62b600c89 100644
--- a/config-ui/src/pages/index.ts
+++ b/config-ui/src/store/transformations/types.ts
@@ -16,7 +16,10 @@
*
*/
-export * from './project'
-export * from './connection'
-export * from './blueprint'
-export * from './pipeline'
+import { Plugins } from '@/plugins'
+
+export type TransformationItemType = {
+ id: ID
+ name: string
+ plugin: Plugins
+}
diff --git a/config-ui/src/store/transformations/use-context-value.ts
b/config-ui/src/store/transformations/use-context-value.ts
new file mode 100644
index 000000000..5c4411dbe
--- /dev/null
+++ b/config-ui/src/store/transformations/use-context-value.ts
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { useState, useEffect, useCallback, useMemo } from 'react'
+
+import { PluginConfig, PluginType, Plugins } from '@/plugins'
+
+import type { TransformationItemType } from './types'
+import * as API from './api'
+
+export const useContextValue = () => {
+ const [loading, setLoading] = useState(false)
+ const [transformations, setTransformations] = useState<
+ TransformationItemType[]
+ >([])
+
+ const allConnections = useMemo(
+ () => PluginConfig.filter((p) => p.type === PluginType.Connection),
+ []
+ )
+
+ const getTransformation = async (plugin: Plugins) => {
+ try {
+ return await API.getTransformation(plugin)
+ } catch {
+ return []
+ }
+ }
+
+ const handleRefresh = useCallback(async () => {
+ setLoading(true)
+
+ const res = await Promise.all(
+ allConnections.map((cs) => getTransformation(cs.plugin))
+ )
+
+ const resWithPlugin = res.map((ts, i) =>
+ ts.map((it: any) => {
+ const { plugin } = allConnections[i]
+
+ return {
+ ...it,
+ plugin
+ }
+ })
+ )
+
+ setTransformations(resWithPlugin.flat())
+ setLoading(false)
+ }, [allConnections])
+
+ useEffect(() => {
+ handleRefresh()
+ }, [])
+
+ return useMemo(
+ () => ({
+ loading,
+ plugins: allConnections,
+ transformations
+ }),
+ [loading, allConnections, transformations]
+ )
+}