mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? feat: Add EntityTypesForm #162 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -22,6 +22,7 @@ import React, { useEffect, useMemo } from 'react';
|
||||
import { useFetchParserListOnMount } from './hooks';
|
||||
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import EntityTypesForm from '../entity-types-form';
|
||||
import LayoutRecognize from '../layout-recognize';
|
||||
import ParseConfiguration, {
|
||||
showRaptorParseConfiguration,
|
||||
@ -41,7 +42,14 @@ interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||
documentId: string;
|
||||
}
|
||||
|
||||
const hidePagesChunkMethods = ['qa', 'table', 'picture', 'resume', 'one'];
|
||||
const hidePagesChunkMethods = [
|
||||
'qa',
|
||||
'table',
|
||||
'picture',
|
||||
'resume',
|
||||
'one',
|
||||
'knowledge_graph',
|
||||
];
|
||||
|
||||
const ChunkMethodModal: React.FC<IProps> = ({
|
||||
documentId,
|
||||
@ -80,7 +88,7 @@ const ChunkMethodModal: React.FC<IProps> = ({
|
||||
return (
|
||||
isPdf &&
|
||||
hidePagesChunkMethods
|
||||
.filter((x) => x !== 'one')
|
||||
.filter((x) => x !== 'one' && x !== 'knowledge_graph')
|
||||
.every((x) => x !== selectedTag)
|
||||
);
|
||||
}, [selectedTag, isPdf]);
|
||||
@ -91,6 +99,8 @@ const ChunkMethodModal: React.FC<IProps> = ({
|
||||
(x) => x === false,
|
||||
);
|
||||
|
||||
const showEntityTypes = selectedTag === 'knowledge_graph';
|
||||
|
||||
const afterClose = () => {
|
||||
form.resetFields();
|
||||
};
|
||||
@ -262,6 +272,7 @@ const ChunkMethodModal: React.FC<IProps> = ({
|
||||
{showRaptorParseConfiguration(selectedTag) && (
|
||||
<ParseConfiguration></ParseConfiguration>
|
||||
)}
|
||||
{showEntityTypes && <EntityTypesForm></EntityTypesForm>}
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
3
web/src/components/edit-tag/index.less
Normal file
3
web/src/components/edit-tag/index.less
Normal file
@ -0,0 +1,3 @@
|
||||
.tweenGroup {
|
||||
display: inline-block;
|
||||
}
|
||||
115
web/src/components/edit-tag/index.tsx
Normal file
115
web/src/components/edit-tag/index.tsx
Normal file
@ -0,0 +1,115 @@
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import type { InputRef } from 'antd';
|
||||
import { Input, Tag, theme } from 'antd';
|
||||
import { TweenOneGroup } from 'rc-tween-one';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import styles from './index.less';
|
||||
|
||||
interface EditTagsProps {
|
||||
tags?: string[];
|
||||
setTags?: (tags: string[]) => void;
|
||||
}
|
||||
|
||||
const EditTag = ({ tags, setTags }: EditTagsProps) => {
|
||||
const { token } = theme.useToken();
|
||||
const [inputVisible, setInputVisible] = useState(false);
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const inputRef = useRef<InputRef>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (inputVisible) {
|
||||
inputRef.current?.focus();
|
||||
}
|
||||
}, [inputVisible]);
|
||||
|
||||
const handleClose = (removedTag: string) => {
|
||||
const newTags = tags?.filter((tag) => tag !== removedTag);
|
||||
setTags?.(newTags ?? []);
|
||||
};
|
||||
|
||||
const showInput = () => {
|
||||
setInputVisible(true);
|
||||
};
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setInputValue(e.target.value);
|
||||
};
|
||||
|
||||
const handleInputConfirm = () => {
|
||||
if (inputValue && tags?.indexOf(inputValue) === -1) {
|
||||
setTags?.([...tags, inputValue]);
|
||||
}
|
||||
setInputVisible(false);
|
||||
setInputValue('');
|
||||
};
|
||||
|
||||
const forMap = (tag: string) => {
|
||||
const tagElem = (
|
||||
<Tag
|
||||
closable
|
||||
onClose={(e) => {
|
||||
e.preventDefault();
|
||||
handleClose(tag);
|
||||
}}
|
||||
>
|
||||
{tag}
|
||||
</Tag>
|
||||
);
|
||||
return (
|
||||
<span key={tag} style={{ display: 'inline-block' }}>
|
||||
{tagElem}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const tagChild = tags?.map(forMap);
|
||||
|
||||
const tagPlusStyle: React.CSSProperties = {
|
||||
background: token.colorBgContainer,
|
||||
borderStyle: 'dashed',
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<span>
|
||||
<TweenOneGroup
|
||||
className={styles.tweenGroup}
|
||||
enter={{
|
||||
scale: 0.8,
|
||||
opacity: 0,
|
||||
type: 'from',
|
||||
duration: 100,
|
||||
}}
|
||||
onEnd={(e) => {
|
||||
if (e.type === 'appear' || e.type === 'enter') {
|
||||
(e.target as any).style = 'display: inline-block';
|
||||
}
|
||||
}}
|
||||
leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
|
||||
appear={false}
|
||||
>
|
||||
{tagChild}
|
||||
</TweenOneGroup>
|
||||
</span>
|
||||
{inputVisible ? (
|
||||
<Input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
size="small"
|
||||
style={{ width: 78 }}
|
||||
value={inputValue}
|
||||
onChange={handleInputChange}
|
||||
onBlur={handleInputConfirm}
|
||||
onPressEnter={handleInputConfirm}
|
||||
/>
|
||||
) : (
|
||||
<Tag onClick={showInput} style={tagPlusStyle}>
|
||||
<PlusOutlined />
|
||||
</Tag>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditTag;
|
||||
29
web/src/components/entity-types-form.tsx
Normal file
29
web/src/components/entity-types-form.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { Form } from 'antd';
|
||||
import EditTag from './edit-tag';
|
||||
|
||||
const initialEntityTypes = [
|
||||
'organization',
|
||||
'person',
|
||||
'location',
|
||||
'event',
|
||||
'time',
|
||||
];
|
||||
|
||||
const EntityTypesForm = () => {
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
return (
|
||||
<Form.Item
|
||||
name={['parser_config', 'entity_types']}
|
||||
label={t('entityTypes')}
|
||||
rules={[{ required: true }]}
|
||||
initialValue={initialEntityTypes}
|
||||
valuePropName="tags"
|
||||
trigger="setTags"
|
||||
>
|
||||
<EditTag></EditTag>
|
||||
</Form.Item>
|
||||
);
|
||||
};
|
||||
|
||||
export default EntityTypesForm;
|
||||
@ -12,7 +12,13 @@ import {
|
||||
} from 'antd';
|
||||
import random from 'lodash/random';
|
||||
|
||||
export const excludedParseMethods = ['table', 'resume', 'one', 'picture'];
|
||||
export const excludedParseMethods = [
|
||||
'table',
|
||||
'resume',
|
||||
'one',
|
||||
'picture',
|
||||
'knowledge_graph',
|
||||
];
|
||||
|
||||
export const showRaptorParseConfiguration = (parserId: string) => {
|
||||
return !excludedParseMethods.includes(parserId);
|
||||
|
||||
Reference in New Issue
Block a user