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 8f1606eda refactor(config-ui): use remote api to replace the gitlab 
proxy interface (#4386)
8f1606eda is described below

commit 8f1606eda9fd10151a196e5f3fc4222b9410eabb
Author: 青湛 <[email protected]>
AuthorDate: Wed Feb 15 14:56:28 2023 +0700

    refactor(config-ui): use remote api to replace the gitlab proxy interface 
(#4386)
    
    * feat(config-ui): add data-scope-miller-columns component for plugin
    
    * feat(config-ui): add data-scope-search component for plugin
    
    * refactor(config-ui): use remote api to replace the gitlab proxy interface
    
    * fix(config-ui): data scope search items error from interface
    
    * feat(config-ui): add props title for data scope miller columns
    
    * fix(config-ui): some bugs for data scope miller columns and search
---
 .../data-scope-miller-columns/api.ts}              |  17 +-
 .../components/data-scope-miller-columns/index.tsx | 116 +++++++++++
 .../data-scope-miller-columns}/styled.ts           |   0
 .../data-scope-miller-columns/types.ts}            |  11 +-
 .../data-scope-search/api.ts}                      |  18 +-
 .../plugins/components/data-scope-search/index.tsx |  78 ++++++++
 .../data-scope-search/types.ts}                    |   8 +-
 config-ui/src/plugins/components/index.ts          |   2 +
 .../plugins/register/gitlab/components/index.ts    |   2 -
 .../gitlab/components/miller-columns/index.tsx     |  97 ----------
 .../miller-columns/use-miller-columns.ts           | 212 ---------------------
 .../gitlab/components/project-selector/index.tsx   |  61 ------
 .../project-selector/use-project-selector.ts       |  89 ---------
 .../src/plugins/register/gitlab/data-scope.tsx     |  30 ++-
 14 files changed, 251 insertions(+), 490 deletions(-)

diff --git 
a/config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts 
b/config-ui/src/plugins/components/data-scope-miller-columns/api.ts
similarity index 73%
copy from 
config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts
copy to config-ui/src/plugins/components/data-scope-miller-columns/api.ts
index 65d52ef76..8ffd85952 100644
--- 
a/config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts
+++ b/config-ui/src/plugins/components/data-scope-miller-columns/api.ts
@@ -16,10 +16,15 @@
  *
  */
 
-import styled from 'styled-components';
+import { request } from '@/utils';
 
