feat(web): memory chat ui upgrade
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:58:03
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-04 12:10:44
|
||||
* @Last Modified time: 2026-03-19 17:19:20
|
||||
*/
|
||||
/**
|
||||
* Conversation Page
|
||||
@@ -24,7 +24,6 @@ import type { HistoryItem, QueryParams, UploadFileListModalRef } from './types'
|
||||
import Empty from '@/components/Empty'
|
||||
import { formatDateTime } from '@/utils/format';
|
||||
import { randomString } from '@/utils/common'
|
||||
import BgImg from '@/assets/images/conversation/bg.png'
|
||||
import ChatEmpty from '@/assets/images/empty/chatEmpty.png'
|
||||
import Chat from '@/components/Chat'
|
||||
import type { ChatItem } from '@/components/Chat/types'
|
||||
@@ -345,20 +344,26 @@ const Conversation: FC = () => {
|
||||
|
||||
return (
|
||||
<Flex className="rb:w-full rb:p-[-16px]!">
|
||||
<div className="rb:w-86.25 rb:h-screen rb:overflow-hidden rb:border-r rb:border-[#EAECEE] rb:p-3">
|
||||
<div className="rb:group rb:flex rb:items-center rb:justify-center rb:font-regular rb:cursor-pointer rb:mb-5 rb:border rb:border-[#DFE4ED] rb:hover:border-[#155EEF] rb:hover:text-[#155EEF] rb:rounded-lg rb:py-2.5"
|
||||
<div className="rb:w-80 rb:h-screen rb:bg-[#F6F6F6] rb:overflow-hidden">
|
||||
<Flex align="center" gap={8} className="rb:p-5!">
|
||||
<div className="rb:size-6 rb:bg-cover rb:bg-[url('src/assets/images/conversation/redbear.png')]"></div>
|
||||
<div className="rb:text-[16px] rb:leading-5 rb:font-[Gilroy-Extrabold] rb:font-extrabold">{t('memoryConversation.chatTitle')}</div>
|
||||
</Flex>
|
||||
|
||||
<Flex align="center" gap={12}
|
||||
className="rb:cursor-pointer rb:border rb:border-[#155EEF] rb:rounded-xl rb:p-3! rb:mx-4! rb:text-[16px] rb:font-medium rb:text-[#155EEF] rb:h-12! rb:mb-5!"
|
||||
onClick={() => handleChangeHistory(null)}
|
||||
>
|
||||
<div
|
||||
className="rb:w-5 rb:h-5 rb:cursor-pointer rb:mr-2 rb:bg-cover rb:bg-[url('@/assets/images/conversation/conversation.svg')] rb:group-hover:bg-[url('@/assets/images/conversation/conversation_hover.svg')]"
|
||||
></div>
|
||||
{t('memoryConversation.startANewConversation')}
|
||||
</div>
|
||||
</Flex>
|
||||
{historyList.length > 0 &&
|
||||
<div
|
||||
ref={scrollRef}
|
||||
id="scrollableDiv"
|
||||
className="rb:overflow-y-auto rb:h-[calc(100vh-255px)]"
|
||||
className="rb:overflow-y-auto rb:h-[calc(100vh-144px)] rb:px-3!"
|
||||
>
|
||||
<InfiniteScroll
|
||||
dataLength={historyList.length}
|
||||
@@ -371,23 +376,25 @@ const Conversation: FC = () => {
|
||||
{Object.entries(groupHistoryList).map(([date, items]) => (
|
||||
<div key={date} className="rb:mt-6 rb:first:mt-0">
|
||||
<div className="rb:leading-5 rb:text-[#5B6167] rb:mb-2 rb:pl-1 rb:font-regular">{date.replace(/\u200e|\u200f/g, '')}</div>
|
||||
{items.map(item => (
|
||||
<div key={item.updated_at} className="rb:mb-3">
|
||||
<div className={clsx("rb:p-[8px_13px] rb:rounded-lg rb:leading-5 rb:cursor-pointer rb:hover:bg-[#F0F3F8]", {
|
||||
'rb:bg-[#FFFFFF] rb:shadow-[0px_2px_4px_0px_rgba(0,0,0,0.15)] rb:font-medium rb:hover:bg-[#FFFFFF]!': item.id === conversation_id,
|
||||
})}
|
||||
onClick={() => handleChangeHistory(item.id)}
|
||||
>
|
||||
{item.title}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<Flex vertical gap={4}>
|
||||
{items.map(item => (
|
||||
<div key={item.updated_at} className="rb:mb-3">
|
||||
<div className={clsx("rb:p-[8px_13px] rb:rounded-lg rb:leading-5 rb:cursor-pointer rb:hover:bg-[#F0F3F8]", {
|
||||
'rb:bg-[#FFFFFF] rb:shadow-[0px_2px_4px_0px_rgba(0,0,0,0.15)] rb:font-medium rb:hover:bg-[#FFFFFF]!': item.id === conversation_id,
|
||||
})}
|
||||
onClick={() => handleChangeHistory(item.id)}
|
||||
>
|
||||
{item.title}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</Flex>
|
||||
</div>
|
||||
))}
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
}
|
||||
<img src={BgImg} className="rb:absolute rb:bottom-0 rb:left-0 rb:w-86.25" />
|
||||
</div>
|
||||
|
||||
<div className="rb:relative rb:h-screen rb:px-4 rb:flex-[1_1_auto]">
|
||||
|
||||
11
web/src/views/MemoryConversation/index.module.css
Normal file
11
web/src/views/MemoryConversation/index.module.css
Normal file
@@ -0,0 +1,11 @@
|
||||
.segmented {
|
||||
background: #F6F6F6;
|
||||
border: 1px solid #EBEBEB;
|
||||
}
|
||||
.segmented:global(.ant-segmented .ant-segmented-item-label) {
|
||||
min-height: 24px;
|
||||
line-height: 24px;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 17:09:03
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 17:09:03
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-19 16:00:39
|
||||
*/
|
||||
/**
|
||||
* Memory Conversation Page
|
||||
@@ -12,48 +12,39 @@
|
||||
|
||||
import { type FC, type ReactNode, useState, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Col, Row, App, Skeleton, Space, Select, Flex } from 'antd'
|
||||
import { Col, Row, App, Skeleton, Select, Segmented, Tooltip, Flex } from 'antd'
|
||||
import dayjs from 'dayjs'
|
||||
import type { AnyObject } from 'antd/es/_util/type';
|
||||
import clsx from 'clsx'
|
||||
|
||||
import ConversationEmptyIcon from '@/assets/images/conversation/conversationEmpty.svg'
|
||||
import AnalysisEmptyIcon from '@/assets/images/conversation/analysisEmpty.png'
|
||||
import Card from './components/Card'
|
||||
import { readService, getUserMemoryList } from '@/api/memory'
|
||||
import Empty from '@/components/Empty'
|
||||
import Markdown from '@/components/Markdown'
|
||||
import type { Data } from '@/views/UserMemory/types'
|
||||
import Chat from '@/components/Chat'
|
||||
import MemoryFunctionIcon from '@/assets/images/conversation/memoryFunction.svg'
|
||||
import OnlineIcon from '@/assets/images/conversation/online.svg'
|
||||
import DeepThinkingIcon from '@/assets/images/conversation/deepThinking.svg'
|
||||
import ButtonCheckbox from '@/components/ButtonCheckbox'
|
||||
import DeepThinkingCheckedIcon from '@/assets/images/conversation/deepThinkingChecked.svg'
|
||||
import OnlineCheckedIcon from '@/assets/images/conversation/onlineChecked.svg'
|
||||
import MemoryFunctionCheckedIcon from '@/assets/images/conversation/memoryFunctionChecked.svg'
|
||||
import type { ChatItem } from '@/components/Chat/types'
|
||||
import RbCard from '@/components/RbCard/Card';
|
||||
import styles from './index.module.css'
|
||||
import ResultCard from '@/components/RbCard/ResultCard'
|
||||
|
||||
|
||||
/** Search mode configuration */
|
||||
const searchSwitchList = [
|
||||
{
|
||||
icon: DeepThinkingIcon,
|
||||
checkedIcon: DeepThinkingCheckedIcon,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:bg-[url('@/assets/images/conversation/deepThinking.svg')]"></div>,
|
||||
value: '0',
|
||||
label: 'deepThinking'
|
||||
key: 'deepThinking'
|
||||
},
|
||||
{
|
||||
icon: MemoryFunctionIcon,
|
||||
checkedIcon: MemoryFunctionCheckedIcon,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:bg-[url('@/assets/images/conversation/normalReply.svg')]"></div>,
|
||||
value: '1',
|
||||
label: 'normalReply'
|
||||
key: 'normalReply'
|
||||
},
|
||||
{
|
||||
icon: OnlineIcon,
|
||||
checkedIcon: OnlineCheckedIcon,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:bg-[url('@/assets/images/conversation/quickReply.svg')]"></div>,
|
||||
value: '2',
|
||||
label: 'quickReply'
|
||||
key: 'quickReply'
|
||||
},
|
||||
]
|
||||
|
||||
@@ -105,7 +96,7 @@ export interface LogItem {
|
||||
* Content wrapper component for analysis items
|
||||
*/
|
||||
const ContentWrapper: FC<{ children: ReactNode }> = ({ children }) => (
|
||||
<div className="rb:p-3 rb:bg-[#F6F8FC] rb:border rb:border-[#DFE4ED] rb:rounded-lg">
|
||||
<div className="rb:px-3 rb:py-2.5 rb:bg-white rb:rounded-xl">
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
@@ -120,6 +111,7 @@ const MemoryConversation: FC = () => {
|
||||
const [userList, setUserList] = useState<Data[]>([])
|
||||
const [search_switch, setSearchSwitch] = useState('0')
|
||||
const [msg, setMsg] = useState<string>('')
|
||||
const [expandedLogs, setExpandedLogs] = useState<Record<number, boolean>>({})
|
||||
|
||||
/** Load user list on mount */
|
||||
useEffect(() => {
|
||||
@@ -139,6 +131,7 @@ const MemoryConversation: FC = () => {
|
||||
}
|
||||
setChatData(prev => [...prev, { content: msg, created_at: new Date().getTime(), role: 'user' }])
|
||||
setLoading(true)
|
||||
setExpandedLogs({})
|
||||
readService({
|
||||
message: msg,
|
||||
end_user_id: userId,
|
||||
@@ -149,6 +142,7 @@ const MemoryConversation: FC = () => {
|
||||
const response = res as { answer: string; intermediate_outputs: LogItem[] }
|
||||
setChatData(prev => [...prev, { content: response.answer || '-', created_at: new Date().getTime(), role: 'assistant' }])
|
||||
setLogs(response.intermediate_outputs)
|
||||
setExpandedLogs(Object.fromEntries(response.intermediate_outputs.map((_, i) => [i, true])))
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false)
|
||||
@@ -175,46 +169,51 @@ const MemoryConversation: FC = () => {
|
||||
placeholder={t('memoryConversation.searchPlaceholder')}
|
||||
style={{ width: '100%', marginBottom: '16px' }}
|
||||
onChange={setUserId}
|
||||
variant="borderless"
|
||||
className="rb:bg-white rb:rounded-lg"
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16} className="rb:h-[calc(100vh-152px)] rb:overflow-hidden">
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Card
|
||||
<RbCard
|
||||
title={t('memoryConversation.conversationContent')}
|
||||
bodyClassName="rb:pb-[0]!"
|
||||
headerType="borderless"
|
||||
headerClassName="rb:min-h-[52px]! rb:font-[MiSans-Bold] rb:font-bold"
|
||||
bodyClassName="rb:px-3! rb:py-0! rb:h-[calc(100%-52px)]!"
|
||||
className="rb:h-[calc(100vh-124px)]!"
|
||||
>
|
||||
<Chat
|
||||
empty={
|
||||
<Empty url={ConversationEmptyIcon} className="rb:h-full" size={[140, 100]} title={t('memoryConversation.conversationContentEmpty')} isNeedSubTitle={false} />
|
||||
}
|
||||
contentClassName='rb:h-[calc(100vh-362px)]'
|
||||
className="rb:pt-0!"
|
||||
contentClassName='rb:h-[calc(100%-144px)]'
|
||||
data={chatData}
|
||||
onChange={setMsg}
|
||||
onSend={handleSend}
|
||||
loading={loading}
|
||||
labelFormat={(item) => dayjs(item.created_at).locale('en').format('MMMM D, YYYY [at] h:mm A')}
|
||||
>
|
||||
<Flex gap={8}>
|
||||
{searchSwitchList.map(item => (
|
||||
<ButtonCheckbox
|
||||
key={item.value}
|
||||
icon={item.icon}
|
||||
checkedIcon={item.checkedIcon}
|
||||
checked={search_switch === item.value}
|
||||
onChange={() => handleChange(item.value)}
|
||||
>
|
||||
{t(`memoryConversation.${item.label}`)}
|
||||
</ButtonCheckbox>
|
||||
))}
|
||||
</Flex>
|
||||
<Segmented
|
||||
options={searchSwitchList.map(item => ({
|
||||
...item,
|
||||
icon: <Tooltip title={t(`memoryConversation.${item.key}`)}>{item.icon}</Tooltip>
|
||||
}))}
|
||||
shape="round"
|
||||
className={styles.segmented}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</Chat>
|
||||
</Card>
|
||||
</RbCard>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Card
|
||||
<RbCard
|
||||
title={t('memoryConversation.memoryConversationAnalysis')}
|
||||
bodyClassName='rb:overflow-auto'
|
||||
headerType="borderless"
|
||||
headerClassName="rb:min-h-[52px]! rb:font-[MiSans-Bold] rb:font-bold"
|
||||
bodyClassName="rb:p-3! rb:pt-0! rb:h-[calc(100%-52px)]! rb:overflow-y-auto!"
|
||||
className="rb:h-[calc(100vh-124px)]!"
|
||||
>
|
||||
{loading ?
|
||||
<Skeleton active />
|
||||
@@ -226,98 +225,98 @@ const MemoryConversation: FC = () => {
|
||||
subTitle={t('memoryConversation.memoryConversationAnalysisEmptySubTitle')}
|
||||
size={[270, 170]}
|
||||
/>
|
||||
: <Space size={12} direction="vertical" style={{width: '100%'}}>
|
||||
: <Flex gap={12} vertical>
|
||||
{logs.map((log, logIndex) => (
|
||||
<div key={logIndex}
|
||||
className={clsx(
|
||||
`rb:p-[16px_24px] rb:rounded-lg`,
|
||||
'rb:border rb:border-[#DFE4ED]',
|
||||
{
|
||||
'rb:shadow-[inset_4px_0px_0px_0px_#155EEF]': logIndex % 3 === 0,
|
||||
'rb:shadow-[inset_4px_0px_0px_0px_#369F21]': logIndex % 3 === 1,
|
||||
'rb:shadow-[inset_4px_0px_0px_0px_#9C6FFF]': logIndex % 3 === 2,
|
||||
}
|
||||
)}
|
||||
<ResultCard
|
||||
key={logIndex}
|
||||
title={log.title}
|
||||
isMiSans={false}
|
||||
bodyClassName={`rb:p-3! rb:pt-0! ${!!expandedLogs[logIndex] ? 'rb:pb-3!' : 'rb:pb-0!'}`}
|
||||
expanded={!!expandedLogs[logIndex]}
|
||||
handleExpand={() => setExpandedLogs(prev => ({ ...prev, [logIndex]: !prev[logIndex] }))}
|
||||
extra={log.type === 'verification' && <div className="rb-border rb:rounded-lg rb:py-1 rb:px-2 rb:text-[12px] rb:font-medium rb:leading-4.5 rb:text-[#FF5D34]">{log.result}</div>}
|
||||
>
|
||||
<div className="rb:text-[16px] rb:font-medium rb:leading-5.5 rb:mb-6">{log.title}</div>
|
||||
{log.type === 'problem_split' && Array.isArray(log.data) && log.data.length > 0
|
||||
? <Space size={12} direction="vertical" style={{width: '100%'}}>
|
||||
{log.data.map(vo => (
|
||||
<ContentWrapper key={vo.id}>
|
||||
<>
|
||||
<div className="rb:font-medium rb:text-[#212332]">{vo.id}. {vo.question}</div>
|
||||
<div className="rb:mt-2 rb:text-[12px] rb:text-[#5B6167]">{vo.reason}</div>
|
||||
</>
|
||||
</ContentWrapper>
|
||||
))}
|
||||
</Space>
|
||||
: log.type === 'problem_extension' && log.data && Object.keys(log.data).length > 0
|
||||
? <Space size={12} direction="vertical" style={{width: '100%'}}>
|
||||
{Object.keys(log.data).map((key: string) => (
|
||||
<ContentWrapper key={key}>
|
||||
<>
|
||||
<div className="rb:font-medium rb:text-[#212332]">{key}</div>
|
||||
{(log.data as Record<string, string[]>)[key].map((item, index) => (
|
||||
<div key={index} className="rb:mt-2 rb:text-[#5B6167] rb:text-[12px]">{item}</div>
|
||||
{log.type === 'problem_split' && Array.isArray(log.data) && log.data.length > 0
|
||||
? <Flex gap={12} vertical>
|
||||
{log.data.map(vo => (
|
||||
<ContentWrapper key={vo.id}>
|
||||
<>
|
||||
<div className="rb:font-medium rb:text-[#212332]">{vo.id}. {vo.question}</div>
|
||||
<div className="rb:mt-2 rb:text-[12px] rb:text-[#5B6167]">{vo.reason}</div>
|
||||
</>
|
||||
</ContentWrapper>
|
||||
))}
|
||||
</Flex>
|
||||
: log.type === 'problem_extension' && log.data && Object.keys(log.data).length > 0
|
||||
? <Flex gap={12} vertical>
|
||||
{Object.keys(log.data).map((key: string) => (
|
||||
<ContentWrapper key={key}>
|
||||
<>
|
||||
<div className="rb:font-medium rb:text-[#212332]">{key}</div>
|
||||
{(log.data as Record<string, string[]>)[key].map((item, index) => (
|
||||
<div key={index} className="rb:mt-2 rb:text-[#5B6167] rb:text-[12px]">{item}</div>
|
||||
))}
|
||||
</>
|
||||
</ContentWrapper>
|
||||
))}
|
||||
</Flex>
|
||||
: log.type === 'search_result' && log.raw_results
|
||||
? <ContentWrapper>
|
||||
<div className="rb:font-medium rb:text-[#212332] rb:mb-2">{log.query}</div>
|
||||
<div className='rb:mt-2 rb:text-[12px] rb:text-[#5B6167]'>
|
||||
{typeof log.raw_results === 'string'
|
||||
? <Markdown content={log.raw_results} />
|
||||
: <>
|
||||
{log.raw_results.reranked_results?.statements.length > 0 && log.raw_results.reranked_results?.statements.map((item: { statement: string }, index: number) => (
|
||||
<div key={index}>{item.statement}</div>
|
||||
))}
|
||||
</>
|
||||
</ContentWrapper>
|
||||
))}
|
||||
</Space>
|
||||
: log.type === 'search_result' && log.raw_results
|
||||
? <ContentWrapper>
|
||||
<div className="rb:font-medium rb:text-[#212332] rb:mb-2">{log.query}</div>
|
||||
<div className='rb:mt-2 rb:text-[12px] rb:text-[#5B6167]'>
|
||||
{typeof log.raw_results === 'string'
|
||||
? <Markdown content={log.raw_results} />
|
||||
: <>
|
||||
{log.raw_results.reranked_results?.statements.length > 0 && log.raw_results.reranked_results?.statements.map((item: { statement: string }, index: number) => (
|
||||
<div key={index}>{item.statement}</div>
|
||||
))}
|
||||
{log.raw_results.reranked_results?.summaries.length > 0 && log.raw_results.reranked_results?.summaries.map((item: { content: string }, index: number) => (
|
||||
<div key={index}>{item.content}</div>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</ContentWrapper>
|
||||
: log.type === 'retrieval_summary' && log.summary
|
||||
? <ContentWrapper><div className="rb:text-[12px] rb:text-[#5B6167]">{log.summary}</div></ContentWrapper>
|
||||
: log.type === 'verification'
|
||||
? <ContentWrapper>
|
||||
<div className="rb:font-medium rb:text-[#212332]">{log.query}</div>
|
||||
<div className="rb:mt-2 rb:text-[12px] rb:text-[#5B6167]">{log.reason}</div>
|
||||
<div className="rb:mt-2 rb:text-[12px] rb:text-[#5B6167]">{log.result}</div>
|
||||
{log.raw_results.reranked_results?.summaries.length > 0 && log.raw_results.reranked_results?.summaries.map((item: { content: string }, index: number) => (
|
||||
<div key={index}>{item.content}</div>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</ContentWrapper>
|
||||
: log.type === 'output_type'
|
||||
? <ContentWrapper>
|
||||
: log.type === 'retrieval_summary' && log.summary
|
||||
? <ContentWrapper>
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167]">{log.summary}</div>
|
||||
</ContentWrapper>
|
||||
: log.type === 'verification'
|
||||
? <ContentWrapper>
|
||||
<div className="rb:font-medium rb:text-[#212332]">{log.query}</div>
|
||||
<div className="rb:mt-2 rb:text-[12px] rb:text-[#5B6167]">{log.reason}</div>
|
||||
<div className="rb:mt-2 rb:text-[12px] rb:text-[#5B6167]">{log.result}</div>
|
||||
</ContentWrapper>
|
||||
: log.type === 'output_type'
|
||||
? <ContentWrapper>
|
||||
<div className="rb:font-medium rb:text-[#212332] rb:mb-2">{log.query}</div>
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167]">{log.summary}</div>
|
||||
</ContentWrapper>
|
||||
: log.type === 'input_summary' && log.raw_results
|
||||
? <ContentWrapper>
|
||||
<div className="rb:font-medium rb:text-[#212332] rb:mb-2">{log.query}</div>
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167]">{log.summary}</div>
|
||||
<div className="rb:font-medium rb:text-[12px] rb:text-[#5B6167] rb:mb-2">{log.summary}</div>
|
||||
<div className='rb:mt-2 rb:text-[12px] rb:text-[#5B6167]'>
|
||||
{typeof log.raw_results === 'string'
|
||||
? <Markdown content={log.raw_results} />
|
||||
: <>
|
||||
{log.raw_results.reranked_results?.statements.length > 0 && log.raw_results.reranked_results?.statements.map((item: { statement: string; } , index: number) => (
|
||||
<div key={index}>{item.statement}</div>
|
||||
))}
|
||||
{log.raw_results.reranked_results?.summaries.length > 0 && log.raw_results.reranked_results?.summaries.map((item: { content: string; }, index: number) => (
|
||||
<div key={index}>{item.content}</div>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</ContentWrapper>
|
||||
: log.type === 'input_summary' && log.raw_results
|
||||
? <ContentWrapper>
|
||||
<div className="rb:font-medium rb:text-[#212332] rb:mb-2">{log.query}</div>
|
||||
<div className="rb:font-medium rb:text-[12px] rb:text-[#5B6167] rb:mb-2">{log.summary}</div>
|
||||
<div className='rb:mt-2 rb:text-[12px] rb:text-[#5B6167]'>
|
||||
{typeof log.raw_results === 'string'
|
||||
? <Markdown content={log.raw_results} />
|
||||
: <>
|
||||
{log.raw_results.reranked_results?.statements.length > 0 && log.raw_results.reranked_results?.statements.map((item: { statement: string; } , index: number) => (
|
||||
<div key={index}>{item.statement}</div>
|
||||
))}
|
||||
{log.raw_results.reranked_results?.summaries.length > 0 && log.raw_results.reranked_results?.summaries.map((item: { content: string; }, index: number) => (
|
||||
<div key={index}>{item.content}</div>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</ContentWrapper>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
</ResultCard>
|
||||
))}
|
||||
</Space>}
|
||||
</Card>
|
||||
</Flex>
|
||||
}
|
||||
</RbCard>
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 17:30:11
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-19 14:22:20
|
||||
* @Last Modified time: 2026-03-19 15:38:38
|
||||
*/
|
||||
/**
|
||||
* Result Component
|
||||
@@ -16,7 +16,6 @@ import { useTranslation } from 'react-i18next'
|
||||
import { Space, Button, Progress, Form, Input, Flex } from 'antd'
|
||||
import { ExclamationCircleFilled, LoadingOutlined } from '@ant-design/icons'
|
||||
import clsx from 'clsx'
|
||||
import ResultCard from './ResultCard'
|
||||
import type { AnyObject } from 'antd/es/_util/type';
|
||||
|
||||
import Card from './Card'
|
||||
@@ -29,6 +28,7 @@ import Markdown from '@/components/Markdown'
|
||||
import { groupDataByType } from '../constant'
|
||||
import Empty from '@/components/Empty'
|
||||
import NoDataIcon from '@/assets/images/empty/noData.png'
|
||||
import ResultCard from '@/components/RbCard/ResultCard'
|
||||
|
||||
/** Result metric mapping */
|
||||
const resultObj = {
|
||||
|
||||
Reference in New Issue
Block a user