mirror of
https://github.com/langgenius/dify.git
synced 2026-04-13 14:48:11 +08:00
feat: Refactor document context and update chunking mode handling across components
This commit is contained in:
parent
0975f5bdc2
commit
0a397ac477
@ -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, {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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'>
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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)
|
||||
|
||||
15
web/app/components/datasets/documents/detail/context.ts
Normal file
15
web/app/components/datasets/documents/detail/context.ts
Normal 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)
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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(() => {
|
||||
|
||||
@ -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 && (
|
||||
|
||||
@ -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'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user