### What problem does this PR solve? Use use-chunk-request.ts to replace chunk-hooks.ts; implement chunk selectAll, enable, disable and other functions [#3221](https://github.com/infiniflow/ragflow/issues/3221) ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)tags/v0.20.0
| @@ -1,9 +1,11 @@ | |||
| import message from '@/components/ui/message'; | |||
| import { ResponseGetType } from '@/interfaces/database/base'; | |||
| import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge'; | |||
| import kbService from '@/services/knowledge-service'; | |||
| import { useQuery } from '@tanstack/react-query'; | |||
| import { useMutation, useQuery } from '@tanstack/react-query'; | |||
| import { useDebounce } from 'ahooks'; | |||
| import { useCallback, useState } from 'react'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| import { IChunkListResult } from './chunk-hooks'; | |||
| import { | |||
| useGetPaginationWithRouter, | |||
| @@ -89,3 +91,27 @@ export const useFetchNextChunkList = (): ResponseGetType<{ | |||
| handleSetAvailable, | |||
| }; | |||
| }; | |||
| export const useSwitchChunk = () => { | |||
| const { t } = useTranslation(); | |||
| const { | |||
| data, | |||
| isPending: loading, | |||
| mutateAsync, | |||
| } = useMutation({ | |||
| mutationKey: ['switchChunk'], | |||
| mutationFn: async (params: { | |||
| chunk_ids?: string[]; | |||
| available_int?: number; | |||
| doc_id: string; | |||
| }) => { | |||
| const { data } = await kbService.switch_chunk(params); | |||
| if (data.code === 0) { | |||
| message.success(t('message.modified')); | |||
| } | |||
| return data?.code; | |||
| }, | |||
| }); | |||
| return { data, loading, switchChunk: mutateAsync }; | |||
| }; | |||
| @@ -3,7 +3,14 @@ import { Label } from '@/components/ui/label'; | |||
| import { Ban, CircleCheck, Trash2 } from 'lucide-react'; | |||
| import { useCallback } from 'react'; | |||
| export default ({ selectAllChunk, checked }) => { | |||
| type ICheckboxSetProps = { | |||
| selectAllChunk: (e: any) => void; | |||
| removeChunk: (e?: any) => void; | |||
| switchChunk: (available: number) => void; | |||
| checked: boolean; | |||
| }; | |||
| export default (props: ICheckboxSetProps) => { | |||
| const { selectAllChunk, removeChunk, switchChunk, checked } = props; | |||
| const handleSelectAllCheck = useCallback( | |||
| (e: any) => { | |||
| console.log('eee=', e); | |||
| @@ -12,25 +19,47 @@ export default ({ selectAllChunk, checked }) => { | |||
| [selectAllChunk], | |||
| ); | |||
| const handleDeleteClick = useCallback(() => { | |||
| removeChunk(); | |||
| }, [removeChunk]); | |||
| const handleEnabledClick = useCallback(() => { | |||
| switchChunk(1); | |||
| }, [switchChunk]); | |||
| const handleDisabledClick = useCallback(() => { | |||
| switchChunk(0); | |||
| }, [switchChunk]); | |||
| return ( | |||
| <div className="flex gap-[40px]"> | |||
| <div className="flex gap-[40px] p-4"> | |||
| <div className="flex items-center gap-3 cursor-pointer"> | |||
| <Checkbox | |||
| id="all_chunks_checkbox" | |||
| onCheckedChange={handleSelectAllCheck} | |||
| checked={checked} | |||
| className=" data-[state=checked]:bg-[#1668dc] data-[state=checked]:border-[#1668dc] data-[state=checked]:text-white" | |||
| /> | |||
| <Label htmlFor="all_chunks_checkbox">All Chunks</Label> | |||
| </div> | |||
| <div className="flex items-center cursor-pointer"> | |||
| <div | |||
| className="flex items-center cursor-pointer" | |||
| onClick={handleEnabledClick} | |||
| > | |||
| <CircleCheck size={16} /> | |||
| <span className="block ml-1">Enable</span> | |||
| </div> | |||
| <div className="flex items-center cursor-pointer"> | |||
| <div | |||
| className="flex items-center cursor-pointer" | |||
| onClick={handleDisabledClick} | |||
| > | |||
| <Ban size={16} /> | |||
| <span className="block ml-1">Disable</span> | |||
| </div> | |||
| <div className="flex items-center text-red-500 cursor-pointer"> | |||
| <div | |||
| className="flex items-center text-red-500 cursor-pointer" | |||
| onClick={handleDeleteClick} | |||
| > | |||
| <Trash2 size={16} /> | |||
| <span className="block ml-1">Delete</span> | |||
| </div> | |||
| @@ -41,7 +41,7 @@ | |||
| .chunkContainer { | |||
| display: flex; | |||
| // height: calc(100vh - 332px); | |||
| height: calc(100vh - 270px); | |||
| height: calc(100vh - 300px); | |||
| } | |||
| .chunkOtherContainer { | |||
| @@ -50,6 +50,7 @@ | |||
| .pageFooter { | |||
| padding-top: 10px; | |||
| padding-right: 10px; | |||
| height: 32px; | |||
| } | |||
| } | |||
| @@ -1,6 +1,9 @@ | |||
| import { useFetchNextChunkList, useSwitchChunk } from '@/hooks/chunk-hooks'; | |||
| import { | |||
| useFetchNextChunkList, | |||
| useSwitchChunk, | |||
| } from '@/hooks/use-chunk-request'; | |||
| import classNames from 'classnames'; | |||
| import { useCallback, useState } from 'react'; | |||
| import { useCallback, useEffect, useState } from 'react'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| import ChunkCard from './components/chunk-card'; | |||
| import CreatingModal from './components/chunk-creating-modal'; | |||
| @@ -43,6 +46,7 @@ const Chunk = () => { | |||
| const { t } = useTranslation(); | |||
| const { changeChunkTextMode, textMode } = useChangeChunkTextMode(); | |||
| const { switchChunk } = useSwitchChunk(); | |||
| const [chunkList, setChunkList] = useState(data); | |||
| const { | |||
| chunkUpdatingLoading, | |||
| onChunkUpdatingOk, | |||
| @@ -53,6 +57,9 @@ const Chunk = () => { | |||
| documentId, | |||
| } = useUpdateChunk(); | |||
| useEffect(() => { | |||
| setChunkList(data); | |||
| }, [data]); | |||
| const onPaginationChange: RAGFlowPaginationType['onChange'] = ( | |||
| page, | |||
| size, | |||
| @@ -115,10 +122,22 @@ const Chunk = () => { | |||
| available_int: available, | |||
| doc_id: documentId, | |||
| }); | |||
| if (!chunkIds && resCode === 0) { | |||
| if (ids?.length && resCode === 0) { | |||
| chunkList.forEach((x: any) => { | |||
| if (ids.indexOf(x['chunk_id']) > -1) { | |||
| x['available_int'] = available; | |||
| } | |||
| }); | |||
| setChunkList(chunkList); | |||
| } | |||
| }, | |||
| [switchChunk, documentId, selectedChunkIds, showSelectedChunkWarning], | |||
| [ | |||
| switchChunk, | |||
| documentId, | |||
| selectedChunkIds, | |||
| showSelectedChunkWarning, | |||
| chunkList, | |||
| ], | |||
| ); | |||
| const { highlights, setWidthAndHeight } = | |||
| @@ -156,7 +175,7 @@ const Chunk = () => { | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div className=" rounded-[16px] bg-[#FFF]/10 pl-[20px] pb-[20px] pt-[20px] box-border "> | |||
| <div className=" rounded-[16px] bg-[#FFF]/10 pl-[20px] pb-[20px] pt-[20px] box-border mb-2"> | |||
| <ChunkResultBar | |||
| handleInputChange={handleInputChange} | |||
| searchString={searchString} | |||
| @@ -169,6 +188,8 @@ const Chunk = () => { | |||
| <div className="pt-[5px] pb-[5px]"> | |||
| <CheckboxSets | |||
| selectAllChunk={selectAllChunk} | |||
| switchChunk={handleSwitchChunk} | |||
| removeChunk={handleRemoveChunk} | |||
| checked={selectedChunkIds.length === data.length} | |||
| /> | |||
| </div> | |||
| @@ -182,7 +203,7 @@ const Chunk = () => { | |||
| 'flex flex-col gap-4', | |||
| )} | |||
| > | |||
| {data.map((item) => ( | |||
| {chunkList.map((item) => ( | |||
| <ChunkCard | |||
| item={item} | |||
| key={item.chunk_id} | |||
| @@ -199,18 +220,18 @@ const Chunk = () => { | |||
| ))} | |||
| </div> | |||
| </div> | |||
| <div className={styles.pageFooter}> | |||
| <RAGFlowPagination | |||
| pageSize={pagination.pageSize} | |||
| current={pagination.current} | |||
| total={total} | |||
| onChange={(page, pageSize) => { | |||
| onPaginationChange(page, pageSize); | |||
| }} | |||
| ></RAGFlowPagination> | |||
| </div> | |||
| </div> | |||
| </Spin> | |||
| <div className={styles.pageFooter}> | |||
| <RAGFlowPagination | |||
| pageSize={pagination.pageSize} | |||
| current={pagination.current} | |||
| total={total} | |||
| onChange={(page, pageSize) => { | |||
| onPaginationChange(page, pageSize); | |||
| }} | |||
| ></RAGFlowPagination> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||