Fix: Added table of contents extraction functionality and optimized form item layout #9869 (#10492)

### What problem does this PR solve?

Fix: Added table of contents extraction functionality and optimized form
item layout #9869

- Added `EnableTocToggle` component to toggle table of contents
extraction on and off
- Added multiple parser configuration components (such as naive, book,
laws, etc.), displaying different parser components based on built-in
slicing methods

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
chanx
2025-10-11 18:45:55 +08:00
committed by GitHub
parent 6a0f448419
commit c21cea2038
35 changed files with 694 additions and 173 deletions

View File

@ -20,6 +20,7 @@ import { IParserConfig } from '@/interfaces/database/document';
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
import {
ChunkMethodItem,
EnableTocToggle,
ParseTypeItem,
} from '@/pages/dataset/dataset-setting/configuration/common-item';
import { zodResolver } from '@hookform/resolvers/zod';
@ -113,6 +114,7 @@ export function ChunkMethodDialog({
auto_keywords: z.coerce.number().optional(),
auto_questions: z.coerce.number().optional(),
html4excel: z.boolean().optional(),
toc_extraction: z.boolean().optional(),
// raptor: z
// .object({
// use_raptor: z.boolean().optional(),
@ -247,7 +249,7 @@ export function ChunkMethodDialog({
}, [parseType, form]);
return (
<Dialog open onOpenChange={hideModal}>
<DialogContent className="max-w-[50vw]">
<DialogContent className="max-w-[50vw] text-text-primary">
<DialogHeader>
<DialogTitle>{t('knowledgeDetails.chunkMethod')}</DialogTitle>
</DialogHeader>
@ -338,6 +340,7 @@ export function ChunkMethodDialog({
show={showAutoKeywords(selectedTag) || showExcelToHtml}
className="space-y-3"
>
<EnableTocToggle />
{showAutoKeywords(selectedTag) && (
<>
<AutoKeywordsFormField></AutoKeywordsFormField>

View File

@ -15,6 +15,7 @@ export function useDefaultParserValues() {
auto_keywords: 0,
auto_questions: 0,
html4excel: false,
toc_extraction: false,
// raptor: {
// use_raptor: false,
// prompt: t('knowledgeConfiguration.promptText'),

View File

@ -1,5 +1,7 @@
import { AgentCategory } from '@/constants/agent';
import { FormLayout } from '@/constants/form';
import { useTranslate } from '@/hooks/common-hooks';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { useFetchAgentList } from '@/hooks/use-agent-request';
import { buildSelectOptions } from '@/utils/component-util';
import { ArrowUpRight } from 'lucide-react';
@ -21,18 +23,27 @@ export interface IDataPipelineSelectNode {
}
interface IProps {
toDataPipeline?: () => void;
showToDataPipeline?: boolean;
formFieldName: string;
isMult?: boolean;
setDataList?: (data: IDataPipelineSelectNode[]) => void;
layout?: FormLayout;
}
export function DataFlowSelect(props: IProps) {
const { toDataPipeline, formFieldName, isMult = false, setDataList } = props;
const {
showToDataPipeline,
formFieldName,
isMult = false,
setDataList,
layout = FormLayout.Vertical,
} = props;
const { t } = useTranslate('knowledgeConfiguration');
const form = useFormContext();
const { navigateToAgents } = useNavigatePage();
const toDataPipLine = () => {
toDataPipeline?.();
navigateToAgents();
};
const { data: dataPipelineOptions } = useFetchAgentList({
canvas_category: AgentCategory.DataflowCanvas,
@ -69,47 +80,92 @@ export function DataFlowSelect(props: IProps) {
name={formFieldName}
render={({ field }) => (
<FormItem className=" items-center space-y-0 ">
<div className="flex flex-col gap-1">
<div className="flex gap-2 justify-between ">
<FormLabel
tooltip={t('dataFlowTip')}
className="text-sm text-text-primary whitespace-wrap "
>
{t('dataPipeline')}
</FormLabel>
{toDataPipeline && (
<div
className="text-sm flex text-text-primary cursor-pointer"
onClick={toDataPipLine}
{layout === FormLayout.Vertical && (
<div className="flex flex-col gap-1">
<div className="flex gap-2 justify-between ">
<FormLabel
// tooltip={t('dataFlowTip')}
className="text-sm text-text-primary whitespace-wrap "
>
{t('buildItFromScratch')}
<ArrowUpRight size={14} />
</div>
)}
</div>
{t('manualSetup')}
</FormLabel>
{showToDataPipeline && (
<div
className="text-sm flex text-text-primary cursor-pointer"
onClick={toDataPipLine}
>
{t('buildItFromScratch')}
<ArrowUpRight size={14} />
</div>
)}
</div>
<div className="text-muted-foreground">
<FormControl>
<>
{!isMult && (
<SelectWithSearch
{...field}
placeholder={t('dataFlowPlaceholder')}
options={options}
/>
)}
{isMult && (
<MultiSelect
{...field}
onValueChange={field.onChange}
placeholder={t('dataFlowPlaceholder')}
options={options}
/>
)}
</>
</FormControl>
<div className="text-muted-foreground">
<FormControl>
<>
{!isMult && (
<SelectWithSearch
{...field}
placeholder={t('dataFlowPlaceholder')}
options={options}
/>
)}
{isMult && (
<MultiSelect
{...field}
onValueChange={field.onChange}
placeholder={t('dataFlowPlaceholder')}
options={options}
/>
)}
</>
</FormControl>
</div>
</div>
</div>
)}
{layout === FormLayout.Horizontal && (
<div className="flex gap-1 items-center">
<div className="flex gap-2 justify-between w-1/4">
<FormLabel
// tooltip={t('dataFlowTip')}
className="text-sm text-text-secondary whitespace-wrap "
>
{t('manualSetup')}
</FormLabel>
</div>
<div className="text-muted-foreground w-3/4 flex flex-col items-end">
{showToDataPipeline && (
<div
className="text-sm flex text-text-primary cursor-pointer"
onClick={toDataPipLine}
>
{t('buildItFromScratch')}
<ArrowUpRight size={14} />
</div>
)}
<FormControl>
<>
{!isMult && (
<SelectWithSearch
{...field}
placeholder={t('dataFlowPlaceholder')}
options={options}
/>
)}
{isMult && (
<MultiSelect
{...field}
onValueChange={field.onChange}
placeholder={t('dataFlowPlaceholder')}
options={options}
/>
)}
</>
</FormControl>
</div>
</div>
)}
<div className="flex pt-1">
<FormMessage />
</div>

View File

@ -61,7 +61,7 @@ export function DelimiterFormField() {
<FormLabel
required
tooltip={t('knowledgeDetails.delimiterTip')}
className="text-sm text-muted-foreground whitespace-break-spaces w-1/4"
className="text-sm text-text-secondary whitespace-break-spaces w-1/4"
>
{t('knowledgeDetails.delimiter')}
</FormLabel>

View File

@ -28,7 +28,7 @@ export function ExcelToHtmlFormField() {
<div className="flex items-center gap-1">
<FormLabel
tooltip={t('html4excelTip')}
className="text-sm text-muted-foreground whitespace-break-spaces w-1/4"
className="text-sm text-text-secondary whitespace-break-spaces w-1/4"
>
{t('html4excel')}
</FormLabel>

View File

@ -79,7 +79,7 @@ export function LayoutRecognizeFormField({
>
<FormLabel
tooltip={t('layoutRecognizeTip')}
className={cn('text-sm text-muted-foreground whitespace-wrap', {
className={cn('text-sm text-text-secondary whitespace-wrap', {
['w-1/4']: horizontal,
})}
>

View File

@ -17,7 +17,7 @@ export function MaxTokenNumberFormField({ max = 2048, initialValue }: IProps) {
tooltip={t('chunkTokenNumberTip')}
max={max}
defaultValue={initialValue ?? 0}
layout={FormLayout.Vertical}
layout={FormLayout.Horizontal}
></SliderInputFormField>
);
}

View File

@ -36,7 +36,7 @@ export function SliderInputFormField({
tooltip,
defaultValue,
className,
layout = FormLayout.Vertical,
layout = FormLayout.Horizontal,
}: SliderInputFormFieldProps) {
const form = useFormContext();

View File

@ -1,5 +1,4 @@
import { cn } from '@/lib/utils';
import { Radio as LucideRadio } from 'lucide-react';
import React, { useContext, useState } from 'react';
const RadioGroupContext = React.createContext<{
@ -57,7 +56,7 @@ function Radio({ value, checked, disabled, onChange, children }: RadioProps) {
onClick={handleClick}
>
{isChecked && (
<LucideRadio className="h-3 w-3 fill-primary text-primary" />
<div className="h-3 w-3 fill-primary text-primary bg-text-primary rounded-full" />
)}
</span>
{children && <span className="text-foreground">{children}</span>}