-export const Container = styled.div`
-  .checkbox {
-    margin: 8px 0 0;
-  }
-`;
+type Params = {
+  groupId: ID | null;
+  pageToken?: string;
+};
+
+export const getScope = (plugin: string, connectionId: ID, params: Params) =>
+  request(`/plugins/${plugin}/connections/${connectionId}/remote-scopes`, {
+    method: 'get',
+    data: params,
+  });
diff --git 
a/config-ui/src/plugins/components/data-scope-miller-columns/index.tsx 
b/config-ui/src/plugins/components/data-scope-miller-columns/index.tsx
new file mode 100644
index 000000000..85fc31ccf
--- /dev/null
+++ b/config-ui/src/plugins/components/data-scope-miller-columns/index.tsx
@@ -0,0 +1,116 @@
+/*
+ * 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 type { McsID, McsItem, McsColumn } from 'miller-columns-select';
+import MillerColumnsSelect from 'miller-columns-select';
+
+import { Loading } from '@/components';
+
+import type { ExtraType } from './types';
+import * as API from './api';
+import * as S from './styled';
+
+interface Props {
+  title?: string;
+  plugin: string;
+  connectionId: ID;
+  selectedItems?: McsItem<ExtraType>[];
+  onChangeItems?: (selectedItems: any) => void;
+}
+
+export const DataScopeMillerColumns = ({ title, plugin, connectionId, 
selectedItems, onChangeItems }: Props) => {
+  const [items, setItems] = useState<McsItem<ExtraType>[]>([]);
+  const [selectedIds, setSelectedIds] = useState<ID[]>([]);
+  const [loadedIds, setLoadedIds] = useState<ID[]>([]);
+  const [nextTokenMap, setNextTokenMap] = useState<Record<ID, string>>({});
+
+  useEffect(() => {
+    setSelectedIds((selectedItems ?? []).map((it: any) => it.id));
+  }, [selectedItems]);
+
+  const getItems = async (groupId: ID | null, pageToken?: string) => {
+    const res = await API.getScope(plugin, connectionId, {
+      groupId,
+      pageToken,
+    });
+
+    setItems([
+      ...items,
+      ...(res.children ?? []).map((it: any) => ({
+        ...it,
+        title: it.name,
+      })),
+    ]);
+
+    if (!res.nextPageToken) {
+      setLoadedIds([...loadedIds, groupId ? groupId : 'root']);
+    } else {
+      setNextTokenMap({
+        ...nextTokenMap,
+        [`${groupId ? groupId : 'root'}`]: res.nextPageToken,
+      });
+    }
+  };
+
+  useEffect(() => {
+    getItems(null);
+  }, []);
+
+  const handleChangeItems = (selectedIds: ID[]) => {
+    const result = selectedIds.map((id) => {
+      const selectedItem = (selectedItems ?? []).find((it) => it.id === id);
+      if (selectedItem) {
+        return selectedItem.data;
+      }
+
+      const item = items.find((it) => it.id === id) as McsItem<ExtraType>;
+      return item.data;
+    });
+
+    onChangeItems ? onChangeItems(result) : setSelectedIds(selectedIds);
+  };
+
+  const handleExpand = (id: McsID) => getItems(id, nextTokenMap[id]);
+
+  const handleScroll = (id: McsID | null) => getItems(id, nextTokenMap[id ?? 
'root']);
+
+  const renderTitle = (column: McsColumn) => {
+    return !column.parentId && <S.ColumnTitle>{title}</S.ColumnTitle>;
+  };
+
+  const renderLoading = () => {
+    return <Loading size={20} style={{ padding: '4px 12px' }} />;
+  };
+
+  return (
+    <MillerColumnsSelect
+      items={items}
+      getCanExpand={(it) => it.type === 'group'}
+      getHasMore={(id) => !loadedIds.includes(id ?? 'root')}
+      onExpand={handleExpand}
+      onScroll={handleScroll}
+      columnCount={2.5}
+      columnHeight={300}
+      renderTitle={renderTitle}
+      renderLoading={renderLoading}
+      selectedIds={selectedIds}
+      onSelectItemIds={handleChangeItems}
+    />
+  );
+};
diff --git 
a/config-ui/src/plugins/register/gitlab/components/miller-columns/styled.ts 
b/config-ui/src/plugins/components/data-scope-miller-columns/styled.ts
similarity index 100%
rename from 
config-ui/src/plugins/register/gitlab/components/miller-columns/styled.ts
rename to config-ui/src/plugins/components/data-scope-miller-columns/styled.ts
diff --git 
a/config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts 
b/config-ui/src/plugins/components/data-scope-miller-columns/types.ts
similarity index 87%
copy from 
config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts
copy to config-ui/src/plugins/components/data-scope-miller-columns/types.ts
index 65d52ef76..e8b87419d 100644
--- 
a/config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts
+++ b/config-ui/src/plugins/components/data-scope-miller-columns/types.ts
@@ -16,10 +16,7 @@
  *
  */
 
-import styled from 'styled-components';
-
-export const Container = styled.div`
-  .checkbox {
-    margin: 8px 0 0;
-  }
-`;
+export type ExtraType = {
+  type: 'group' | 'scope';
+  data: any;
+};
diff --git 
a/config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts 
b/config-ui/src/plugins/components/data-scope-search/api.ts
similarity index 71%
rename from 
config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts
rename to config-ui/src/plugins/components/data-scope-search/api.ts
index 65d52ef76..e1e7e74a4 100644
--- 
a/config-ui/src/plugins/register/gitlab/components/project-selector/styled.ts
+++ b/config-ui/src/plugins/components/data-scope-search/api.ts
@@ -16,10 +16,16 @@
  *
  */
 
-import styled from 'styled-components';
+import { request } from '@/utils';
 
