feat: result ui

This commit is contained in:
Joel 2024-12-11 16:34:32 +08:00
parent 9dce37bb24
commit 599345879e
7 changed files with 53 additions and 31 deletions

View File

@ -48,6 +48,11 @@ export const generalResultData: HitTesting[] = [
score: 0.8771945,
content: 'It is quite natural for academics who are continuously told to “publish or perish” to want to always create something from scratch that is their own fresh creation.',
},
{
id: '2',
score: 0.5,
content: 'It is quite natural for ',
},
],
score: 0.8771945,
tsne_position: null,

View File

@ -1,9 +1,8 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { SliceContent, SliceLabel } from '../../formatted-text/flavours/shared'
import cn from '@/utils/classnames'
import { SliceContent } from '../../formatted-text/flavours/shared'
import Score from './score'
import type { HitTestingChildChunk } from '@/models/datasets'
type Props = {
@ -15,16 +14,16 @@ const ChildChunks: FC<Props> = ({
payload,
isShowAll,
}) => {
const { t } = useTranslation()
const { id, score, content } = payload
return (
<div className='flex items-center space-x-2'>
<SliceLabel>
{id} {score}
</SliceLabel>
<SliceContent className={cn(!isShowAll && 'line-clamp-2')}>
{content}
</SliceContent>
<div
className={!isShowAll ? 'line-clamp-2' : ''}
>
<div className='inline-flex'>
<div className='bg-state-accent-solid system-2xs-semibold-uppercase px-1'>C-{id}</div>
<Score value={score} />
</div>
<SliceContent className='bg-state-accent-hover group-hover:bg-state-accent-hover'>{content}</SliceContent>
</div>
)
}

View File

@ -13,6 +13,8 @@ import type { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader
import cn from '@/utils/classnames'
import Tag from '@/app/components/datasets/documents/detail/completed/common/tag'
const i18nPrefix = 'datasetHitTesting'
type Props = {
payload: HitTesting
onHide: () => void
@ -24,19 +26,19 @@ const ChunkDetailModal: FC<Props> = ({
}) => {
const { t } = useTranslation()
const { segment, score, child_chunks } = payload
const { position, word_count, content, keywords, document } = segment
const { position, content, keywords, document } = segment
const isParentChildRetrieval = !!(child_chunks && child_chunks.length > 0)
const extension = document.name.split('.').slice(0, -1)[0] as FileAppearanceTypeEnum
const maxHeighClassName = 'max-h-[752px] overflow-y-auto'
return (
<Modal
title={t('dataset.chunkDetail')}
title={t(`${i18nPrefix}.chunkDetail`)}
isShow
closable
onClose={onHide}
className={cn(isParentChildRetrieval ? '!min-w-[1200px]' : '!min-w-[720px]')}
>
<div className='flex h-'>
<div className='flex pb-6'>
<div>
{/* Meta info */}
<div className='flex justify-between items-center'>
@ -54,12 +56,12 @@ const ChunkDetailModal: FC<Props> = ({
</div>
<Score value={score} />
</div>
<div className=' max-h-[752px] overflow-y-auto'>
<div className={cn('mt-2 body-md-regular text-text-secondary', maxHeighClassName)}>
{content}
</div>
{!isParentChildRetrieval && keywords && keywords.length > 0 && (
<div>
<div>{t('dataset.keywords')}</div>
<div className='mt-6'>
<div className='font-medium text-xs text-text-tertiary uppercase'>{t(`${i18nPrefix}.keyword`)}</div>
<div className='flex flex-wrap'>
{keywords.map(keyword => (
<Tag key={keyword} text={keyword} className='mr-2' />
@ -71,8 +73,8 @@ const ChunkDetailModal: FC<Props> = ({
{isParentChildRetrieval && (
<div className='shrink-0 w-[552px] px-6'>
<div>{t('dataset.hitChunks', { num: child_chunks.length })}</div>
<div className='space-y-2'>
<div className='system-xs-semibold-uppercase text-text-secondary'>{t(`${i18nPrefix}.hitChunks`, { num: child_chunks.length })}</div>
<div className={cn('mt-1 space-y-2', maxHeighClassName)}>
{child_chunks.map(item => (
<ChildChunksItem key={item.id} payload={item} isShowAll />
))}

View File

@ -15,6 +15,7 @@ import FileIcon from '@/app/components/base/file-uploader/file-type-icon'
import type { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader/types'
import Tag from '@/app/components/datasets/documents/detail/completed/common/tag'
const i18nPrefix = 'datasetHitTesting'
type Props = {
payload: HitTesting
}
@ -54,17 +55,21 @@ const ResultItem: FC<Props> = ({
</div>
{/* Main */}
<div className='px-3'>
<div className='line-clamp-2'>{content}</div>
<div className='mt-1 px-3'>
<div className='line-clamp-2 body-md-regular'>{content}</div>
{isParentChildRetrieval && (
<div>
<div className='mt-1'>
<div className='flex items-center space-x-0.5 text-text-secondary' onClick={toggleFold}>
<Icon className={cn('w-4 h-4', isFold && 'opacity-50')} />
<div>{t('dataset.hitChunks', { num: child_chunks.length })}</div>
<div>{t(`${i18nPrefix}.dataset.hitChunks`, { num: child_chunks.length })}</div>
</div>
<div className='space-y-2'>
{child_chunks.map(item => (
<div key={item.id} className='ml-[7px] pl-[7px] border-l-[2px] border-text-accent-secondary'>
<ChildChunkItem payload={item} isShowAll={false} />
</div>
))}
</div>
{child_chunks.map(item => (
<ChildChunkItem key={item.id} payload={item} isShowAll={false} />
))}
</div>
)}
{!isParentChildRetrieval && keywords && keywords.length > 0 && (
@ -76,7 +81,7 @@ const ResultItem: FC<Props> = ({
)}
</div>
{/* Foot */}
<div className='flex justify-between items-center h-10 pl-3 pr-2 border-t border-divider-subtle'>
<div className='mt-3 flex justify-between items-center h-10 pl-3 pr-2 border-t border-divider-subtle'>
<div className='flex items-center space-x-1'>
<FileIcon type={extension} size='sm' />
<span className='grow w-0 truncate text-text-secondary text-[13px] font-normal'>{document.name}</span>
@ -85,7 +90,7 @@ const ResultItem: FC<Props> = ({
className='flex items-center space-x-1 cursor-pointer text-text-tertiary'
onClick={showDetailModal}
>
<div className='text-xs uppercase'>{t('dataset.open')}</div>
<div className='text-xs uppercase'>{t(`${i18nPrefix}.open`)}</div>
<RiArrowRightUpLine className='size-3.5' />
</div>
</div>

View File

@ -1,18 +1,21 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
type Props = {
value: number
besideChunkName?: boolean
}
const Score: FC<Props> = ({
value,
besideChunkName,
}) => {
return (
<div className='relative items-center px-[5px] rounded-md border border-components-progress-bar-border overflow-hidden'>
<div className={cn('relative items-center px-[5px] border border-components-progress-bar-border overflow-hidden', besideChunkName ? 'border-l-0' : 'rounded-md')}>
<div className='absolute top-0 left-0 h-full bg-util-colors-blue-brand-blue-brand-100 border-r-[1.5px] border-components-progress-brand-progress ' style={{ width: `${value * 100}%` }} />
<div className='relative flex items-center h-4 space-x-0.5 text-util-colors-blue-brand-blue-brand-700'>
<div className={cn('relative flex items-center h-5 space-x-0.5 text-util-colors-blue-brand-blue-brand-700')}>
<div className='system-2xs-medium-uppercase'>score</div>
<div className='system-xs-semibold'>{value.toFixed(2)}</div>
</div>

View File

@ -25,6 +25,10 @@ const translation = {
noRecentTip: 'No recent query results here',
viewChart: 'View VECTOR CHART',
viewDetail: 'View Detail',
chunkDetail: 'Chunk Detail',
hitChunks: 'Hit {{num}} child chunks',
open: 'Open',
keyword: 'Keywords',
}
export default translation

View File

@ -25,6 +25,10 @@ const translation = {
noRecentTip: '最近无查询结果',
viewChart: '查看向量图表',
viewDetail: '查看详情',
chunkDetail: '段落详情',
hitChunks: '命中 {{num}} 个子段落',
open: '打开',
keyword: '关键词',
}
export default translation