mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-23 15:06:50 +08:00
### What problem does this PR solve? Fix: Improved knowledge base configuration and related logic #9869 - Optimized the display logic of the Generate Log button to support displaying completion time and task ID - Implemented the ability to pause task generation and connect to the data flow cancellation interface - Fixed issues with type definitions and optional chaining calls in some components ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -23,7 +23,6 @@ import {
|
|||||||
ParseTypeItem,
|
ParseTypeItem,
|
||||||
} from '@/pages/dataset/dataset-setting/configuration/common-item';
|
} from '@/pages/dataset/dataset-setting/configuration/common-item';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import get from 'lodash/get';
|
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
import {} from 'module';
|
import {} from 'module';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
@ -41,13 +40,6 @@ import { ExcelToHtmlFormField } from '../excel-to-html-form-field';
|
|||||||
import { FormContainer } from '../form-container';
|
import { FormContainer } from '../form-container';
|
||||||
import { LayoutRecognizeFormField } from '../layout-recognize-form-field';
|
import { LayoutRecognizeFormField } from '../layout-recognize-form-field';
|
||||||
import { MaxTokenNumberFormField } from '../max-token-number-from-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 { ButtonLoading } from '../ui/button';
|
import { ButtonLoading } from '../ui/button';
|
||||||
import { Input } from '../ui/input';
|
import { Input } from '../ui/input';
|
||||||
import { DynamicPageRange } from './dynamic-page-range';
|
import { DynamicPageRange } from './dynamic-page-range';
|
||||||
@ -121,19 +113,19 @@ export function ChunkMethodDialog({
|
|||||||
auto_keywords: z.coerce.number().optional(),
|
auto_keywords: z.coerce.number().optional(),
|
||||||
auto_questions: z.coerce.number().optional(),
|
auto_questions: z.coerce.number().optional(),
|
||||||
html4excel: z.boolean().optional(),
|
html4excel: z.boolean().optional(),
|
||||||
raptor: z
|
// raptor: z
|
||||||
.object({
|
// .object({
|
||||||
use_raptor: z.boolean().optional(),
|
// use_raptor: z.boolean().optional(),
|
||||||
prompt: z.string().optional().optional(),
|
// prompt: z.string().optional().optional(),
|
||||||
max_token: z.coerce.number().optional(),
|
// max_token: z.coerce.number().optional(),
|
||||||
threshold: z.coerce.number().optional(),
|
// threshold: z.coerce.number().optional(),
|
||||||
max_cluster: z.coerce.number().optional(),
|
// max_cluster: z.coerce.number().optional(),
|
||||||
random_seed: z.coerce.number().optional(),
|
// random_seed: z.coerce.number().optional(),
|
||||||
})
|
// })
|
||||||
.optional(),
|
// .optional(),
|
||||||
graphrag: z.object({
|
// graphrag: z.object({
|
||||||
use_graphrag: z.boolean().optional(),
|
// use_graphrag: z.boolean().optional(),
|
||||||
}),
|
// }),
|
||||||
entity_types: z.array(z.string()).optional(),
|
entity_types: z.array(z.string()).optional(),
|
||||||
pages: z
|
pages: z
|
||||||
.array(z.object({ from: z.coerce.number(), to: z.coerce.number() }))
|
.array(z.object({ from: z.coerce.number(), to: z.coerce.number() }))
|
||||||
@ -223,13 +215,13 @@ export function ChunkMethodDialog({
|
|||||||
parser_config: fillDefaultParserValue({
|
parser_config: fillDefaultParserValue({
|
||||||
pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }],
|
pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }],
|
||||||
...omit(parserConfig, 'pages'),
|
...omit(parserConfig, 'pages'),
|
||||||
graphrag: {
|
// graphrag: {
|
||||||
use_graphrag: get(
|
// use_graphrag: get(
|
||||||
parserConfig,
|
// parserConfig,
|
||||||
'graphrag.use_graphrag',
|
// 'graphrag.use_graphrag',
|
||||||
useGraphRag,
|
// useGraphRag,
|
||||||
),
|
// ),
|
||||||
},
|
// },
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -351,19 +343,19 @@ export function ChunkMethodDialog({
|
|||||||
<ExcelToHtmlFormField></ExcelToHtmlFormField>
|
<ExcelToHtmlFormField></ExcelToHtmlFormField>
|
||||||
)}
|
)}
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
{showRaptorParseConfiguration(
|
{/* {showRaptorParseConfiguration(
|
||||||
selectedTag as DocumentParserType,
|
selectedTag as DocumentParserType,
|
||||||
) && (
|
) && (
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<RaptorFormFields></RaptorFormFields>
|
<RaptorFormFields></RaptorFormFields>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
)}
|
)} */}
|
||||||
{showGraphRagItems(selectedTag as DocumentParserType) &&
|
{/* {showGraphRagItems(selectedTag as DocumentParserType) &&
|
||||||
useGraphRag && (
|
useGraphRag && (
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<UseGraphRagFormField></UseGraphRagFormField>
|
<UseGraphRagFormField></UseGraphRagFormField>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
)}
|
)} */}
|
||||||
{showEntityTypes && (
|
{showEntityTypes && (
|
||||||
<EntityTypesFormField></EntityTypesFormField>
|
<EntityTypesFormField></EntityTypesFormField>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -15,17 +15,17 @@ export function useDefaultParserValues() {
|
|||||||
auto_keywords: 0,
|
auto_keywords: 0,
|
||||||
auto_questions: 0,
|
auto_questions: 0,
|
||||||
html4excel: false,
|
html4excel: false,
|
||||||
raptor: {
|
// raptor: {
|
||||||
use_raptor: false,
|
// use_raptor: false,
|
||||||
prompt: t('knowledgeConfiguration.promptText'),
|
// prompt: t('knowledgeConfiguration.promptText'),
|
||||||
max_token: 256,
|
// max_token: 256,
|
||||||
threshold: 0.1,
|
// threshold: 0.1,
|
||||||
max_cluster: 64,
|
// max_cluster: 64,
|
||||||
random_seed: 0,
|
// random_seed: 0,
|
||||||
},
|
// },
|
||||||
graphrag: {
|
// graphrag: {
|
||||||
use_graphrag: false,
|
// use_graphrag: false,
|
||||||
},
|
// },
|
||||||
entity_types: [],
|
entity_types: [],
|
||||||
pages: [],
|
pages: [],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useFetchAgentList } from '@/hooks/use-agent-request';
|
import { useFetchAgentList } from '@/hooks/use-agent-request';
|
||||||
import { buildSelectOptions } from '@/utils/component-util';
|
import { buildSelectOptions } from '@/utils/component-util';
|
||||||
import { ArrowUpRight } from 'lucide-react';
|
import { ArrowUpRight } from 'lucide-react';
|
||||||
import { useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import { SelectWithSearch } from '../originui/select-with-search';
|
import { SelectWithSearch } from '../originui/select-with-search';
|
||||||
import {
|
import {
|
||||||
@ -13,15 +13,21 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from '../ui/form';
|
} from '../ui/form';
|
||||||
import { MultiSelect } from '../ui/multi-select';
|
import { MultiSelect } from '../ui/multi-select';
|
||||||
|
export interface IDataPipelineSelectNode {
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
avatar?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
toDataPipeline?: () => void;
|
toDataPipeline?: () => void;
|
||||||
formFieldName: string;
|
formFieldName: string;
|
||||||
isMult?: boolean;
|
isMult?: boolean;
|
||||||
|
setDataList?: (data: IDataPipelineSelectNode[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DataFlowSelect(props: IProps) {
|
export function DataFlowSelect(props: IProps) {
|
||||||
const { toDataPipeline, formFieldName, isMult = true } = props;
|
const { toDataPipeline, formFieldName, isMult = false, setDataList } = props;
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
const { t } = useTranslate('knowledgeConfiguration');
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
const toDataPipLine = () => {
|
const toDataPipLine = () => {
|
||||||
@ -36,8 +42,26 @@ export function DataFlowSelect(props: IProps) {
|
|||||||
'id',
|
'id',
|
||||||
'title',
|
'title',
|
||||||
);
|
);
|
||||||
|
|
||||||
return option || [];
|
return option || [];
|
||||||
}, [dataPipelineOptions]);
|
}, [dataPipelineOptions]);
|
||||||
|
|
||||||
|
const nodes = useMemo(() => {
|
||||||
|
return (
|
||||||
|
dataPipelineOptions?.canvas?.map((item) => {
|
||||||
|
return {
|
||||||
|
id: item?.id,
|
||||||
|
name: item?.title,
|
||||||
|
avatar: item?.avatar,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
}, [dataPipelineOptions]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setDataList?.(nodes);
|
||||||
|
}, [nodes, setDataList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { cn } from '@/lib/utils';
|
|||||||
import {
|
import {
|
||||||
GenerateLogButton,
|
GenerateLogButton,
|
||||||
GenerateType,
|
GenerateType,
|
||||||
|
IGenerateLogButtonProps,
|
||||||
} from '@/pages/dataset/dataset/generate-button/generate';
|
} from '@/pages/dataset/dataset/generate-button/generate';
|
||||||
import { upperFirst } from 'lodash';
|
import { upperFirst } from 'lodash';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
@ -51,10 +52,14 @@ export const showGraphRagItems = (parserId: DocumentParserType | undefined) => {
|
|||||||
type GraphRagItemsProps = {
|
type GraphRagItemsProps = {
|
||||||
marginBottom?: boolean;
|
marginBottom?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
showGenerateItem?: boolean;
|
data: IGenerateLogButtonProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function UseGraphRagFormField() {
|
export function UseGraphRagFormField({
|
||||||
|
data,
|
||||||
|
}: {
|
||||||
|
data: IGenerateLogButtonProps;
|
||||||
|
}) {
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
const { t } = useTranslate('knowledgeConfiguration');
|
||||||
|
|
||||||
@ -73,10 +78,16 @@ export function UseGraphRagFormField() {
|
|||||||
</FormLabel>
|
</FormLabel>
|
||||||
<div className="w-3/4">
|
<div className="w-3/4">
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
{/* <Switch
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
onCheckedChange={field.onChange}
|
onCheckedChange={field.onChange}
|
||||||
></Switch>
|
></Switch> */}
|
||||||
|
<GenerateLogButton
|
||||||
|
{...data}
|
||||||
|
className="w-full text-text-secondary"
|
||||||
|
status={1}
|
||||||
|
type={GenerateType.KnowledgeGraph}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -93,8 +104,8 @@ export function UseGraphRagFormField() {
|
|||||||
// The three types "table", "resume" and "one" do not display this configuration.
|
// The three types "table", "resume" and "one" do not display this configuration.
|
||||||
const GraphRagItems = ({
|
const GraphRagItems = ({
|
||||||
marginBottom = false,
|
marginBottom = false,
|
||||||
showGenerateItem = false,
|
|
||||||
className = 'p-10',
|
className = 'p-10',
|
||||||
|
data,
|
||||||
}: GraphRagItemsProps) => {
|
}: GraphRagItemsProps) => {
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
const { t } = useTranslate('knowledgeConfiguration');
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
@ -120,7 +131,7 @@ const GraphRagItems = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormContainer className={cn({ 'mb-4': marginBottom }, className)}>
|
<FormContainer className={cn({ 'mb-4': marginBottom }, className)}>
|
||||||
<UseGraphRagFormField></UseGraphRagFormField>
|
<UseGraphRagFormField data={data}></UseGraphRagFormField>
|
||||||
{useRaptor && (
|
{useRaptor && (
|
||||||
<>
|
<>
|
||||||
<EntityTypesFormField name="parser_config.graphrag.entity_types"></EntityTypesFormField>
|
<EntityTypesFormField name="parser_config.graphrag.entity_types"></EntityTypesFormField>
|
||||||
@ -216,7 +227,7 @@ const GraphRagItems = ({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{showGenerateItem && (
|
{/* {showGenerateItem && (
|
||||||
<div className="w-full flex items-center">
|
<div className="w-full flex items-center">
|
||||||
<div className="text-sm whitespace-nowrap w-1/4">
|
<div className="text-sm whitespace-nowrap w-1/4">
|
||||||
{t('extractKnowledgeGraph')}
|
{t('extractKnowledgeGraph')}
|
||||||
@ -227,7 +238,7 @@ const GraphRagItems = ({
|
|||||||
type={GenerateType.KnowledgeGraph}
|
type={GenerateType.KnowledgeGraph}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)} */}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { useTranslate } from '@/hooks/common-hooks';
|
|||||||
import {
|
import {
|
||||||
GenerateLogButton,
|
GenerateLogButton,
|
||||||
GenerateType,
|
GenerateType,
|
||||||
|
IGenerateLogButtonProps,
|
||||||
} from '@/pages/dataset/dataset/generate-button/generate';
|
} from '@/pages/dataset/dataset/generate-button/generate';
|
||||||
import random from 'lodash/random';
|
import random from 'lodash/random';
|
||||||
import { Shuffle } from 'lucide-react';
|
import { Shuffle } from 'lucide-react';
|
||||||
@ -18,7 +19,6 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from '../ui/form';
|
} from '../ui/form';
|
||||||
import { ExpandedInput } from '../ui/input';
|
import { ExpandedInput } from '../ui/input';
|
||||||
import { Switch } from '../ui/switch';
|
|
||||||
import { Textarea } from '../ui/textarea';
|
import { Textarea } from '../ui/textarea';
|
||||||
|
|
||||||
export const excludedParseMethods = [
|
export const excludedParseMethods = [
|
||||||
@ -56,11 +56,7 @@ const Prompt = 'parser_config.raptor.prompt';
|
|||||||
|
|
||||||
// The three types "table", "resume" and "one" do not display this configuration.
|
// The three types "table", "resume" and "one" do not display this configuration.
|
||||||
|
|
||||||
const RaptorFormFields = ({
|
const RaptorFormFields = ({ data }: { data: IGenerateLogButtonProps }) => {
|
||||||
showGenerateItem = false,
|
|
||||||
}: {
|
|
||||||
showGenerateItem?: boolean;
|
|
||||||
}) => {
|
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
const { t } = useTranslate('knowledgeConfiguration');
|
||||||
const useRaptor = useWatch({ name: UseRaptorField });
|
const useRaptor = useWatch({ name: UseRaptorField });
|
||||||
@ -108,13 +104,12 @@ const RaptorFormFields = ({
|
|||||||
</FormLabel>
|
</FormLabel>
|
||||||
<div className="w-3/4">
|
<div className="w-3/4">
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
<GenerateLogButton
|
||||||
checked={field.value}
|
{...data}
|
||||||
onCheckedChange={(e) => {
|
className="w-full text-text-secondary"
|
||||||
changeRaptor(e);
|
status={1}
|
||||||
field.onChange(e);
|
type={GenerateType.Raptor}
|
||||||
}}
|
/>
|
||||||
></Switch>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -219,18 +214,6 @@ const RaptorFormFields = ({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{showGenerateItem && (
|
|
||||||
<div className="w-full flex items-center">
|
|
||||||
<div className="text-sm whitespace-nowrap w-1/4">
|
|
||||||
{t('extractRaptor')}
|
|
||||||
</div>
|
|
||||||
<GenerateLogButton
|
|
||||||
className="w-3/4 text-text-secondary"
|
|
||||||
status={1}
|
|
||||||
type={GenerateType.Raptor}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -14,6 +14,9 @@ export interface IKnowledge {
|
|||||||
name: string;
|
name: string;
|
||||||
parser_config: ParserConfig;
|
parser_config: ParserConfig;
|
||||||
parser_id: string;
|
parser_id: string;
|
||||||
|
pipeline_id: string;
|
||||||
|
pipeline_name: string;
|
||||||
|
pipeline_avatar: string;
|
||||||
permission: string;
|
permission: string;
|
||||||
similarity_threshold: number;
|
similarity_threshold: number;
|
||||||
status: string;
|
status: string;
|
||||||
@ -26,6 +29,10 @@ export interface IKnowledge {
|
|||||||
nickname: string;
|
nickname: string;
|
||||||
operator_permission: number;
|
operator_permission: number;
|
||||||
size: number;
|
size: number;
|
||||||
|
raptor_task_finish_at?: string;
|
||||||
|
raptor_task_id?: string;
|
||||||
|
mindmap_task_finish_at?: string;
|
||||||
|
mindmap_task_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IKnowledgeResult {
|
export interface IKnowledgeResult {
|
||||||
|
|||||||
@ -115,7 +115,7 @@ const FormatPreserveEditor = ({
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{content.key === 'json' && */}
|
{content.key === 'json' && */}
|
||||||
{content.value.map((item, index) => (
|
{content.value?.map((item, index) => (
|
||||||
<section
|
<section
|
||||||
key={index}
|
key={index}
|
||||||
className={
|
className={
|
||||||
|
|||||||
@ -45,11 +45,17 @@ const useFetchFileLogList = () => {
|
|||||||
queryKey: [
|
queryKey: [
|
||||||
'fileLogList',
|
'fileLogList',
|
||||||
knowledgeBaseId,
|
knowledgeBaseId,
|
||||||
pagination.current,
|
pagination,
|
||||||
pagination.pageSize,
|
|
||||||
searchString,
|
searchString,
|
||||||
active,
|
active,
|
||||||
],
|
],
|
||||||
|
placeholderData: (previousData) => {
|
||||||
|
if (previousData === undefined) {
|
||||||
|
return { logs: [], total: 0 };
|
||||||
|
}
|
||||||
|
return previousData;
|
||||||
|
},
|
||||||
|
enabled: true,
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data: res = {} } = await fetchFunc({
|
const { data: res = {} } = await fetchFunc({
|
||||||
kb_id: knowledgeBaseId,
|
kb_id: knowledgeBaseId,
|
||||||
@ -73,6 +79,7 @@ const useFetchFileLogList = () => {
|
|||||||
searchString,
|
searchString,
|
||||||
handleInputChange: onInputChange,
|
handleInputChange: onInputChange,
|
||||||
pagination: { ...pagination, total: data?.total },
|
pagination: { ...pagination, total: data?.total },
|
||||||
|
setPagination,
|
||||||
active,
|
active,
|
||||||
setActive,
|
setActive,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import SvgIcon from '@/components/svg-icon';
|
import SvgIcon from '@/components/svg-icon';
|
||||||
import { useIsDarkTheme } from '@/components/theme-provider';
|
import { useIsDarkTheme } from '@/components/theme-provider';
|
||||||
|
import { useFetchDocumentList } from '@/hooks/use-document-request';
|
||||||
import { parseColorToRGBA } from '@/utils/common-util';
|
import { parseColorToRGBA } from '@/utils/common-util';
|
||||||
import { CircleQuestionMark } from 'lucide-react';
|
import { CircleQuestionMark } from 'lucide-react';
|
||||||
import { FC, useEffect, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
@ -90,6 +91,9 @@ const FileLogsPage: FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { data: topData } = useFetchOverviewTital();
|
const { data: topData } = useFetchOverviewTital();
|
||||||
|
const {
|
||||||
|
pagination: { total: fileTotal },
|
||||||
|
} = useFetchDocumentList();
|
||||||
console.log('topData --> ', topData);
|
console.log('topData --> ', topData);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTopAllData((prev) => {
|
setTopAllData((prev) => {
|
||||||
@ -104,11 +108,24 @@ const FileLogsPage: FC = () => {
|
|||||||
});
|
});
|
||||||
}, [topData]);
|
}, [topData]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTopAllData((prev) => {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
totalFiles: {
|
||||||
|
value: fileTotal || 0,
|
||||||
|
precent: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [fileTotal]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: tableOriginData,
|
data: tableOriginData,
|
||||||
searchString,
|
searchString,
|
||||||
handleInputChange,
|
handleInputChange,
|
||||||
pagination,
|
pagination,
|
||||||
|
setPagination,
|
||||||
active,
|
active,
|
||||||
setActive,
|
setActive,
|
||||||
} = useFetchFileLogList();
|
} = useFetchFileLogList();
|
||||||
@ -131,6 +148,11 @@ const FileLogsPage: FC = () => {
|
|||||||
};
|
};
|
||||||
const handlePaginationChange = (page: number, pageSize: number) => {
|
const handlePaginationChange = (page: number, pageSize: number) => {
|
||||||
console.log('Pagination changed:', { page, pageSize });
|
console.log('Pagination changed:', { page, pageSize });
|
||||||
|
setPagination({
|
||||||
|
...pagination,
|
||||||
|
page,
|
||||||
|
pageSize: pageSize,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDark = useIsDarkTheme();
|
const isDark = useIsDarkTheme();
|
||||||
|
|||||||
@ -1,23 +1,26 @@
|
|||||||
|
import { IDataPipelineSelectNode } from '@/components/data-pipeline-select';
|
||||||
import { IconFont } from '@/components/icon-font';
|
import { IconFont } from '@/components/icon-font';
|
||||||
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Modal } from '@/components/ui/modal/modal';
|
import { Modal } from '@/components/ui/modal/modal';
|
||||||
import { omit } from 'lodash';
|
import { Link } from 'lucide-react';
|
||||||
import { Link, Settings2, Unlink } from 'lucide-react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useState } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { z } from 'zod';
|
|
||||||
import { linkPiplineFormSchema } from '../form-schema';
|
|
||||||
import LinkDataPipelineModal from './link-data-pipline-modal';
|
import LinkDataPipelineModal from './link-data-pipline-modal';
|
||||||
|
export interface IDataPipelineNodeProps extends IDataPipelineSelectNode {
|
||||||
interface DataPipelineItemProps {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
avatar?: string;
|
|
||||||
isDefault?: boolean;
|
isDefault?: boolean;
|
||||||
linked?: boolean;
|
linked?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ILinkDataPipelineProps {
|
||||||
|
data?: IDataPipelineNodeProps;
|
||||||
|
handleLinkOrEditSubmit?: (data: IDataPipelineNodeProps | undefined) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataPipelineItemProps extends IDataPipelineNodeProps {
|
||||||
openLinkModalFunc?: (open: boolean, data?: IDataPipelineNodeProps) => void;
|
openLinkModalFunc?: (open: boolean, data?: IDataPipelineNodeProps) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DataPipelineItem = (props: DataPipelineItemProps) => {
|
const DataPipelineItem = (props: DataPipelineItemProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { name, avatar, isDefault, linked, openLinkModalFunc } = props;
|
const { name, avatar, isDefault, linked, openLinkModalFunc } = props;
|
||||||
@ -57,17 +60,17 @@ const DataPipelineItem = (props: DataPipelineItemProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between gap-1 px-2 rounded-lg border">
|
<div className="flex items-center justify-between gap-1 px-2 rounded-md border">
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<RAGFlowAvatar avatar={avatar} name={name} className="size-4" />
|
<RAGFlowAvatar avatar={avatar} name={name} className="size-4" />
|
||||||
<div>{name}</div>
|
<div>{name}</div>
|
||||||
{isDefault && (
|
{/* {isDefault && (
|
||||||
<div className="text-xs bg-text-secondary text-bg-base px-2 py-1 rounded-md">
|
<div className="text-xs bg-text-secondary text-bg-base px-2 py-1 rounded-md">
|
||||||
{t('knowledgeConfiguration.default')}
|
{t('knowledgeConfiguration.default')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-1 items-center">
|
{/* <div className="flex gap-1 items-center">
|
||||||
<Button
|
<Button
|
||||||
variant={'transparent'}
|
variant={'transparent'}
|
||||||
className="border-none"
|
className="border-none"
|
||||||
@ -94,50 +97,29 @@ const DataPipelineItem = (props: DataPipelineItemProps) => {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IDataPipelineNodeProps {
|
const LinkDataPipeline = (props: ILinkDataPipelineProps) => {
|
||||||
id: string;
|
const { data, handleLinkOrEditSubmit: submit } = props;
|
||||||
name: string;
|
|
||||||
avatar?: string;
|
|
||||||
isDefault?: boolean;
|
|
||||||
linked?: boolean;
|
|
||||||
}
|
|
||||||
const LinkDataPipeline = () => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [openLinkModal, setOpenLinkModal] = useState(false);
|
const [openLinkModal, setOpenLinkModal] = useState(false);
|
||||||
const [currentDataPipeline, setCurrentDataPipeline] =
|
const [currentDataPipeline, setCurrentDataPipeline] =
|
||||||
useState<IDataPipelineNodeProps>();
|
useState<IDataPipelineNodeProps>();
|
||||||
const testNode = [
|
const pipelineNode: IDataPipelineNodeProps[] = useMemo(
|
||||||
{
|
() => [
|
||||||
id: '1',
|
{
|
||||||
name: 'Data Pipeline 1',
|
id: data?.id,
|
||||||
avatar: 'https://avatars.githubusercontent.com/u/10656201?v=4',
|
name: data?.name,
|
||||||
isDefault: true,
|
avatar: data?.avatar,
|
||||||
linked: true,
|
isDefault: data?.isDefault,
|
||||||
},
|
linked: true,
|
||||||
{
|
},
|
||||||
id: '2',
|
],
|
||||||
name: 'Data Pipeline 2',
|
[data],
|
||||||
avatar: 'https://avatars.githubusercontent.com/u/10656201?v=4',
|
);
|
||||||
linked: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3',
|
|
||||||
name: 'Data Pipeline 3',
|
|
||||||
avatar: 'https://avatars.githubusercontent.com/u/10656201?v=4',
|
|
||||||
linked: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4',
|
|
||||||
name: 'Data Pipeline 4',
|
|
||||||
avatar: 'https://avatars.githubusercontent.com/u/10656201?v=4',
|
|
||||||
linked: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const openLinkModalFunc = (open: boolean, data?: IDataPipelineNodeProps) => {
|
const openLinkModalFunc = (open: boolean, data?: IDataPipelineNodeProps) => {
|
||||||
console.log('open', open, data);
|
console.log('open', open, data);
|
||||||
setOpenLinkModal(open);
|
setOpenLinkModal(open);
|
||||||
@ -148,9 +130,11 @@ const LinkDataPipeline = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleLinkOrEditSubmit = (
|
const handleLinkOrEditSubmit = (
|
||||||
data: z.infer<typeof linkPiplineFormSchema>,
|
data: IDataPipelineSelectNode | undefined,
|
||||||
) => {
|
) => {
|
||||||
console.log('handleLinkOrEditSubmit', data);
|
console.log('handleLinkOrEditSubmit', data);
|
||||||
|
submit?.(data);
|
||||||
|
setOpenLinkModal(false);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
@ -178,13 +162,20 @@ const LinkDataPipeline = () => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section className="flex flex-col gap-2">
|
<section className="flex flex-col gap-2">
|
||||||
{testNode.map((item) => (
|
{pipelineNode.map(
|
||||||
<DataPipelineItem
|
(item) =>
|
||||||
key={item.name}
|
item.id && (
|
||||||
openLinkModalFunc={openLinkModalFunc}
|
<DataPipelineItem
|
||||||
{...item}
|
key={item.id}
|
||||||
/>
|
openLinkModalFunc={openLinkModalFunc}
|
||||||
))}
|
id={item.id}
|
||||||
|
name={item.name}
|
||||||
|
avatar={item.avatar}
|
||||||
|
isDefault={item.isDefault}
|
||||||
|
linked={item.linked}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
<LinkDataPipelineModal
|
<LinkDataPipelineModal
|
||||||
data={currentDataPipeline}
|
data={currentDataPipeline}
|
||||||
|
|||||||
@ -1,19 +1,14 @@
|
|||||||
import { DataFlowSelect } from '@/components/data-pipeline-select';
|
|
||||||
import Input from '@/components/originui/input';
|
|
||||||
import { Button } from '@/components/ui/button';
|
|
||||||
import {
|
import {
|
||||||
Form,
|
DataFlowSelect,
|
||||||
FormControl,
|
IDataPipelineSelectNode,
|
||||||
FormField,
|
} from '@/components/data-pipeline-select';
|
||||||
FormItem,
|
import { Button } from '@/components/ui/button';
|
||||||
FormLabel,
|
import { Form } from '@/components/ui/form';
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import { Modal } from '@/components/ui/modal/modal';
|
import { Modal } from '@/components/ui/modal/modal';
|
||||||
import { Switch } from '@/components/ui/switch';
|
|
||||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
import { useState } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { pipelineFormSchema } from '../form-schema';
|
import { pipelineFormSchema } from '../form-schema';
|
||||||
@ -28,13 +23,14 @@ const LinkDataPipelineModal = ({
|
|||||||
data: IDataPipelineNodeProps | undefined;
|
data: IDataPipelineNodeProps | undefined;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
setOpen: (open: boolean) => void;
|
setOpen: (open: boolean) => void;
|
||||||
onSubmit?: (data: any) => void;
|
onSubmit?: (pipeline: IDataPipelineSelectNode | undefined) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const isEdit = !!data;
|
const isEdit = !!data;
|
||||||
|
const [list, setList] = useState<IDataPipelineSelectNode[]>();
|
||||||
const form = useForm<z.infer<typeof pipelineFormSchema>>({
|
const form = useForm<z.infer<typeof pipelineFormSchema>>({
|
||||||
resolver: zodResolver(pipelineFormSchema),
|
resolver: zodResolver(pipelineFormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
data_flow: [],
|
pipeline_id: '',
|
||||||
set_default: false,
|
set_default: false,
|
||||||
file_filter: '',
|
file_filter: '',
|
||||||
},
|
},
|
||||||
@ -43,11 +39,12 @@ const LinkDataPipelineModal = ({
|
|||||||
const { navigateToAgents } = useNavigatePage();
|
const { navigateToAgents } = useNavigatePage();
|
||||||
const handleFormSubmit = (values: any) => {
|
const handleFormSubmit = (values: any) => {
|
||||||
console.log(values, data);
|
console.log(values, data);
|
||||||
const param = {
|
// const param = {
|
||||||
...data,
|
// ...data,
|
||||||
...values,
|
// ...values,
|
||||||
};
|
// };
|
||||||
onSubmit?.(param);
|
const pipeline = list?.find((item) => item.id === values.pipeline_id);
|
||||||
|
onSubmit?.(pipeline);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@ -67,10 +64,11 @@ const LinkDataPipelineModal = ({
|
|||||||
{!isEdit && (
|
{!isEdit && (
|
||||||
<DataFlowSelect
|
<DataFlowSelect
|
||||||
toDataPipeline={navigateToAgents}
|
toDataPipeline={navigateToAgents}
|
||||||
formFieldName="data_flow"
|
formFieldName="pipeline_id"
|
||||||
|
setDataList={setList}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<FormField
|
{/* <FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name={'file_filter'}
|
name={'file_filter'}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
@ -135,7 +133,7 @@ const LinkDataPipelineModal = ({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)} */}
|
||||||
<div className="flex justify-end gap-1">
|
<div className="flex justify-end gap-1">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@ -11,6 +11,9 @@ export const formSchema = z.object({
|
|||||||
avatar: z.any().nullish(),
|
avatar: z.any().nullish(),
|
||||||
permission: z.string().optional(),
|
permission: z.string().optional(),
|
||||||
parser_id: z.string(),
|
parser_id: z.string(),
|
||||||
|
pipeline_id: z.string().optional(),
|
||||||
|
pipeline_name: z.string().optional(),
|
||||||
|
pipeline_avatar: z.string().optional(),
|
||||||
embd_id: z.string(),
|
embd_id: z.string(),
|
||||||
parser_config: z
|
parser_config: z
|
||||||
.object({
|
.object({
|
||||||
@ -73,16 +76,16 @@ export const formSchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const pipelineFormSchema = z.object({
|
export const pipelineFormSchema = z.object({
|
||||||
data_flow: z.array(z.string()).optional(),
|
pipeline_id: z.string().optional(),
|
||||||
set_default: z.boolean().optional(),
|
set_default: z.boolean().optional(),
|
||||||
file_filter: z.string().optional(),
|
file_filter: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const linkPiplineFormSchema = pipelineFormSchema.pick({
|
// export const linkPiplineFormSchema = pipelineFormSchema.pick({
|
||||||
data_flow: true,
|
// pipeline_id: true,
|
||||||
file_filter: true,
|
// file_filter: true,
|
||||||
});
|
// });
|
||||||
export const editPiplineFormSchema = pipelineFormSchema.pick({
|
// export const editPiplineFormSchema = pipelineFormSchema.pick({
|
||||||
set_default: true,
|
// set_default: true,
|
||||||
file_filter: true,
|
// file_filter: true,
|
||||||
});
|
// });
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { AvatarUpload } from '@/components/avatar-upload';
|
import { AvatarUpload } from '@/components/avatar-upload';
|
||||||
|
import PageRankFormField from '@/components/page-rank-form-field';
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormField,
|
FormField,
|
||||||
@ -9,6 +10,7 @@ import {
|
|||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { TagItems } from './components/tag-item';
|
||||||
import { EmbeddingModelItem } from './configuration/common-item';
|
import { EmbeddingModelItem } from './configuration/common-item';
|
||||||
import { PermissionFormField } from './permission-form-field';
|
import { PermissionFormField } from './permission-form-field';
|
||||||
|
|
||||||
@ -87,6 +89,9 @@ export function GeneralForm() {
|
|||||||
/>
|
/>
|
||||||
<PermissionFormField></PermissionFormField>
|
<PermissionFormField></PermissionFormField>
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
<EmbeddingModelItem></EmbeddingModelItem>
|
||||||
|
<PageRankFormField></PageRankFormField>
|
||||||
|
|
||||||
|
<TagItems></TagItems>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,16 @@ export const useFetchKnowledgeConfigurationOnMount = (
|
|||||||
const parser_config = {
|
const parser_config = {
|
||||||
...form.formState?.defaultValues?.parser_config,
|
...form.formState?.defaultValues?.parser_config,
|
||||||
...knowledgeDetails.parser_config,
|
...knowledgeDetails.parser_config,
|
||||||
|
raptor: {
|
||||||
|
...form.formState?.defaultValues?.parser_config?.raptor,
|
||||||
|
...knowledgeDetails.parser_config?.raptor,
|
||||||
|
use_raptor: true,
|
||||||
|
},
|
||||||
|
graphrag: {
|
||||||
|
...form.formState?.defaultValues?.parser_config?.graphrag,
|
||||||
|
...knowledgeDetails.parser_config?.graphrag,
|
||||||
|
use_graphrag: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const formValues = {
|
const formValues = {
|
||||||
...pick({ ...knowledgeDetails, parser_config: parser_config }, [
|
...pick({ ...knowledgeDetails, parser_config: parser_config }, [
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { IDataPipelineSelectNode } from '@/components/data-pipeline-select';
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@ -6,11 +7,15 @@ import { Form } from '@/components/ui/form';
|
|||||||
import { DocumentParserType } from '@/constants/knowledge';
|
import { DocumentParserType } from '@/constants/knowledge';
|
||||||
import { PermissionRole } from '@/constants/permission';
|
import { PermissionRole } from '@/constants/permission';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { TopTitle } from '../dataset-title';
|
import { TopTitle } from '../dataset-title';
|
||||||
import LinkDataPipeline from './components/link-data-pipeline';
|
import { IGenerateLogButtonProps } from '../dataset/generate-button/generate';
|
||||||
|
import LinkDataPipeline, {
|
||||||
|
IDataPipelineNodeProps,
|
||||||
|
} from './components/link-data-pipeline';
|
||||||
import { MainContainer } from './configuration-form-container';
|
import { MainContainer } from './configuration-form-container';
|
||||||
import { formSchema } from './form-schema';
|
import { formSchema } from './form-schema';
|
||||||
import { GeneralForm } from './general-form';
|
import { GeneralForm } from './general-form';
|
||||||
@ -51,24 +56,70 @@ export default function DatasetSettings() {
|
|||||||
html4excel: false,
|
html4excel: false,
|
||||||
topn_tags: 3,
|
topn_tags: 3,
|
||||||
raptor: {
|
raptor: {
|
||||||
use_raptor: false,
|
use_raptor: true,
|
||||||
|
max_token: 256,
|
||||||
|
threshold: 0.1,
|
||||||
|
max_cluster: 64,
|
||||||
|
random_seed: 0,
|
||||||
|
prompt: t('knowledgeConfiguration.promptText'),
|
||||||
},
|
},
|
||||||
graphrag: {
|
graphrag: {
|
||||||
use_graphrag: false,
|
use_graphrag: true,
|
||||||
entity_types: initialEntityTypes,
|
entity_types: initialEntityTypes,
|
||||||
method: MethodValue.Light,
|
method: MethodValue.Light,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
pipeline_id: '',
|
||||||
pagerank: 0,
|
pagerank: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useFetchKnowledgeConfigurationOnMount(form);
|
const knowledgeDetails = useFetchKnowledgeConfigurationOnMount(form);
|
||||||
|
|
||||||
|
const [pipelineData, setPipelineData] = useState<IDataPipelineNodeProps>();
|
||||||
|
const [graphRagGenerateData, setGraphRagGenerateData] =
|
||||||
|
useState<IGenerateLogButtonProps>();
|
||||||
|
const [raptorGenerateData, setRaptorGenerateData] =
|
||||||
|
useState<IGenerateLogButtonProps>();
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('🚀 ~ DatasetSettings ~ knowledgeDetails:', knowledgeDetails);
|
||||||
|
if (knowledgeDetails) {
|
||||||
|
const data: IDataPipelineNodeProps = {
|
||||||
|
id: knowledgeDetails.pipeline_id,
|
||||||
|
name: knowledgeDetails.pipeline_name,
|
||||||
|
avatar: knowledgeDetails.pipeline_avatar,
|
||||||
|
linked: true,
|
||||||
|
};
|
||||||
|
setPipelineData(data);
|
||||||
|
setGraphRagGenerateData({
|
||||||
|
finish_at: knowledgeDetails.mindmap_task_finish_at,
|
||||||
|
task_id: knowledgeDetails.mindmap_task_id,
|
||||||
|
} as IGenerateLogButtonProps);
|
||||||
|
setRaptorGenerateData({
|
||||||
|
finish_at: knowledgeDetails.raptor_task_finish_at,
|
||||||
|
task_id: knowledgeDetails.raptor_task_id,
|
||||||
|
} as IGenerateLogButtonProps);
|
||||||
|
}
|
||||||
|
}, [knowledgeDetails]);
|
||||||
|
|
||||||
async function onSubmit(data: z.infer<typeof formSchema>) {
|
async function onSubmit(data: z.infer<typeof formSchema>) {
|
||||||
console.log('🚀 ~ DatasetSettings ~ data:', data);
|
try {
|
||||||
|
console.log('Form validation passed, submit data', data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('An error occurred during submission:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
const handleLinkOrEditSubmit = (
|
||||||
|
data: IDataPipelineSelectNode | undefined,
|
||||||
|
) => {
|
||||||
|
console.log('🚀 ~ DatasetSettings ~ data:', data);
|
||||||
|
if (data) {
|
||||||
|
setPipelineData(data);
|
||||||
|
form.setValue('pipeline_id', data.id || '');
|
||||||
|
// form.setValue('pipeline_name', data.name || '');
|
||||||
|
// form.setValue('pipeline_avatar', data.avatar || '');
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<section className="p-5 h-full flex flex-col">
|
<section className="p-5 h-full flex flex-col">
|
||||||
<TopTitle
|
<TopTitle
|
||||||
@ -88,12 +139,17 @@ export default function DatasetSettings() {
|
|||||||
|
|
||||||
<GraphRagItems
|
<GraphRagItems
|
||||||
className="border-none p-0"
|
className="border-none p-0"
|
||||||
showGenerateItem={true}
|
data={graphRagGenerateData as IGenerateLogButtonProps}
|
||||||
></GraphRagItems>
|
></GraphRagItems>
|
||||||
<Divider />
|
<Divider />
|
||||||
<RaptorFormFields showGenerateItem={true}></RaptorFormFields>
|
<RaptorFormFields
|
||||||
|
data={raptorGenerateData as IGenerateLogButtonProps}
|
||||||
|
></RaptorFormFields>
|
||||||
<Divider />
|
<Divider />
|
||||||
<LinkDataPipeline />
|
<LinkDataPipeline
|
||||||
|
data={pipelineData}
|
||||||
|
handleLinkOrEditSubmit={handleLinkOrEditSubmit}
|
||||||
|
/>
|
||||||
</MainContainer>
|
</MainContainer>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-right items-center flex justify-end gap-3 w-[768px]">
|
<div className="text-right items-center flex justify-end gap-3 w-[768px]">
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export function SavingButton() {
|
|||||||
if (beValid) {
|
if (beValid) {
|
||||||
form.handleSubmit(async (values) => {
|
form.handleSubmit(async (values) => {
|
||||||
console.log('saveKnowledgeConfiguration: ', values);
|
console.log('saveKnowledgeConfiguration: ', values);
|
||||||
delete values['avatar'];
|
// delete values['avatar'];
|
||||||
await saveKnowledgeConfiguration({
|
await saveKnowledgeConfiguration({
|
||||||
kb_id,
|
kb_id,
|
||||||
...values,
|
...values,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
import { Modal } from '@/components/ui/modal/modal';
|
import { Modal } from '@/components/ui/modal/modal';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { toFixed } from '@/utils/common-util';
|
import { toFixed } from '@/utils/common-util';
|
||||||
|
import { formatDate } from '@/utils/date';
|
||||||
import { UseMutateAsyncFunction } from '@tanstack/react-query';
|
import { UseMutateAsyncFunction } from '@tanstack/react-query';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { lowerFirst } from 'lodash';
|
import { lowerFirst } from 'lodash';
|
||||||
@ -29,7 +30,13 @@ export enum GenerateType {
|
|||||||
const MenuItem: React.FC<{
|
const MenuItem: React.FC<{
|
||||||
name: GenerateType;
|
name: GenerateType;
|
||||||
data: ITraceInfo;
|
data: ITraceInfo;
|
||||||
pauseGenerate: () => void;
|
pauseGenerate: ({
|
||||||
|
task_id,
|
||||||
|
type,
|
||||||
|
}: {
|
||||||
|
task_id: string;
|
||||||
|
type: GenerateType;
|
||||||
|
}) => void;
|
||||||
runGenerate: UseMutateAsyncFunction<
|
runGenerate: UseMutateAsyncFunction<
|
||||||
any,
|
any,
|
||||||
Error,
|
Error,
|
||||||
@ -38,13 +45,12 @@ const MenuItem: React.FC<{
|
|||||||
},
|
},
|
||||||
unknown
|
unknown
|
||||||
>;
|
>;
|
||||||
}> = ({ name, runGenerate, data, pauseGenerate }) => {
|
}> = ({ name: type, runGenerate, data, pauseGenerate }) => {
|
||||||
console.log(name, 'pppp', data);
|
|
||||||
const iconKeyMap = {
|
const iconKeyMap = {
|
||||||
KnowledgeGraph: 'knowledgegraph',
|
KnowledgeGraph: 'knowledgegraph',
|
||||||
Raptor: 'dataflow-01',
|
Raptor: 'dataflow-01',
|
||||||
};
|
};
|
||||||
const type = useMemo(() => {
|
const status = useMemo(() => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return generateStatus.start;
|
return generateStatus.start;
|
||||||
}
|
}
|
||||||
@ -60,9 +66,9 @@ const MenuItem: React.FC<{
|
|||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
const percent =
|
const percent =
|
||||||
type === generateStatus.failed
|
status === generateStatus.failed
|
||||||
? 100
|
? 100
|
||||||
: type === generateStatus.running
|
: status === generateStatus.running
|
||||||
? data.progress * 100
|
? data.progress * 100
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
@ -72,9 +78,9 @@ const MenuItem: React.FC<{
|
|||||||
'border cursor-pointer p-2 rounded-md focus:bg-transparent',
|
'border cursor-pointer p-2 rounded-md focus:bg-transparent',
|
||||||
{
|
{
|
||||||
'hover:border-accent-primary hover:bg-[rgba(59,160,92,0.1)]':
|
'hover:border-accent-primary hover:bg-[rgba(59,160,92,0.1)]':
|
||||||
type === generateStatus.start,
|
status === generateStatus.start,
|
||||||
'hover:border-border hover:bg-[rgba(59,160,92,0)]':
|
'hover:border-border hover:bg-[rgba(59,160,92,0)]':
|
||||||
type !== generateStatus.start,
|
status !== generateStatus.start,
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
onSelect={(e) => {
|
onSelect={(e) => {
|
||||||
@ -87,56 +93,65 @@ const MenuItem: React.FC<{
|
|||||||
<div
|
<div
|
||||||
className="flex items-start gap-2 flex-col w-full"
|
className="flex items-start gap-2 flex-col w-full"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (type === generateStatus.start) {
|
if (status === generateStatus.start) {
|
||||||
runGenerate({ type: name });
|
runGenerate({ type });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex justify-start text-text-primary items-center gap-2">
|
<div className="flex justify-start text-text-primary items-center gap-2">
|
||||||
<IconFontFill
|
<IconFontFill
|
||||||
name={iconKeyMap[name]}
|
name={iconKeyMap[type]}
|
||||||
className="text-accent-primary"
|
className="text-accent-primary"
|
||||||
/>
|
/>
|
||||||
{t(`knowledgeDetails.${lowerFirst(name)}`)}
|
{t(`knowledgeDetails.${lowerFirst(type)}`)}
|
||||||
</div>
|
</div>
|
||||||
{type === generateStatus.start && (
|
{status === generateStatus.start && (
|
||||||
<div className="text-text-secondary text-sm">
|
<div className="text-text-secondary text-sm">
|
||||||
{t(`knowledgeDetails.generate${name}`)}
|
{t(`knowledgeDetails.generate${type}`)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(type === generateStatus.running ||
|
{(status === generateStatus.running ||
|
||||||
type === generateStatus.failed) && (
|
status === generateStatus.failed) && (
|
||||||
<div className="flex justify-between items-center w-full px-2.5 py-1">
|
<div className="flex justify-between items-center w-full px-2.5 py-1">
|
||||||
<div
|
<div
|
||||||
className={cn(' bg-border-button h-1 rounded-full', {
|
className={cn(' bg-border-button h-1 rounded-full', {
|
||||||
'w-[calc(100%-100px)]': type === generateStatus.running,
|
'w-[calc(100%-100px)]': status === generateStatus.running,
|
||||||
'w-[calc(100%-50px)]': type === generateStatus.failed,
|
'w-[calc(100%-50px)]': status === generateStatus.failed,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={cn('h-1 rounded-full', {
|
className={cn('h-1 rounded-full', {
|
||||||
'bg-state-error': type === generateStatus.failed,
|
'bg-state-error': status === generateStatus.failed,
|
||||||
'bg-accent-primary': type === generateStatus.running,
|
'bg-accent-primary': status === generateStatus.running,
|
||||||
})}
|
})}
|
||||||
style={{ width: `${toFixed(percent)}%` }}
|
style={{ width: `${toFixed(percent)}%` }}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
{type === generateStatus.running && (
|
{status === generateStatus.running && (
|
||||||
<span>{(toFixed(percent) as string) + '%'}</span>
|
<span>{(toFixed(percent) as string) + '%'}</span>
|
||||||
)}
|
)}
|
||||||
<span
|
{status === generateStatus.failed && (
|
||||||
className="text-state-error"
|
<span
|
||||||
onClick={(e) => {
|
className="text-state-error"
|
||||||
e.stopPropagation();
|
onClick={(e) => {
|
||||||
pauseGenerate();
|
e.stopPropagation();
|
||||||
}}
|
runGenerate({ type });
|
||||||
>
|
}}
|
||||||
{type === generateStatus.failed ? (
|
>
|
||||||
<IconFontFill name="reparse" className="text-accent-primary" />
|
<IconFontFill name="reparse" className="text-accent-primary" />
|
||||||
) : (
|
</span>
|
||||||
|
)}
|
||||||
|
{status !== generateStatus.failed && (
|
||||||
|
<span
|
||||||
|
className="text-state-error"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
pauseGenerate({ task_id: data.id, type });
|
||||||
|
}}
|
||||||
|
>
|
||||||
<CirclePause />
|
<CirclePause />
|
||||||
)}
|
</span>
|
||||||
</span>
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="w-full whitespace-pre-line text-wrap rounded-lg h-fit max-h-[350px] overflow-y-auto scrollbar-auto px-2.5 py-1">
|
<div className="w-full whitespace-pre-line text-wrap rounded-lg h-fit max-h-[350px] overflow-y-auto scrollbar-auto px-2.5 py-1">
|
||||||
@ -202,7 +217,12 @@ const Generate: React.FC = () => {
|
|||||||
|
|
||||||
export default Generate;
|
export default Generate;
|
||||||
|
|
||||||
export type IGenerateLogProps = {
|
export type IGenerateLogButtonProps = {
|
||||||
|
finish_at: string;
|
||||||
|
task_id: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type IGenerateLogProps = IGenerateLogButtonProps & {
|
||||||
id?: string;
|
id?: string;
|
||||||
status: 0 | 1;
|
status: 0 | 1;
|
||||||
message?: string;
|
message?: string;
|
||||||
@ -214,16 +234,7 @@ export type IGenerateLogProps = {
|
|||||||
};
|
};
|
||||||
export const GenerateLogButton = (props: IGenerateLogProps) => {
|
export const GenerateLogButton = (props: IGenerateLogProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const {
|
const { task_id, message, finish_at, type, onDelete } = props;
|
||||||
id,
|
|
||||||
status,
|
|
||||||
message,
|
|
||||||
created_at,
|
|
||||||
updated_at,
|
|
||||||
type,
|
|
||||||
className,
|
|
||||||
onDelete,
|
|
||||||
} = props;
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
Modal.show({
|
Modal.show({
|
||||||
visible: true,
|
visible: true,
|
||||||
@ -278,11 +289,11 @@ export const GenerateLogButton = (props: IGenerateLogProps) => {
|
|||||||
className={cn('flex bg-bg-card rounded-md py-1 px-3', props.className)}
|
className={cn('flex bg-bg-card rounded-md py-1 px-3', props.className)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between w-full">
|
<div className="flex items-center justify-between w-full">
|
||||||
{status === 1 && (
|
{finish_at && (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
{message || t('knowledgeDetails.generatedOn')}
|
{message || t('knowledgeDetails.generatedOn')}
|
||||||
{created_at}
|
{formatDate(finish_at)}
|
||||||
</div>
|
</div>
|
||||||
<Trash2
|
<Trash2
|
||||||
size={14}
|
size={14}
|
||||||
@ -295,7 +306,7 @@ export const GenerateLogButton = (props: IGenerateLogProps) => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{status === 0 && <div>{t('knowledgeDetails.notGenerated')}</div>}
|
{!finish_at && <div>{t('knowledgeDetails.notGenerated')}</div>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import message from '@/components/ui/message';
|
import message from '@/components/ui/message';
|
||||||
|
import agentService from '@/services/agent-service';
|
||||||
import kbService from '@/services/knowledge-service';
|
import kbService from '@/services/knowledge-service';
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useParams } from 'umi';
|
import { useParams } from 'umi';
|
||||||
import { GenerateType } from './generate';
|
import { GenerateType } from './generate';
|
||||||
export const generateStatus = {
|
export const generateStatus = {
|
||||||
@ -14,6 +15,7 @@ export const generateStatus = {
|
|||||||
|
|
||||||
enum DatasetKey {
|
enum DatasetKey {
|
||||||
generate = 'generate',
|
generate = 'generate',
|
||||||
|
pauseGenerate = 'pauseGenerate',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITraceInfo {
|
export interface ITraceInfo {
|
||||||
@ -126,9 +128,28 @@ export const useDatasetGenerate = () => {
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const pauseGenerate = useCallback(() => {
|
// const pauseGenerate = useCallback(() => {
|
||||||
// TODO: pause generate
|
// // TODO: pause generate
|
||||||
console.log('pause generate');
|
// console.log('pause generate');
|
||||||
}, []);
|
// }, []);
|
||||||
|
const { mutateAsync: pauseGenerate } = useMutation({
|
||||||
|
mutationKey: [DatasetKey.pauseGenerate],
|
||||||
|
mutationFn: async ({
|
||||||
|
task_id,
|
||||||
|
type,
|
||||||
|
}: {
|
||||||
|
task_id: string;
|
||||||
|
type: GenerateType;
|
||||||
|
}) => {
|
||||||
|
const { data } = await agentService.cancelDataflow(task_id);
|
||||||
|
if (data.code === 0) {
|
||||||
|
message.success(t('message.operated'));
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: [type],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
});
|
||||||
return { runGenerate: mutateAsync, pauseGenerate, data, loading };
|
return { runGenerate: mutateAsync, pauseGenerate, data, loading };
|
||||||
};
|
};
|
||||||
|
|||||||
@ -23,7 +23,9 @@ const IconMap = {
|
|||||||
[RunningStatus.UNSTART]: (
|
[RunningStatus.UNSTART]: (
|
||||||
<div className="w-0 h-0 border-l-[10px] border-l-accent-primary border-t-8 border-r-4 border-b-8 border-transparent"></div>
|
<div className="w-0 h-0 border-l-[10px] border-l-accent-primary border-t-8 border-r-4 border-b-8 border-transparent"></div>
|
||||||
),
|
),
|
||||||
[RunningStatus.RUNNING]: <CircleX size={14} color="var(--state-error)" />,
|
[RunningStatus.RUNNING]: (
|
||||||
|
<CircleX size={14} color="rgba(var(--state-error))" />
|
||||||
|
),
|
||||||
[RunningStatus.CANCEL]: (
|
[RunningStatus.CANCEL]: (
|
||||||
<IconFontFill name="reparse" className="text-accent-primary" />
|
<IconFontFill name="reparse" className="text-accent-primary" />
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user