From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001
From: wwf <yearningwang@iqtogether.com>
Date: 星期三, 04 六月 2025 15:17:49 +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