import React, { type FC, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiDeleteBinLine, RiEditLine } from '@remixicon/react' import { StatusItem } from '../../list' import DocumentFileIcon from '../../../common/document-file-icon' import { useDocumentContext } from '../index' import ChildSegmentList from './child-segment-list' import { SegmentIndexTag, useSegmentListContext } from '.' import type { SegmentDetailModel } from '@/models/datasets' import Indicator from '@/app/components/header/indicator' import Switch from '@/app/components/base/switch' import Divider from '@/app/components/base/divider' import { formatNumber } from '@/utils/format' import Confirm from '@/app/components/base/confirm' import cn from '@/utils/classnames' import Badge from '@/app/components/base/badge' const Dot = React.memo(() => { return (
ยท
) }) Dot.displayName = 'Dot' const ProgressBar: FC<{ percent: number; loading: boolean }> = React.memo(({ percent, loading }) => { return (
{loading ? null : percent.toFixed(2)}
) }) ProgressBar.displayName = 'ProgressBar' type DocumentTitleProps = { name: string extension?: string } const DocumentTitle: FC = React.memo(({ extension, name }) => { return (
{name || '--'}
) }) DocumentTitle.displayName = 'DocumentTitle' const Tag = React.memo(({ text }: { text: string }) => { return (
# {text}
) }) Tag.displayName = 'Tag' export type UsageScene = 'doc' | 'hitTesting' type ISegmentCardProps = { loading: boolean detail?: SegmentDetailModel & { document?: { name: string } } contentExternal?: string refSource?: { title: string uri: string } isExternal?: boolean score?: number onClick?: () => void onChangeSwitch?: (enabled: boolean, segId?: string) => Promise onDelete?: (segId: string) => Promise onClickEdit?: () => void scene?: UsageScene className?: string archived?: boolean embeddingAvailable?: boolean } const SegmentCard: FC = ({ detail = {}, contentExternal, isExternal, refSource, score, onClick, onChangeSwitch, onDelete, onClickEdit, loading = true, scene = 'doc', className = '', archived, embeddingAvailable, }) => { const { t } = useTranslation() const { id, position, enabled, content, word_count, hit_count, answer, keywords, child_chunks = [], } = detail as Required['detail'] const [showModal, setShowModal] = useState(false) const isCollapsed = useSegmentListContext(s => s.isCollapsed) const [mode, parentMode] = useDocumentContext(s => [s.mode, s.parentMode]) const isDocScene = useMemo(() => { return scene === 'doc' }, [scene]) const isGeneralMode = useMemo(() => { return mode === 'custom' }, [mode]) const isFullDocMode = useMemo(() => { return mode === 'hierarchical' && parentMode === 'full-doc' }, [mode, parentMode]) // todo: change to real logic const chunkEdited = useMemo(() => { return mode !== 'hierarchical' || parentMode !== 'full-doc' }, [mode, parentMode]) const textOpacity = useMemo(() => { return enabled ? '' : 'opacity-50 group-hover/card:opacity-100' }, [enabled]) const handleClickCard = useCallback(() => { if (!isFullDocMode) onClick?.() }, [isFullDocMode, onClick]) const renderContent = () => { if (answer) { return ( <>
Q
{content}
A
{answer}
) } if (contentExternal) return contentExternal return content } return (
{isDocScene ? <>
{`${formatNumber(word_count)} Characters`}
{`${formatNumber(hit_count)} Retrieval Count`}
{chunkEdited && ( <> )}
{!isFullDocMode ?
{loading ? ( ) : ( <> {embeddingAvailable && (
{!archived && ( <>
{ e.stopPropagation() onClickEdit?.() }}>
{ e.stopPropagation() setShowModal(true) } }>
)}
) => e.stopPropagation() } className="flex items-center" > { await onChangeSwitch?.(val, id) }} />
)} )}
: null} : ( score !== null ? (
) : null )}
{loading ? (
) : ( isDocScene ? <>
{renderContent()}
{isGeneralMode &&
{keywords?.map(keyword => )}
} { isFullDocMode ? : null } { child_chunks.length > 0 && {}} enabled={enabled} /> } : <>
{renderContent()}
{isExternal ? t('datasetHitTesting.viewDetail') : t('datasetHitTesting.viewChart')}
)} {showModal && { await onDelete?.(id) }} onCancel={() => setShowModal(false)} /> }
) } export default React.memo(SegmentCard)