This is an automated email from the ASF dual-hosted git repository.
klesh 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 3e77dd5da fix(config-ui): switch data scope lost data (#6085)
3e77dd5da is described below
commit 3e77dd5da8da19ff0f98811549a16366b4525baa
Author: 青湛 <[email protected]>
AuthorDate: Fri Sep 15 16:32:52 2023 +1200
fix(config-ui): switch data scope lost data (#6085)
* refactor(config-ui): remove data scope search
* fix(config-ui): switch data scope lost data
---
.../plugins/components/data-scope-search/api.ts | 31 ------
.../plugins/components/data-scope-search/index.tsx | 70 ------------
.../plugins/components/data-scope-search/types.ts | 24 -----
.../components/data-scope-select-remote/api.ts | 2 +-
.../components/data-scope-select-remote/index.tsx | 120 ++++++++++++---------
config-ui/src/plugins/components/index.ts | 1 -
6 files changed, 71 insertions(+), 177 deletions(-)
diff --git a/config-ui/src/plugins/components/data-scope-search/api.ts
b/config-ui/src/plugins/components/data-scope-search/api.ts
deleted file mode 100644
index e1e7e74a4..000000000
--- a/config-ui/src/plugins/components/data-scope-search/api.ts
+++ /dev/null
@@ -1,31 +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 { request } from '@/utils';
-
-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
deleted file mode 100644
index 5ab73d613..000000000
--- a/config-ui/src/plugins/components/data-scope-search/index.tsx
+++ /dev/null
@@ -1,70 +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 } from 'react';
-import { useDebounce } from 'ahooks';
-
-import { MultiSelector } from '@/components';
-import { useRefreshData } from '@/hooks';
-
-import type { ItemType } from './types';
-import * as API from './api';
-
-interface Props {
- plugin: string;
- connectionId: ID;
- disabledItems?: any[];
- selectedItems?: any[];
- onChangeItems?: (selectedItems: any[]) => void;
-}
-
-export const DataScopeSearch = ({ plugin, connectionId, disabledItems,
selectedItems, onChangeItems }: Props) => {
- const [query, setQuery] = useState('');
-
- const search = useDebounce(query, { wait: 500 });
-
- const { ready, data } = useRefreshData<{ children: ItemType[] }>(async () =>
{
- if (!search) return { children: [] };
- return API.searchScope(plugin, connectionId, {
- search,
- page: 1,
- pageSize: 50,
- });
- }, [search]);
-
- const getKey = (it: ItemType) => it.id;
-
- const getName = (it: ItemType) => it.fullName;
-
- const handleChangeItems = (selectedItems: ItemType[]) =>
onChangeItems?.(selectedItems);
-
- return (
- <MultiSelector
- placeholder="Search Repositories..."
- items={data?.children ?? []}
- getKey={getKey}
- getName={getName}
- disabledItems={disabledItems}
- selectedItems={selectedItems}
- onChangeItems={handleChangeItems}
- loading={!ready}
- noResult="No Repositories Available."
- onQueryChange={(query) => setQuery(query)}
- />
- );
-};
diff --git a/config-ui/src/plugins/components/data-scope-search/types.ts
b/config-ui/src/plugins/components/data-scope-search/types.ts
deleted file mode 100644
index c3f6318a3..000000000
--- a/config-ui/src/plugins/components/data-scope-search/types.ts
+++ /dev/null
@@ -1,24 +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.
- *
- */
-
-export type ItemType = {
- id: ID;
- name: string;
- fullName: string;
- data: any;
-};
diff --git a/config-ui/src/plugins/components/data-scope-select-remote/api.ts
b/config-ui/src/plugins/components/data-scope-select-remote/api.ts
index fab503b8e..4c042d6b6 100644
--- a/config-ui/src/plugins/components/data-scope-select-remote/api.ts
+++ b/config-ui/src/plugins/components/data-scope-select-remote/api.ts
@@ -34,7 +34,7 @@ export const searchRemoteScope = (
plugin: string,
connectionId: ID,
params: T.SearchRemoteScopeParams,
-): Promise<{ children: T.ResItem[] }> =>
+): Promise<{ children: T.ResItem[]; count: number }> =>
request(`/plugins/${plugin}/connections/${connectionId}/search-remote-scopes`, {
method: 'get',
data: params,
diff --git
a/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
b/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
index 262756381..5be9d3fd4 100644
--- a/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
+++ b/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
@@ -105,20 +105,31 @@ const SelectRemote = ({
selectedScope: any[];
onChangeSelectedScope: (selectedScope: any[]) => void;
}) => {
- // miller columns
- const [items, setItems] = useState<McsItem<T.ResItem>[]>([]);
- const [loadedIds, setLoadedIds] = useState<ID[]>([]);
- const [nextTokenMap, setNextTokenMap] = useState<Record<ID, string>>({});
-
- // search
- const [query, setQuery] = useState('');
- const [items2, setItems2] = useState<McsItem<T.ResItem>[]>([]);
- const [page, setPage] = useState(1);
- const [total] = useState(0);
-
- const search = useDebounce(query, { wait: 500 });
-
- const allItems = useMemo(() => uniqBy([...items, ...items2], 'id'), [items,
items2]);
+ const [miller, setMiller] = useState<{
+ items: McsItem<T.ResItem>[];
+ loadedIds: ID[];
+ nextTokenMap: Record<ID, string>;
+ }>({
+ items: [],
+ loadedIds: [],
+ nextTokenMap: {},
+ });
+
+ const [search, setSearch] = useState<{
+ items: McsItem<T.ResItem>[];
+ query: string;
+ page: number;
+ total: number;
+ }>({
+ items: [],
+ query: '',
+ page: 1,
+ total: 0,
+ });
+
+ const searchDebounce = useDebounce(search.query, { wait: 500 });
+
+ const allItems = useMemo(() => uniqBy([...miller.items, ...search.items],
'id'), [miller.items, search.items]);
const getItems = async (groupId: ID | null, currentPageToken?: string) => {
const res = await API.getRemoteScope(plugin, connectionId, {
@@ -126,21 +137,26 @@ const SelectRemote = ({
pageToken: currentPageToken,
});
- setItems([
- ...items,
- ...(res.children ?? []).map((it: any) => ({
- ...it,
- title: it.name,
- })),
- ]);
-
- if (!res.nextPageToken) {
- setLoadedIds([...loadedIds, groupId ? groupId : 'root']);
+ const newItems = (res.children ?? []).map((it) => ({
+ ...it,
+ title: it.name,
+ }));
+
+ if (res.nextPageToken) {
+ setMiller((m) => ({
+ ...m,
+ items: [...m.items, ...newItems],
+ nextTokenMap: {
+ ...m.nextTokenMap,
+ [`${groupId ? groupId : 'root'}`]: res.nextPageToken,
+ },
+ }));
} else {
- setNextTokenMap({
- ...nextTokenMap,
- [`${groupId ? groupId : 'root'}`]: res.nextPageToken,
- });
+ setMiller((m) => ({
+ ...m,
+ items: [...m.items, ...newItems],
+ loadedIds: [...m.loadedIds, groupId ?? 'root'],
+ }));
}
};
@@ -149,29 +165,29 @@ const SelectRemote = ({
}, []);
const searchItems = async () => {
- if (!search) return;
+ if (!searchDebounce) return;
const res = await API.searchRemoteScope(plugin, connectionId, {
- search,
- page,
+ search: searchDebounce,
+ page: search.page,
pageSize: 50,
});
- setItems2(
- res.children.map((it) => ({
- ...it,
- title: it.fullName,
- })),
- );
+ const newItems = (res.children ?? []).map((it) => ({
+ ...it,
+ title: it.name,
+ }));
- if (page === 1) {
- // setTotal(res.count);
- }
+ setSearch((s) => ({
+ ...s,
+ items: [...s.items, ...newItems],
+ total: res.count,
+ }));
};
useEffect(() => {
searchItems();
- }, [search, page]);
+ }, [searchDebounce, search.page]);
return (
<S.Wrapper>
@@ -185,16 +201,20 @@ const SelectRemote = ({
/>
</FormItem>
<FormItem>
- <InputGroup leftIcon="search" value={query} onChange={(e) =>
setQuery(e.target.value)} />
- {!search ? (
+ <InputGroup
+ leftIcon="search"
+ value={search.query}
+ onChange={(e) => setSearch({ ...search, query: e.target.value })}
+ />
+ {!searchDebounce ? (
<MillerColumnsSelect
- items={items}
+ items={miller.items}
columnCount={config.millerColumnCount ?? 1}
columnHeight={300}
getCanExpand={(it) => it.type === 'group'}
- getHasMore={(id) => !loadedIds.includes(id ?? 'root')}
- onExpand={(id: McsID) => getItems(id, nextTokenMap[id])}
- onScroll={(id: McsID | null) => getItems(id, nextTokenMap[id ??
'root'])}
+ getHasMore={(id) => !miller.loadedIds.includes(id ?? 'root')}
+ onExpand={(id: McsID) => getItems(id, miller.nextTokenMap[id])}
+ onScroll={(id: McsID | null) => getItems(id,
miller.nextTokenMap[id ?? 'root'])}
renderTitle={(column: McsColumn) =>
!column.parentId && config.millerFirstTitle &&
<S.ColumnTitle>{config.millerFirstTitle}</S.ColumnTitle>
}
@@ -207,12 +227,12 @@ const SelectRemote = ({
/>
) : (
<MillerColumnsSelect
- items={items2}
+ items={search.items}
columnCount={1}
columnHeight={300}
getCanExpand={() => false}
- getHasMore={() => total === 0}
- onScroll={() => setPage(page + 1)}
+ getHasMore={() => search.total === 0}
+ onScroll={() => setSearch({ ...search, page: search.page + 1 })}
renderLoading={() => <Loading size={20} style={{ padding: '4px
12px' }} />}
disabledIds={(disabledScope ?? []).map((it) =>
getPluginScopeId(plugin, it))}
selectedIds={selectedScope.map((it) => it.id)}
diff --git a/config-ui/src/plugins/components/index.ts
b/config-ui/src/plugins/components/index.ts
index 03f86c5a9..9f3e71026 100644
--- a/config-ui/src/plugins/components/index.ts
+++ b/config-ui/src/plugins/components/index.ts
@@ -19,7 +19,6 @@
export * from './connection-form';
export * from './connection-list';
export * from './connection-status';
-export * from './data-scope-search';
export * from './data-scope-select';
export * from './data-scope-select-remote';
export * from './scope-config-form';