From 77950e48c76f4a3b29d01831d43039caba29888a Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 18 十一月 2025 14:12:42 +0800
Subject: [PATCH] 修改
---
app/components/datasets/documents/index.tsx | 124 +++++++++++++----------------------------
1 files changed, 40 insertions(+), 84 deletions(-)
diff --git a/app/components/datasets/documents/index.tsx b/app/components/datasets/documents/index.tsx
index 32980ee..c9df2f2 100644
--- a/app/components/datasets/documents/index.tsx
+++ b/app/components/datasets/documents/index.tsx
@@ -1,12 +1,13 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
+import useSWR from 'swr'
import { useTranslation } from 'react-i18next'
import { useRouter } from 'next/navigation'
import { useDebounce, useDebounceFn } from 'ahooks'
-import { groupBy } from 'lodash-es'
+import { groupBy, omit } from 'lodash-es'
import { PlusIcon } from '@heroicons/react/24/solid'
-import { RiDraftLine, RiExternalLinkLine } from '@remixicon/react'
+import { RiExternalLinkLine } from '@remixicon/react'
import AutoDisabledDocument from '../common/document-status-with-action/auto-disabled-document'
import List from './list'
import s from './style.module.css'
@@ -14,23 +15,18 @@
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { get } from '@/service/base'
-import { createDocument } from '@/service/datasets'
+import { createDocument, fetchDocuments } from '@/service/datasets'
import { useDatasetDetailContext } from '@/context/dataset-detail'
import { NotionPageSelectorModal } from '@/app/components/base/notion-page-selector'
import type { NotionPage } from '@/models/common'
import type { CreateDocumentReq } from '@/models/datasets'
-import { DataSourceType, ProcessMode } from '@/models/datasets'
+import { DataSourceType } from '@/models/datasets'
import IndexFailed from '@/app/components/datasets/common/document-status-with-action/index-failed'
import { useProviderContext } from '@/context/provider-context'
import cn from '@/utils/classnames'
-import { useDocumentList, useInvalidDocumentDetailKey, useInvalidDocumentList } from '@/service/knowledge/use-document'
+import { useInvalidDocumentDetailKey } from '@/service/knowledge/use-document'
import { useInvalid } from '@/service/use-base'
import { useChildSegmentListKey, useSegmentListKey } from '@/service/knowledge/use-segment'
-import useEditDocumentMetadata from '../metadata/hooks/use-edit-dataset-metadata'
-import DatasetMetadataDrawer from '../metadata/metadata-dataset/dataset-metadata-drawer'
-import StatusWithAction from '../common/document-status-with-action/status-with-action'
-import { LanguagesSupported } from '@/i18n/language'
-import { getLocaleOnClient } from '@/i18n'
const FolderPlusIcon = ({ className }: React.SVGProps<SVGElement>) => {
return <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
@@ -66,7 +62,7 @@
<div className={s.emptySymbolIconWrapper}>
{type === 'upload' ? <FolderPlusIcon /> : <NotionIcon />}
</div>
- <span className={s.emptyTitle}>{t('datasetDocuments.list.empty.title')}<ThreeDotsIcon className='relative -left-1.5 -top-3 inline' /></span>
+ <span className={s.emptyTitle}>{t('datasetDocuments.list.empty.title')}<ThreeDotsIcon className='inline relative -top-3 -left-1.5' /></span>
<div className={s.emptyTip}>
{t(`datasetDocuments.list.empty.${type}.tip`)}
</div>
@@ -82,7 +78,7 @@
}
export const fetcher = (url: string) => get(url, {}, {})
-const DEFAULT_LIMIT = 10
+const DEFAULT_LIMIT = 15
const Documents: FC<IDocumentsProps> = ({ datasetId }) => {
const { t } = useTranslation()
@@ -100,36 +96,36 @@
const isDataSourceWeb = dataset?.data_source_type === DataSourceType.WEB
const isDataSourceFile = dataset?.data_source_type === DataSourceType.FILE
const embeddingAvailable = !!dataset?.embedding_available
- const locale = getLocaleOnClient()
+
const debouncedSearchValue = useDebounce(searchValue, { wait: 500 })
- const { data: documentsRes, isFetching: isListLoading } = useDocumentList({
- datasetId,
- query: {
- page: currPage + 1,
- limit,
- keyword: debouncedSearchValue,
+ const query = useMemo(() => {
+ return { page: currPage + 1, limit, keyword: debouncedSearchValue, fetch: isDataSourceNotion ? true : '' }
+ }, [currPage, debouncedSearchValue, isDataSourceNotion, limit])
+
+ const { data: documentsRes, mutate, isLoading: isListLoading } = useSWR(
+ {
+ action: 'fetchDocuments',
+ datasetId,
+ params: query,
},
- refetchInterval: (isDataSourceNotion && timerCanRun) ? 2500 : 0,
- })
+ apiParams => fetchDocuments(omit(apiParams, 'action')),
+ { refreshInterval: (isDataSourceNotion && timerCanRun) ? 2500 : 0 },
+ )
- const invalidDocumentList = useInvalidDocumentList(datasetId)
-
+ const [isMuting, setIsMuting] = useState(false)
useEffect(() => {
- if (documentsRes) {
- const totalPages = Math.ceil(documentsRes.total / limit)
- if (totalPages < currPage + 1)
- setCurrPage(totalPages === 0 ? 0 : totalPages - 1)
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [documentsRes])
+ if (!isListLoading && isMuting)
+ setIsMuting(false)
+ }, [isListLoading, isMuting])
const invalidDocumentDetail = useInvalidDocumentDetailKey()
const invalidChunkList = useInvalid(useSegmentListKey)
const invalidChildChunkList = useInvalid(useChildSegmentListKey)
const handleUpdate = useCallback(() => {
- invalidDocumentList()
+ setIsMuting(true)
+ mutate()
invalidDocumentDetail()
setTimeout(() => {
invalidChunkList()
@@ -179,6 +175,8 @@
router.push(`/datasets/${datasetId}/documents/create`)
}
+ const isLoading = isListLoading // !documentsRes && !error
+
const handleSaveNotionPageSelected = async (selectedPages: NotionPage[]) => {
const workspacesMap = groupBy(selectedPages, 'workspace_id')
const workspaces = Object.keys(workspacesMap).map((workspaceId) => {
@@ -211,7 +209,7 @@
indexing_technique: dataset?.indexing_technique,
process_rule: {
rules: {},
- mode: ProcessMode.general,
+ mode: 'automatic',
},
} as CreateDocumentReq
@@ -219,7 +217,7 @@
datasetId,
body: params,
})
- invalidDocumentList()
+ mutate()
setTimerCanRun(true)
// mutateDatasetIndexingStatus(undefined, { revalidate: true })
setNotionPageSelectorModalVisible(false)
@@ -236,45 +234,23 @@
handleSearch()
}
- const {
- isShowEditModal: isShowEditMetadataModal,
- showEditModal: showEditMetadataModal,
- hideEditModal: hideEditMetadataModal,
- datasetMetaData,
- handleAddMetaData,
- handleRename,
- handleDeleteMetaData,
- builtInEnabled,
- setBuiltInEnabled,
- builtInMetaData,
- } = useEditDocumentMetadata({
- datasetId,
- dataset,
- onUpdateDocList: invalidDocumentList,
- })
-
return (
- <div className='flex h-full flex-col overflow-y-auto'>
+ <div className='flex flex-col h-full overflow-y-auto'>
<div className='flex flex-col justify-center gap-1 px-6 pt-4'>
<h1 className='text-base font-semibold text-text-primary'>{t('datasetDocuments.list.title')}</h1>
- <div className='flex items-center space-x-0.5 text-sm font-normal text-text-tertiary'>
+ <div className='flex items-center text-sm font-normal text-text-tertiary space-x-0.5'>
<span>{t('datasetDocuments.list.desc')}</span>
<a
className='flex items-center text-text-accent'
target='_blank'
- href={
- locale === LanguagesSupported[1]
- ? 'https://docs.dify.ai/zh-hans/guides/knowledge-base/integrate-knowledge-within-application'
- : 'https://docs.dify.ai/en/guides/knowledge-base/integrate-knowledge-within-application'
- }
- >
+ href='https://docs.dify.ai/guides/knowledge-base/integrate-knowledge-within-application'>
<span>{t('datasetDocuments.list.learnMore')}</span>
- <RiExternalLinkLine className='h-3 w-3' />
+ <RiExternalLinkLine className='w-3 h-3' />
</a>
</div>
</div>
- <div className='flex flex-1 flex-col px-6 py-4'>
- <div className='flex flex-wrap items-center justify-between'>
+ <div className='flex flex-col px-6 py-4 flex-1'>
+ <div className='flex items-center justify-between flex-wrap'>
<Input
showLeftIcon
showClearIcon
@@ -283,31 +259,12 @@
onChange={e => handleInputChange(e.target.value)}
onClear={() => handleInputChange('')}
/>
- <div className='flex !h-8 items-center justify-center gap-2'>
+ <div className='flex gap-2 justify-center items-center !h-8'>
{!isFreePlan && <AutoDisabledDocument datasetId={datasetId} />}
<IndexFailed datasetId={datasetId} />
- {!embeddingAvailable && <StatusWithAction type='warning' description={t('dataset.embeddingModelNotAvailable')} />}
- {embeddingAvailable && (
- <Button variant='secondary' className='shrink-0' onClick={showEditMetadataModal}>
- <RiDraftLine className='mr-1 size-4' />
- {t('dataset.metadata.metadata')}
- </Button>
- )}
- {isShowEditMetadataModal && (
- <DatasetMetadataDrawer
- userMetadata={datasetMetaData || []}
- onClose={hideEditMetadataModal}
- onAdd={handleAddMetaData}
- onRename={handleRename}
- onRemove={handleDeleteMetaData}
- builtInMetadata={builtInMetaData || []}
- isBuiltInEnabled={!!builtInEnabled}
- onIsBuiltInEnabledChange={setBuiltInEnabled}
- />
- )}
{embeddingAvailable && (
<Button variant='primary' onClick={routeToDocCreate} className='shrink-0'>
- <PlusIcon className={cn('mr-2 h-4 w-4 stroke-current')} />
+ <PlusIcon className={cn('h-4 w-4 mr-2 stroke-current')} />
{isDataSourceNotion && t('datasetDocuments.list.addPages')}
{isDataSourceWeb && t('datasetDocuments.list.addUrl')}
{(!dataset?.data_source_type || isDataSourceFile) && t('datasetDocuments.list.addFile')}
@@ -315,7 +272,7 @@
)}
</div>
</div>
- {isListLoading
+ {(isLoading && !isMuting)
? <Loading type='app' />
: total > 0
? <List
@@ -332,7 +289,6 @@
current: currPage,
onChange: setCurrPage,
}}
- onManageMetadata={showEditMetadataModal}
/>
: <EmptyElement canAdd={embeddingAvailable} onClick={routeToDocCreate} type={isDataSourceNotion ? 'sync' : 'upload'} />
}
--
Gitblit v1.8.0