-export const Container = styled.div`
-  .checkbox {
-    margin: 8px 0 0;
-  }
-`;
+type Params = {
+  search?: string;
+  page?: number;
+  pageSize?: number;
+};
+
+export const searchScope = (plugin: string, connectionId: ID, params: Params) 
=>
+  
request(`/plugins/${plugin}/connections/${connectionId}/search-remote-scopes`, {
+    method: 'get',
+    data: params,
+  });
diff --git a/config-ui/src/plugins/components/data-scope-search/index.tsx 
b/config-ui/src/plugins/components/data-scope-search/index.tsx
new file mode 100644
index 000000000..62fa91254
--- /dev/null
+++ b/config-ui/src/plugins/components/data-scope-search/index.tsx
@@ -0,0 +1,78 @@
+/*
+ * 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 { MultiSelector } from '@/components';
+
+import type { ItemType } from './types';
+import * as API from './api';
+
+interface Props {
+  plugin: string;
+  connectionId: ID;
+  selectedItems?: ItemType[];
+  onChangeItems?: (selectedItems: any) => void;
+}
+
+export const DataScopeSearch = ({ plugin, connectionId, selectedItems, 
onChangeItems }: Props) => {
+  const [loading, setLoading] = useState(false);
+  const [items, setItems] = useState<ItemType[]>([]);
+  const [search, setSearch] = useState('');
+
+  useEffect(() => {
+    if (!search) return;
+    setItems([]);
+    setLoading(true);
+
+    const timer = setTimeout(async () => {
+      try {
+        const res = await API.searchScope(plugin, connectionId, {
+          search,
+          page: 1,
+          pageSize: 50,
+        });
+        setItems(res.children ?? []);
+      } finally {
+        setLoading(false);
+      }
+    }, 1000);
+
+    return () => clearTimeout(timer);
+  }, [search]);
+
+  const getKey = (it: ItemType) => it.id;
+
+  const getName = (it: ItemType) => it.name;
+
+  const handleChangeItems = (selectedItems: ItemType[]) => 
onChangeItems?.(selectedItems.map((it) => it.data));
+
+  return (
+    <MultiSelector
+      placeholder="Search Repositories..."
+      items={items}
+      getKey={getKey}
+      getName={getName}
+      selectedItems={selectedItems}
+      onChangeItems={handleChangeItems}
+      loading={loading}
+      noResult="No Repositories Available."
+      onQueryChange={(s) => setSearch(s)}
+    />
+  );
+};
diff --git a/config-ui/src/plugins/register/gitlab/components/index.ts 
b/config-ui/src/plugins/components/data-scope-search/types.ts
similarity index 89%
copy from config-ui/src/plugins/register/gitlab/components/index.ts
copy to config-ui/src/plugins/components/data-scope-search/types.ts
index 92108cfde..42d7a30a8 100644
--- a/config-ui/src/plugins/register/gitlab/components/index.ts
+++ b/config-ui/src/plugins/components/data-scope-search/types.ts
@@ -16,6 +16,8 @@
  *
  */
 
-export * from './miller-columns';
-export * from './project-selector';
-export * from './ci-cd';
+export type ItemType = {
+  id: ID;
+  name: string;
+  data: any;
+};
diff --git a/config-ui/src/plugins/components/index.ts 
b/config-ui/src/plugins/components/index.ts
index e0d0014d6..b98f87654 100644
--- a/config-ui/src/plugins/components/index.ts
+++ b/config-ui/src/plugins/components/index.ts
@@ -19,4 +19,6 @@
 export * from './connection-form';
 export * from './data-scope-list';
 export * from './data-scope';
+export * from './data-scope-miller-columns';
+export * from './data-scope-search';
 export * from './transformation';
diff --git a/config-ui/src/plugins/register/gitlab/components/index.ts 
b/config-ui/src/plugins/register/gitlab/components/index.ts
index 92108cfde..a8a5796be 100644
--- a/config-ui/src/plugins/register/gitlab/components/index.ts
+++ b/config-ui/src/plugins/register/gitlab/components/index.ts
@@ -16,6 +16,4 @@
  *
  */
 
