Kevin Hu commited on
Commit
52b2996
·
1 Parent(s): 1bf9501

Revert "Feat: Scrolling knowledge base list #3695" (#3708)

Browse files
api/apps/kb_app.py CHANGED
@@ -125,16 +125,15 @@ def detail():
125
  @manager.route('/list', methods=['GET'])
126
  @login_required
127
  def list_kbs():
128
- keywords = request.args.get("keywords", "")
129
  page_number = int(request.args.get("page", 1))
130
  items_per_page = int(request.args.get("page_size", 150))
131
  orderby = request.args.get("orderby", "create_time")
132
  desc = request.args.get("desc", True)
133
  try:
134
  tenants = TenantService.get_joined_tenants_by_user_id(current_user.id)
135
- kbs, total = KnowledgebaseService.get_by_tenant_ids(
136
- [m["tenant_id"] for m in tenants], current_user.id, page_number, items_per_page, orderby, desc, keywords)
137
- return get_json_result(data={"kbs": kbs, "total": total})
138
  except Exception as e:
139
  return server_error_response(e)
140
 
 
125
  @manager.route('/list', methods=['GET'])
126
  @login_required
127
  def list_kbs():
 
128
  page_number = int(request.args.get("page", 1))
129
  items_per_page = int(request.args.get("page_size", 150))
130
  orderby = request.args.get("orderby", "create_time")
131
  desc = request.args.get("desc", True)
132
  try:
133
  tenants = TenantService.get_joined_tenants_by_user_id(current_user.id)
134
+ kbs = KnowledgebaseService.get_by_tenant_ids(
135
+ [m["tenant_id"] for m in tenants], current_user.id, page_number, items_per_page, orderby, desc)
136
+ return get_json_result(data=kbs)
137
  except Exception as e:
138
  return server_error_response(e)
139
 
api/db/services/knowledgebase_service.py CHANGED
@@ -34,7 +34,7 @@ class KnowledgebaseService(CommonService):
34
  @classmethod
35
  @DB.connection_context()
36
  def get_by_tenant_ids(cls, joined_tenant_ids, user_id,
37
- page_number, items_per_page, orderby, desc, keywords):
38
  fields = [
39
  cls.model.id,
40
  cls.model.avatar,
@@ -51,31 +51,20 @@ class KnowledgebaseService(CommonService):
51
  User.avatar.alias('tenant_avatar'),
52
  cls.model.update_time
53
  ]
54
- if keywords:
55
- kbs = cls.model.select(*fields).join(User, on=(cls.model.tenant_id == User.id)).where(
56
- ((cls.model.tenant_id.in_(joined_tenant_ids) & (cls.model.permission ==
57
- TenantPermission.TEAM.value)) | (
58
- cls.model.tenant_id == user_id))
59
- & (cls.model.status == StatusEnum.VALID.value),
60
- (fn.LOWER(cls.model.name).contains(keywords.lower()))
61
- )
62
- else:
63
- kbs = cls.model.select(*fields).join(User, on=(cls.model.tenant_id == User.id)).where(
64
- ((cls.model.tenant_id.in_(joined_tenant_ids) & (cls.model.permission ==
65
- TenantPermission.TEAM.value)) | (
66
- cls.model.tenant_id == user_id))
67
- & (cls.model.status == StatusEnum.VALID.value)
68
- )
69
  if desc:
70
  kbs = kbs.order_by(cls.model.getter_by(orderby).desc())
71
  else:
72
  kbs = kbs.order_by(cls.model.getter_by(orderby).asc())
73
 
74
- count = kbs.count()
75
-
76
  kbs = kbs.paginate(page_number, items_per_page)
77
 
78
- return list(kbs.dicts()), count
79
 
80
  @classmethod
81
  @DB.connection_context()
 
34
  @classmethod
35
  @DB.connection_context()
36
  def get_by_tenant_ids(cls, joined_tenant_ids, user_id,
37
+ page_number, items_per_page, orderby, desc):
38
  fields = [
39
  cls.model.id,
40
  cls.model.avatar,
 
51
  User.avatar.alias('tenant_avatar'),
52
  cls.model.update_time
53
  ]
54
+ kbs = cls.model.select(*fields).join(User, on=(cls.model.tenant_id == User.id)).where(
55
+ ((cls.model.tenant_id.in_(joined_tenant_ids) & (cls.model.permission ==
56
+ TenantPermission.TEAM.value)) | (
57
+ cls.model.tenant_id == user_id))
58
+ & (cls.model.status == StatusEnum.VALID.value)
59
+ )
 
 
 
 
 
 
 
 
 
60
  if desc:
61
  kbs = kbs.order_by(cls.model.getter_by(orderby).desc())
62
  else:
63
  kbs = kbs.order_by(cls.model.getter_by(orderby).asc())
64
 
 
 
65
  kbs = kbs.paginate(page_number, items_per_page)
66
 
67
+ return list(kbs.dicts())
68
 
69
  @classmethod
70
  @DB.connection_context()
web/.umirc.ts CHANGED
@@ -34,7 +34,7 @@ export default defineConfig({
34
  proxy: [
35
  {
36
  context: ['/api', '/v1'],
37
- target: 'http://127.0.0.1:9380/',
38
  changeOrigin: true,
39
  ws: true,
40
  logger: console,
 
34
  proxy: [
35
  {
36
  context: ['/api', '/v1'],
37
+ target: 'http://127.0.0.1:9456/',
38
  changeOrigin: true,
39
  ws: true,
40
  logger: console,
web/package-lock.json CHANGED
@@ -57,7 +57,6 @@
57
  "react-force-graph": "^1.44.4",
58
  "react-hook-form": "^7.53.1",
59
  "react-i18next": "^14.0.0",
60
- "react-infinite-scroll-component": "^6.1.0",
61
  "react-markdown": "^9.0.1",
62
  "react-pdf-highlighter": "^6.1.0",
63
  "react-string-replace": "^1.1.1",
@@ -24706,25 +24705,6 @@
24706
  }
24707
  }
24708
  },
24709
- "node_modules/react-infinite-scroll-component": {
24710
- "version": "6.1.0",
24711
- "resolved": "https://registry.npmmirror.com/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
24712
- "integrity": "sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==",
24713
- "dependencies": {
24714
- "throttle-debounce": "^2.1.0"
24715
- },
24716
- "peerDependencies": {
24717
- "react": ">=16.0.0"
24718
- }
24719
- },
24720
- "node_modules/react-infinite-scroll-component/node_modules/throttle-debounce": {
24721
- "version": "2.3.0",
24722
- "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
24723
- "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==",
24724
- "engines": {
24725
- "node": ">=8"
24726
- }
24727
- },
24728
  "node_modules/react-is": {
24729
  "version": "18.2.0",
24730
  "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz",
 
57
  "react-force-graph": "^1.44.4",
58
  "react-hook-form": "^7.53.1",
59
  "react-i18next": "^14.0.0",
 
60
  "react-markdown": "^9.0.1",
61
  "react-pdf-highlighter": "^6.1.0",
62
  "react-string-replace": "^1.1.1",
 
24705
  }
24706
  }
24707
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24708
  "node_modules/react-is": {
24709
  "version": "18.2.0",
24710
  "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz",
web/package.json CHANGED
@@ -68,7 +68,6 @@
68
  "react-force-graph": "^1.44.4",
69
  "react-hook-form": "^7.53.1",
70
  "react-i18next": "^14.0.0",
71
- "react-infinite-scroll-component": "^6.1.0",
72
  "react-markdown": "^9.0.1",
73
  "react-pdf-highlighter": "^6.1.0",
74
  "react-string-replace": "^1.1.1",
 
68
  "react-force-graph": "^1.44.4",
69
  "react-hook-form": "^7.53.1",
70
  "react-i18next": "^14.0.0",
 
71
  "react-markdown": "^9.0.1",
72
  "react-pdf-highlighter": "^6.1.0",
73
  "react-string-replace": "^1.1.1",
web/src/hooks/knowledge-hooks.ts CHANGED
@@ -3,17 +3,14 @@ import { IKnowledge, ITestingResult } from '@/interfaces/database/knowledge';
3
  import i18n from '@/locales/config';
4
  import kbService from '@/services/knowledge-service';
5
  import {
6
- useInfiniteQuery,
7
  useIsMutating,
8
  useMutation,
9
  useMutationState,
10
  useQuery,
11
  useQueryClient,
12
  } from '@tanstack/react-query';
13
- import { useDebounce } from 'ahooks';
14
  import { message } from 'antd';
15
  import { useSearchParams } from 'umi';
16
- import { useHandleSearchChange } from './logic-hooks';
17
  import { useSetPaginationParams } from './route-hook';
18
 
19
  export const useKnowledgeBaseId = (): string => {
@@ -53,7 +50,7 @@ export const useNextFetchKnowledgeList = (
53
  gcTime: 0, // https://tanstack.com/query/latest/docs/framework/react/guides/caching?from=reactQueryV3
54
  queryFn: async () => {
55
  const { data } = await kbService.getList();
56
- const list = data?.data?.kbs ?? [];
57
  return shouldFilterListWithoutDocument
58
  ? list.filter((x: IKnowledge) => x.chunk_num > 0)
59
  : list;
@@ -63,52 +60,6 @@ export const useNextFetchKnowledgeList = (
63
  return { list: data, loading };
64
  };
65
 
66
- export const useInfiniteFetchKnowledgeList = () => {
67
- const { searchString, handleInputChange } = useHandleSearchChange();
68
- const debouncedSearchString = useDebounce(searchString, { wait: 500 });
69
-
70
- const PageSize = 10;
71
- const {
72
- data,
73
- error,
74
- fetchNextPage,
75
- hasNextPage,
76
- isFetching,
77
- isFetchingNextPage,
78
- status,
79
- } = useInfiniteQuery({
80
- queryKey: ['infiniteFetchKnowledgeList', debouncedSearchString],
81
- queryFn: async ({ pageParam }) => {
82
- const { data } = await kbService.getList({
83
- page: pageParam,
84
- page_size: PageSize,
85
- keywords: debouncedSearchString,
86
- });
87
- const list = data?.data ?? [];
88
- return list;
89
- },
90
- initialPageParam: 1,
91
- getNextPageParam: (lastPage, pages, lastPageParam) => {
92
- if (lastPageParam * PageSize <= lastPage.total) {
93
- return lastPageParam + 1;
94
- }
95
- return undefined;
96
- },
97
- });
98
- return {
99
- data,
100
- loading: isFetching,
101
- error,
102
- fetchNextPage,
103
- hasNextPage,
104
- isFetching,
105
- isFetchingNextPage,
106
- status,
107
- handleInputChange,
108
- searchString,
109
- };
110
- };
111
-
112
  export const useCreateKnowledge = () => {
113
  const queryClient = useQueryClient();
114
  const {
@@ -144,9 +95,7 @@ export const useDeleteKnowledge = () => {
144
  const { data } = await kbService.rmKb({ kb_id: id });
145
  if (data.code === 0) {
146
  message.success(i18n.t(`message.deleted`));
147
- queryClient.invalidateQueries({
148
- queryKey: ['infiniteFetchKnowledgeList'],
149
- });
150
  }
151
  return data?.data ?? [];
152
  },
 
3
  import i18n from '@/locales/config';
4
  import kbService from '@/services/knowledge-service';
5
  import {
 
6
  useIsMutating,
7
  useMutation,
8
  useMutationState,
9
  useQuery,
10
  useQueryClient,
11
  } from '@tanstack/react-query';
 
12
  import { message } from 'antd';
13
  import { useSearchParams } from 'umi';
 
14
  import { useSetPaginationParams } from './route-hook';
15
 
16
  export const useKnowledgeBaseId = (): string => {
 
50
  gcTime: 0, // https://tanstack.com/query/latest/docs/framework/react/guides/caching?from=reactQueryV3
51
  queryFn: async () => {
52
  const { data } = await kbService.getList();
53
+ const list = data?.data ?? [];
54
  return shouldFilterListWithoutDocument
55
  ? list.filter((x: IKnowledge) => x.chunk_num > 0)
56
  : list;
 
60
  return { list: data, loading };
61
  };
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  export const useCreateKnowledge = () => {
64
  const queryClient = useQueryClient();
65
  const {
 
95
  const { data } = await kbService.rmKb({ kb_id: id });
96
  if (data.code === 0) {
97
  message.success(i18n.t(`message.deleted`));
98
+ queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeList'] });
 
 
99
  }
100
  return data?.data ?? [];
101
  },
web/src/locales/en.ts CHANGED
@@ -75,7 +75,6 @@ export default {
75
  namePlaceholder: 'Please input name!',
76
  doc: 'Docs',
77
  searchKnowledgePlaceholder: 'Search',
78
- noMoreData: 'It is all, nothing more',
79
  },
80
  knowledgeDetails: {
81
  dataset: 'Dataset',
 
75
  namePlaceholder: 'Please input name!',
76
  doc: 'Docs',
77
  searchKnowledgePlaceholder: 'Search',
 
78
  },
79
  knowledgeDetails: {
80
  dataset: 'Dataset',
web/src/locales/zh-traditional.ts CHANGED
@@ -75,7 +75,6 @@ export default {
75
  namePlaceholder: '請輸入名稱',
76
  doc: '文件',
77
  searchKnowledgePlaceholder: '搜索',
78
- noMoreData: 'It is all, nothing more',
79
  },
80
  knowledgeDetails: {
81
  dataset: '數據集',
 
75
  namePlaceholder: '請輸入名稱',
76
  doc: '文件',
77
  searchKnowledgePlaceholder: '搜索',
 
78
  },
79
  knowledgeDetails: {
80
  dataset: '數據集',
web/src/locales/zh.ts CHANGED
@@ -75,7 +75,6 @@ export default {
75
  namePlaceholder: '请输入名称',
76
  doc: '文档',
77
  searchKnowledgePlaceholder: '搜索',
78
- noMoreData: '沒有更多的數據了',
79
  },
80
  knowledgeDetails: {
81
  dataset: '数据集',
 
75
  namePlaceholder: '请输入名称',
76
  doc: '文档',
77
  searchKnowledgePlaceholder: '搜索',
 
78
  },
79
  knowledgeDetails: {
80
  dataset: '数据集',
web/src/pages/knowledge/index.less CHANGED
@@ -2,7 +2,6 @@
2
 
3
  .knowledge {
4
  padding: 48px 0;
5
- overflow: auto;
6
  }
7
 
8
  .topWrapper {
 
2
 
3
  .knowledge {
4
  padding: 48px 0;
 
5
  }
6
 
7
  .topWrapper {
web/src/pages/knowledge/index.tsx CHANGED
@@ -1,26 +1,18 @@
1
- import { useInfiniteFetchKnowledgeList } from '@/hooks/knowledge-hooks';
2
  import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
3
  import { PlusOutlined, SearchOutlined } from '@ant-design/icons';
4
- import {
5
- Button,
6
- Divider,
7
- Empty,
8
- Flex,
9
- Input,
10
- Skeleton,
11
- Space,
12
- Spin,
13
- } from 'antd';
14
- import { useTranslation } from 'react-i18next';
15
- import InfiniteScroll from 'react-infinite-scroll-component';
16
- import { useSaveKnowledge } from './hooks';
17
  import KnowledgeCard from './knowledge-card';
18
  import KnowledgeCreatingModal from './knowledge-creating-modal';
19
 
20
- import { useMemo } from 'react';
 
21
  import styles from './index.less';
22
 
23
  const KnowledgeList = () => {
 
 
 
24
  const { data: userInfo } = useFetchUserInfo();
25
  const { t } = useTranslation('translation', { keyPrefix: 'knowledgeList' });
26
  const {
@@ -30,23 +22,9 @@ const KnowledgeList = () => {
30
  onCreateOk,
31
  loading: creatingLoading,
32
  } = useSaveKnowledge();
33
- const {
34
- fetchNextPage,
35
- data,
36
- hasNextPage,
37
- searchString,
38
- handleInputChange,
39
- loading,
40
- } = useInfiniteFetchKnowledgeList();
41
- console.log('🚀 ~ KnowledgeList ~ data:', data);
42
- const nextList = data?.pages?.flatMap((x) => x.kbs) ?? [];
43
-
44
- const total = useMemo(() => {
45
- return data?.pages.at(-1).total ?? 0;
46
- }, [data?.pages]);
47
 
48
  return (
49
- <Flex className={styles.knowledge} vertical flex={1} id="scrollableDiv">
50
  <div className={styles.topWrapper}>
51
  <div>
52
  <span className={styles.title}>
@@ -75,30 +53,21 @@ const KnowledgeList = () => {
75
  </Space>
76
  </div>
77
  <Spin spinning={loading}>
78
- <InfiniteScroll
79
- dataLength={nextList?.length ?? 0}
80
- next={fetchNextPage}
81
- hasMore={hasNextPage}
82
- loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
83
- endMessage={total && <Divider plain>{t('noMoreData')} 🤐</Divider>}
84
- scrollableTarget="scrollableDiv"
85
  >
86
- <Flex
87
- gap={'large'}
88
- wrap="wrap"
89
- className={styles.knowledgeCardContainer}
90
- >
91
- {nextList?.length > 0 ? (
92
- nextList.map((item: any) => {
93
- return (
94
- <KnowledgeCard item={item} key={item.name}></KnowledgeCard>
95
- );
96
- })
97
- ) : (
98
- <Empty className={styles.knowledgeEmpty}></Empty>
99
- )}
100
- </Flex>
101
- </InfiniteScroll>
102
  </Spin>
103
  <KnowledgeCreatingModal
104
  loading={creatingLoading}
 
1
+ import { useNextFetchKnowledgeList } from '@/hooks/knowledge-hooks';
2
  import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
3
  import { PlusOutlined, SearchOutlined } from '@ant-design/icons';
4
+ import { Button, Empty, Flex, Input, Space, Spin } from 'antd';
 
 
 
 
 
 
 
 
 
 
 
 
5
  import KnowledgeCard from './knowledge-card';
6
  import KnowledgeCreatingModal from './knowledge-creating-modal';
7
 
8
+ import { useTranslation } from 'react-i18next';
9
+ import { useSaveKnowledge, useSearchKnowledge } from './hooks';
10
  import styles from './index.less';
11
 
12
  const KnowledgeList = () => {
13
+ const { searchString, handleInputChange } = useSearchKnowledge();
14
+ const { loading, list: data } = useNextFetchKnowledgeList();
15
+ const list = data.filter((x) => x.name.includes(searchString));
16
  const { data: userInfo } = useFetchUserInfo();
17
  const { t } = useTranslation('translation', { keyPrefix: 'knowledgeList' });
18
  const {
 
22
  onCreateOk,
23
  loading: creatingLoading,
24
  } = useSaveKnowledge();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  return (
27
+ <Flex className={styles.knowledge} vertical flex={1}>
28
  <div className={styles.topWrapper}>
29
  <div>
30
  <span className={styles.title}>
 
53
  </Space>
54
  </div>
55
  <Spin spinning={loading}>
56
+ <Flex
57
+ gap={'large'}
58
+ wrap="wrap"
59
+ className={styles.knowledgeCardContainer}
 
 
 
60
  >
61
+ {list.length > 0 ? (
62
+ list.map((item: any) => {
63
+ return (
64
+ <KnowledgeCard item={item} key={item.name}></KnowledgeCard>
65
+ );
66
+ })
67
+ ) : (
68
+ <Empty className={styles.knowledgeEmpty}></Empty>
69
+ )}
70
+ </Flex>
 
 
 
 
 
 
71
  </Spin>
72
  <KnowledgeCreatingModal
73
  loading={creatingLoading}