balibabu commited on
Commit
0dad3f5
·
1 Parent(s): 29e6d3f

feat: The search box is displayed globally when the page is loaded for the first time #2247 (#2325)

Browse files

### What problem does this PR solve?

feat: The search box is displayed globally when the page is loaded for
the first time #2247

### Type of change


- [x] New Feature (non-breaking change which adds functionality)

web/src/pages/search/hooks.ts CHANGED
@@ -3,7 +3,7 @@ import { useTestChunkRetrieval } from '@/hooks/knowledge-hooks';
3
  import { useSendMessageWithSse } from '@/hooks/logic-hooks';
4
  import { IAnswer } from '@/interfaces/database/chat';
5
  import api from '@/utils/api';
6
- import { isEmpty } from 'lodash';
7
  import { ChangeEventHandler, useCallback, useEffect, useState } from 'react';
8
 
9
  export const useSendQuestion = (kbIds: string[]) => {
@@ -19,18 +19,22 @@ export const useSendQuestion = (kbIds: string[]) => {
19
  loading: mindMapLoading,
20
  } = useFetchMindMap();
21
  const [searchStr, setSearchStr] = useState<string>('');
 
22
 
23
  const sendQuestion = useCallback(
24
  (question: string) => {
 
 
 
25
  setCurrentAnswer({} as IAnswer);
26
  setSendingLoading(true);
27
- send({ kb_ids: kbIds, question });
28
- testChunk({ kb_id: kbIds, highlight: true, question });
29
  fetchMindMap({
30
- question,
31
  kb_ids: kbIds,
32
  });
33
- fetchRelatedQuestions(question);
34
  },
35
  [send, testChunk, kbIds, fetchRelatedQuestions, fetchMindMap],
36
  );
@@ -65,14 +69,15 @@ export const useSendQuestion = (kbIds: string[]) => {
65
 
66
  return {
67
  sendQuestion,
 
 
68
  loading,
69
  sendingLoading,
70
  answer: currentAnswer,
71
  relatedQuestions: relatedQuestions?.slice(0, 5) ?? [],
72
  mindMap,
73
  mindMapLoading,
74
- handleClickRelatedQuestion,
75
  searchStr,
76
- handleSearchStrChange,
77
  };
78
  };
 
3
  import { useSendMessageWithSse } from '@/hooks/logic-hooks';
4
  import { IAnswer } from '@/interfaces/database/chat';
5
  import api from '@/utils/api';
6
+ import { isEmpty, trim } from 'lodash';
7
  import { ChangeEventHandler, useCallback, useEffect, useState } from 'react';
8
 
9
  export const useSendQuestion = (kbIds: string[]) => {
 
19
  loading: mindMapLoading,
20
  } = useFetchMindMap();
21
  const [searchStr, setSearchStr] = useState<string>('');
22
+ const [isFirstRender, setIsFirstRender] = useState(true);
23
 
24
  const sendQuestion = useCallback(
25
  (question: string) => {
26
+ const q = trim(question);
27
+ if (isEmpty(q)) return;
28
+ setIsFirstRender(false);
29
  setCurrentAnswer({} as IAnswer);
30
  setSendingLoading(true);
31
+ send({ kb_ids: kbIds, question: q });
32
+ testChunk({ kb_id: kbIds, highlight: true, question: q });
33
  fetchMindMap({
34
+ question: q,
35
  kb_ids: kbIds,
36
  });
37
+ fetchRelatedQuestions(q);
38
  },
39
  [send, testChunk, kbIds, fetchRelatedQuestions, fetchMindMap],
40
  );
 
69
 
70
  return {
71
  sendQuestion,
72
+ handleSearchStrChange,
73
+ handleClickRelatedQuestion,
74
  loading,
75
  sendingLoading,
76
  answer: currentAnswer,
77
  relatedQuestions: relatedQuestions?.slice(0, 5) ?? [],
78
  mindMap,
79
  mindMapLoading,
 
80
  searchStr,
81
+ isFirstRender,
82
  };
83
  };
web/src/pages/search/index.less CHANGED
@@ -49,18 +49,22 @@
49
  }
50
  }
51
 
 
 
 
 
52
  .content {
53
  height: 100%;
54
  .main {
55
  width: 60%;
56
  // background-color: aqua;
57
  overflow: auto;
58
- padding: 10px;
59
  }
60
 
61
  .graph {
62
  width: 40%;
63
- padding-right: 10px;
64
  }
65
  }
66
  .answerWrapper {
@@ -72,3 +76,28 @@
72
  margin: 0;
73
  }
74
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
  }
51
 
52
+ .firstRenderContent {
53
+ height: 100%;
54
+ }
55
+
56
  .content {
57
  height: 100%;
58
  .main {
59
  width: 60%;
60
  // background-color: aqua;
61
  overflow: auto;
62
+ padding: 20px 10px 10px;
63
  }
64
 
65
  .graph {
66
  width: 40%;
67
+ padding: 20px 10px 10px;
68
  }
69
  }
