balibabu
commited on
Commit
·
7043f18
1
Parent(s):
89444d3
fix: fixed the issue that the prompt word for registering an account is not in English and fixed the issue where the last message would keep loading if the backend reported an error during chat and fixed the issue where the next button would float above the file list on the file upload page (#133)
Browse files* feat: fixed the issue where the next button would float above the file list on the file upload page.
* feat: fixed the issue where the last message would keep loading if the backend reported an error during chat.
* fix: fixed the issue that the prompt word for registering an account is not in English
- web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.less +15 -2
- web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.tsx +6 -7
- web/src/pages/add-knowledge/components/knowledge-testing/testing-result/index.tsx +1 -1
- web/src/pages/chat/chat-container/index.tsx +4 -21
- web/src/pages/chat/hooks.ts +75 -9
- web/src/pages/login/index.tsx +5 -1
- web/src/pages/login/model.ts +1 -1
web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.less
CHANGED
@@ -8,6 +8,7 @@
|
|
8 |
}
|
9 |
.footer {
|
10 |
text-align: right;
|
|
|
11 |
.nextButton {
|
12 |
background-color: @purple;
|
13 |
}
|
@@ -17,8 +18,9 @@
|
|
17 |
padding-top: 60px;
|
18 |
}
|
19 |
.uploader {
|
20 |
-
|
21 |
-
|
|
|
22 |
}
|
23 |
.hiddenUploader {
|
24 |
:global(.ant-upload-drag) {
|
@@ -29,6 +31,17 @@
|
|
29 |
font-size: 40px;
|
30 |
align-items: end;
|
31 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
.deleteIcon {
|
33 |
font-size: 20px;
|
34 |
}
|
|
|
8 |
}
|
9 |
.footer {
|
10 |
text-align: right;
|
11 |
+
padding-top: 16px;
|
12 |
.nextButton {
|
13 |
background-color: @purple;
|
14 |
}
|
|
|
18 |
padding-top: 60px;
|
19 |
}
|
20 |
.uploader {
|
21 |
+
:global(.ant-upload) {
|
22 |
+
height: 126px;
|
23 |
+
}
|
24 |
}
|
25 |
.hiddenUploader {
|
26 |
:global(.ant-upload-drag) {
|
|
|
31 |
font-size: 40px;
|
32 |
align-items: end;
|
33 |
}
|
34 |
+
.uploaderButton {
|
35 |
+
padding: 10px;
|
36 |
+
vertical-align: middle;
|
37 |
+
height: 40px;
|
38 |
+
}
|
39 |
+
.uploaderIcon {
|
40 |
+
svg {
|
41 |
+
width: 20px;
|
42 |
+
height: 20px;
|
43 |
+
}
|
44 |
+
}
|
45 |
.deleteIcon {
|
46 |
font-size: 20px;
|
47 |
}
|
web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.tsx
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
import { ReactComponent as SelectFilesEndIcon } from '@/assets/svg/select-files-end.svg';
|
2 |
import { ReactComponent as SelectFilesStartIcon } from '@/assets/svg/select-files-start.svg';
|
|
|
3 |
import {
|
4 |
useDeleteDocumentById,
|
5 |
useFetchKnowledgeDetail,
|
@@ -10,14 +11,14 @@ import {
|
|
10 |
useFetchTenantInfo,
|
11 |
useSelectParserList,
|
12 |
} from '@/hooks/userSettingHook';
|
13 |
-
|
14 |
import uploadService from '@/services/uploadService';
|
|
|
15 |
import {
|
16 |
ArrowLeftOutlined,
|
|
|
17 |
DeleteOutlined,
|
18 |
EditOutlined,
|
19 |
FileDoneOutlined,
|
20 |
-
InboxOutlined,
|
21 |
} from '@ant-design/icons';
|
22 |
import {
|
23 |
Button,
|
@@ -43,8 +44,6 @@ import {
|
|
43 |
} from 'react';
|
44 |
import { Link, useDispatch, useNavigate } from 'umi';
|
45 |
|
46 |
-
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
47 |
-
import { isFileUploadDone } from '@/utils/documentUtils';
|
48 |
import styles from './index.less';
|
49 |
|
50 |
const { Dragger } = Upload;
|
@@ -290,9 +289,9 @@ const KnowledgeUploadFile = () => {
|
|
290 |
[styles.hiddenUploader]: !isUpload,
|
291 |
})}
|
292 |
>
|
293 |
-
<
|
294 |
-
<
|
295 |
-
</
|
296 |
<p className="ant-upload-text">
|
297 |
Click or drag file to this area to upload
|
298 |
</p>
|
|
|
1 |
import { ReactComponent as SelectFilesEndIcon } from '@/assets/svg/select-files-end.svg';
|
2 |
import { ReactComponent as SelectFilesStartIcon } from '@/assets/svg/select-files-start.svg';
|
3 |
+
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
4 |
import {
|
5 |
useDeleteDocumentById,
|
6 |
useFetchKnowledgeDetail,
|
|
|
11 |
useFetchTenantInfo,
|
12 |
useSelectParserList,
|
13 |
} from '@/hooks/userSettingHook';
|
|
|
14 |
import uploadService from '@/services/uploadService';
|
15 |
+
import { isFileUploadDone } from '@/utils/documentUtils';
|
16 |
import {
|
17 |
ArrowLeftOutlined,
|
18 |
+
CloudUploadOutlined,
|
19 |
DeleteOutlined,
|
20 |
EditOutlined,
|
21 |
FileDoneOutlined,
|
|
|
22 |
} from '@ant-design/icons';
|
23 |
import {
|
24 |
Button,
|
|
|
44 |
} from 'react';
|
45 |
import { Link, useDispatch, useNavigate } from 'umi';
|
46 |
|
|
|
|
|
47 |
import styles from './index.less';
|
48 |
|
49 |
const { Dragger } = Upload;
|
|
|
289 |
[styles.hiddenUploader]: !isUpload,
|
290 |
})}
|
291 |
>
|
292 |
+
<Button className={styles.uploaderButton}>
|
293 |
+
<CloudUploadOutlined className={styles.uploaderIcon} />
|
294 |
+
</Button>
|
295 |
<p className="ant-upload-text">
|
296 |
Click or drag file to this area to upload
|
297 |
</p>
|
web/src/pages/add-knowledge/components/knowledge-testing/testing-result/index.tsx
CHANGED
@@ -27,7 +27,7 @@ const ChunkTitle = ({ item }: { item: ITestingChunk }) => {
|
|
27 |
{similarityList.map((x) => (
|
28 |
<Space key={x.field}>
|
29 |
<span className={styles.similarityCircle}>
|
30 |
-
{((item[x.field] as number) * 100).toFixed(2)}
|
31 |
</span>
|
32 |
<span className={styles.similarityText}>{x.label}</span>
|
33 |
</Space>
|
|
|
27 |
{similarityList.map((x) => (
|
28 |
<Space key={x.field}>
|
29 |
<span className={styles.similarityCircle}>
|
30 |
+
{((item[x.field] as number) * 100).toFixed(2)}
|
31 |
</span>
|
32 |
<span className={styles.similarityText}>{x.label}</span>
|
33 |
</Space>
|
web/src/pages/chat/chat-container/index.tsx
CHANGED
@@ -4,7 +4,6 @@ import NewDocumentLink from '@/components/new-document-link';
|
|
4 |
import DocumentPreviewer from '@/components/pdf-previewer';
|
5 |
import { MessageType } from '@/constants/chat';
|
6 |
import { useSelectFileThumbnails } from '@/hooks/knowledgeHook';
|
7 |
-
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
8 |
import { useSelectUserInfo } from '@/hooks/userSettingHook';
|
9 |
import { IReference, Message } from '@/interfaces/database/chat';
|
10 |
import { IChunk } from '@/interfaces/database/knowledge';
|
@@ -21,7 +20,7 @@ import {
|
|
21 |
Space,
|
22 |
} from 'antd';
|
23 |
import classNames from 'classnames';
|
24 |
-
import {
|
25 |
import Markdown from 'react-markdown';
|
26 |
import reactStringReplace from 'react-string-replace';
|
27 |
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
@@ -243,35 +242,19 @@ const MessageItem = ({
|
|
243 |
};
|
244 |
|
245 |
const ChatContainer = () => {
|
246 |
-
const [value, setValue] = useState('');
|
247 |
const {
|
248 |
ref,
|
249 |
currentConversation: conversation,
|
250 |
addNewestConversation,
|
|
|
251 |
} = useFetchConversationOnMount();
|
252 |
-
const {
|
|
|
253 |
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
|
254 |
useClickDrawer();
|
255 |
|
256 |
-
const loading = useOneNamespaceEffectsLoading('chatModel', [
|
257 |
-
'completeConversation',
|
258 |
-
]);
|
259 |
useGetFileIcon();
|
260 |
|
261 |
-
const handlePressEnter = () => {
|
262 |
-
if (!loading) {
|
263 |
-
setValue('');
|
264 |
-
addNewestConversation(value);
|
265 |
-
sendMessage(value.trim());
|
266 |
-
}
|
267 |
-
};
|
268 |
-
|
269 |
-
const handleInputChange: ChangeEventHandler<HTMLInputElement> = (e) => {
|
270 |
-
const value = e.target.value;
|
271 |
-
const nextValue = value.replaceAll('\\n', '\n').replaceAll('\\t', '\t');
|
272 |
-
setValue(nextValue);
|
273 |
-
};
|
274 |
-
|
275 |
return (
|
276 |
<>
|
277 |
<Flex flex={1} className={styles.chatContainer} vertical>
|
|
|
4 |
import DocumentPreviewer from '@/components/pdf-previewer';
|
5 |
import { MessageType } from '@/constants/chat';
|
6 |
import { useSelectFileThumbnails } from '@/hooks/knowledgeHook';
|
|
|
7 |
import { useSelectUserInfo } from '@/hooks/userSettingHook';
|
8 |
import { IReference, Message } from '@/interfaces/database/chat';
|
9 |
import { IChunk } from '@/interfaces/database/knowledge';
|
|
|
20 |
Space,
|
21 |
} from 'antd';
|
22 |
import classNames from 'classnames';
|
23 |
+
import { useCallback, useMemo } from 'react';
|
24 |
import Markdown from 'react-markdown';
|
25 |
import reactStringReplace from 'react-string-replace';
|
26 |
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
|
|
242 |
};
|
243 |
|
244 |
const ChatContainer = () => {
|
|
|
245 |
const {
|
246 |
ref,
|
247 |
currentConversation: conversation,
|
248 |
addNewestConversation,
|
249 |
+
removeLatestMessage,
|
250 |
} = useFetchConversationOnMount();
|
251 |
+
const { handleInputChange, handlePressEnter, value, loading } =
|
252 |
+
useSendMessage(conversation, addNewestConversation, removeLatestMessage);
|
253 |
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
|
254 |
useClickDrawer();
|
255 |
|
|
|
|
|
|
|
256 |
useGetFileIcon();
|
257 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
return (
|
259 |
<>
|
260 |
<Flex flex={1} className={styles.chatContainer} vertical>
|
web/src/pages/chat/hooks.ts
CHANGED
@@ -7,7 +7,14 @@ import { IConversation, IDialog } from '@/interfaces/database/chat';
|
|
7 |
import { IChunk } from '@/interfaces/database/knowledge';
|
8 |
import { getFileExtension } from '@/utils';
|
9 |
import omit from 'lodash/omit';
|
10 |
-
import {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
import { useDispatch, useSearchParams, useSelector } from 'umi';
|
12 |
import { v4 as uuid } from 'uuid';
|
13 |
import { ChatSearchParams } from './constants';
|
@@ -432,6 +439,16 @@ export const useSelectCurrentConversation = () => {
|
|
432 |
});
|
433 |
}, []);
|
434 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
435 |
const addPrologue = useCallback(() => {
|
436 |
if (dialogId !== '' && conversationId === '') {
|
437 |
const prologue = dialog.prompt_config?.prologue;
|
@@ -459,7 +476,7 @@ export const useSelectCurrentConversation = () => {
|
|
459 |
setCurrentConversation(conversation);
|
460 |
}, [conversation]);
|
461 |
|
462 |
-
return { currentConversation, addNewestConversation };
|
463 |
};
|
464 |
|
465 |
export const useFetchConversation = () => {
|
@@ -501,7 +518,7 @@ export const useScrollToBottom = (currentConversation: IClientConversation) => {
|
|
501 |
export const useFetchConversationOnMount = () => {
|
502 |
const { conversationId } = useGetChatSearchParams();
|
503 |
const fetchConversation = useFetchConversation();
|
504 |
-
const { currentConversation, addNewestConversation } =
|
505 |
useSelectCurrentConversation();
|
506 |
const ref = useScrollToBottom(currentConversation);
|
507 |
|
@@ -515,16 +532,45 @@ export const useFetchConversationOnMount = () => {
|
|
515 |
fetchConversationOnMount();
|
516 |
}, [fetchConversationOnMount]);
|
517 |
|
518 |
-
return {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
519 |
};
|
520 |
|
521 |
-
export const useSendMessage = (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
522 |
const dispatch = useDispatch();
|
523 |
const { setConversation } = useSetConversation();
|
524 |
const { conversationId } = useGetChatSearchParams();
|
525 |
-
const
|
526 |
-
|
527 |
-
)
|
|
|
528 |
const fetchConversation = useFetchConversation();
|
529 |
|
530 |
const { handleClickConversation } = useClickConversationCard();
|
@@ -549,10 +595,15 @@ export const useSendMessage = () => {
|
|
549 |
|
550 |
if (retcode === 0) {
|
551 |
if (id) {
|
|
|
552 |
handleClickConversation(id);
|
553 |
} else {
|
554 |
fetchConversation(conversationId);
|
555 |
}
|
|
|
|
|
|
|
|
|
556 |
}
|
557 |
},
|
558 |
[
|
@@ -561,6 +612,8 @@ export const useSendMessage = () => {
|
|
561 |
conversationId,
|
562 |
fetchConversation,
|
563 |
handleClickConversation,
|
|
|
|
|
564 |
],
|
565 |
);
|
566 |
|
@@ -579,7 +632,20 @@ export const useSendMessage = () => {
|
|
579 |
[conversationId, setConversation, sendMessage],
|
580 |
);
|
581 |
|
582 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
};
|
584 |
|
585 |
export const useGetFileIcon = () => {
|
|
|
7 |
import { IChunk } from '@/interfaces/database/knowledge';
|
8 |
import { getFileExtension } from '@/utils';
|
9 |
import omit from 'lodash/omit';
|
10 |
+
import {
|
11 |
+
ChangeEventHandler,
|
12 |
+
useCallback,
|
13 |
+
useEffect,
|
14 |
+
useMemo,
|
15 |
+
useRef,
|
16 |
+
useState,
|
17 |
+
} from 'react';
|
18 |
import { useDispatch, useSearchParams, useSelector } from 'umi';
|
19 |
import { v4 as uuid } from 'uuid';
|
20 |
import { ChatSearchParams } from './constants';
|
|
|
439 |
});
|
440 |
}, []);
|
441 |
|
442 |
+
const removeLatestMessage = useCallback(() => {
|
443 |
+
setCurrentConversation((pre) => {
|
444 |
+
const nextMessages = pre.message.slice(0, -2);
|
445 |
+
return {
|
446 |
+
...pre,
|
447 |
+
message: nextMessages,
|
448 |
+
};
|
449 |
+
});
|
450 |
+
}, []);
|
451 |
+
|
452 |
const addPrologue = useCallback(() => {
|
453 |
if (dialogId !== '' && conversationId === '') {
|
454 |
const prologue = dialog.prompt_config?.prologue;
|
|
|
476 |
setCurrentConversation(conversation);
|
477 |
}, [conversation]);
|
478 |
|
479 |
+
return { currentConversation, addNewestConversation, removeLatestMessage };
|
480 |
};
|
481 |
|
482 |
export const useFetchConversation = () => {
|
|
|
518 |
export const useFetchConversationOnMount = () => {
|
519 |
const { conversationId } = useGetChatSearchParams();
|
520 |
const fetchConversation = useFetchConversation();
|
521 |
+
const { currentConversation, addNewestConversation, removeLatestMessage } =
|
522 |
useSelectCurrentConversation();
|
523 |
const ref = useScrollToBottom(currentConversation);
|
524 |
|
|
|
532 |
fetchConversationOnMount();
|
533 |
}, [fetchConversationOnMount]);
|
534 |
|
535 |
+
return {
|
536 |
+
currentConversation,
|
537 |
+
addNewestConversation,
|
538 |
+
ref,
|
539 |
+
removeLatestMessage,
|
540 |
+
};
|
541 |
+
};
|
542 |
+
|
543 |
+
export const useHandleMessageInputChange = () => {
|
544 |
+
const [value, setValue] = useState('');
|
545 |
+
|
546 |
+
const handleInputChange: ChangeEventHandler<HTMLInputElement> = (e) => {
|
547 |
+
const value = e.target.value;
|
548 |
+
const nextValue = value.replaceAll('\\n', '\n').replaceAll('\\t', '\t');
|
549 |
+
setValue(nextValue);
|
550 |
+
};
|
551 |
+
|
552 |
+
return {
|
553 |
+
handleInputChange,
|
554 |
+
value,
|
555 |
+
setValue,
|
556 |
+
};
|
557 |
};
|
558 |
|
559 |
+
export const useSendMessage = (
|
560 |
+
conversation: IClientConversation,
|
561 |
+
addNewestConversation: (message: string) => void,
|
562 |
+
removeLatestMessage: () => void,
|
563 |
+
) => {
|
564 |
+
const loading = useOneNamespaceEffectsLoading('chatModel', [
|
565 |
+
'completeConversation',
|
566 |
+
]);
|
567 |
const dispatch = useDispatch();
|
568 |
const { setConversation } = useSetConversation();
|
569 |
const { conversationId } = useGetChatSearchParams();
|
570 |
+
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
|
571 |
+
// const conversation: IClientConversation = useSelector(
|
572 |
+
// (state: any) => state.chatModel.currentConversation,
|
573 |
+
// );
|
574 |
const fetchConversation = useFetchConversation();
|
575 |
|
576 |
const { handleClickConversation } = useClickConversationCard();
|
|
|
595 |
|
596 |
if (retcode === 0) {
|
597 |
if (id) {
|
598 |
+
// new conversation
|
599 |
handleClickConversation(id);
|
600 |
} else {
|
601 |
fetchConversation(conversationId);
|
602 |
}
|
603 |
+
} else {
|
604 |
+
// cancel loading
|
605 |
+
setValue(message);
|
606 |
+
removeLatestMessage();
|
607 |
}
|
608 |
},
|
609 |
[
|
|
|
612 |
conversationId,
|
613 |
fetchConversation,
|
614 |
handleClickConversation,
|
615 |
+
removeLatestMessage,
|
616 |
+
setValue,
|
617 |
],
|
618 |
);
|
619 |
|
|
|
632 |
[conversationId, setConversation, sendMessage],
|
633 |
);
|
634 |
|
635 |
+
const handlePressEnter = () => {
|
636 |
+
if (!loading) {
|
637 |
+
setValue('');
|
638 |
+
addNewestConversation(value);
|
639 |
+
handleSendMessage(value.trim());
|
640 |
+
}
|
641 |
+
};
|
642 |
+
|
643 |
+
return {
|
644 |
+
handlePressEnter,
|
645 |
+
handleInputChange,
|
646 |
+
value,
|
647 |
+
loading,
|
648 |
+
};
|
649 |
};
|
650 |
|
651 |
export const useGetFileIcon = () => {
|
web/src/pages/login/index.tsx
CHANGED
@@ -115,7 +115,11 @@ const Login = () => {
|
|
115 |
label="Password"
|
116 |
rules={[{ required: true, message: 'Please input value' }]}
|
117 |
>
|
118 |
-
<Input.Password
|
|
|
|
|
|
|
|
|
119 |
</Form.Item>
|
120 |
{title === 'login' && (
|
121 |
<Form.Item name="remember" valuePropName="checked">
|
|
|
115 |
label="Password"
|
116 |
rules={[{ required: true, message: 'Please input value' }]}
|
117 |
>
|
118 |
+
<Input.Password
|
119 |
+
size="large"
|
120 |
+
placeholder="Please input value"
|
121 |
+
onPressEnter={onCheck}
|
122 |
+
/>
|
123 |
</Form.Item>
|
124 |
{title === 'login' && (
|
125 |
<Form.Item name="remember" valuePropName="checked">
|
web/src/pages/login/model.ts
CHANGED
@@ -51,7 +51,7 @@ const model: DvaModel<LoginModelState> = {
|
|
51 |
console.log();
|
52 |
const { retcode } = data;
|
53 |
if (retcode === 0) {
|
54 |
-
message.success('
|
55 |
}
|
56 |
return retcode;
|
57 |
},
|
|
|
51 |
console.log();
|
52 |
const { retcode } = data;
|
53 |
if (retcode === 0) {
|
54 |
+
message.success('Registered!');
|
55 |
}
|
56 |
return retcode;
|
57 |
},
|