mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-23 23:16:58 +08:00
feat: display chunk type in chunk editor and dialog (#12086)
### What problem does this PR solve? Display chunk type in chunk editor and dialog, may be one of below: - Image - Table - Text ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1,11 +1,10 @@
|
||||
import { api_host } from '@/utils/api';
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
|
||||
|
||||
interface IImage {
|
||||
interface IImage extends React.ImgHTMLAttributes<HTMLImageElement> {
|
||||
id: string;
|
||||
className?: string;
|
||||
onClick?(): void;
|
||||
t?: string | number;
|
||||
}
|
||||
|
||||
|
||||
@ -116,12 +116,15 @@ export interface ITenantInfo {
|
||||
tts_id: string;
|
||||
}
|
||||
|
||||
export type ChunkDocType = 'image' | 'table';
|
||||
|
||||
export interface IChunk {
|
||||
available_int: number; // Whether to enable, 0: not enabled, 1: enabled
|
||||
chunk_id: string;
|
||||
content_with_weight: string;
|
||||
doc_id: string;
|
||||
doc_name: string;
|
||||
doc_type_kwd?: ChunkDocType;
|
||||
image_id: string;
|
||||
important_kwd?: string[];
|
||||
question_kwd?: string[]; // keywords
|
||||
|
||||
@ -604,6 +604,12 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s
|
||||
'The document being parsed cannot be deleted',
|
||||
},
|
||||
chunk: {
|
||||
type: 'Type',
|
||||
docType: {
|
||||
image: 'Image',
|
||||
table: 'Table',
|
||||
text: 'Text',
|
||||
},
|
||||
chunk: 'Chunk',
|
||||
bulk: 'Bulk',
|
||||
selectAll: 'Select all',
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
}
|
||||
|
||||
.imagePreview {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 50vw;
|
||||
max-height: 50vh;
|
||||
object-fit: contain;
|
||||
|
||||
@ -2,17 +2,19 @@ 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 {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip';
|
||||
import { IChunk } from '@/interfaces/database/knowledge';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { CheckedState } from '@radix-ui/react-checkbox';
|
||||
import classNames from 'classnames';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ChunkTextMode } from '../../constant';
|
||||
import styles from './index.less';
|
||||
|
||||
@ -39,6 +41,7 @@ const ChunkCard = ({
|
||||
textMode,
|
||||
t: imageCacheKey,
|
||||
}: IProps) => {
|
||||
const { t } = useTranslation();
|
||||
const available = Number(item.available_int);
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
const { theme } = useTheme();
|
||||
@ -63,51 +66,59 @@ const ChunkCard = ({
|
||||
useEffect(() => {
|
||||
setEnabled(available === 1);
|
||||
}, [available]);
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={classNames(styles.chunkCard, {
|
||||
className={classNames('relative flex-none', styles.chunkCard, {
|
||||
[`${theme === 'dark' ? styles.cardSelectedDark : styles.cardSelected}`]:
|
||||
selected,
|
||||
})}
|
||||
>
|
||||
<span
|
||||
className="
|
||||
absolute top-0 right-0 px-4 py-1
|
||||
leading-none text-xs text-text-disabled
|
||||
bg-bg-card rounded-bl-2xl rounded-tr-lg
|
||||
border-l-0.5 border-b-0.5 border-border-button"
|
||||
>
|
||||
{t(
|
||||
`chunk.docType.${item.doc_type_kwd ? String(item.doc_type_kwd).toLowerCase() : 'text'}`,
|
||||
)}
|
||||
</span>
|
||||
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<Checkbox onCheckedChange={handleCheck} checked={checked}></Checkbox>
|
||||
|
||||
{/* Using <Tooltip> instead of <Popover> to avoid flickering when hovering over the image */}
|
||||
{item.image_id && (
|
||||
<Popover open={open}>
|
||||
<PopoverTrigger
|
||||
asChild
|
||||
onMouseEnter={() => setOpen(true)}
|
||||
onMouseLeave={() => setOpen(false)}
|
||||
>
|
||||
<div>
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<Image
|
||||
t={imageCacheKey}
|
||||
id={item.image_id}
|
||||
className={styles.image}
|
||||
/>
|
||||
</div>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
className="p-0"
|
||||
align={'start'}
|
||||
side={'right'}
|
||||
sideOffset={-20}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div>
|
||||
<Image
|
||||
t={imageCacheKey}
|
||||
id={item.image_id}
|
||||
className={styles.imagePreview}
|
||||
></Image>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
/>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<section
|
||||
onDoubleClick={handleContentDoubleClick}
|
||||
onClick={handleContentClick}
|
||||
className={styles.content}
|
||||
className={cn(styles.content, 'mt-2')}
|
||||
>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
@ -118,7 +129,8 @@ const ChunkCard = ({
|
||||
})}
|
||||
></div>
|
||||
</section>
|
||||
<div>
|
||||
|
||||
<div className="mt-2">
|
||||
<Switch
|
||||
checked={enabled}
|
||||
onCheckedChange={onChange}
|
||||
|
||||
@ -15,6 +15,7 @@ import {
|
||||
HoverCardContent,
|
||||
HoverCardTrigger,
|
||||
} from '@/components/ui/hover-card';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Modal } from '@/components/ui/modal/modal';
|
||||
import Space from '@/components/ui/space';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
@ -76,6 +77,7 @@ const ChunkCreatingModal: React.FC<IModalProps<any> & kFProps> = ({
|
||||
const { removeChunk } = useDeleteChunkByIds();
|
||||
const { data } = useFetchChunk(chunkId);
|
||||
const { t } = useTranslation();
|
||||
const isEditMode = !!chunkId;
|
||||
|
||||
const isTagParser = parserId === 'tag';
|
||||
const onSubmit = useCallback(
|
||||
@ -144,6 +146,28 @@ const ChunkCreatingModal: React.FC<IModalProps<any> & kFProps> = ({
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Do not display the type field in create mode */}
|
||||
{isEditMode && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="doc_type_kwd"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t(`chunk.type`)}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="text"
|
||||
value={t(
|
||||
`chunk.docType.${field.value ? String(field.value).toLowerCase() : 'text'}`,
|
||||
)}
|
||||
readOnly
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="image"
|
||||
|
||||
@ -45,7 +45,7 @@ export default (props: ICheckboxSetProps) => {
|
||||
}, [selectedChunkIds]);
|
||||
|
||||
return (
|
||||
<div className="flex gap-[40px] py-4 px-2">
|
||||
<div className="flex gap-[40px] py-4 px-2 h-14">
|
||||
<div className="flex items-center gap-3 cursor-pointer text-muted-foreground hover:text-text-primary">
|
||||
<Checkbox
|
||||
id="all_chunks_checkbox"
|
||||
|
||||
Reference in New Issue
Block a user