-export * from './miller-columns';
-export * from './project-selector';
 export * from './ci-cd';
diff --git 
a/config-ui/src/plugins/register/gitlab/components/miller-columns/index.tsx 
b/config-ui/src/plugins/register/gitlab/components/miller-columns/index.tsx
deleted file mode 100644
index 68974626b..000000000
--- a/config-ui/src/plugins/register/gitlab/components/miller-columns/index.tsx
+++ /dev/null
@@ -1,97 +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, { useEffect, useState } from 'react';
-import type { McsItem, McsColumn } from 'miller-columns-select';
-import MillerColumnsSelect from 'miller-columns-select';
-
-import { Loading } from '@/components';
-
-import type { ScopeItemType } from '../../types';
-
-import type { UseMillerColumnsProps, ExtraType } from './use-miller-columns';
-import { useMillerColumns } from './use-miller-columns';
-import * as S from './styled';
-
-interface Props extends UseMillerColumnsProps {
-  selectedItems: ScopeItemType[];
-  onChangeItems: (selectedItems: ScopeItemType[]) => void;
-}
-
-export const MillerColumns = ({ connectionId, selectedItems, onChangeItems }: 
Props) => {
-  const [selectedIds, setSelectedIds] = useState<ID[]>([]);
-
-  const { items, getHasMore, onExpand, onScroll } = useMillerColumns({
-    connectionId,
-  });
-
-  useEffect(() => {
-    setSelectedIds(selectedItems.map((it) => it.gitlabId));
-  }, [selectedItems]);
-
-  const handleChangeItems = (selectedIds: ID[]) => {
-    const result = selectedIds.map((id) => {
-      const selectedItem = selectedItems.find((it) => it.gitlabId === id);
-      if (selectedItem) {
-        return selectedItem;
-      }
-
-      const item = items.find((it) => it.id === id) as McsItem<ExtraType>;
-      return {
-        connectionId,
-        gitlabId: item.id,
-        name: item.name,
-        pathWithNamespace: item.pathWithNamespace,
-        creatorId: item.creatorId,
-        defaultBranch: item.defaultBranch,
-        description: item.description,
-        openIssuesCount: item.openIssuesCount,
-        starCount: item.starCount,
-        visibility: item.visibility,
-        webUrl: item.webUrl,
-        httpUrlToRepo: item.httpUrlToRepo,
-      };
-    });
-
-    onChangeItems(result);
-  };
-
-  const renderTitle = (column: McsColumn) => {
-    return !column.parentId && 
<S.ColumnTitle>Subgroups/Projects</S.ColumnTitle>;
-  };
-
-  const renderLoading = () => {
-    return <Loading size={20} style={{ padding: '4px 12px' }} />;
-  };
-
-  return (
-    <MillerColumnsSelect
-      items={items}
-      getCanExpand={(it) => it.type === 'group'}
-      getHasMore={getHasMore}
-      onExpand={onExpand}
-      onScroll={onScroll}
-      columnCount={2.5}
-      columnHeight={300}
-      renderTitle={renderTitle}
-      renderLoading={renderLoading}
-      selectedIds={selectedIds}
-      onSelectItemIds={handleChangeItems}
-    />
-  );
-};
diff --git 
a/config-ui/src/plugins/register/gitlab/components/miller-columns/use-miller-columns.ts
 
