You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by li...@apache.org on 2022/11/18 07:39:29 UTC

[incubator-devlake] branch main updated: feat(config-ui): jenkins select job to support miller-columns component (#3755)

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 2ddf42dfe feat(config-ui): jenkins select job to support miller-columns component (#3755)
2ddf42dfe is described below

commit 2ddf42dfea869b983d77c364a33601b62efed974
Author: 青湛 <0x...@gmail.com>
AuthorDate: Fri Nov 18 15:39:25 2022 +0800

    feat(config-ui): jenkins select job to support miller-columns component (#3755)
    
    * feat(config-ui): jenkins select job to support miller-columns component
    
    * fix(config-ui): custom miller-columns will exceed the container
    
    * fix(config-ui): jenkins onExpandItem not return
    
    * feat(config-ui): adjust the jenkins job entity
---
 .../components/blueprints/StandardStackedList.jsx  |   2 +
 .../blueprints/create-workflow/DataScopes.jsx      |  39 +++++---
 .../src/components/github/miller-columns/index.tsx |  28 +++---
 .../src/components/gitlab/miller-columns/index.tsx |  28 +++---
 config-ui/src/components/jenkins/config.ts         |  20 ++++
 config-ui/src/components/jenkins/index.ts          |  19 ++++
 .../{github => jenkins}/miller-columns/index.tsx   |  59 +++++------
 .../miller-columns/use-jenkins-miller-columns.ts   | 111 +++++++++++++++++++++
 .../src/components/jira/miller-columns/index.tsx   |  24 +++--
 config-ui/src/models/JenkinsJob.js                 |   4 +-
 10 files changed, 254 insertions(+), 80 deletions(-)

diff --git a/config-ui/src/components/blueprints/StandardStackedList.jsx b/config-ui/src/components/blueprints/StandardStackedList.jsx
index 771f45a94..f3c3c4d31 100644
--- a/config-ui/src/components/blueprints/StandardStackedList.jsx
+++ b/config-ui/src/components/blueprints/StandardStackedList.jsx
@@ -94,6 +94,8 @@ const StandardStackedList = (props) => {
                   >
                     {item.shortTitle || item.title}
                   </Popover>
+                ) : item.providerId === 'jenkins' ? (
+                  `${item.jobPath}${item.title}`
                 ) : (
                   item.title
                 )}
diff --git a/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx b/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
index 7fb6f901e..9d09f81d7 100644
--- a/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
+++ b/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
@@ -36,7 +36,9 @@ import { JIRAMillerColumns } from '@/components/jira'
 import JiraBoard from '@/models/JiraBoard'
 import { GitHubMillerColumns } from '@/components/github'
 import GitHubProject from '@/models/GithubProject'
+import { JenkinsMillerColumns } from '@/components/jenkins'
 import JenkinsJobsSelector from '@/components/blueprints/JenkinsJobsSelector'
+import JenkinsJob from '@/models/JenkinsJob'
 
 const DataScopes = (props) => {
   const {
@@ -319,19 +321,30 @@ const DataScopes = (props) => {
                   ) && (
                     <>
                       <h4>Jobs *</h4>
-                      <p>Select the job you would like to sync.</p>
-                      <JenkinsJobsSelector
-                        onFetch={fetchJenkinsJobs}
-                        isFetching={isFetchingJenkins}
-                        items={jenkinsJobs}
-                        selectedItems={selectedScopeEntities}
-                        onItemSelect={setScopeEntities}
-                        onClear={setScopeEntities}
-                        onRemove={setScopeEntities}
-                        disabled={isSaving}
-                        configuredConnection={configuredConnection}
-                        isLoading={isFetching}
-                      />
+                      <p>Select the jobs you would like to sync.</p>
+                      {!activeStep ? (
+                        <JenkinsJobsSelector
+                          onFetch={fetchJenkinsJobs}
+                          isFetching={isFetchingJenkins}
+                          items={jenkinsJobs}
+                          selectedItems={selectedScopeEntities}
+                          onItemSelect={setScopeEntities}
+                          onClear={setScopeEntities}
+                          onRemove={setScopeEntities}
+                          disabled={isSaving}
+                          configuredConnection={configuredConnection}
+                          isLoading={isFetching}
+                        />
+                      ) : (
+                        <JenkinsMillerColumns
+                          connectionId={configuredConnection.connectionId}
+                          onChangeItems={(items) =>
+                            setScopeEntities(
+                              items.map((it) => new JenkinsJob(it))
+                            )
+                          }
+                        />
+                      )}
                     </>
                   )}
 
diff --git a/config-ui/src/components/github/miller-columns/index.tsx b/config-ui/src/components/github/miller-columns/index.tsx
index 9690ce643..14341b50e 100644
--- a/config-ui/src/components/github/miller-columns/index.tsx
+++ b/config-ui/src/components/github/miller-columns/index.tsx
@@ -57,18 +57,20 @@ export const GitHubMillerColumns = ({ connectionId, onChangeItems }: Props) => {
   }, [seletedIds])
 
   return (
-    <MillerColumns
-      height={300}
-      columnCount={2}
-      firstColumnTitle='Organizations/Owners'
-      items={items}
-      selectedItemIds={seletedIds}
-      onSelectedItemIds={setSelectedIds}
-      onExpandItem={onExpandItem}
-      scrollProps={{
-        hasMore,
-        onScroll
-      }}
-    />
+    <div style={{ width: 450 }}>
+      <MillerColumns
+        height={300}
+        columnCount={2}
+        firstColumnTitle='Organizations/Owners'
+        items={items}
+        selectedItemIds={seletedIds}
+        onSelectedItemIds={setSelectedIds}
+        onExpandItem={onExpandItem}
+        scrollProps={{
+          hasMore,
+          onScroll
+        }}
+      />
+    </div>
   )
 }
diff --git a/config-ui/src/components/gitlab/miller-columns/index.tsx b/config-ui/src/components/gitlab/miller-columns/index.tsx
index a3242ab39..0548424d4 100644
--- a/config-ui/src/components/gitlab/miller-columns/index.tsx
+++ b/config-ui/src/components/gitlab/miller-columns/index.tsx
@@ -48,18 +48,20 @@ export const GitLabMillerColumns = ({
   }, [seletedIds])
 
   return (
-    <MillerColumns
-      height={300}
-      firstColumnTitle='Subgroups/Projects'
-      items={items}
-      disabledItemIds={disabledItemIds}
-      selectedItemIds={seletedIds}
-      onSelectedItemIds={setSelectedIds}
-      onExpandItem={onExpandItem}
-      scrollProps={{
-        hasMore,
-        onScroll
-      }}
-    />
+    <div style={{ width: 450 }}>
+      <MillerColumns
+        height={300}
+        firstColumnTitle='Subgroups/Projects'
+        items={items}
+        disabledItemIds={disabledItemIds}
+        selectedItemIds={seletedIds}
+        onSelectedItemIds={setSelectedIds}
+        onExpandItem={onExpandItem}
+        scrollProps={{
+          hasMore,
+          onScroll
+        }}
+      />
+    </div>
   )
 }
