import React, { type FC, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiCloseLine, RiCollapseDiagonalLine, RiExpandDiagonalLine, } from '@remixicon/react' import { useDocumentContext } from '../index' import ActionButtons from './common/action-buttons' import ChunkContent from './common/chunk-content' import Keywords from './common/keywords' import RegenerationModal from './common/regeneration-modal' import { SegmentIndexTag } from './common/segment-index-tag' import Dot from './common/dot' import { useSegmentListContext } from './index' import { ChunkingMode, type SegmentDetailModel } from '@/models/datasets' import { useEventEmitterContextContext } from '@/context/event-emitter' import { formatNumber } from '@/utils/format' import classNames from '@/utils/classnames' import Divider from '@/app/components/base/divider' type ISegmentDetailProps = { segInfo?: Partial & { id: string } onUpdate: (segmentId: string, q: string, a: string, k: string[], needRegenerate?: boolean) => void onCancel: () => void isEditMode?: boolean docForm: ChunkingMode } /** * Show all the contents of the segment */ const SegmentDetail: FC = ({ segInfo, onUpdate, onCancel, isEditMode, docForm, }) => { const { t } = useTranslation() const [question, setQuestion] = useState(isEditMode ? segInfo?.content || '' : segInfo?.sign_content || '') const [answer, setAnswer] = useState(segInfo?.answer || '') const [keywords, setKeywords] = useState(segInfo?.keywords || []) const { eventEmitter } = useEventEmitterContextContext() const [loading, setLoading] = useState(false) const [showRegenerationModal, setShowRegenerationModal] = useState(false) const fullScreen = useSegmentListContext(s => s.fullScreen) const toggleFullScreen = useSegmentListContext(s => s.toggleFullScreen) const mode = useDocumentContext(s => s.mode) const parentMode = useDocumentContext(s => s.parentMode) eventEmitter?.useSubscription((v) => { if (v === 'update-segment') setLoading(true) if (v === 'update-segment-done') setLoading(false) }) const handleCancel = () => { onCancel() } const handleSave = () => { onUpdate(segInfo?.id || '', question, answer, keywords) } const handleRegeneration = () => { setShowRegenerationModal(true) } const onCancelRegeneration = () => { setShowRegenerationModal(false) } const onConfirmRegeneration = () => { onUpdate(segInfo?.id || '', question, answer, keywords, true) } const isParentChildMode = useMemo(() => { return mode === 'hierarchical' }, [mode]) const isFullDocMode = useMemo(() => { return mode === 'hierarchical' && parentMode === 'full-doc' }, [mode, parentMode]) const titleText = useMemo(() => { return isEditMode ? t('datasetDocuments.segment.editChunk') : t('datasetDocuments.segment.chunkDetail') }, [isEditMode, t]) const isQAModel = useMemo(() => { return docForm === ChunkingMode.qa }, [docForm]) const wordCountText = useMemo(() => { const contentLength = isQAModel ? (question.length + answer.length) : question.length const total = formatNumber(isEditMode ? contentLength : segInfo!.word_count as number) const count = isEditMode ? contentLength : segInfo!.word_count as number return `${total} ${t('datasetDocuments.segment.characters', { count })}` }, [isEditMode, question.length, answer.length, isQAModel, segInfo, t]) const labelPrefix = useMemo(() => { return isParentChildMode ? t('datasetDocuments.segment.parentChunk') : t('datasetDocuments.segment.chunk') }, [isParentChildMode, t]) return (
{titleText}
{wordCountText}
{isEditMode && fullScreen && ( <> )}
{fullScreen ? : }
setQuestion(question)} onAnswerChange={answer => setAnswer(answer)} isEditMode={isEditMode} />
{mode === 'custom' && setKeywords(keywords)} />}
{isEditMode && !fullScreen && (
)} { showRegenerationModal && ( ) }
) } export default React.memo(SegmentDetail)