import React, { type FC, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiCloseLine, RiCollapseDiagonalLine, RiExpandDiagonalLine, } from '@remixicon/react' import { useDocumentContext } from '../context' 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 cn from '@/utils/classnames' import Divider from '@/app/components/base/divider' import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail' import { IndexingType } from '../../../create/step-two' type ISegmentDetailProps = { segInfo?: Partial & { id: string } onUpdate: (segmentId: string, q: string, a: string, k: string[], needRegenerate?: boolean) => void onCancel: () => void isEditMode?: boolean docForm: ChunkingMode onModalStateChange?: (isOpen: boolean) => void } /** * Show all the contents of the segment */ const SegmentDetail: FC = ({ segInfo, onUpdate, onCancel, isEditMode, docForm, onModalStateChange, }) => { 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 parentMode = useDocumentContext(s => s.parentMode) const indexingTechnique = useDatasetDetailContextWithSelector(s => s.dataset?.indexing_technique) eventEmitter?.useSubscription((v) => { if (v === 'update-segment') setLoading(true) if (v === 'update-segment-done') setLoading(false) }) const handleCancel = useCallback(() => { onCancel() }, [onCancel]) const handleSave = useCallback(() => { onUpdate(segInfo?.id || '', question, answer, keywords) }, [onUpdate, segInfo?.id, question, answer, keywords]) const handleRegeneration = useCallback(() => { setShowRegenerationModal(true) onModalStateChange?.(true) }, [onModalStateChange]) const onCancelRegeneration = useCallback(() => { setShowRegenerationModal(false) onModalStateChange?.(false) }, [onModalStateChange]) const onCloseAfterRegeneration = useCallback(() => { setShowRegenerationModal(false) onModalStateChange?.(false) onCancel() // Close the edit drawer }, [onCancel, onModalStateChange]) const onConfirmRegeneration = useCallback(() => { onUpdate(segInfo?.id || '', question, answer, keywords, true) }, [onUpdate, segInfo?.id, question, answer, keywords]) const wordCountText = useMemo(() => { const contentLength = docForm === ChunkingMode.qa ? (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, docForm, segInfo, t]) const isFullDocMode = docForm === ChunkingMode.parentChild && parentMode === 'full-doc' const titleText = isEditMode ? t('datasetDocuments.segment.editChunk') : t('datasetDocuments.segment.chunkDetail') const labelPrefix = docForm === ChunkingMode.parentChild ? t('datasetDocuments.segment.parentChunk') : t('datasetDocuments.segment.chunk') const isECOIndexing = indexingTechnique === IndexingType.ECONOMICAL return (
{titleText}
{wordCountText}
{isEditMode && fullScreen && ( <> )}
{fullScreen ? : }
setQuestion(question)} onAnswerChange={answer => setAnswer(answer)} isEditMode={isEditMode} />
{isECOIndexing && setKeywords(keywords)} />}
{isEditMode && !fullScreen && (
)} { showRegenerationModal && ( ) }
) } export default React.memo(SegmentDetail)