70
  .answerWrapper {
 
76
  margin: 0;
77
  }
78
  }
79
+
80
+ .input() {
81
+ :global(.ant-input-affix-wrapper) {
82
+ padding: 4px 8px;
83
+ border-start-start-radius: 30px !important;
84
+ border-end-start-radius: 30px !important;
85
+ }
86
+ input {
87
+ height: 40px;
88
+ }
89
+ button {
90
+ height: 50px !important;
91
+ border-start-end-radius: 30px !important;
92
+ border-end-end-radius: 30px !important;
93
+ }
94
+ }
95
+
96
+ .globalInput {
97
+ width: 600px;
98
+ .input();
99
+ }
100
+ .partialInput {
101
+ width: 100%;
102
+ .input();
103
+ }
web/src/pages/search/index.tsx CHANGED
@@ -1,14 +1,24 @@
1
  import HightLightMarkdown from '@/components/highlight-markdown';
2
  import { ImageWithPopover } from '@/components/image';
 
3
  import { useSelectTestingResult } from '@/hooks/knowledge-hooks';
4
  import { IReference } from '@/interfaces/database/chat';
5
- import { Card, Flex, Input, Layout, List, Skeleton, Space, Tag } from 'antd';
 
 
 
 
 
 
 
 
 
 
6
  import { useState } from 'react';
7
  import MarkdownContent from '../chat/markdown-content';
8
  import { useSendQuestion } from './hooks';
9
  import SearchSidebar from './sidebar';
10
 
11
- import IndentedTree from '@/components/indented-tree/indented-tree';
12
  import styles from './index.less';
13
 
14
  const { Content } = Layout;