b/config-ui/src/plugins/register/gitlab/components/miller-columns/use-miller-columns.ts
deleted file mode 100644
index 8fe436ebf..000000000
--- 
a/config-ui/src/plugins/register/gitlab/components/miller-columns/use-miller-columns.ts
+++ /dev/null
@@ -1,212 +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 { useState, useEffect, useMemo } from 'react';
-import { McsID, McsItem } from 'miller-columns-select';
-
-import { useProxyPrefix } from '@/hooks';
-
-import type { ScopeItemType } from '../../types';
-import * as API from '../../api';
-
-const DEFAULT_PAGE_SIZE = 20;
-
-export type ExtraType = {
-  type: 'group' | 'project';
-} & ScopeItemType;
-
-type MapValueType = {
-  groupPage: number;
-  groupLoaded: boolean;
-  projectPage: number;
-  projectLoaded: boolean;
-};
-
-type MapType = Record<ID, MapValueType>;
-
-export interface UseMillerColumnsProps {
-  connectionId: ID;
-}
-
-export const useMillerColumns = ({ connectionId }: UseMillerColumnsProps) => {
-  const [user, setUser] = useState<any>({});
-  const [items, setItems] = useState<McsItem<ExtraType>[]>([]);
-  const [map, setMap] = useState<MapType>({});
-
-  const prefix = useProxyPrefix({
-    plugin: 'gitlab',
-    connectionId,
-  });
-
-  const formatGroups = (arr: any, parentId: ID | null = null): 
McsItem<ExtraType>[] =>
-    arr.map((it: any) => ({
-      parentId,
-      id: it.id,
-      title: it.name,
-      type: 'group',
-    }));
-
-  const formatProjects = (arr: any, parentId: ID | null = null): 
McsItem<ExtraType>[] =>
-    arr.map((it: any) => ({
-      parentId,
-      id: it.id,
-      title: it.name,
-      type: 'project',
-      gitlabId: it.id,
-      name: it.path_with_namespace,
-      pathWithNamespace: it.path_with_namespace,
-      creatorId: it.creator_id,
-      defaultBranch: it.default_branch,
-      description: it.description,
-      openIssuesCount: it.open_issues_count,
-      starCount: it.star_count,
-      visibility: it.visibility,
-      webUrl: it.web_url,
-      httpUrlToRepo: it.http_url_to_repo,
-    }));
-
-  const setLoaded = (id: ID, params: MapValueType) => {
-    setMap({
-      ...map,
-      [`${id}`]: params,
-    });
-  };
-
-  useEffect(() => {
-    (async () => {
-      const user = await API.getUser(prefix);
-      setUser(user);
-
-      let groupLoaded = false;
-      let projectLoaded = false;
-      let groups = [];
-      let projects = [];
-
-      groups = await API.getUserGroups(prefix, {
-        page: 1,
-        per_page: DEFAULT_PAGE_SIZE,
-      });
-
-      groupLoaded = !groups.length || groups.length < DEFAULT_PAGE_SIZE;
-
-      if (groupLoaded) {
-        projects = await API.getUserProjects(prefix, user.id, {
-          page: 1,
-          per_page: DEFAULT_PAGE_SIZE,
-        });
-
-        projectLoaded = !projects.length || projects.length < 
DEFAULT_PAGE_SIZE;
-      }
-
-      setLoaded('root', {
-        groupLoaded,
-        groupPage: groupLoaded ? 1 : 2,
-        projectLoaded,
-        projectPage: projectLoaded ? 1 : 2,
-      });
-      setItems([...formatGroups(groups), ...formatProjects(projects)]);
-    })();
-  }, [prefix]);
-
-  const onExpand = async (id: McsID) => {
-    let groupLoaded = false;
-    let projectLoaded = false;
-    let groups = [];
-    let projects = [];
-
-    groups = await API.getGroupSubgroups(prefix, id, {
-      page: 1,
-      per_page: DEFAULT_PAGE_SIZE,
-    });
-
-    groupLoaded = !groups.length || groups.length < DEFAULT_PAGE_SIZE;
-
-    if (groupLoaded) {
-      projects = await API.getGroupProjects(prefix, id, {
-        page: 1,
-        per_page: DEFAULT_PAGE_SIZE,
-      });
-
-      projectLoaded = !projects.length || projects.length < DEFAULT_PAGE_SIZE;
-    }
-
-    setLoaded(id, {
-      groupLoaded,
-      groupPage: groupLoaded ? 1 : 2,
-      projectLoaded,
-      projectPage: projectLoaded ? 1 : 2,
-    });
-    setItems([...items, ...formatGroups(groups, id), 
...formatProjects(projects, id)]);
-  };
-
-  const onScroll = async (id: McsID | null) => {
-    const mapValue = map[id ?? 'root'];
-
-    let groupLoaded = mapValue.groupLoaded;
-    let projectLoaded = mapValue.projectLoaded;
-    let groups = [];
-    let projects = [];
-
-    if (!groupLoaded) {
-      groups = id
-        ? await API.getGroupSubgroups(prefix, id, {
-            page: mapValue.groupPage,
-            per_page: DEFAULT_PAGE_SIZE,
-          })
-        : await API.getUserGroups(prefix, {
-            page: mapValue.groupPage,
-            per_page: DEFAULT_PAGE_SIZE,
-          });
-
-      groupLoaded = !groups.length || groups.length < DEFAULT_PAGE_SIZE;
-    } else if (!projectLoaded) {
-      projects = id
-        ? await API.getGroupProjects(prefix, id, {
-            page: mapValue.projectPage,
-            per_page: DEFAULT_PAGE_SIZE,
-          })
-        : await API.getUserProjects(prefix, user.id, {
-            page: mapValue.projectPage,
-            per_page: DEFAULT_PAGE_SIZE,
-          });
-
-      projectLoaded = !projects.length || projects.length < DEFAULT_PAGE_SIZE;
-    }
-
-    setLoaded(id ?? 'root', {
-      groupLoaded,
-      groupPage: groupLoaded ? mapValue.groupPage : mapValue.groupPage + 1,
-      projectLoaded,
-      projectPage: projectLoaded ? mapValue.projectPage : mapValue.projectPage 
+ 1,
-    });
-    setItems([...items, ...formatGroups(groups, id), 
...formatProjects(projects, id)]);
-  };
-
-  return useMemo(
-    () => ({
-      items,
-      getHasMore(id: McsID | null) {
-        const mapValue = map[id ?? 'root'];
-        return !(mapValue?.groupLoaded && mapValue?.projectLoaded);
-      },
-      onExpand,
-      onScroll,
-    }),
-    [items, map],
-  );
-};
diff --git 
a/config-ui/src/plugins/register/gitlab/components/project-selector/index.tsx 
b/config-ui/src/plugins/register/gitlab/components/project-selector/index.tsx
deleted file mode 100644
index 93ecdfa1e..000000000
--- 
a/config-ui/src/plugins/register/gitlab/components/project-selector/index.tsx
+++ /dev/null
@@ -1,61 +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 from 'react';
-import { Checkbox } from '@blueprintjs/core';
-
-import { MultiSelector } from '@/components';
-
-import type { ScopeItemType } from '../../types';
-
-import type { UseProjectSelectorProps } from './use-project-selector';
-import { useProjectSelector } from './use-project-selector';
-import * as S from './styled';
-
-interface Props extends UseProjectSelectorProps {
-  selectedItems: ScopeItemType[];
-  onChangeItems: (selectedItems: ScopeItemType[]) => void;
-}
-
-export const ProjectSelector = ({ connectionId, selectedItems, onChangeItems 
}: Props) => {
-  const { loading, items, membership, onSearch, onChangeMembership } = 
useProjectSelector({
-    connectionId,
-  });
-
-  return (
-    <S.Container>
-      <MultiSelector
-        placeholder="Select Projects..."
-        items={items}
-        getKey={(it) => `${it.gitlabId}`}
-        getName={(it) => it.name}
-        selectedItems={selectedItems}
-        onChangeItems={onChangeItems}
-        loading={loading}
-        noResult="No Projects Available."
-        onQueryChange={onSearch}
-      />
-      <Checkbox
-        className="checkbox"
-        label="Only search my repositories"
-        checked={membership}
-        onChange={onChangeMembership}
-      />
-    </S.Container>
-  );
-};
diff --git 
a/config-ui/src/plugins/register/gitlab/components/project-selector/use-project-selector.ts
 
