feat: Refactor document context and update chunking mode handling across components

This commit is contained in:
twwu 2025-08-05 14:19:28 +08:00
parent 0975f5bdc2
commit 0a397ac477
13 changed files with 134 additions and 126 deletions

View File

@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'
import FileIcon from '../document-file-icon'
import DocumentList from './document-list'
import type { DocumentItem, ParentMode, SimpleDocumentDetail } from '@/models/datasets'
import { ProcessMode } from '@/models/datasets'
import { ChunkingMode } from '@/models/datasets'
import {
PortalToFollowElem,
PortalToFollowElemContent,
@ -24,7 +24,7 @@ type Props = {
value: {
name?: string
extension?: string
processMode?: ProcessMode
chunkingMode?: ChunkingMode
parentMode?: ParentMode
}
onChange: (value: SimpleDocumentDetail) => void
@ -39,7 +39,7 @@ const DocumentPicker: FC<Props> = ({
const {
name,
extension,
processMode,
chunkingMode,
parentMode,
} = value
const [query, setQuery] = useState('')
@ -53,7 +53,7 @@ const DocumentPicker: FC<Props> = ({
},
})
const documentsList = data?.data
const isParentChild = processMode === ProcessMode.parentChild
const isParentChild = chunkingMode === ChunkingMode.parentChild
const TypeIcon = isParentChild ? ParentChildChunk : GeneralChunk
const [open, {

View File

@ -2,14 +2,14 @@ import { type FC, useMemo, useState } from 'react'
import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { EditSlice } from '../../../formatted-text/flavours/edit-slice'
import { useDocumentContext } from '../index'
import { useDocumentContext } from '../context'
import { FormattedText } from '../../../formatted-text/formatted'
import Empty from './common/empty'
import FullDocListSkeleton from './skeleton/full-doc-list-skeleton'
import { useSegmentListContext } from './index'
import type { ChildChunkDetail } from '@/models/datasets'
import Input from '@/app/components/base/input'
import classNames from '@/utils/classnames'
import cn from '@/utils/classnames'
import Divider from '@/app/components/base/divider'
import { formatNumber } from '@/utils/format'
@ -84,28 +84,27 @@ const ChildSegmentList: FC<IChildSegmentCardProps> = ({
const count = text === '--' ? 0 : total
return `${count} ${t('datasetDocuments.segment.searchResults', { count })}`
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFullDocMode, total, childChunks.length, inputValue])
return (
<div className={classNames(
<div className={cn(
'flex flex-col',
contentOpacity,
isParagraphMode ? 'pt-1 pb-2' : 'px-3 grow',
isParagraphMode ? 'pb-2 pt-1' : 'grow px-3',
(isFullDocMode && isLoading) && 'overflow-y-hidden',
)}>
{isFullDocMode ? <Divider type='horizontal' className='my-1 h-[1px] bg-divider-subtle' /> : null}
<div className={classNames('flex items-center justify-between', isFullDocMode ? 'pt-2 pb-3 sticky -top-2 left-0 bg-background-default' : '')}>
<div className={classNames(
'h-7 flex items-center pl-1 pr-3 rounded-lg',
<div className={cn('flex items-center justify-between', isFullDocMode ? 'sticky -top-2 left-0 bg-background-default pb-3 pt-2' : '')}>
<div className={cn(
'flex h-7 items-center rounded-lg pl-1 pr-3',
isParagraphMode && 'cursor-pointer',
(isParagraphMode && collapsed) && 'bg-dataset-child-chunk-expand-btn-bg',
isFullDocMode && 'pl-0',
)}
onClick={(event) => {
event.stopPropagation()
toggleCollapse()
}}
onClick={(event) => {
event.stopPropagation()
toggleCollapse()
}}
>
{
isParagraphMode
@ -117,11 +116,11 @@ const ChildSegmentList: FC<IChildSegmentCardProps> = ({
: null
}
<span className='system-sm-semibold-uppercase text-text-secondary'>{totalText}</span>
<span className={classNames('text-text-quaternary text-xs font-medium pl-1.5', isParagraphMode ? 'hidden group-hover/card:inline-block' : '')}>·</span>
<span className={cn('pl-1.5 text-xs font-medium text-text-quaternary', isParagraphMode ? 'hidden group-hover/card:inline-block' : '')}>·</span>
<button
type='button'
className={classNames(
'px-1.5 py-1 text-components-button-secondary-accent-text system-xs-semibold-uppercase',
className={cn(
'system-xs-semibold-uppercase px-1.5 py-1 text-components-button-secondary-accent-text',
isParagraphMode ? 'hidden group-hover/card:inline-block' : '',
(isFullDocMode && isLoading) ? 'text-components-button-secondary-accent-text-disabled' : '',
)}
@ -147,14 +146,14 @@ const ChildSegmentList: FC<IChildSegmentCardProps> = ({
</div>
{isLoading ? <FullDocListSkeleton /> : null}
{((isFullDocMode && !isLoading) || !collapsed)
? <div className={classNames('flex gap-x-0.5', isFullDocMode ? 'grow mb-6' : 'items-center')}>
? <div className={cn('flex gap-x-0.5', isFullDocMode ? 'mb-6 grow' : 'items-center')}>
{isParagraphMode && (
<div className='self-stretch'>
<Divider type='vertical' className='mx-[7px] w-[2px] bg-text-accent-secondary' />
</div>
)}
{childChunks.length > 0
? <FormattedText className={classNames('w-full !leading-6 flex flex-col', isParagraphMode ? 'gap-y-2' : 'gap-y-3')}>
? <FormattedText className={cn('flex w-full flex-col !leading-6', isParagraphMode ? 'gap-y-2' : 'gap-y-3')}>
{childChunks.map((childChunk) => {
const edited = childChunk.updated_at !== childChunk.created_at
const focused = currChildChunk?.childChunkInfo?.id === childChunk.id
@ -165,7 +164,7 @@ const ChildSegmentList: FC<IChildSegmentCardProps> = ({
onDelete={() => onDelete?.(childChunk.segment_id, childChunk.id)}
labelClassName={focused ? 'bg-state-accent-solid text-text-primary-on-surface' : ''}
labelInnerClassName={'text-[10px] font-semibold align-bottom leading-6'}
contentClassName={classNames('!leading-6', focused ? 'bg-state-accent-hover-alt text-text-primary' : 'text-text-secondary')}
contentClassName={cn('!leading-6', focused ? 'bg-state-accent-hover-alt text-text-primary' : 'text-text-secondary')}
showDivider={false}
onClick={(e) => {
e.stopPropagation()

View File

@ -1,9 +1,10 @@
import React, { type FC, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useKeyPress } from 'ahooks'
import { useDocumentContext } from '../../index'
import { useDocumentContext } from '../../context'
import Button from '@/app/components/base/button'
import { getKeyboardKeyCodeBySystem, getKeyboardKeyNameBySystem } from '@/app/components/workflow/utils'
import { ChunkingMode } from '@/models/datasets'
type IActionButtonsProps = {
handleCancel: () => void
@ -23,7 +24,7 @@ const ActionButtons: FC<IActionButtonsProps> = ({
isChildChunk = false,
}) => {
const { t } = useTranslation()
const mode = useDocumentContext(s => s.mode)
const docForm = useDocumentContext(s => s.docForm)
const parentMode = useDocumentContext(s => s.parentMode)
useKeyPress(['esc'], (e) => {
@ -37,11 +38,11 @@ const ActionButtons: FC<IActionButtonsProps> = ({
return
handleSave()
},
{ exactMatch: true, useCapture: true })
{ exactMatch: true, useCapture: true })
const isParentChildParagraphMode = useMemo(() => {
return mode === 'hierarchical' && parentMode === 'paragraph'
}, [mode, parentMode])
return docForm === ChunkingMode.parentChild && parentMode === 'paragraph'
}, [docForm, parentMode])
return (
<div className='flex items-center gap-x-2'>

View File

@ -5,7 +5,7 @@ import { useDebounceFn } from 'ahooks'
import { useTranslation } from 'react-i18next'
import { createContext, useContext, useContextSelector } from 'use-context-selector'
import { usePathname } from 'next/navigation'
import { useDocumentContext } from '../index'
import { useDocumentContext } from '../context'
import { ProcessStatus } from '../segment-add'
import s from './style.module.css'
import SegmentList from './segment-list'
@ -105,7 +105,6 @@ const Completed: FC<ICompletedProps> = ({
const datasetId = useDocumentContext(s => s.datasetId) || ''
const documentId = useDocumentContext(s => s.documentId) || ''
const docForm = useDocumentContext(s => s.docForm)
const mode = useDocumentContext(s => s.mode)
const parentMode = useDocumentContext(s => s.parentMode)
// the current segment id and whether to show the modal
const [currSegment, setCurrSegment] = useState<CurrSegmentType>({ showModal: false })
@ -151,8 +150,8 @@ const Completed: FC<ICompletedProps> = ({
}
const isFullDocMode = useMemo(() => {
return mode === 'hierarchical' && parentMode === 'full-doc'
}, [mode, parentMode])
return docForm === ChunkingMode.parentChild && parentMode === 'full-doc'
}, [docForm, parentMode])
const { isFetching: isLoadingSegmentList, data: segmentListData } = useSegmentList(
{
@ -175,7 +174,6 @@ const Completed: FC<ICompletedProps> = ({
if (totalPages < currentPage)
setCurrentPage(totalPages === 0 ? 1 : totalPages)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [segmentListData])
useEffect(() => {
@ -214,7 +212,6 @@ const Completed: FC<ICompletedProps> = ({
if (totalPages < currentPage)
setCurrentPage(totalPages === 0 ? 1 : totalPages)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [childChunkListData])
const resetList = useCallback(() => {
@ -375,13 +372,11 @@ const Completed: FC<ICompletedProps> = ({
useEffect(() => {
resetList()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname])
useEffect(() => {
if (importStatus === ProcessStatus.COMPLETED)
resetList()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [importStatus])
const onCancelBatchOperation = useCallback(() => {
@ -417,7 +412,7 @@ const Completed: FC<ICompletedProps> = ({
if (!isSearch) {
const total = segmentListData?.total ? formatNumber(segmentListData.total) : '--'
const count = total === '--' ? 0 : segmentListData!.total
const translationKey = (mode === 'hierarchical' && parentMode === 'paragraph')
const translationKey = (docForm === ChunkingMode.parentChild && parentMode === 'paragraph')
? 'datasetDocuments.segment.parentChunks'
: 'datasetDocuments.segment.chunks'
return `${total} ${t(translationKey, { count })}`
@ -427,7 +422,7 @@ const Completed: FC<ICompletedProps> = ({
const count = segmentListData?.total || 0
return `${total} ${t('datasetDocuments.segment.searchResults', { count })}`
}
}, [segmentListData, mode, parentMode, searchValue, selectedStatus, t])
}, [segmentListData, docForm, parentMode, searchValue, selectedStatus, t])
const toggleFullScreen = useCallback(() => {
setFullScreen(!fullScreen)

View File

@ -5,7 +5,7 @@ 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 { useDocumentContext } from '../context'
import { SegmentIndexTag } from './common/segment-index-tag'
import ActionButtons from './common/action-buttons'
import ChunkContent from './common/chunk-content'
@ -110,12 +110,11 @@ const NewChildSegmentModal: FC<NewChildSegmentModalProps> = ({
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 (
<div className={'flex h-full flex-col'}>
<div className={classNames('flex items-center justify-between', fullScreen ? 'py-3 pr-4 pl-6 border border-divider-subtle' : 'pt-3 pr-3 pl-4')}>
<div className={classNames('flex items-center justify-between', fullScreen ? 'border border-divider-subtle py-3 pl-6 pr-4' : 'pl-4 pr-3 pt-3')}>
<div className='flex flex-col'>
<div className='system-xl-semibold text-text-primary'>{t('datasetDocuments.segment.addChildChunk')}</div>
<div className='flex items-center gap-x-2'>
@ -146,8 +145,8 @@ const NewChildSegmentModal: FC<NewChildSegmentModalProps> = ({
</div>
</div>
</div>
<div className={classNames('flex grow w-full', fullScreen ? 'flex-row justify-center px-6 pt-6' : 'py-3 px-4')}>
<div className={classNames('break-all overflow-hidden whitespace-pre-line h-full', fullScreen ? 'w-1/2' : 'w-full')}>
<div className={classNames('flex w-full grow', fullScreen ? 'flex-row justify-center px-6 pt-6' : 'px-4 py-3')}>
<div className={classNames('h-full overflow-hidden whitespace-pre-line break-all', fullScreen ? 'w-1/2' : 'w-full')}>
<ChunkContent
docForm={ChunkingMode.parentChild}
question={content}

View File

@ -2,13 +2,13 @@ import React, { type FC, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiDeleteBinLine, RiEditLine } from '@remixicon/react'
import StatusItem from '../../../status-item'
import { useDocumentContext } from '../../index'
import { useDocumentContext } from '../../context'
import ChildSegmentList from '../child-segment-list'
import Tag from '../common/tag'
import Dot from '../common/dot'
import { SegmentIndexTag } from '../common/segment-index-tag'
import ParentChunkCardSkeleton from '../skeleton/parent-chunk-card-skeleton'
import type { ChildChunkDetail, SegmentDetailModel } from '@/models/datasets'
import { type ChildChunkDetail, ChunkingMode, type SegmentDetailModel } from '@/models/datasets'
import Switch from '@/app/components/base/switch'
import Divider from '@/app/components/base/divider'
import { formatNumber } from '@/utils/format'
@ -69,39 +69,39 @@ const SegmentCard: FC<ISegmentCardProps> = ({
updated_at,
} = detail as Required<ISegmentCardProps>['detail']
const [showModal, setShowModal] = useState(false)
const mode = useDocumentContext(s => s.mode)
const docForm = useDocumentContext(s => s.docForm)
const parentMode = useDocumentContext(s => s.parentMode)
const isGeneralMode = useMemo(() => {
return mode === 'custom'
}, [mode])
return docForm === ChunkingMode.text
}, [docForm])
const isParentChildMode = useMemo(() => {
return mode === 'hierarchical'
}, [mode])
return docForm === ChunkingMode.parentChild
}, [docForm])
const isParagraphMode = useMemo(() => {
return mode === 'hierarchical' && parentMode === 'paragraph'
}, [mode, parentMode])
return docForm === ChunkingMode.parentChild && parentMode === 'paragraph'
}, [docForm, parentMode])
const isFullDocMode = useMemo(() => {
return mode === 'hierarchical' && parentMode === 'full-doc'
}, [mode, parentMode])
return docForm === ChunkingMode.parentChild && parentMode === 'full-doc'
}, [docForm, parentMode])
const chunkEdited = useMemo(() => {
if (mode === 'hierarchical' && parentMode === 'full-doc')
if (docForm === ChunkingMode.parentChild && parentMode === 'full-doc')
return false
return isAfter(updated_at * 1000, created_at * 1000)
}, [mode, parentMode, updated_at, created_at])
}, [docForm, parentMode, updated_at, created_at])
const contentOpacity = useMemo(() => {
return (enabled || focused.segmentContent) ? '' : 'opacity-50 group-hover/card:opacity-100'
}, [enabled, focused.segmentContent])
const handleClickCard = useCallback(() => {
if (mode !== 'hierarchical' || parentMode !== 'full-doc')
if (docForm !== ChunkingMode.parentChild || parentMode !== 'full-doc')
onClick?.()
}, [mode, parentMode, onClick])
}, [docForm, parentMode, onClick])
const wordCountText = useMemo(() => {
const total = formatNumber(word_count)

View File

@ -5,7 +5,7 @@ import {
RiCollapseDiagonalLine,
RiExpandDiagonalLine,
} from '@remixicon/react'
import { useDocumentContext } from '../index'
import { useDocumentContext } from '../context'
import ActionButtons from './common/action-buttons'
import ChunkContent from './common/chunk-content'
import Keywords from './common/keywords'
@ -48,7 +48,6 @@ const SegmentDetail: FC<ISegmentDetailProps> = ({
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)
const indexingTechnique = useDatasetDetailContextWithSelector(s => s.dataset?.indexing_technique)
@ -86,9 +85,9 @@ const SegmentDetail: FC<ISegmentDetailProps> = ({
return `${total} ${t('datasetDocuments.segment.characters', { count })}`
}, [isEditMode, question.length, answer.length, docForm, segInfo, t])
const isFullDocMode = mode === 'hierarchical' && parentMode === 'full-doc'
const isFullDocMode = docForm === ChunkingMode.parentChild && parentMode === 'full-doc'
const titleText = isEditMode ? t('datasetDocuments.segment.editChunk') : t('datasetDocuments.segment.chunkDetail')
const labelPrefix = mode === 'hierarchical' ? t('datasetDocuments.segment.parentChunk') : t('datasetDocuments.segment.chunk')
const labelPrefix = docForm === ChunkingMode.parentChild ? t('datasetDocuments.segment.parentChunk') : t('datasetDocuments.segment.chunk')
const isECOIndexing = indexingTechnique === IndexingType.ECONOMICAL
return (

View File

@ -1,11 +1,11 @@
import React, { useMemo } from 'react'
import { useDocumentContext } from '../index'
import { useDocumentContext } from '../context'
import SegmentCard from './segment-card'
import Empty from './common/empty'
import GeneralListSkeleton from './skeleton/general-list-skeleton'
import ParagraphListSkeleton from './skeleton/paragraph-list-skeleton'
import { useSegmentListContext } from './index'
import type { ChildChunkDetail, SegmentDetailModel } from '@/models/datasets'
import { type ChildChunkDetail, ChunkingMode, type SegmentDetailModel } from '@/models/datasets'
import Checkbox from '@/app/components/base/checkbox'
import Divider from '@/app/components/base/divider'
@ -45,14 +45,14 @@ const SegmentList = (
ref: React.LegacyRef<HTMLDivElement>
},
) => {
const mode = useDocumentContext(s => s.mode)
const docForm = useDocumentContext(s => s.docForm)
const parentMode = useDocumentContext(s => s.parentMode)
const currSegment = useSegmentListContext(s => s.currSegment)
const currChildChunk = useSegmentListContext(s => s.currChildChunk)
const Skeleton = useMemo(() => {
return (mode === 'hierarchical' && parentMode === 'paragraph') ? ParagraphListSkeleton : GeneralListSkeleton
}, [mode, parentMode])
return (docForm === ChunkingMode.parentChild && parentMode === 'paragraph') ? ParagraphListSkeleton : GeneralListSkeleton
}, [docForm, parentMode])
// Loading skeleton
if (isLoading)

View File

@ -0,0 +1,15 @@
import type { ChunkingMode, ParentMode } from '@/models/datasets'
import { createContext, useContextSelector } from 'use-context-selector'
type DocumentContextValue = {
datasetId?: string
documentId?: string
docForm?: ChunkingMode
parentMode?: ParentMode
}
export const DocumentContext = createContext<DocumentContextValue>({})
export const useDocumentContext = (selector: (value: DocumentContextValue) => any) => {
return useContextSelector(DocumentContext, selector)
}

View File

@ -0,0 +1,43 @@
import type { FC } from 'react'
import type { ChunkingMode, ParentMode } from '@/models/datasets'
import { useRouter } from 'next/navigation'
import DocumentPicker from '../../common/document-picker'
import cn from '@/utils/classnames'
type DocumentTitleProps = {
datasetId: string
extension?: string
name?: string
chunkingMode?: ChunkingMode
parent_mode?: ParentMode
iconCls?: string
textCls?: string
wrapperCls?: string
}
export const DocumentTitle: FC<DocumentTitleProps> = ({
datasetId,
extension,
name,
chunkingMode,
parent_mode,
wrapperCls,
}) => {
const router = useRouter()
return (
<div className={cn('flex flex-1 items-center justify-start', wrapperCls)}>
<DocumentPicker
datasetId={datasetId}
value={{
name,
extension,
chunkingMode,
parentMode: parent_mode || 'paragraph',
}}
onChange={(doc) => {
router.push(`/datasets/${datasetId}/documents/${doc.id}`)
}}
/>
</div>
)
}

View File

@ -7,7 +7,7 @@ import { omit } from 'lodash-es'
import { RiLoader2Line, RiPauseCircleLine, RiPlayCircleLine } from '@remixicon/react'
import Image from 'next/image'
import { FieldInfo } from '../metadata'
import { useDocumentContext } from '../index'
import { useDocumentContext } from '../context'
import { IndexingType } from '../../../create/step-two'
import { indexMethodIcon, retrievalIcon } from '../../../create/icons'
import EmbeddingSkeleton from './skeleton'
@ -101,7 +101,6 @@ const RuleDetail: FC<IRuleDetailProps> = React.memo(({
break
}
return value
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sourceData])
return <div className='py-3'>
@ -198,7 +197,6 @@ const EmbeddingDetail: FC<IEmbeddingDetailProps> = ({
await sleep(2500)
await startQueryStatus()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [stopQueryStatus])
useEffect(() => {

View File

@ -1,13 +1,11 @@
'use client'
import type { FC } from 'react'
import React, { useMemo, useState } from 'react'
import { createContext, useContextSelector } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { useRouter } from 'next/navigation'
import { RiArrowLeftLine, RiLayoutLeft2Line, RiLayoutRight2Line } from '@remixicon/react'
import Operations from '../operations'
import StatusItem from '../status-item'
import DocumentPicker from '../../common/document-picker'
import Completed from './completed'
import Embedding from './embedding'
import Metadata from '@/app/components/datasets/metadata/metadata-document'
@ -18,65 +16,22 @@ import cn from '@/utils/classnames'
import Divider from '@/app/components/base/divider'
import Loading from '@/app/components/base/loading'
import Toast from '@/app/components/base/toast'
import type { ChunkingMode, FileItem, ParentMode, ProcessMode } from '@/models/datasets'
import type { ChunkingMode, FileItem } from '@/models/datasets'
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
import FloatRightContainer from '@/app/components/base/float-right-container'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { useCheckSegmentBatchImportProgress, useChildSegmentListKey, useSegmentBatchImport, useSegmentListKey } from '@/service/knowledge/use-segment'
import { useDocumentDetail, useDocumentMetadata, useInvalidDocumentList } from '@/service/knowledge/use-document'
import { useInvalid } from '@/service/use-base'
import { DocumentContext } from './context'
import { DocumentTitle } from './document-title'
type DocumentContextValue = {
datasetId?: string
documentId?: string
docForm: string
mode?: ProcessMode
parentMode?: ParentMode
}
export const DocumentContext = createContext<DocumentContextValue>({ docForm: '' })
export const useDocumentContext = (selector: (value: DocumentContextValue) => any) => {
return useContextSelector(DocumentContext, selector)
}
type DocumentTitleProps = {
datasetId: string
extension?: string
name?: string
processMode?: ProcessMode
parent_mode?: ParentMode
iconCls?: string
textCls?: string
wrapperCls?: string
}
export const DocumentTitle: FC<DocumentTitleProps> = ({ datasetId, extension, name, processMode, parent_mode, wrapperCls }) => {
const router = useRouter()
return (
<div className={cn('flex flex-1 items-center justify-start', wrapperCls)}>
<DocumentPicker
datasetId={datasetId}
value={{
name,
extension,
processMode,
parentMode: parent_mode,
}}
onChange={(doc) => {
router.push(`/datasets/${datasetId}/documents/${doc.id}`)
}}
/>
</div>
)
}
type Props = {
type DocumentDetailProps = {
datasetId: string
documentId: string
}
const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
const DocumentDetail: FC<DocumentDetailProps> = ({ datasetId, documentId }) => {
const router = useRouter()
const { t } = useTranslation()
@ -105,7 +60,8 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
Toast.notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}` })
},
onError: (e) => {
Toast.notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}${'message' in e ? `: ${e.message}` : ''}` })
const message = 'message' in e ? `: ${e.message}` : ''
Toast.notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}${message}` })
},
})
}
@ -121,7 +77,8 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
checkProcess(res.job_id)
},
onError: (e) => {
Toast.notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}${'message' in e ? `: ${e.message}` : ''}` })
const message = 'message' in e ? `: ${e.message}` : ''
Toast.notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}${message}` })
},
})
}
@ -131,6 +88,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
documentId,
params: { metadata: 'without' },
})
console.log('🚀 ~ DocumentDetail ~ documentDetail:', documentDetail)
const { data: documentMetadata } = useDocumentMetadata({
datasetId,
@ -173,7 +131,9 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
}
const mode = useMemo(() => {
return documentDetail?.document_process_rule?.mode || documentDetail?.dataset_process_rule?.mode
if (documentDetail?.document_process_rule?.mode)
return documentDetail.document_process_rule.mode
return documentDetail?.doc_form === 'hierarchical_model' ? 'hierarchical' : 'custom'
}, [documentDetail?.document_process_rule?.mode, documentDetail?.dataset_process_rule?.mode])
const parentMode = useMemo(() => {
@ -188,8 +148,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
<DocumentContext.Provider value={{
datasetId,
documentId,
docForm: documentDetail?.doc_form || '',
mode,
docForm: documentDetail?.doc_form as ChunkingMode,
parentMode,
}}>
<div className='flex h-full flex-col bg-background-default'>
@ -203,7 +162,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
name={documentDetail?.name}
wrapperCls='mr-2'
parent_mode={parentMode}
processMode={mode}
chunkingMode={documentDetail?.doc_form as ChunkingMode}
/>
<div className='flex flex-wrap items-center'>
{embeddingAvailable && documentDetail && !documentDetail.archived && !isFullDocMode && (

View File

@ -5,7 +5,7 @@ import { PencilIcon } from '@heroicons/react/24/outline'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { get } from 'lodash-es'
import { useDocumentContext } from '../index'
import { useDocumentContext } from '../context'
import s from './style.module.css'
import cn from '@/utils/classnames'
import Input from '@/app/components/base/input'