mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Display the document configuration dialog with shadcn #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
30
web/src/components/auto-keywords-form-field.tsx
Normal file
30
web/src/components/auto-keywords-form-field.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { SliderInputFormField } from './slider-input-form-field';
|
||||
|
||||
export function AutoKeywordsFormField() {
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
return (
|
||||
<SliderInputFormField
|
||||
name={'parser_config.auto_keywords'}
|
||||
label={t('autoKeywords')}
|
||||
max={30}
|
||||
min={0}
|
||||
tooltip={t('autoKeywordsTip')}
|
||||
></SliderInputFormField>
|
||||
);
|
||||
}
|
||||
|
||||
export function AutoQuestionsFormField() {
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
return (
|
||||
<SliderInputFormField
|
||||
name={'parser_config.auto_questions'}
|
||||
label={t('autoQuestions')}
|
||||
max={10}
|
||||
min={0}
|
||||
tooltip={t('autoQuestionsTip')}
|
||||
></SliderInputFormField>
|
||||
);
|
||||
}
|
||||
@ -14,21 +14,42 @@ import {
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { DocumentParserType } from '@/constants/knowledge';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-request';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { IParserConfig } from '@/interfaces/database/document';
|
||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import {} from 'module';
|
||||
import { useMemo } from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '../ui/select';
|
||||
import { useFetchParserListOnMount } from './hooks';
|
||||
AutoKeywordsFormField,
|
||||
AutoQuestionsFormField,
|
||||
} from '../auto-keywords-form-field';
|
||||
import { DatasetConfigurationContainer } from '../dataset-configuration-container';
|
||||
import { DelimiterFormField } from '../delimiter-form-field';
|
||||
import { EntityTypesFormField } from '../entity-types-form-field';
|
||||
import { ExcelToHtmlFormField } from '../excel-to-html-form-field';
|
||||
import {
|
||||
DocumentType,
|
||||
LayoutRecognizeFormField,
|
||||
} from '../layout-recognize-form-field';
|
||||
import { MaxTokenNumberFormField } from '../max-token-number-from-field';
|
||||
import {
|
||||
UseGraphRagFormField,
|
||||
showGraphRagItems,
|
||||
} from '../parse-configuration/graph-rag-form-fields';
|
||||
import RaptorFormFields, {
|
||||
showRaptorParseConfiguration,
|
||||
} from '../parse-configuration/raptor-form-fields';
|
||||
import { Input } from '../ui/input';
|
||||
import { RAGFlowSelect } from '../ui/select';
|
||||
import { useFetchParserListOnMount, useShowAutoKeywords } from './hooks';
|
||||
|
||||
const FormId = 'ChunkMethodDialogForm';
|
||||
|
||||
interface IProps
|
||||
extends IModalProps<{
|
||||
@ -42,6 +63,15 @@ interface IProps
|
||||
documentId: string;
|
||||
}
|
||||
|
||||
const hidePagesChunkMethods = [
|
||||
DocumentParserType.Qa,
|
||||
DocumentParserType.Table,
|
||||
DocumentParserType.Picture,
|
||||
DocumentParserType.Resume,
|
||||
DocumentParserType.One,
|
||||
DocumentParserType.KnowledgeGraph,
|
||||
];
|
||||
|
||||
export function ChunkMethodDialog({
|
||||
hideModal,
|
||||
onOk,
|
||||
@ -58,68 +88,171 @@ export function ChunkMethodDialog({
|
||||
// form,
|
||||
);
|
||||
|
||||
const { data: knowledgeDetails } = useFetchKnowledgeBaseConfiguration();
|
||||
|
||||
const useGraphRag = useMemo(() => {
|
||||
return knowledgeDetails.parser_config?.graphrag?.use_graphrag;
|
||||
}, [knowledgeDetails.parser_config?.graphrag?.use_graphrag]);
|
||||
|
||||
const FormSchema = z.object({
|
||||
name: z
|
||||
parser_id: z
|
||||
.string()
|
||||
.min(1, {
|
||||
message: 'namePlaceholder',
|
||||
})
|
||||
.trim(),
|
||||
parser_config: z.object({
|
||||
task_page_size: z.coerce.number(),
|
||||
layout_recognize: z.string(),
|
||||
}),
|
||||
});
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: { name: '' },
|
||||
defaultValues: {
|
||||
parser_id: parserId,
|
||||
parser_config: {
|
||||
task_page_size: 12,
|
||||
layout_recognize: DocumentType.DeepDOC,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const layoutRecognize = useWatch({
|
||||
name: 'parser_config.layout_recognize',
|
||||
control: form.control,
|
||||
});
|
||||
|
||||
const selectedTag = useWatch({
|
||||
name: 'parser_id',
|
||||
control: form.control,
|
||||
});
|
||||
|
||||
const isPdf = documentExtension === 'pdf';
|
||||
|
||||
const showPages = useMemo(() => {
|
||||
return isPdf && hidePagesChunkMethods.every((x) => x !== selectedTag);
|
||||
}, [selectedTag, isPdf]);
|
||||
|
||||
const showOne = useMemo(() => {
|
||||
return (
|
||||
isPdf &&
|
||||
hidePagesChunkMethods
|
||||
.filter((x) => x !== DocumentParserType.One)
|
||||
.every((x) => x !== selectedTag)
|
||||
);
|
||||
}, [selectedTag, isPdf]);
|
||||
|
||||
const showMaxTokenNumber =
|
||||
selectedTag === DocumentParserType.Naive ||
|
||||
selectedTag === DocumentParserType.KnowledgeGraph;
|
||||
|
||||
const showEntityTypes = selectedTag === DocumentParserType.KnowledgeGraph;
|
||||
|
||||
const showExcelToHtml =
|
||||
selectedTag === DocumentParserType.Naive && documentExtension === 'xlsx';
|
||||
|
||||
const showAutoKeywords = useShowAutoKeywords();
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
const ret = await onOk?.();
|
||||
if (ret) {
|
||||
hideModal?.();
|
||||
}
|
||||
console.log('🚀 ~ onSubmit ~ data:', data);
|
||||
// const ret = await onOk?.();
|
||||
// if (ret) {
|
||||
// hideModal?.();
|
||||
// }
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open onOpenChange={hideModal}>
|
||||
<DialogContent>
|
||||
<DialogContent className="max-w-[50vw]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('chunkMethod')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-6"
|
||||
id={FormId}
|
||||
>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
name="parser_id"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('name')}</FormLabel>
|
||||
<FormControl>
|
||||
<Select
|
||||
<RAGFlowSelect
|
||||
{...field}
|
||||
autoComplete="off"
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a verified email to display" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{parserList.map((x) => (
|
||||
<SelectItem value={x.value} key={x.value}>
|
||||
{x.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
options={parserList}
|
||||
></RAGFlowSelect>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{showPages && layoutRecognize && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="parser_config.task_page_size"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip={t('taskPageSizeTip')}>
|
||||
{t('taskPageSize')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type={'number'}
|
||||
min={1}
|
||||
max={128}
|
||||
></Input>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<DatasetConfigurationContainer show={showOne || showMaxTokenNumber}>
|
||||
{showOne && <LayoutRecognizeFormField></LayoutRecognizeFormField>}
|
||||
{showMaxTokenNumber && (
|
||||
<>
|
||||
<MaxTokenNumberFormField
|
||||
max={
|
||||
selectedTag === DocumentParserType.KnowledgeGraph
|
||||
? 8192 * 2
|
||||
: 2048
|
||||
}
|
||||
></MaxTokenNumberFormField>
|
||||
<DelimiterFormField></DelimiterFormField>
|
||||
</>
|
||||
)}
|
||||
</DatasetConfigurationContainer>
|
||||
<DatasetConfigurationContainer
|
||||
show={showAutoKeywords(selectedTag) || showExcelToHtml}
|
||||
>
|
||||
{showAutoKeywords(selectedTag) && (
|
||||
<>
|
||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
||||
</>
|
||||
)}
|
||||
{showExcelToHtml && <ExcelToHtmlFormField></ExcelToHtmlFormField>}
|
||||
</DatasetConfigurationContainer>
|
||||
{showRaptorParseConfiguration(
|
||||
selectedTag as DocumentParserType,
|
||||
) && (
|
||||
<DatasetConfigurationContainer>
|
||||
<RaptorFormFields></RaptorFormFields>
|
||||
</DatasetConfigurationContainer>
|
||||
)}
|
||||
{showGraphRagItems(selectedTag as DocumentParserType) &&
|
||||
useGraphRag && <UseGraphRagFormField></UseGraphRagFormField>}
|
||||
{showEntityTypes && <EntityTypesFormField></EntityTypesFormField>}
|
||||
</form>
|
||||
</Form>
|
||||
<DialogFooter>
|
||||
<Button type="submit">Save changes</Button>
|
||||
<Button type="submit" form={FormId}>
|
||||
Save changes
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
59
web/src/components/delimiter-form-field.tsx
Normal file
59
web/src/components/delimiter-form-field.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import { forwardRef } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from './ui/form';
|
||||
import { Input, InputProps } from './ui/input';
|
||||
|
||||
interface IProps {
|
||||
value?: string | undefined;
|
||||
onChange?: (val: string | undefined) => void;
|
||||
}
|
||||
|
||||
export const DelimiterInput = forwardRef<HTMLInputElement, InputProps & IProps>(
|
||||
({ value, onChange, maxLength, defaultValue }, ref) => {
|
||||
const nextValue = value?.replaceAll('\n', '\\n');
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const val = e.target.value;
|
||||
const nextValue = val.replaceAll('\\n', '\n');
|
||||
onChange?.(nextValue);
|
||||
};
|
||||
return (
|
||||
<Input
|
||||
value={nextValue}
|
||||
onChange={handleInputChange}
|
||||
maxLength={maxLength}
|
||||
defaultValue={defaultValue}
|
||||
ref={ref}
|
||||
></Input>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export function DelimiterFormField() {
|
||||
const { t } = useTranslation();
|
||||
const form = useFormContext();
|
||||
|
||||
return (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'parser_config.delimiter'}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip={t('knowledgeDetails.delimiterTip')}>
|
||||
{t('knowledgeDetails.delimiter')}
|
||||
</FormLabel>
|
||||
<FormControl defaultValue={`\n`}>
|
||||
<DelimiterInput {...field}></DelimiterInput>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
37
web/src/components/entity-types-form-field.tsx
Normal file
37
web/src/components/entity-types-form-field.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import EditTag from './edit-tag';
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from './ui/form';
|
||||
|
||||
type EntityTypesFormFieldProps = {
|
||||
name?: string;
|
||||
};
|
||||
|
||||
export function EntityTypesFormField({
|
||||
name = 'parser_config.entity_types',
|
||||
}: EntityTypesFormFieldProps) {
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
const form = useFormContext();
|
||||
|
||||
return (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('entityTypes')}</FormLabel>
|
||||
<FormControl>
|
||||
<EditTag {...field}></EditTag>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
34
web/src/components/excel-to-html-form-field.tsx
Normal file
34
web/src/components/excel-to-html-form-field.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from './ui/form';
|
||||
import { Switch } from './ui/switch';
|
||||
|
||||
export function ExcelToHtmlFormField() {
|
||||
const form = useFormContext();
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
return (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="parser_config.html4excel"
|
||||
render={({ field }) => (
|
||||
<FormItem defaultChecked={false}>
|
||||
<FormLabel tooltip={t('html4excelTip')}>{t('html4excel')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
></Switch>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
70
web/src/components/layout-recognize-form-field.tsx
Normal file
70
web/src/components/layout-recognize-form-field.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
import { LlmModelType } from '@/constants/knowledge';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { useSelectLlmOptionsByModelType } from '@/hooks/llm-hooks';
|
||||
import { camelCase } from 'lodash';
|
||||
import { useMemo } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from './ui/form';
|
||||
import { RAGFlowSelect } from './ui/select';
|
||||
|
||||
export const enum DocumentType {
|
||||
DeepDOC = 'DeepDOC',
|
||||
PlainText = 'Plain Text',
|
||||
}
|
||||
|
||||
export function LayoutRecognizeFormField() {
|
||||
const form = useFormContext();
|
||||
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
const allOptions = useSelectLlmOptionsByModelType();
|
||||
|
||||
const options = useMemo(() => {
|
||||
const list = [DocumentType.DeepDOC, DocumentType.PlainText].map((x) => ({
|
||||
label: x === DocumentType.PlainText ? t(camelCase(x)) : 'DeepDoc',
|
||||
value: x,
|
||||
}));
|
||||
|
||||
const image2TextList = allOptions[LlmModelType.Image2text].map((x) => {
|
||||
return {
|
||||
...x,
|
||||
options: x.options.map((y) => {
|
||||
return {
|
||||
...y,
|
||||
label: (
|
||||
<div className="flex justify-between items-center gap-2">
|
||||
{y.label}
|
||||
<span className="text-red-500 text-sm">Experimental</span>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
return [...list, ...image2TextList];
|
||||
}, [allOptions, t]);
|
||||
|
||||
return (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="parser_config.layout_recognize"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip={t('layoutRecognizeTip')}>
|
||||
{t('layoutRecognize')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RAGFlowSelect {...field} options={options}></RAGFlowSelect>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
19
web/src/components/max-token-number-from-field.tsx
Normal file
19
web/src/components/max-token-number-from-field.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { SliderInputFormField } from './slider-input-form-field';
|
||||
|
||||
interface IProps {
|
||||
initialValue?: number;
|
||||
max?: number;
|
||||
}
|
||||
|
||||
export function MaxTokenNumberFormField({ max = 2048 }: IProps) {
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
|
||||
return (
|
||||
<SliderInputFormField
|
||||
name={'parser_config.chunk_token_num'}
|
||||
label={t('chunkTokenNumber')}
|
||||
max={max}
|
||||
></SliderInputFormField>
|
||||
);
|
||||
}
|
||||
173
web/src/components/parse-configuration/graph-rag-form-fields.tsx
Normal file
173
web/src/components/parse-configuration/graph-rag-form-fields.tsx
Normal file
@ -0,0 +1,173 @@
|
||||
import { DocumentParserType } from '@/constants/knowledge';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Switch as AntSwitch, Form, Select } from 'antd';
|
||||
import { upperFirst } from 'lodash';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { DatasetConfigurationContainer } from '../dataset-configuration-container';
|
||||
import EntityTypesItem from '../entity-types-item';
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '../ui/form';
|
||||
import { Switch } from '../ui/switch';
|
||||
|
||||
const excludedTagParseMethods = [
|
||||
DocumentParserType.Table,
|
||||
DocumentParserType.KnowledgeGraph,
|
||||
DocumentParserType.Tag,
|
||||
];
|
||||
|
||||
export const showTagItems = (parserId: DocumentParserType) => {
|
||||
return !excludedTagParseMethods.includes(parserId);
|
||||
};
|
||||
|
||||
const enum MethodValue {
|
||||
General = 'general',
|
||||
Light = 'light',
|
||||
}
|
||||
|
||||
export const excludedParseMethods = [
|
||||
DocumentParserType.Table,
|
||||
DocumentParserType.Resume,
|
||||
DocumentParserType.Picture,
|
||||
DocumentParserType.KnowledgeGraph,
|
||||
DocumentParserType.Qa,
|
||||
DocumentParserType.Tag,
|
||||
];
|
||||
|
||||
export const showGraphRagItems = (parserId: DocumentParserType | undefined) => {
|
||||
return !excludedParseMethods.some((x) => x === parserId);
|
||||
};
|
||||
|
||||
type GraphRagItemsProps = {
|
||||
marginBottom?: boolean;
|
||||
};
|
||||
|
||||
export function UseGraphRagItem() {
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
|
||||
return (
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'use_graphrag']}
|
||||
label={t('useGraphRag')}
|
||||
initialValue={false}
|
||||
valuePropName="checked"
|
||||
tooltip={t('useGraphRagTip')}
|
||||
>
|
||||
<AntSwitch />
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
|
||||
export function UseGraphRagFormField() {
|
||||
const form = useFormContext();
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
|
||||
return (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="parser_config.graphrag.use_graphrag"
|
||||
render={({ field }) => (
|
||||
<FormItem defaultChecked={false}>
|
||||
<FormLabel tooltip={t('useGraphRagTip')}>
|
||||
{t('useGraphRag')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
></Switch>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// The three types "table", "resume" and "one" do not display this configuration.
|
||||
const GraphRagItems = ({ marginBottom = false }: GraphRagItemsProps) => {
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
|
||||
const methodOptions = useMemo(() => {
|
||||
return [MethodValue.Light, MethodValue.General].map((x) => ({
|
||||
value: x,
|
||||
label: upperFirst(x),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const renderWideTooltip = useCallback(
|
||||
(title: React.ReactNode | string) => {
|
||||
return {
|
||||
title: typeof title === 'string' ? t(title) : title,
|
||||
overlayInnerStyle: { width: '32vw' },
|
||||
};
|
||||
},
|
||||
[t],
|
||||
);
|
||||
|
||||
return (
|
||||
<DatasetConfigurationContainer className={cn({ 'mb-4': marginBottom })}>
|
||||
<UseGraphRagItem></UseGraphRagItem>
|
||||
<Form.Item
|
||||
shouldUpdate={(prevValues, curValues) =>
|
||||
prevValues.parser_config.graphrag.use_graphrag !==
|
||||
curValues.parser_config.graphrag.use_graphrag
|
||||
}
|
||||
>
|
||||
{({ getFieldValue }) => {
|
||||
const useRaptor = getFieldValue([
|
||||
'parser_config',
|
||||
'graphrag',
|
||||
'use_graphrag',
|
||||
]);
|
||||
|
||||
return (
|
||||
useRaptor && (
|
||||
<>
|
||||
<EntityTypesItem
|
||||
field={['parser_config', 'graphrag', 'entity_types']}
|
||||
></EntityTypesItem>
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'method']}
|
||||
label={t('graphRagMethod')}
|
||||
tooltip={renderWideTooltip(
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: t('graphRagMethodTip'),
|
||||
}}
|
||||
></div>,
|
||||
)}
|
||||
initialValue={MethodValue.Light}
|
||||
>
|
||||
<Select options={methodOptions} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'resolution']}
|
||||
label={t('resolution')}
|
||||
tooltip={renderWideTooltip('resolutionTip')}
|
||||
>
|
||||
<AntSwitch />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name={['parser_config', 'graphrag', 'community']}
|
||||
label={t('community')}
|
||||
tooltip={renderWideTooltip('communityTip')}
|
||||
>
|
||||
<AntSwitch />
|
||||
</Form.Item>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}}
|
||||
</Form.Item>
|
||||
</DatasetConfigurationContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default GraphRagItems;
|
||||
142
web/src/components/parse-configuration/raptor-form-fields.tsx
Normal file
142
web/src/components/parse-configuration/raptor-form-fields.tsx
Normal file
@ -0,0 +1,142 @@
|
||||
import { DocumentParserType } from '@/constants/knowledge';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import random from 'lodash/random';
|
||||
import { Plus } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useFormContext, useWatch } from 'react-hook-form';
|
||||
import { SliderInputFormField } from '../slider-input-form-field';
|
||||
import { Button } from '../ui/button';
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '../ui/form';
|
||||
import { Input } from '../ui/input';
|
||||
import { Switch } from '../ui/switch';
|
||||
import { Textarea } from '../ui/textarea';
|
||||
|
||||
export const excludedParseMethods = [
|
||||
DocumentParserType.Table,
|
||||
DocumentParserType.Resume,
|
||||
DocumentParserType.One,
|
||||
DocumentParserType.Picture,
|
||||
DocumentParserType.KnowledgeGraph,
|
||||
DocumentParserType.Qa,
|
||||
DocumentParserType.Tag,
|
||||
];
|
||||
|
||||
export const showRaptorParseConfiguration = (
|
||||
parserId: DocumentParserType | undefined,
|
||||
) => {
|
||||
return !excludedParseMethods.some((x) => x === parserId);
|
||||
};
|
||||
|
||||
export const excludedTagParseMethods = [
|
||||
DocumentParserType.Table,
|
||||
DocumentParserType.KnowledgeGraph,
|
||||
DocumentParserType.Tag,
|
||||
];
|
||||
|
||||
export const showTagItems = (parserId: DocumentParserType) => {
|
||||
return !excludedTagParseMethods.includes(parserId);
|
||||
};
|
||||
|
||||
const UseRaptorField = 'parser_config.raptor.use_raptor';
|
||||
const RandomSeedField = 'parser_config.raptor.random_seed';
|
||||
|
||||
// The three types "table", "resume" and "one" do not display this configuration.
|
||||
|
||||
const RaptorFormFields = () => {
|
||||
const form = useFormContext();
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
const useRaptor = useWatch({ name: UseRaptorField });
|
||||
|
||||
const handleGenerate = useCallback(() => {
|
||||
form.setValue(RandomSeedField, random(10000));
|
||||
}, [form]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={UseRaptorField}
|
||||
render={({ field }) => (
|
||||
<FormItem defaultChecked={false}>
|
||||
<FormLabel tooltip={t('useRaptorTip')}>{t('useRaptor')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
></Switch>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{useRaptor && (
|
||||
<>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'parser_config.raptor.prompt'}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip={t('promptTip')}>{t('prompt')}</FormLabel>
|
||||
<FormControl defaultValue={t('promptText')}>
|
||||
<Textarea {...field} rows={8} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<SliderInputFormField
|
||||
name={'parser_config.raptor.max_token'}
|
||||
label={t('maxToken')}
|
||||
tooltip={t('maxTokenTip')}
|
||||
defaultValue={256}
|
||||
max={2048}
|
||||
min={0}
|
||||
></SliderInputFormField>
|
||||
<SliderInputFormField
|
||||
name={'parser_config.raptor.threshold'}
|
||||
label={t('threshold')}
|
||||
tooltip={t('thresholdTip')}
|
||||
defaultValue={0.1}
|
||||
step={0.01}
|
||||
max={1}
|
||||
min={0}
|
||||
></SliderInputFormField>
|
||||
<SliderInputFormField
|
||||
name={'parser_config.raptor.max_cluster'}
|
||||
label={t('maxCluster')}
|
||||
tooltip={t('maxClusterTip')}
|
||||
defaultValue={64}
|
||||
max={1024}
|
||||
min={1}
|
||||
></SliderInputFormField>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'parser_config.raptor.random_seed'}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('randomSeed')}</FormLabel>
|
||||
<FormControl defaultValue={0}>
|
||||
<div className="flex gap-4">
|
||||
<Input {...field} />
|
||||
<Button size={'sm'} onClick={handleGenerate}>
|
||||
<Plus />
|
||||
</Button>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default RaptorFormFields;
|
||||
71
web/src/components/slider-input-form-field.tsx
Normal file
71
web/src/components/slider-input-form-field.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { SingleFormSlider } from './ui/dual-range-slider';
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from './ui/form';
|
||||
import { Input } from './ui/input';
|
||||
|
||||
type SliderInputFormFieldProps = {
|
||||
max?: number;
|
||||
min?: number;
|
||||
step?: number;
|
||||
name: string;
|
||||
label: string;
|
||||
tooltip?: ReactNode;
|
||||
defaultValue?: number;
|
||||
};
|
||||
|
||||
export function SliderInputFormField({
|
||||
max,
|
||||
min,
|
||||
step,
|
||||
label,
|
||||
name,
|
||||
tooltip,
|
||||
defaultValue,
|
||||
}: SliderInputFormFieldProps) {
|
||||
const form = useFormContext();
|
||||
|
||||
return (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={name}
|
||||
defaultValue={defaultValue}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<div className="flex items-center justify-between">
|
||||
<FormLabel tooltip={tooltip}>{label}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type={'number'}
|
||||
className="h-7 w-20"
|
||||
max={max}
|
||||
min={min}
|
||||
step={step}
|
||||
{...field}
|
||||
// defaultValue={defaultValue}
|
||||
></Input>
|
||||
</FormControl>
|
||||
</div>
|
||||
<FormControl>
|
||||
<SingleFormSlider
|
||||
{...field}
|
||||
max={max}
|
||||
min={min}
|
||||
step={step}
|
||||
// defaultValue={
|
||||
// typeof defaultValue === 'number' ? [defaultValue] : undefined
|
||||
// }
|
||||
></SingleFormSlider>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -222,11 +222,12 @@ export const RAGFlowSelect = forwardRef<
|
||||
allowClear,
|
||||
placeholder,
|
||||
contentProps = {},
|
||||
defaultValue,
|
||||
},
|
||||
ref,
|
||||
) {
|
||||
const [key, setKey] = React.useState(+new Date());
|
||||
const [value, setValue] = React.useState<string | undefined>(undefined);
|
||||
const [value, setValue] = React.useState<string | undefined>(defaultValue);
|
||||
|
||||
const FormControlWidget = FormControlComponent
|
||||
? FormControlComponent
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||
import i18n from '@/locales/config';
|
||||
import kbService from '@/services/knowledge-service';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
@ -20,6 +21,7 @@ export const enum DocumentApiAction {
|
||||
RunDocumentByIds = 'runDocumentByIds',
|
||||
RemoveDocument = 'removeDocument',
|
||||
SaveDocumentName = 'saveDocumentName',
|
||||
SetDocumentParser = 'setDocumentParser',
|
||||
}
|
||||
|
||||
export const useUploadNextDocument = () => {
|
||||
@ -247,3 +249,40 @@ export const useSaveDocumentName = () => {
|
||||
|
||||
return { loading, saveName: mutateAsync, data };
|
||||
};
|
||||
|
||||
export const useSetDocumentParser = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation({
|
||||
mutationKey: [DocumentApiAction.SetDocumentParser],
|
||||
mutationFn: async ({
|
||||
parserId,
|
||||
documentId,
|
||||
parserConfig,
|
||||
}: {
|
||||
parserId: string;
|
||||
documentId: string;
|
||||
parserConfig: IChangeParserConfigRequestBody;
|
||||
}) => {
|
||||
const { data } = await kbService.document_change_parser({
|
||||
parser_id: parserId,
|
||||
doc_id: documentId,
|
||||
parser_config: parserConfig,
|
||||
});
|
||||
if (data.code === 0) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [DocumentApiAction.FetchDocumentList],
|
||||
});
|
||||
|
||||
message.success(i18n.t('message.modified'));
|
||||
}
|
||||
return data.code;
|
||||
},
|
||||
});
|
||||
|
||||
return { setDocumentParser: mutateAsync, data, loading };
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import {
|
||||
IKnowledge,
|
||||
IKnowledgeResult,
|
||||
INextTestingResult,
|
||||
} from '@/interfaces/database/knowledge';
|
||||
@ -22,6 +23,7 @@ export const enum KnowledgeApiAction {
|
||||
CreateKnowledge = 'createKnowledge',
|
||||
DeleteKnowledge = 'deleteKnowledge',
|
||||
SaveKnowledge = 'saveKnowledge',
|
||||
FetchKnowledgeDetail = 'fetchKnowledgeDetail',
|
||||
}
|
||||
|
||||
export const useKnowledgeBaseId = () => {
|
||||
@ -204,3 +206,21 @@ export const useUpdateKnowledge = (shouldFetchList = false) => {
|
||||
|
||||
return { data, loading, saveKnowledgeConfiguration: mutateAsync };
|
||||
};
|
||||
|
||||
export const useFetchKnowledgeBaseConfiguration = () => {
|
||||
const { id } = useParams();
|
||||
|
||||
const { data, isFetching: loading } = useQuery<IKnowledge>({
|
||||
queryKey: [KnowledgeApiAction.FetchKnowledgeDetail],
|
||||
initialData: {} as IKnowledge,
|
||||
gcTime: 0,
|
||||
queryFn: async () => {
|
||||
const { data } = await kbService.get_kb_detail({
|
||||
kb_id: id,
|
||||
});
|
||||
return data?.data ?? {};
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading };
|
||||
};
|
||||
|
||||
@ -29,7 +29,7 @@ import { useFetchDocumentList } from '@/hooks/use-document-request';
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import { getExtension } from '@/utils/document-util';
|
||||
import { useMemo } from 'react';
|
||||
import { useChangeDocumentParser } from './hooks';
|
||||
import { useChangeDocumentParser } from './use-change-document-parser';
|
||||
import { useDatasetTableColumns } from './use-dataset-table-columns';
|
||||
import { useRenameDocument } from './use-rename-document';
|
||||
|
||||
@ -57,7 +57,8 @@ export function DatasetTable() {
|
||||
changeParserVisible,
|
||||
hideChangeParserModal,
|
||||
showChangeParserModal,
|
||||
} = useChangeDocumentParser(currentRecord.id);
|
||||
changeParserRecord,
|
||||
} = useChangeDocumentParser();
|
||||
|
||||
const {
|
||||
renameLoading,
|
||||
@ -198,10 +199,10 @@ export function DatasetTable() {
|
||||
</div>
|
||||
{changeParserVisible && (
|
||||
<ChunkMethodDialog
|
||||
documentId={currentRecord.id}
|
||||
parserId={currentRecord.parser_id}
|
||||
parserConfig={currentRecord.parser_config}
|
||||
documentExtension={getExtension(currentRecord.name)}
|
||||
documentId={changeParserRecord.id}
|
||||
parserId={changeParserRecord.parser_id}
|
||||
parserConfig={changeParserRecord.parser_config}
|
||||
documentExtension={getExtension(changeParserRecord.name)}
|
||||
onOk={onChangeParserOk}
|
||||
visible={changeParserVisible}
|
||||
hideModal={hideChangeParserModal}
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import {
|
||||
useCreateNextDocument,
|
||||
useNextWebCrawl,
|
||||
useSetNextDocumentParser,
|
||||
} from '@/hooks/document-hooks';
|
||||
import { useCreateNextDocument, useNextWebCrawl } from '@/hooks/document-hooks';
|
||||
import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
|
||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useNavigate } from 'umi';
|
||||
|
||||
@ -50,44 +45,6 @@ export const useCreateEmptyDocument = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const useChangeDocumentParser = (documentId: string) => {
|
||||
const { setDocumentParser, loading } = useSetNextDocumentParser();
|
||||
|
||||
const {
|
||||
visible: changeParserVisible,
|
||||
hideModal: hideChangeParserModal,
|
||||
showModal: showChangeParserModal,
|
||||
} = useSetModalState();
|
||||
|
||||
const onChangeParserOk = useCallback(
|
||||
async ({
|
||||
parserId,
|
||||
parserConfig,
|
||||
}: {
|
||||
parserId: string;
|
||||
parserConfig: IChangeParserConfigRequestBody;
|
||||
}) => {
|
||||
const ret = await setDocumentParser({
|
||||
parserId,
|
||||
documentId,
|
||||
parserConfig,
|
||||
});
|
||||
if (ret === 0) {
|
||||
hideChangeParserModal();
|
||||
}
|
||||
},
|
||||
[hideChangeParserModal, setDocumentParser, documentId],
|
||||
);
|
||||
|
||||
return {
|
||||
changeParserLoading: loading,
|
||||
onChangeParserOk,
|
||||
changeParserVisible,
|
||||
hideChangeParserModal,
|
||||
showChangeParserModal,
|
||||
};
|
||||
};
|
||||
|
||||
export const useGetRowSelection = () => {
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
|
||||
|
||||
@ -1,12 +1,20 @@
|
||||
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
HoverCard,
|
||||
HoverCardContent,
|
||||
HoverCardTrigger,
|
||||
} from '@/components/ui/hover-card';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { CircleX, Play, RefreshCw } from 'lucide-react';
|
||||
import { PropsWithChildren, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RunningStatus } from './constant';
|
||||
import { ParsingCard } from './parsing-card';
|
||||
import { UseChangeDocumentParserShowType } from './use-change-document-parser';
|
||||
import { useHandleRunDocumentByIds } from './use-run-document';
|
||||
import { isParserRunning } from './utils';
|
||||
|
||||
@ -18,7 +26,26 @@ const IconMap = {
|
||||
[RunningStatus.FAIL]: <RefreshCw />,
|
||||
};
|
||||
|
||||
export function ParsingStatusCell({ record }: { record: IDocumentInfo }) {
|
||||
function MenuItem({
|
||||
children,
|
||||
onClick,
|
||||
}: PropsWithChildren & { onClick?(): void }) {
|
||||
return (
|
||||
<div
|
||||
onClick={onClick}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ParsingStatusCell({
|
||||
record,
|
||||
showChangeParserModal,
|
||||
}: { record: IDocumentInfo } & UseChangeDocumentParserShowType) {
|
||||
const { t } = useTranslation();
|
||||
const { run, parser_id, progress, chunk_num, id } = record;
|
||||
const operationIcon = IconMap[run];
|
||||
@ -33,12 +60,27 @@ export function ParsingStatusCell({ record }: { record: IDocumentInfo }) {
|
||||
handleRunDocumentByIds(record.id, isRunning, shouldDelete);
|
||||
};
|
||||
|
||||
const handleShowChangeParserModal = useCallback(() => {
|
||||
showChangeParserModal(record);
|
||||
}, [record, showChangeParserModal]);
|
||||
|
||||
return (
|
||||
<section className="flex gap-2 items-center ">
|
||||
<div>
|
||||
<Button variant={'ghost'} size={'sm'}>
|
||||
{parser_id}
|
||||
</Button>
|
||||
<HoverCard>
|
||||
<HoverCardTrigger>
|
||||
<Button variant={'ghost'} size={'sm'}>
|
||||
{parser_id}
|
||||
</Button>
|
||||
</HoverCardTrigger>
|
||||
<HoverCardContent>
|
||||
<MenuItem onClick={handleShowChangeParserModal}>
|
||||
{t('knowledgeDetails.chunkMethod')}
|
||||
</MenuItem>
|
||||
<MenuItem>{t('knowledgeDetails.setMetaData')}</MenuItem>
|
||||
</HoverCardContent>
|
||||
</HoverCard>
|
||||
|
||||
<Separator orientation="vertical" />
|
||||
</div>
|
||||
<ConfirmDeleteDialog
|
||||
|
||||
54
web/src/pages/dataset/dataset/use-change-document-parser.ts
Normal file
54
web/src/pages/dataset/dataset/use-change-document-parser.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useSetDocumentParser } from '@/hooks/use-document-request';
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export const useChangeDocumentParser = () => {
|
||||
const { setDocumentParser, loading } = useSetDocumentParser();
|
||||
const [record, setRecord] = useState<IDocumentInfo>({} as IDocumentInfo);
|
||||
|
||||
const {
|
||||
visible: changeParserVisible,
|
||||
hideModal: hideChangeParserModal,
|
||||
showModal: showChangeParserModal,
|
||||
} = useSetModalState();
|
||||
|
||||
const onChangeParserOk = useCallback(
|
||||
async (parserId: string, parserConfig: IChangeParserConfigRequestBody) => {
|
||||
if (record?.id) {
|
||||
const ret = await setDocumentParser({
|
||||
parserId,
|
||||
documentId: record?.id,
|
||||
parserConfig,
|
||||
});
|
||||
if (ret === 0) {
|
||||
hideChangeParserModal();
|
||||
}
|
||||
}
|
||||
},
|
||||
[record?.id, setDocumentParser, hideChangeParserModal],
|
||||
);
|
||||
|
||||
const handleShowChangeParserModal = useCallback(
|
||||
(row: IDocumentInfo) => {
|
||||
setRecord(row);
|
||||
showChangeParserModal();
|
||||
},
|
||||
[showChangeParserModal],
|
||||
);
|
||||
|
||||
return {
|
||||
changeParserLoading: loading,
|
||||
onChangeParserOk,
|
||||
changeParserVisible,
|
||||
hideChangeParserModal,
|
||||
showChangeParserModal: handleShowChangeParserModal,
|
||||
changeParserRecord: record,
|
||||
};
|
||||
};
|
||||
|
||||
export type UseChangeDocumentParserShowType = Pick<
|
||||
ReturnType<typeof useChangeDocumentParser>,
|
||||
'showChangeParserModal'
|
||||
>;
|
||||
@ -15,17 +15,13 @@ import { formatDate } from '@/utils/date';
|
||||
import { getExtension } from '@/utils/document-util';
|
||||
import { ColumnDef } from '@tanstack/table-core';
|
||||
import { ArrowUpDown } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DatasetActionCell } from './dataset-action-cell';
|
||||
import { useChangeDocumentParser } from './hooks';
|
||||
import { ParsingStatusCell } from './parsing-status-cell';
|
||||
import { UseChangeDocumentParserShowType } from './use-change-document-parser';
|
||||
import { UseRenameDocumentShowType } from './use-rename-document';
|
||||
|
||||
type UseDatasetTableColumnsType = Pick<
|
||||
ReturnType<typeof useChangeDocumentParser>,
|
||||
'showChangeParserModal'
|
||||
> & {
|
||||
type UseDatasetTableColumnsType = UseChangeDocumentParserShowType & {
|
||||
setCurrentRecord: (record: IDocumentInfo) => void;
|
||||
} & UseRenameDocumentShowType;
|
||||
|
||||
@ -42,13 +38,6 @@ export function useDatasetTableColumns({
|
||||
// setCurrentRecord(record);
|
||||
// showRenameModal();
|
||||
// };
|
||||
const onShowChangeParserModal = useCallback(
|
||||
(record: IDocumentInfo) => () => {
|
||||
setCurrentRecord(record);
|
||||
showChangeParserModal();
|
||||
},
|
||||
[setCurrentRecord, showChangeParserModal],
|
||||
);
|
||||
|
||||
// const onShowSetMetaModal = useCallback(() => {
|
||||
// setRecord();
|
||||
@ -168,7 +157,12 @@ export function useDatasetTableColumns({
|
||||
header: t('parsingStatus'),
|
||||
// meta: { cellClassName: 'min-w-[20vw]' },
|
||||
cell: ({ row }) => {
|
||||
return <ParsingStatusCell record={row.original}></ParsingStatusCell>;
|
||||
return (
|
||||
<ParsingStatusCell
|
||||
record={row.original}
|
||||
showChangeParserModal={showChangeParserModal}
|
||||
></ParsingStatusCell>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user