b/config-ui/src/plugins/register/gitlab/components/project-selector/use-project-selector.ts
deleted file mode 100644
index adcae293c..000000000
--- 
a/config-ui/src/plugins/register/gitlab/components/project-selector/use-project-selector.ts
+++ /dev/null
@@ -1,89 +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 { useState, useEffect, useMemo } from 'react';
-
-import { useProxyPrefix } from '@/hooks';
-
-import type { ScopeItemType } from '../../types';
-import * as API from '../../api';
-
-export interface UseProjectSelectorProps {
-  connectionId: ID;
-}
-
-export const useProjectSelector = ({ connectionId }: UseProjectSelectorProps) 
=> {
-  const [loading, setLoading] = useState(false);
-  const [items, setItems] = useState<ScopeItemType[]>([]);
-  const [search, setSearch] = useState('');
-  const [membership, setMembership] = useState(true);
-
-  const prefix = useProxyPrefix({
-    plugin: 'gitlab',
-    connectionId,
-  });
-
-  useEffect(() => {
-    if (!search) return;
-    setItems([]);
-    setLoading(true);
-
-    const timer = setTimeout(async () => {
-      try {
-        const res = await API.searchProject(prefix, {
-          search,
-          membership,
-        });
-        setItems(
-          res.map((it: any) => ({
-            gitlabId: it.id,
-            name: it.path_with_namespace,
-            pathWithNamespace: it.path_with_namespace,
-            creatorId: it.creator_id,
-            defaultBranch: it.default_branch,
-            description: it.description,
-            openIssuesCount: it.open_issues_count,
-            starCount: it.star_count,
-            visibility: it.visibility,
-            webUrl: it.web_url,
-            httpUrlToRepo: it.http_url_to_repo,
-          })),
-        );
-      } finally {
-        setLoading(false);
-      }
-    }, 1000);
-
-    return () => clearTimeout(timer);
-  }, [prefix, search, membership]);
-
-  return useMemo(
-    () => ({
-      loading,
-      items,
-      membership,
-      onSearch(s: string) {
-        setSearch(s);
-      },
-      onChangeMembership(e: React.ChangeEvent<HTMLInputElement>) {
-        setMembership(e.target.checked);
-      },
-    }),
-    [loading, items, membership],
-  );
-};
diff --git a/config-ui/src/plugins/register/gitlab/data-scope.tsx 
b/config-ui/src/plugins/register/gitlab/data-scope.tsx
index 081f7b1cd..c7f46e11e 100644
--- a/config-ui/src/plugins/register/gitlab/data-scope.tsx
+++ b/config-ui/src/plugins/register/gitlab/data-scope.tsx
@@ -16,11 +16,11 @@
  *
  */
 
