diff --git a/web/app/components/datasets/documents/detail/index.tsx b/web/app/components/datasets/documents/detail/index.tsx index 891c177169..cf9aa62fab 100644 --- a/web/app/components/datasets/documents/detail/index.tsx +++ b/web/app/components/datasets/documents/detail/index.tsx @@ -1,8 +1,8 @@ 'use client' import type { FC } from 'react' -import type { DataSourceInfo, FileItem, FullDocumentDetail, LegacyDataSourceInfo } from '@/models/datasets' +import type { DataSourceInfo, DocumentDisplayStatus, FileItem, FullDocumentDetail, LegacyDataSourceInfo } from '@/models/datasets' import * as React from 'react' -import { useMemo, useState } from 'react' +import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Divider from '@/app/components/base/divider' import FloatRightContainer from '@/app/components/base/float-right-container' @@ -11,7 +11,7 @@ import Toast from '@/app/components/base/toast' import Metadata from '@/app/components/datasets/metadata/metadata-document' import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' -import { ChunkingMode } from '@/models/datasets' +import { ChunkingMode, DisplayStatusList } from '@/models/datasets' import { useRouter, useSearchParams } from '@/next/navigation' import { useDocumentDetail, useDocumentMetadata, useInvalidDocumentList } from '@/service/knowledge/use-document' import { useCheckSegmentBatchImportProgress, useChildSegmentListKey, useSegmentBatchImport, useSegmentListKey } from '@/service/knowledge/use-segment' @@ -32,6 +32,14 @@ type DocumentDetailProps = { documentId: string } +const NON_TERMINAL_DISPLAY_STATUSES = new Set( + DisplayStatusList.filter(s => s === 'queuing' || s === 'indexing' || s === 'paused'), +) + +const isLegacyDataSourceInfo = (info?: DataSourceInfo): info is LegacyDataSourceInfo => { + return !!info && 'upload_file' in info +} + const DocumentDetail: FC = ({ datasetId, documentId }) => { const router = useRouter() const searchParams = useSearchParams() @@ -89,6 +97,12 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { datasetId, documentId, params: { metadata: 'without' }, + refetchInterval: (query) => { + const status = query.state.data?.display_status + if (!status || NON_TERMINAL_DISPLAY_STATUSES.has(status)) + return 2500 + return false + }, }) const { data: documentMetadata } = useDocumentMetadata({ @@ -97,19 +111,15 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { params: { metadata: 'only' }, }) - const backToPrev = () => { + const backToPrev = useCallback(() => { const queryString = searchParams.toString() const backPath = `/datasets/${datasetId}/documents${queryString ? `?${queryString}` : ''}` router.push(backPath) - } + }, [searchParams, datasetId, router]) const isDetailLoading = !documentDetail && !error - const embedding = ['queuing', 'indexing', 'paused'].includes((documentDetail?.display_status || '').toLowerCase()) - - const isLegacyDataSourceInfo = (info?: DataSourceInfo): info is LegacyDataSourceInfo => { - return !!info && 'upload_file' in info - } + const embedding = NON_TERMINAL_DISPLAY_STATUSES.has(documentDetail?.display_status as DocumentDisplayStatus) const documentUploadFile = useMemo(() => { if (!documentDetail?.data_source_info) @@ -123,7 +133,7 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { const invalidChildChunkList = useInvalid(useChildSegmentListKey) const invalidDocumentList = useInvalidDocumentList(datasetId) - const handleOperate = (operateName?: string) => { + const handleOperate = useCallback((operateName?: string) => { invalidDocumentList() if (operateName === 'delete') { backToPrev() @@ -138,7 +148,7 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { }, 5000) } } - } + }, [invalidDocumentList, backToPrev, detailMutate, invalidChunkList, invalidChildChunkList]) const parentMode = useMemo(() => { return documentDetail?.document_process_rule?.rules?.parent_mode || documentDetail?.dataset_process_rule?.rules?.parent_mode || 'paragraph' @@ -149,19 +159,41 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { return chunkMode === ChunkingMode.parentChild && parentMode === 'full-doc' }, [documentDetail?.doc_form, parentMode]) + const contextValue = useMemo(() => ({ + datasetId, + documentId, + docForm: documentDetail?.doc_form as ChunkingMode, + parentMode, + }), [datasetId, documentId, documentDetail?.doc_form, parentMode]) + + const statusDetail = useMemo(() => ({ + enabled: documentDetail?.enabled || false, + archived: documentDetail?.archived || false, + id: documentId, + }), [documentDetail?.enabled, documentDetail?.archived, documentId]) + + const operationsDetail = useMemo(() => ({ + name: documentDetail?.name || '', + enabled: documentDetail?.enabled || false, + archived: documentDetail?.archived || false, + id: documentId, + data_source_type: documentDetail?.data_source_type || '', + doc_form: documentDetail?.doc_form || '', + }), [documentDetail?.name, documentDetail?.enabled, documentDetail?.archived, documentId, documentDetail?.data_source_type, documentDetail?.doc_form]) + + const docDetail = useMemo(() => ({ + ...documentDetail, + ...documentMetadata, + doc_type: documentMetadata?.doc_type === 'others' ? '' : documentMetadata?.doc_type, + } as FullDocumentDetail), [documentDetail, documentMetadata]) + const backButtonLabel = t('operation.back', { ns: 'common' }) const metadataToggleLabel = `${showMetadata ? t('operation.close', { ns: 'common' }) : t('operation.view', { ns: 'common' })} ${t('metadata.title', { ns: 'datasetDocuments' })}` return ( - +
diff --git a/web/service/knowledge/use-document.ts b/web/service/knowledge/use-document.ts index 4eb2b7d282..6e48d7b6f4 100644 --- a/web/service/knowledge/use-document.ts +++ b/web/service/knowledge/use-document.ts @@ -133,15 +133,19 @@ export const useSyncWebsite = () => { } const useDocumentDetailKey = [NAME_SPACE, 'documentDetail', 'withoutMetaData'] +type DocumentDetailRefetchInterval = UseQueryOptions['refetchInterval'] + export const useDocumentDetail = (payload: { datasetId: string documentId: string params: { metadata: MetadataType } + refetchInterval?: DocumentDetailRefetchInterval }) => { - const { datasetId, documentId, params } = payload + const { datasetId, documentId, params, refetchInterval } = payload return useQuery({ queryKey: [...useDocumentDetailKey, 'withoutMetaData', datasetId, documentId, params], queryFn: () => get(`/datasets/${datasetId}/documents/${documentId}`, { params }), + refetchInterval, }) }