diff --git a/config-ui/src/components/jenkins/config.ts b/config-ui/src/components/jenkins/config.ts
new file mode 100644
index 000000000..245f74f84
--- /dev/null
+++ b/config-ui/src/components/jenkins/config.ts
@@ -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.
+ *
+ */
+
+export const getJenkinsProxyApiPrefix = (connectionId: string) =>
+  `/plugins/jenkins/connections/${connectionId}/proxy/rest`
diff --git a/config-ui/src/components/jenkins/index.ts b/config-ui/src/components/jenkins/index.ts
new file mode 100644
index 000000000..1c06557ce
--- /dev/null
+++ b/config-ui/src/components/jenkins/index.ts
@@ -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.
+ *
+ */
+
+export * from './miller-columns'
diff --git a/config-ui/src/components/github/miller-columns/index.tsx b/config-ui/src/components/jenkins/miller-columns/index.tsx
similarity index 60%
copy from config-ui/src/components/github/miller-columns/index.tsx
copy to config-ui/src/components/jenkins/miller-columns/index.tsx
index 9690ce643..1923dea7e 100644
--- a/config-ui/src/components/github/miller-columns/index.tsx
+++ b/config-ui/src/components/jenkins/miller-columns/index.tsx
@@ -22,18 +22,21 @@ import { ItemType, ItemTypeEnum } from '@/components/miller-columns'
 import { MillerColumns } from '@/components/miller-columns'
 
 import {
-  useGitHubMillerColumns,
-  UseGitHubMillerColumnsProps
-} from './use-github-miller-columns'
+  useJenkinsMillerColumns,
+  UseJenkinsMillerColumnsProps
+} from './use-jenkins-miller-columns'
 
