#4288 Added a "Copy" button next to each search result. (#5389)

Co-authored-by: eeee0717 <chentao020717Work@outlook.com>
Co-authored-by: Chen Tao <70054568+eeee0717@users.noreply.github.com>
This commit is contained in:
木子不是木子狸 2025-04-27 19:41:30 +08:00 committed by GitHub
parent 634b9f276b
commit 2ade08a9b7

View File

@ -1,9 +1,10 @@
import { CopyOutlined } from '@ant-design/icons'
import type { ExtractChunkData } from '@cherrystudio/embedjs-interfaces'
import { TopView } from '@renderer/components/TopView'
import { DEFAULT_KNOWLEDGE_THRESHOLD } from '@renderer/config/constant'
import { getFileFromUrl, getKnowledgeBaseParams } from '@renderer/services/KnowledgeService'
import { FileType, KnowledgeBase } from '@renderer/types'
import { Input, List, Modal, Spin, Typography } from 'antd'
import { Input, List, message, Modal, Spin, Tooltip, Typography } from 'antd'
import { useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -93,6 +94,16 @@ const PopupContainer: React.FC<Props> = ({ base, resolve }) => {
)
}
const handleCopy = async (text: string) => {
try {
await navigator.clipboard.writeText(text)
message.success(t('message.copied'))
} catch (error) {
console.error('Failed to copy text:', error)
message.error(t('message.copyError') || 'Failed to copy text')
}
}
return (
<Modal
title={t('knowledge.search')}
@ -125,7 +136,14 @@ const PopupContainer: React.FC<Props> = ({ base, resolve }) => {
renderItem={(item) => (
<List.Item>
<ResultItem>
<ScoreTag>Score: {(item.score * 100).toFixed(1)}%</ScoreTag>
<TagContainer>
<ScoreTag>Score: {(item.score * 100).toFixed(1)}%</ScoreTag>
<Tooltip title={t('common.copy')}>
<CopyButton onClick={() => handleCopy(item.pageContent)}>
<CopyOutlined />
</CopyButton>
</Tooltip>
</TagContainer>
<Paragraph style={{ userSelect: 'text' }}>{highlightText(item.pageContent)}</Paragraph>
<MetadataContainer>
<Text type="secondary">
@ -176,10 +194,16 @@ const ResultItem = styled.div`
border-radius: 8px;
`
const ScoreTag = styled.div`
const TagContainer = styled.div`
position: absolute;
top: 8px;
right: 8px;
display: flex;
align-items: center;
gap: 8px;
`
const ScoreTag = styled.div`
padding: 2px 8px;
background: var(--color-primary);
color: white;
@ -187,6 +211,24 @@ const ScoreTag = styled.div`
font-size: 12px;
`
const CopyButton = styled.div`
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
background: var(--color-background);
color: var(--color-text);
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
&:hover {
background: var(--color-primary);
color: white;
}
`
const MetadataContainer = styled.div`
margin-top: 8px;
padding-top: 8px;