mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-26 00:46:52 +08:00
fix: Change the data in the dataset page to be obtained using the interface (#8726)
### What problem does this PR solve? Change the data in the dataset page to be obtained using the interface, and change the import to obtain all data every 15 seconds to obtain the data of the current page every 5 seconds when parsing the existing file. [#3221](https://github.com/infiniflow/ragflow/issues/3221) ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -24,11 +24,13 @@
|
||||
|
||||
.chunkCard {
|
||||
width: 100%;
|
||||
padding: 18px 10px;
|
||||
}
|
||||
|
||||
.cardSelected {
|
||||
background-color: @selectedBackgroundColor;
|
||||
}
|
||||
|
||||
.cardSelectedDark {
|
||||
background-color: #ffffff2f;
|
||||
}
|
||||
|
||||
@ -1,11 +1,18 @@
|
||||
import Image from '@/components/image';
|
||||
import { useTheme } from '@/components/theme-provider';
|
||||
import { Card } from '@/components/ui/card';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { IChunk } from '@/interfaces/database/knowledge';
|
||||
import { Card, Checkbox, CheckboxProps, Flex, Popover, Switch } from 'antd';
|
||||
import { CheckedState } from '@radix-ui/react-checkbox';
|
||||
import classNames from 'classnames';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useTheme } from '@/components/theme-provider';
|
||||
import { ChunkTextMode } from '../../constant';
|
||||
import styles from './index.less';
|
||||
|
||||
@ -39,8 +46,8 @@ const ChunkCard = ({
|
||||
switchChunk(available === 0 ? 1 : 0, [item.chunk_id]);
|
||||
};
|
||||
|
||||
const handleCheck: CheckboxProps['onChange'] = (e) => {
|
||||
handleCheckboxClick(item.chunk_id, e.target.checked);
|
||||
const handleCheck = (e: CheckedState) => {
|
||||
handleCheckboxClick(item.chunk_id, e === 'indeterminate' ? false : e);
|
||||
};
|
||||
|
||||
const handleContentDoubleClick = () => {
|
||||
@ -54,7 +61,7 @@ const ChunkCard = ({
|
||||
useEffect(() => {
|
||||
setEnabled(available === 1);
|
||||
}, [available]);
|
||||
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
return (
|
||||
<Card
|
||||
className={classNames(styles.chunkCard, {
|
||||
@ -62,19 +69,34 @@ const ChunkCard = ({
|
||||
selected,
|
||||
})}
|
||||
>
|
||||
<Flex gap={'middle'} justify={'space-between'}>
|
||||
<Checkbox onChange={handleCheck} checked={checked}></Checkbox>
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<Checkbox onCheckedChange={handleCheck} checked={checked}></Checkbox>
|
||||
{item.image_id && (
|
||||
<Popover
|
||||
placement="right"
|
||||
content={
|
||||
<Image id={item.image_id} className={styles.imagePreview}></Image>
|
||||
}
|
||||
>
|
||||
<Image id={item.image_id} className={styles.image}></Image>
|
||||
<Popover open={open}>
|
||||
<PopoverTrigger
|
||||
asChild
|
||||
onMouseEnter={() => setOpen(true)}
|
||||
onMouseLeave={() => setOpen(false)}
|
||||
>
|
||||
<div>
|
||||
<Image id={item.image_id} className={styles.image}></Image>
|
||||
</div>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="p-0"
|
||||
align={'start'}
|
||||
side={'right'}
|
||||
sideOffset={-20}
|
||||
>
|
||||
<div>
|
||||
<Image
|
||||
id={item.image_id}
|
||||
className={styles.imagePreview}
|
||||
></Image>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)}
|
||||
|
||||
<section
|
||||
onDoubleClick={handleContentDoubleClick}
|
||||
onClick={handleContentClick}
|
||||
@ -89,11 +111,15 @@ const ChunkCard = ({
|
||||
})}
|
||||
></div>
|
||||
</section>
|
||||
|
||||
<div>
|
||||
<Switch checked={enabled} onChange={onChange} />
|
||||
<Switch
|
||||
checked={enabled}
|
||||
onCheckedChange={onChange}
|
||||
aria-readonly
|
||||
className="!m-0"
|
||||
/>
|
||||
</div>
|
||||
</Flex>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@ import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Ban, CircleCheck, Trash2 } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type ICheckboxSetProps = {
|
||||
selectAllChunk: (e: any) => void;
|
||||
@ -11,6 +12,7 @@ type ICheckboxSetProps = {
|
||||
};
|
||||
export default (props: ICheckboxSetProps) => {
|
||||
const { selectAllChunk, removeChunk, switchChunk, checked } = props;
|
||||
const { t } = useTranslation();
|
||||
const handleSelectAllCheck = useCallback(
|
||||
(e: any) => {
|
||||
console.log('eee=', e);
|
||||
@ -33,35 +35,35 @@ export default (props: ICheckboxSetProps) => {
|
||||
|
||||
return (
|
||||
<div className="flex gap-[40px] p-4">
|
||||
<div className="flex items-center gap-3 cursor-pointer">
|
||||
<div className="flex items-center gap-3 cursor-pointer text-muted-foreground hover:text-white">
|
||||
<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"
|
||||
className=" data-[state=checked]:bg-white data-[state=checked]:border-white data-[state=checked]:text-black border-muted-foreground text-muted-foreground hover:text-black hover:border-white "
|
||||
/>
|
||||
<Label htmlFor="all_chunks_checkbox">All Chunks</Label>
|
||||
<Label htmlFor="all_chunks_checkbox">{t('chunk.selectAll')}</Label>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center cursor-pointer"
|
||||
className="flex items-center cursor-pointer text-muted-foreground hover:text-white"
|
||||
onClick={handleEnabledClick}
|
||||
>
|
||||
<CircleCheck size={16} />
|
||||
<span className="block ml-1">Enable</span>
|
||||
<span className="block ml-1">{t('chunk.enable')}</span>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center cursor-pointer"
|
||||
className="flex items-center cursor-pointer text-muted-foreground hover:text-white"
|
||||
onClick={handleDisabledClick}
|
||||
>
|
||||
<Ban size={16} />
|
||||
<span className="block ml-1">Disable</span>
|
||||
<span className="block ml-1">{t('chunk.disable')}</span>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center text-red-500 cursor-pointer"
|
||||
className="flex items-center cursor-pointer text-red-400 hover:text-red-500"
|
||||
onClick={handleDeleteClick}
|
||||
>
|
||||
<Trash2 size={16} />
|
||||
<span className="block ml-1">Delete</span>
|
||||
<span className="block ml-1">{t('chunk.delete')}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -183,9 +183,9 @@ const Chunk = () => {
|
||||
<Spin spinning={loading} className={styles.spin} size="large">
|
||||
<div className="h-[100px] flex flex-col justify-end pb-[5px]">
|
||||
<div>
|
||||
<h2 className="text-[24px]">Chunk Result</h2>
|
||||
<h2 className="text-[24px]">{t('chunk.chunkResult')}</h2>
|
||||
<div className="text-[14px] text-[#979AAB]">
|
||||
View the chunked segments used for embedding and retrieval.
|
||||
{t('chunk.chunkResultTip')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -12,9 +12,7 @@ import {
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { useRowSelection } from '@/hooks/logic-hooks/use-row-selection';
|
||||
import { useFetchDocumentList } from '@/hooks/use-document-request';
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import { Upload } from 'lucide-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DatasetTable } from './dataset-table';
|
||||
import { useBulkOperateDataset } from './use-bulk-operate-dataset';
|
||||
@ -42,16 +40,7 @@ export default function Dataset() {
|
||||
handleFilterSubmit,
|
||||
loading,
|
||||
} = useFetchDocumentList();
|
||||
const { filters, documents: filteredDocuments } = useSelectDatasetFilters();
|
||||
const [datasetInfo, setDatasetInfo] = useState<IDocumentInfo[]>(documents);
|
||||
|
||||
useMemo(() => {
|
||||
setDatasetInfo(documents);
|
||||
}, [documents]);
|
||||
|
||||
useMemo(() => {
|
||||
setDatasetInfo(filteredDocuments);
|
||||
}, [filteredDocuments]);
|
||||
const { filters, onOpenChange } = useSelectDatasetFilters();
|
||||
|
||||
const {
|
||||
createLoading,
|
||||
@ -69,7 +58,6 @@ export default function Dataset() {
|
||||
rowSelection,
|
||||
setRowSelection,
|
||||
});
|
||||
|
||||
return (
|
||||
<section className="p-5">
|
||||
<ListFilterBar
|
||||
@ -78,13 +66,13 @@ export default function Dataset() {
|
||||
searchString={searchString}
|
||||
value={filterValue}
|
||||
onChange={handleFilterSubmit}
|
||||
onOpenChange={onOpenChange}
|
||||
filters={filters}
|
||||
leftPanel={
|
||||
<div className="items-start">
|
||||
<div className="pb-1">Dataset</div>
|
||||
<div className="pb-1">{t('knowledgeDetails.dataset')}</div>
|
||||
<div className="text-text-sub-title-invert text-sm">
|
||||
Please wait for your files to finish parsing before starting an
|
||||
AI-powered chat.
|
||||
{t('knowledgeDetails.datasetDescription')}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@ -111,7 +99,7 @@ export default function Dataset() {
|
||||
<BulkOperateBar list={list} count={selectedCount}></BulkOperateBar>
|
||||
)}
|
||||
<DatasetTable
|
||||
documents={datasetInfo}
|
||||
documents={documents}
|
||||
pagination={pagination}
|
||||
setPagination={setPagination}
|
||||
rowSelection={rowSelection}
|
||||
|
||||
@ -1,30 +1,36 @@
|
||||
import { useFetchAllDocumentList } from '@/hooks/use-document-request';
|
||||
import { groupListByType } from '@/utils/dataset-util';
|
||||
import { FilterCollection } from '@/components/list-filter-bar/interface';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { useGetDocumentFilter } from '@/hooks/use-document-request';
|
||||
import { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function useSelectDatasetFilters() {
|
||||
const {
|
||||
data: { docs: documents },
|
||||
} = useFetchAllDocumentList();
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
const { filter, onOpenChange } = useGetDocumentFilter();
|
||||
|
||||
const fileTypes = useMemo(() => {
|
||||
return groupListByType(documents, 'type', 'type');
|
||||
}, [documents]);
|
||||
|
||||
if (filter.suffix) {
|
||||
return Object.keys(filter.suffix).map((x) => ({
|
||||
id: x,
|
||||
label: x.toUpperCase(),
|
||||
count: filter.suffix[x],
|
||||
}));
|
||||
}
|
||||
}, [filter.suffix]);
|
||||
const fileStatus = useMemo(() => {
|
||||
return groupListByType(documents, 'run', 'run').map((x) => ({
|
||||
...x,
|
||||
label: t(`knowledgeDetails.runningStatus${x.label}`),
|
||||
}));
|
||||
}, [documents, t]);
|
||||
const filters = useMemo(() => {
|
||||
if (filter.run_status) {
|
||||
return Object.keys(filter.run_status).map((x) => ({
|
||||
id: x,
|
||||
label: t(`runningStatus${x}`),
|
||||
count: filter.run_status[x as unknown as number],
|
||||
}));
|
||||
}
|
||||
}, [filter.run_status, t]);
|
||||
const filters: FilterCollection[] = useMemo(() => {
|
||||
return [
|
||||
{ field: 'type', label: 'File Type', list: fileTypes },
|
||||
{ field: 'run', label: 'Status', list: fileStatus },
|
||||
];
|
||||
] as FilterCollection[];
|
||||
}, [fileStatus, fileTypes]);
|
||||
|
||||
return { fileTypes, fileStatus, filters, documents };
|
||||
return { filters, onOpenChange };
|
||||
}
|
||||
|
||||
@ -35,9 +35,8 @@ export default function RetrievalTesting() {
|
||||
<div className="p-5">
|
||||
<section className="flex justify-between items-center">
|
||||
<TopTitle
|
||||
title={'Configuration'}
|
||||
description={` Update your knowledge base configuration here, particularly the chunk
|
||||
method.`}
|
||||
title={'Retrieval testing'}
|
||||
description={`Conduct a retrieval test to check if RAGFlow can recover the intended content for the LLM.`}
|
||||
></TopTitle>
|
||||
{/* <Button>Save as Preset</Button> */}
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user