import { memo, useMemo, useRef, useState } from 'react' import type { FC } from 'react' import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import { useParams } from 'next/navigation' import { RiCloseLine, RiExpandDiagonalLine } from '@remixicon/react' import { useShallow } from 'zustand/react/shallow' import { useDocumentContext } from '../index' import { SegmentIndexTag } from './common/segment-index-tag' import ActionButtons from './common/action-buttons' import ChunkContent from './common/chunk-content' import AddAnother from './common/add-another' import Dot from './common/dot' import { useSegmentListContext } from './index' import { useStore as useAppStore } from '@/app/components/app/store' import { ToastContext } from '@/app/components/base/toast' import { type ChildChunkDetail, ChunkingMode, type SegmentUpdater } from '@/models/datasets' import classNames from '@/utils/classnames' import { formatNumber } from '@/utils/format' import Divider from '@/app/components/base/divider' import { useAddChildSegment } from '@/service/knowledge/use-segment' type NewChildSegmentModalProps = { chunkId: string onCancel: () => void onSave: (ChildChunk?: ChildChunkDetail) => void viewNewlyAddedChildChunk?: () => void } const NewChildSegmentModal: FC = ({ chunkId, onCancel, onSave, viewNewlyAddedChildChunk, }) => { const { t } = useTranslation() const { notify } = useContext(ToastContext) const [content, setContent] = useState('') const { datasetId, documentId } = useParams<{ datasetId: string; documentId: string }>() const [loading, setLoading] = useState(false) const [addAnother, setAddAnother] = useState(true) const fullScreen = useSegmentListContext(s => s.fullScreen) const toggleFullScreen = useSegmentListContext(s => s.toggleFullScreen) const { appSidebarExpand } = useAppStore(useShallow(state => ({ appSidebarExpand: state.appSidebarExpand, }))) const parentMode = useDocumentContext(s => s.parentMode) const refreshTimer = useRef(null) const isFullDocMode = useMemo(() => { return parentMode === 'full-doc' }, [parentMode]) const CustomButton = <> const handleCancel = (actionType: 'esc' | 'add' = 'esc') => { if (actionType === 'esc' || !addAnother) onCancel() } const { mutateAsync: addChildSegment } = useAddChildSegment() const handleSave = async () => { const params: SegmentUpdater = { content: '' } if (!content.trim()) return notify({ type: 'error', message: t('datasetDocuments.segment.contentEmpty') }) params.content = content setLoading(true) await addChildSegment({ datasetId, documentId, segmentId: chunkId, body: params }, { onSuccess(res) { notify({ type: 'success', message: t('datasetDocuments.segment.childChunkAdded'), className: `!w-[296px] !bottom-0 ${appSidebarExpand === 'expand' ? '!left-[216px]' : '!left-14'} !top-auto !right-auto !mb-[52px] !ml-11`, customComponent: isFullDocMode && CustomButton, }) handleCancel('add') if (isFullDocMode) { refreshTimer.current = setTimeout(() => { onSave() }, 3000) } else { onSave(res.data) } }, onSettled() { setLoading(false) }, }) } const wordCountText = useMemo(() => { const count = content.length return `${formatNumber(count)} ${t('datasetDocuments.segment.characters', { count })}` // eslint-disable-next-line react-hooks/exhaustive-deps }, [content.length]) return (
{t('datasetDocuments.segment.addChildChunk')}
{wordCountText}
{fullScreen && ( <> setAddAnother(!addAnother)} /> )}
setContent(content)} isEditMode={true} />
{!fullScreen && (
setAddAnother(!addAnother)} />
)}
) } export default memo(NewChildSegmentModal)