-interface Props extends UseGitHubMillerColumnsProps {
+interface Props extends UseJenkinsMillerColumnsProps {
   onChangeItems: (items: Array<Pick<ItemType, 'id' | 'title'>>) => void
 }
 
-export const GitHubMillerColumns = ({ connectionId, onChangeItems }: Props) => {
+export const JenkinsMillerColumns = ({
+  connectionId,
+  onChangeItems
+}: Props) => {
   const [seletedIds, setSelectedIds] = useState<Array<ItemType['id']>>([])
 
-  const { items, onExpandItem, hasMore, onScroll } = useGitHubMillerColumns({
+  const { items, onExpandItem, hasMore } = useJenkinsMillerColumns({
     connectionId
   })
 
@@ -43,32 +46,30 @@ export const GitHubMillerColumns = ({ connectionId, onChangeItems }: Props) => {
         .filter(
           (it) => seletedIds.includes(it.id) && it.type !== ItemTypeEnum.BRANCH
         )
-        .map((it: any) => {
-          return {
-            id: it.id,
-            title: `${it.owner}/${it.repo}`,
-            owner: it.owner,
-            repo: it.repo,
-            value: `${it.owner}/${it.repo}`,
-            type: 'miller-columns'
-          }
-        })
+        .map((it: any) => ({
+          id: it.id,
+          key: it.id,
+          title: it.title,
+          value: it.title,
+          jobPath: it.jobPath || null
+        }))
     )
   }, [seletedIds])
 
   return (
-    <MillerColumns
-      height={300}
-      columnCount={2}
-      firstColumnTitle='Organizations/Owners'
-      items={items}
-      selectedItemIds={seletedIds}
-      onSelectedItemIds={setSelectedIds}
-      onExpandItem={onExpandItem}
-      scrollProps={{
-        hasMore,
-        onScroll
-      }}
-    />
+    <div style={{ width: 450 }}>
+      <MillerColumns
+        height={300}
+        columnCount={2}
+        items={items}
+        selectedItemIds={seletedIds}
+        onSelectedItemIds={setSelectedIds}
+        onExpandItem={onExpandItem}
+        scrollProps={{
+          hasMore,
+          onScroll: () => {}
+        }}
+      />
+    </div>
   )
 }
diff --git a/config-ui/src/components/jenkins/miller-columns/use-jenkins-miller-columns.ts b/config-ui/src/components/jenkins/miller-columns/use-jenkins-miller-columns.ts
new file mode 100644
index 000000000..7ba1ce9a2
--- /dev/null
+++ b/config-ui/src/components/jenkins/miller-columns/use-jenkins-miller-columns.ts
@@ -0,0 +1,111 @@
+/*
+ * 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 type { MillerColumnsItem } from '@/components/miller-columns'
+import { ItemTypeEnum, ItemStatusEnum } from '@/components/miller-columns'
+import request from '@/components/utils/request'
+
+import { getJenkinsProxyApiPrefix } from '../config'
+
+export interface UseJenkinsMillerColumnsProps {
+  connectionId: string
+}
+
+export const useJenkinsMillerColumns = ({
+  connectionId
+}: UseJenkinsMillerColumnsProps) => {
+  const [items, setItems] = useState<Array<MillerColumnsItem>>([])
+  const [hasMore, setHasMore] = useState(true)
+
+  const prefix = useMemo(
+    () => getJenkinsProxyApiPrefix(connectionId),
+    [connectionId]
+  )
+
+  useEffect(() => {
+    ;(async () => {
+      const res = await request(
+        `${prefix}/api/json?tree=jobs[name,jobs]{0,10000}`
+      )
+      setHasMore(false)
+      setItems(
+        res.jobs.map((it: any) => ({
+          parentId: null,
+          id: it.name,
+          title: it.name,
+          type: it.jobs ? ItemTypeEnum.BRANCH : ItemTypeEnum.LEAF,
+          status: it.jobs ? ItemStatusEnum.PENDING : ItemStatusEnum.READY
+        }))
+      )
+    })()
+  }, [prefix])
+
+  const getJobs = (
+    item?: MillerColumnsItem
+  ): Array<MillerColumnsItem['id']> => {
+    let result = []
+
+    if (item) {
+      result.push(item.id)
+      result.unshift(...getJobs(items.find((it) => it.id === item.parentId)))
+    }
+    return result
+  }
+
+  const onExpandItem = async (item: MillerColumnsItem) => {
+    if (item.status === ItemStatusEnum.READY) {
+      return
+    }
+
+    const jobs = getJobs(item)
+    const res = await request(
+      `${prefix}/job/${jobs.join(
+        '/job/'
+      )}/api/json?tree=jobs[name,jobs]{0,10000}`
+    )
+    setItems([
+      ...items.map((it) =>
+        it.id !== item.id
+          ? it
+          : {
+              ...it,
+              status: ItemStatusEnum.READY
+            }
+      ),
+      ...res.jobs.map((it: any) => ({
+        parentId: item.id,
+        id: it.name,
+        title: it.name,
+        type: it.jobs ? ItemTypeEnum.BRANCH : ItemTypeEnum.LEAF,
+        status: it.jobs ? ItemStatusEnum.PENDING : ItemStatusEnum.READY,
+        jobPath: `${jobs.join('/')}/`
+      }))
+    ])
+  }
+
+  return useMemo(
+    () => ({
+      items,
+      onExpandItem,
+      hasMore
+    }),
+    [items]
+  )
+}
diff --git a/config-ui/src/components/jira/miller-columns/index.tsx b/config-ui/src/components/jira/miller-columns/index.tsx
index c2adb1d40..9bac19a4d 100644
--- a/config-ui/src/components/jira/miller-columns/index.tsx
+++ b/config-ui/src/components/jira/miller-columns/index.tsx
@@ -47,16 +47,18 @@ export const JIRAMillerColumns = ({ connectionId, onChangeItems }: Props) => {
   }, [seletedIds])
 
   return (
-    <MillerColumns
-      height={300}
-      columnCount={1}
-      items={items}
-      selectedItemIds={seletedIds}
-      onSelectedItemIds={setSelectedIds}
-      scrollProps={{
-        hasMore,
-        onScroll
-      }}
-    />
+    <div style={{ width: 450 }}>
+      <MillerColumns
+        height={300}
+        columnCount={1}
+        items={items}
+        selectedItemIds={seletedIds}
+        onSelectedItemIds={setSelectedIds}
+        scrollProps={{
+          hasMore,
+          onScroll
+        }}
+      />
+    </div>
   )
 }
diff --git a/config-ui/src/models/JenkinsJob.js b/config-ui/src/models/JenkinsJob.js
index bbf0340e6..3c0770df6 100644
--- a/config-ui/src/models/JenkinsJob.js
+++ b/config-ui/src/models/JenkinsJob.js
@@ -38,6 +38,7 @@ class JenkinsJob extends Entity {
     this.name = data?.name || null
     this.value = data?.value || this.name || this.id || null
     this.title = data?.title || this.name || this.id || null
+    this.jobPath = data?.jobPath || ''
 
     this.useApi = data?.useApi || true
     this.variant = data?.variant || 'job'
@@ -50,7 +51,8 @@ class JenkinsJob extends Entity {
 
   getTransformationScopeOptions() {
     return {
-      jobName: this.value
+      jobName: this.value,
+      jobPath: this.jobPath
     }
   }
 }