@@ -27,8 +37,25 @@ const SearchPage = () => {
27
  mindMap,
28
  mindMapLoading,
29
  searchStr,
 
 
30
  } = useSendQuestion(checkedList);
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  return (
33
  <Layout className={styles.searchPage}>
34
  <SearchSidebar
@@ -37,70 +64,78 @@ const SearchPage = () => {
37
  ></SearchSidebar>
38
  <Layout>
39
  <Content>
40
- <Flex className={styles.content}>
41
- <section className={styles.main}>
42
- <Search
43
- value={searchStr}
44
- onChange={handleSearchStrChange}
45
- placeholder="input search text"
46
- onSearch={sendQuestion}
47
- size="large"
48
- loading={sendingLoading}
49
- disabled={checkedList.length === 0}
50
- />
51
- {answer.answer && (
52
- <div className={styles.answerWrapper}>
53
- <MarkdownContent
54
- loading={sendingLoading}
55
- content={answer.answer}
56
- reference={answer.reference ?? ({} as IReference)}
57
- clickDocumentButton={() => {}}
58
- ></MarkdownContent>
59
- </div>
60
- )}
61
- <List
62
- dataSource={list.chunks}
63
- renderItem={(item) => (
64
- <List.Item>
65
- <Card className={styles.card}>
66
- <Space>
67
- <ImageWithPopover id={item.img_id}></ImageWithPopover>
68
- <HightLightMarkdown>
69
- {item.highlight}
70
- </HightLightMarkdown>
71
- </Space>
72
- </Card>
73
- </List.Item>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  )}
75
- />
76
- {relatedQuestions?.length > 0 && (
77
- <Card>
78
- <Flex wrap="wrap" gap={'10px 0'}>
79
- {relatedQuestions?.map((x, idx) => (
80
- <Tag
81
- key={idx}
82
- className={styles.tag}
83
- onClick={handleClickRelatedQuestion(x)}
84
- >
85
- {x}
86
- </Tag>
87
- ))}
88
- </Flex>
89
- </Card>
90
- )}
91
- </section>
92
- <section className={styles.graph}>
93
- {mindMapLoading ? (
94
- <Skeleton active />
95
- ) : (
96
- <IndentedTree
97
- data={mindMap}
98
- show
99
- style={{ width: '100%', height: '100%' }}
100
- ></IndentedTree>
101
- )}
102
- </section>
103
- </Flex>
104
  </Content>
105
  </Layout>
106
  </Layout>
 
1
  import HightLightMarkdown from '@/components/highlight-markdown';
2
  import { ImageWithPopover } from '@/components/image';
3
+ import IndentedTree from '@/components/indented-tree/indented-tree';
4
  import { useSelectTestingResult } from '@/hooks/knowledge-hooks';
5
  import { IReference } from '@/interfaces/database/chat';
6
+ import {
7
+ Card,
8
+ Divider,
9
+ Flex,
10
+ Input,
11
+ Layout,
12
+ List,
13
+ Skeleton,
14
+ Space,
15
+ Tag,
16
+ } from 'antd';
17
  import { useState } from 'react';
18
  import MarkdownContent from '../chat/markdown-content';
19
  import { useSendQuestion } from './hooks';
20
  import SearchSidebar from './sidebar';
21
 
 
22
  import styles from './index.less';
23
 
24
  const { Content } = Layout;
 
37
  mindMap,
38
  mindMapLoading,
39
  searchStr,
40
+ loading,
41
+ isFirstRender,
42
  } = useSendQuestion(checkedList);
43
 
44
+ const InputSearch = (
45
+ <Search
46
+ value={searchStr}
47
+ onChange={handleSearchStrChange}
48
+ placeholder="input search text"
49
+ allowClear
50
+ enterButton
51
+ onSearch={sendQuestion}
52
+ size="large"
53
+ loading={sendingLoading}
54
+ disabled={checkedList.length === 0}
55
+ className={isFirstRender ? styles.globalInput : styles.partialInput}
56
+ />
57
+ );
58
+
59
  return (
60
  <Layout className={styles.searchPage}>
61
  <SearchSidebar
 
64
  ></SearchSidebar>
65
  <Layout>
66
  <Content>
67
+ {isFirstRender ? (
68
+ <Flex
69
+ justify="center"
70
+ align="center"
71
+ className={styles.firstRenderContent}
72
+ >
73
+ {InputSearch}
74
+ </Flex>
75
+ ) : (
76
+ <Flex className={styles.content}>
77
+ <section className={styles.main}>
78
+ {InputSearch}
79
+ {answer.answer && (
80
+ <div className={styles.answerWrapper}>
81
+ <MarkdownContent
82
+ loading={sendingLoading}
83
+ content={answer.answer}
84
+ reference={answer.reference ?? ({} as IReference)}
85
+ clickDocumentButton={() => {}}
86
+ ></MarkdownContent>
87
+ </div>
88
+ )}
89
+ <Divider></Divider>
90
+ {list.chunks.length > 0 && (
91
+ <List
92
+ dataSource={list.chunks}
93
+ loading={loading}
94
+ renderItem={(item) => (
95
+ <List.Item>
96
+ <Card className={styles.card}>
97
+ <Space>
98
+ <ImageWithPopover
99
+ id={item.img_id}
100
+ ></ImageWithPopover>
101
+ <HightLightMarkdown>
102
+ {item.highlight}
103
+ </HightLightMarkdown>
104
+ </Space>
105
+ </Card>
106
+ </List.Item>
107
+ )}
108
+ />
109
+ )}
110
+ {relatedQuestions?.length > 0 && (
111
+ <Card>
112
+ <Flex wrap="wrap" gap={'10px 0'}>
113
+ {relatedQuestions?.map((x, idx) => (
114
+ <Tag
115
+ key={idx}
116
+ className={styles.tag}
117
+ onClick={handleClickRelatedQuestion(x)}
118
+ >
119
+ {x}
120
+ </Tag>
121
+ ))}
122
+ </Flex>
123
+ </Card>
124
+ )}
125
+ </section>
126
+ <section className={styles.graph}>
127
+ {mindMapLoading ? (
128
+ <Skeleton active />
129
+ ) : (
130
+ <IndentedTree
131
+ data={mindMap}
132
+ show
133
+ style={{ width: '100%', height: '100%' }}
134
+ ></IndentedTree>
135
  )}
136
+ </section>
137
+ </Flex>
138
+ )}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  </Content>
140
  </Layout>
141
  </Layout>
web/src/pages/search/sidebar.tsx CHANGED
@@ -22,7 +22,7 @@ interface IProps {
22
  }
23
 
24
  const SearchSidebar = ({ checkedList, setCheckedList }: IProps) => {
25
- const { list } = useNextFetchKnowledgeList();
26
  const ids = useMemo(() => list.map((x) => x.id), [list]);
27
 
28
  const checkAll = list.length === checkedList.length;
@@ -67,6 +67,7 @@ const SearchSidebar = ({ checkedList, setCheckedList }: IProps) => {
67
  bordered
68
  dataSource={list}
69
  className={styles.list}
 
70
  renderItem={(item) => (
71
  <List.Item>
72
  <Checkbox value={item.id} className={styles.checkbox}>
 
22
  }
23
 
24
  const SearchSidebar = ({ checkedList, setCheckedList }: IProps) => {
25
+ const { list, loading } = useNextFetchKnowledgeList();
26
  const ids = useMemo(() => list.map((x) => x.id), [list]);
27
 
28
  const checkAll = list.length === checkedList.length;
 
67
  bordered
68
  dataSource={list}
69
  className={styles.list}
70
+ loading={loading}
71
  renderItem={(item) => (
72
  <List.Item>
73
  <Checkbox value={item.id} className={styles.checkbox}>