ソースを参照

fix: enhance chunk list management with new invalidation keys and imp… (#12396)

ok
Wu Tianwei 3 ヶ月 前
コミット
34519de3b7
共有3 個のファイルを変更した60 個の追加25 個の削除を含む
  1. 50 20
      web/app/components/datasets/documents/detail/completed/index.tsx
  2. 6 3
      web/service/knowledge/use-segment.ts
  3. 4 2
      web/service/use-base.ts

+ 50 - 20
web/app/components/datasets/documents/detail/completed/index.tsx

@@ -32,6 +32,9 @@ import Checkbox from '@/app/components/base/checkbox'
 import {
   useChildSegmentList,
   useChildSegmentListKey,
+  useChunkListAllKey,
+  useChunkListDisabledKey,
+  useChunkListEnabledKey,
   useDeleteChildSegment,
   useDeleteSegment,
   useDisableSegment,
@@ -156,18 +159,18 @@ const Completed: FC<ICompletedProps> = ({
         page: isFullDocMode ? 1 : currentPage,
         limit: isFullDocMode ? 10 : limit,
         keyword: isFullDocMode ? '' : searchValue,
-        enabled: selectedStatus === 'all' ? 'all' : !!selectedStatus,
+        enabled: selectedStatus,
       },
     },
-    currentPage === 0,
   )
   const invalidSegmentList = useInvalid(useSegmentListKey)
 
   useEffect(() => {
     if (segmentListData) {
       setSegments(segmentListData.data || [])
-      if (segmentListData.total_pages < currentPage)
-        setCurrentPage(segmentListData.total_pages)
+      const totalPages = segmentListData.total_pages
+      if (totalPages < currentPage)
+        setCurrentPage(totalPages === 0 ? 1 : totalPages)
     }
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [segmentListData])
@@ -185,12 +188,12 @@ const Completed: FC<ICompletedProps> = ({
       documentId,
       segmentId: segments[0]?.id || '',
       params: {
-        page: currentPage,
+        page: currentPage === 0 ? 1 : currentPage,
         limit,
         keyword: searchValue,
       },
     },
-    !isFullDocMode || segments.length === 0 || currentPage === 0,
+    !isFullDocMode || segments.length === 0,
   )
   const invalidChildSegmentList = useInvalid(useChildSegmentListKey)
 
@@ -204,21 +207,20 @@ const Completed: FC<ICompletedProps> = ({
   useEffect(() => {
     if (childChunkListData) {
       setChildSegments(childChunkListData.data || [])
-      if (childChunkListData.total_pages < currentPage)
-        setCurrentPage(childChunkListData.total_pages)
+      const totalPages = childChunkListData.total_pages
+      if (totalPages < currentPage)
+        setCurrentPage(totalPages === 0 ? 1 : totalPages)
     }
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [childChunkListData])
 
   const resetList = useCallback(() => {
-    setSegments([])
     setSelectedSegmentIds([])
     invalidSegmentList()
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [])
 
   const resetChildList = useCallback(() => {
-    setChildSegments([])
     invalidChildSegmentList()
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [])
@@ -244,6 +246,20 @@ const Completed: FC<ICompletedProps> = ({
 
   const { mutateAsync: enableSegment } = useEnableSegment()
   const { mutateAsync: disableSegment } = useDisableSegment()
+  const invalidChunkListAll = useInvalid(useChunkListAllKey)
+  const invalidChunkListEnabled = useInvalid(useChunkListEnabledKey)
+  const invalidChunkListDisabled = useInvalid(useChunkListDisabledKey)
+
+  const refreshChunkListWithStatusChanged = () => {
+    switch (selectedStatus) {
+      case 'all':
+        invalidChunkListDisabled()
+        invalidChunkListEnabled()
+        break
+      default:
+        invalidSegmentList()
+    }
+  }
 
   const onChangeSwitch = useCallback(async (enable: boolean, segId?: string) => {
     const operationApi = enable ? enableSegment : disableSegment
@@ -255,6 +271,7 @@ const Completed: FC<ICompletedProps> = ({
             seg.enabled = enable
         }
         setSegments([...segments])
+        refreshChunkListWithStatusChanged()
       },
       onError: () => {
         notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
@@ -281,6 +298,23 @@ const Completed: FC<ICompletedProps> = ({
 
   const { mutateAsync: updateSegment } = useUpdateSegment()
 
+  const refreshChunkListDataWithDetailChanged = () => {
+    switch (selectedStatus) {
+      case 'all':
+        invalidChunkListDisabled()
+        invalidChunkListEnabled()
+        break
+      case true:
+        invalidChunkListAll()
+        invalidChunkListDisabled()
+        break
+      case false:
+        invalidChunkListAll()
+        invalidChunkListEnabled()
+        break
+    }
+  }
+
   const handleUpdateSegment = useCallback(async (
     segmentId: string,
     question: string,
@@ -330,6 +364,7 @@ const Completed: FC<ICompletedProps> = ({
           }
         }
         setSegments([...segments])
+        refreshChunkListDataWithDetailChanged()
         eventEmitter?.emit('update-segment-success')
       },
       onSettled() {
@@ -442,6 +477,7 @@ const Completed: FC<ICompletedProps> = ({
           seg.child_chunks?.push(newChildChunk!)
       }
       setSegments([...segments])
+      refreshChunkListDataWithDetailChanged()
     }
     else {
       resetChildList()
@@ -506,17 +542,10 @@ const Completed: FC<ICompletedProps> = ({
             }
           }
           setSegments([...segments])
+          refreshChunkListDataWithDetailChanged()
         }
         else {
-          for (const childSeg of childSegments) {
-            if (childSeg.id === childChunkId) {
-              childSeg.content = res.data.content
-              childSeg.type = res.data.type
-              childSeg.word_count = res.data.word_count
-              childSeg.updated_at = res.data.updated_at
-            }
-          }
-          setChildSegments([...childSegments])
+          resetChildList()
         }
       },
       onSettled: () => {
@@ -554,12 +583,13 @@ const Completed: FC<ICompletedProps> = ({
         <SimpleSelect
           onSelect={onChangeStatus}
           items={statusList.current}
-          defaultValue={'all'}
+          defaultValue={selectedStatus === 'all' ? 'all' : selectedStatus ? 1 : 0}
           className={s.select}
           wrapperClassName='h-fit mr-2'
           optionWrapClassName='w-[160px]'
           optionClassName='p-0'
           renderOption={({ item, selected }) => <StatusItem item={item} selected={selected} />}
+          notClearable
         />
         <Input
           showLeftIcon

+ 6 - 3
web/service/knowledge/use-segment.ts

@@ -14,6 +14,9 @@ import type {
 const NAME_SPACE = 'segment'
 
 export const useSegmentListKey = [NAME_SPACE, 'chunkList']
+export const useChunkListEnabledKey = [NAME_SPACE, 'chunkList', { enabled: true }]
+export const useChunkListDisabledKey = [NAME_SPACE, 'chunkList', { enabled: false }]
+export const useChunkListAllKey = [NAME_SPACE, 'chunkList', { enabled: 'all' }]
 
 export const useSegmentList = (
   payload: {
@@ -23,7 +26,7 @@ export const useSegmentList = (
       page: number
       limit: number
       keyword: string
-      enabled: boolean | 'all'
+      enabled: boolean | 'all' | ''
     }
   },
   disable?: boolean,
@@ -31,7 +34,7 @@ export const useSegmentList = (
   const { datasetId, documentId, params } = payload
   const { page, limit, keyword, enabled } = params
   return useQuery<SegmentsResponse>({
-    queryKey: [...useSegmentListKey, datasetId, documentId, page, limit, keyword, enabled],
+    queryKey: [...useSegmentListKey, { datasetId, documentId, page, limit, keyword, enabled }],
     queryFn: () => {
       return get<SegmentsResponse>(`/datasets/${datasetId}/documents/${documentId}/segments`, { params })
     },
@@ -110,7 +113,7 @@ export const useChildSegmentList = (
   const { datasetId, documentId, segmentId, params } = payload
   const { page, limit, keyword } = params
   return useQuery({
-    queryKey: [...useChildSegmentListKey, datasetId, documentId, segmentId, page, limit, keyword],
+    queryKey: [...useChildSegmentListKey, { datasetId, documentId, segmentId, page, limit, keyword }],
     queryFn: () => {
       return get<ChildSegmentsResponse>(`/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}/child_chunks`, { params })
     },

+ 4 - 2
web/service/use-base.ts

@@ -1,13 +1,15 @@
 import {
+  type QueryKey,
   useQueryClient,
 } from '@tanstack/react-query'
 
-export const useInvalid = (key: string[]) => {
+export const useInvalid = (key: QueryKey) => {
   const queryClient = useQueryClient()
   return () => {
     queryClient.invalidateQueries(
       {
         queryKey: key,
-      })
+      },
+    )
   }
 }