### What problem does this PR solve? feat: Modify the style of the answer card on the search page #2247 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.11.0
| const HightLightMarkdown = ({ | const HightLightMarkdown = ({ | ||||
| children, | children, | ||||
| className, | |||||
| }: { | }: { | ||||
| children: string | null | undefined; | children: string | null | undefined; | ||||
| className?: string; | |||||
| }) => { | }) => { | ||||
| return ( | return ( | ||||
| <Markdown | <Markdown | ||||
| remarkPlugins={[remarkGfm]} | remarkPlugins={[remarkGfm]} | ||||
| rehypePlugins={[rehypeRaw]} | rehypePlugins={[rehypeRaw]} | ||||
| className={classNames(styles.text, className)} | |||||
| className={classNames(styles.text)} | |||||
| components={ | components={ | ||||
| { | { | ||||
| code(props: any) { | code(props: any) { |
| ttsTip: | ttsTip: | ||||
| 'To play the voice using voice conversion, please select TTS (speech conversion model) in the settings first.', | 'To play the voice using voice conversion, please select TTS (speech conversion model) in the settings first.', | ||||
| relatedQuestion: 'Related question', | relatedQuestion: 'Related question', | ||||
| answerTitle: 'R', | |||||
| }, | }, | ||||
| setting: { | setting: { | ||||
| profile: 'Profile', | profile: 'Profile', |
| tts: '文字轉語音', | tts: '文字轉語音', | ||||
| ttsTip: '是否用語音轉換播放語音,請先在設定裡面選擇TTS(語音轉換模型)。', | ttsTip: '是否用語音轉換播放語音,請先在設定裡面選擇TTS(語音轉換模型)。', | ||||
| relatedQuestion: '相關問題', | relatedQuestion: '相關問題', | ||||
| answerTitle: '智慧回答', | |||||
| }, | }, | ||||
| setting: { | setting: { | ||||
| profile: '概述', | profile: '概述', |
| tts: '文本转语音', | tts: '文本转语音', | ||||
| ttsTip: '是否用语音转换播放语音,请先在设置里面选择TTS(语音转换模型)。', | ttsTip: '是否用语音转换播放语音,请先在设置里面选择TTS(语音转换模型)。', | ||||
| relatedQuestion: '相关问题', | relatedQuestion: '相关问题', | ||||
| answerTitle: '智能回答', | |||||
| }, | }, | ||||
| setting: { | setting: { | ||||
| profile: '概要', | profile: '概要', |
| width: 40%; | width: 40%; | ||||
| padding: 20px 10px 10px; | padding: 20px 10px 10px; | ||||
| } | } | ||||
| .highlightContent { | |||||
| .multipleLineEllipsis(2); | |||||
| em { | |||||
| color: red; | |||||
| font-style: normal; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| .answerWrapper { | .answerWrapper { | ||||
| background-color: #e6f4ff; | |||||
| padding: 14px; | |||||
| margin-top: 16px; | margin-top: 16px; | ||||
| border-radius: 8px; | |||||
| & > p { | |||||
| background: rgb(232 242 251 / 70%); | |||||
| box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.08); | |||||
| :global(.ant-card-head) { | |||||
| background-color: #e6f4ff; | |||||
| } | |||||
| & p { | |||||
| margin: 0; | margin: 0; | ||||
| } | } | ||||
| } | } |
| Spin, | Spin, | ||||
| Tag, | Tag, | ||||
| } from 'antd'; | } from 'antd'; | ||||
| import DOMPurify from 'dompurify'; | |||||
| import { isEmpty } from 'lodash'; | |||||
| import { useMemo, useState } from 'react'; | import { useMemo, useState } from 'react'; | ||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||
| import MarkdownContent from '../chat/markdown-content'; | import MarkdownContent from '../chat/markdown-content'; | ||||
| import { useFetchBackgroundImage, useSendQuestion } from './hooks'; | import { useFetchBackgroundImage, useSendQuestion } from './hooks'; | ||||
| import SearchSidebar from './sidebar'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| import SearchSidebar from './sidebar'; | |||||
| const { Content } = Layout; | const { Content } = Layout; | ||||
| const { Search } = Input; | const { Search } = Input; | ||||
| className={isMindMapEmpty ? styles.largeMain : styles.main} | className={isMindMapEmpty ? styles.largeMain : styles.main} | ||||
| > | > | ||||
| {InputSearch} | {InputSearch} | ||||
| {answer.answer && ( | |||||
| <div className={styles.answerWrapper}> | |||||
| <MarkdownContent | |||||
| loading={sendingLoading} | |||||
| content={answer.answer} | |||||
| reference={answer.reference ?? ({} as IReference)} | |||||
| clickDocumentButton={clickDocumentButton} | |||||
| ></MarkdownContent> | |||||
| </div> | |||||
| )} | |||||
| <Card | |||||
| title={ | |||||
| <Flex gap={10}> | |||||
| <img src="/logo.svg" alt="" width={20} /> | |||||
| {t('chat.answerTitle')} | |||||
| </Flex> | |||||
| } | |||||
| className={styles.answerWrapper} | |||||
| > | |||||
| {isEmpty(answer) && sendingLoading ? ( | |||||
| <Skeleton active /> | |||||
| ) : ( | |||||
| answer.answer && ( | |||||
| <MarkdownContent | |||||
| loading={sendingLoading} | |||||
| content={answer.answer} | |||||
| reference={answer.reference ?? ({} as IReference)} | |||||
| clickDocumentButton={clickDocumentButton} | |||||
| ></MarkdownContent> | |||||
| ) | |||||
| )} | |||||
| </Card> | |||||
| <Divider></Divider> | <Divider></Divider> | ||||
| <RetrievalDocuments | <RetrievalDocuments | ||||
| selectedDocumentIds={selectedDocumentIds} | selectedDocumentIds={selectedDocumentIds} | ||||
| </div> | </div> | ||||
| } | } | ||||
| > | > | ||||
| <div> | |||||
| <HightLightMarkdown> | |||||
| {item.highlight} | |||||
| </HightLightMarkdown> | |||||
| </div> | |||||
| <div | |||||
| dangerouslySetInnerHTML={{ | |||||
| __html: DOMPurify.sanitize( | |||||
| item.highlight, | |||||
| ), | |||||
| }} | |||||
| className={styles.highlightContent} | |||||
| ></div> | |||||
| </Popover> | </Popover> | ||||
| </Space> | </Space> | ||||
| </Card> | </Card> |