-import React from 'react';
+import React, { useMemo } from 'react';
 
-import type { ScopeItemType } from './types';
+import { DataScopeMillerColumns, DataScopeSearch } from '@/plugins';
 
-import { MillerColumns, ProjectSelector } from './components';
+import type { ScopeItemType } from './types';
 
 interface Props {
   connectionId: ID;
@@ -28,15 +28,31 @@ interface Props {
   onChangeItems: (selectedItems: ScopeItemType[]) => void;
 }
 
-export const GitLabDataScope = ({ connectionId, selectedItems, onChangeItems 
}: Props) => {
+export const GitLabDataScope = ({ connectionId, onChangeItems, ...props }: 
Props) => {
+  const selectedItems = useMemo(
+    () => props.selectedItems.map((it) => ({ id: `${it.gitlabId}`, name: 
it.name, data: it })),
+    [props.selectedItems],
+  );
+
   return (
     <>
       <h4>Projects *</h4>
       <p>Select the project you would like to sync.</p>
-      <MillerColumns connectionId={connectionId} selectedItems={selectedItems} 
onChangeItems={onChangeItems} />
-      <h5>Add repositories outside of your projects</h5>
+      <DataScopeMillerColumns
+        title="Subgroups/Projects"
+        plugin="gitlab"
+        connectionId={connectionId}
+        selectedItems={selectedItems}
+        onChangeItems={onChangeItems}
+      />
+      <h4>Add repositories outside of your projects</h4>
       <p>Search for repositories and add to them</p>
-      <ProjectSelector connectionId={connectionId} 
selectedItems={selectedItems} onChangeItems={onChangeItems} />
+      <DataScopeSearch
+        plugin="gitlab"
+        connectionId={connectionId}
+        selectedItems={selectedItems}
+        onChangeItems={onChangeItems}
+      />
     </>
   );
 };

Reply via email to