Feat: Display the configuration of data flow operators on the node #9869 (#10533)

### What problem does this PR solve?

Feat: Display the configuration of data flow operators on the node #9869

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-10-14 13:30:54 +08:00
committed by GitHub
parent aaae938f54
commit 781d49cd0e
6 changed files with 68 additions and 61 deletions

View File

@ -1,57 +1,12 @@
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { cn } from '@/lib/utils';
import { PropsWithChildren } from 'react';
export function CardWithForm() {
type LabelCardProps = {
className?: string;
} & PropsWithChildren;
export function LabelCard({ children, className }: LabelCardProps) {
return (
<Card className="w-[350px]">
<CardHeader>
<CardTitle>Create project</CardTitle>
<CardDescription>Deploy your new project in one-click.</CardDescription>
</CardHeader>
<CardContent>
<form>
<div className="grid w-full items-center gap-4">
<div className="flex flex-col space-y-1.5">
<Label htmlFor="name">Name</Label>
<Input id="name" placeholder="Name of your project" />
</div>
<div className="flex flex-col space-y-1.5">
<Label htmlFor="framework">Framework</Label>
<Select>
<SelectTrigger id="framework">
<SelectValue placeholder="Select" />
</SelectTrigger>
<SelectContent position="popper">
<SelectItem value="next">Next.js</SelectItem>
<SelectItem value="sveltekit">SvelteKit</SelectItem>
<SelectItem value="astro">Astro</SelectItem>
<SelectItem value="nuxt">Nuxt.js</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</form>
</CardContent>
<CardFooter className="flex justify-between">
<Button variant="outline">Cancel</Button>
<Button>Deploy</Button>
</CardFooter>
</Card>
<div className={cn('bg-bg-card rounded-sm p-1', className)}>{children}</div>
);
}

View File

@ -1 +1,18 @@
export { RagNode as ExtractorNode } from './index';
import LLMLabel from '@/components/llm-select/llm-label';
import { IRagNode } from '@/interfaces/database/agent';
import { NodeProps } from '@xyflow/react';
import { get } from 'lodash';
import { LabelCard } from './card';
import { RagNode } from './index';
export function ExtractorNode({ ...props }: NodeProps<IRagNode>) {
const { data } = props;
return (
<RagNode {...props}>
<LabelCard>
<LLMLabel value={get(data, 'form.llm_id')}></LLMLabel>
</LabelCard>
</RagNode>
);
}

View File

@ -1,6 +1,6 @@
import { IRagNode } from '@/interfaces/database/flow';
import { NodeProps, Position } from '@xyflow/react';
import { memo, useMemo } from 'react';
import { PropsWithChildren, memo, useMemo } from 'react';
import { NodeHandleId, SingleOperators } from '../../constant';
import useGraphStore from '../../store';
import { CommonHandle } from './handle';
@ -9,12 +9,14 @@ import NodeHeader from './node-header';
import { NodeWrapper } from './node-wrapper';
import { ToolBar } from './toolbar';
type RagNodeProps = NodeProps<IRagNode> & PropsWithChildren;
function InnerRagNode({
id,
data,
isConnectable = true,
selected,
}: NodeProps<IRagNode>) {
children,
}: RagNodeProps) {
const getOperatorTypeFromId = useGraphStore(
(state) => state.getOperatorTypeFromId,
);
@ -45,6 +47,7 @@ function InnerRagNode({
isConnectableEnd={false}
></CommonHandle>
<NodeHeader id={id} name={data.name} label={data.label}></NodeHeader>
{children}
</NodeWrapper>
</ToolBar>
);

View File

@ -1,7 +1,10 @@
import { IRagNode } from '@/interfaces/database/flow';
import { BaseNode } from '@/interfaces/database/agent';
import { NodeProps, Position } from '@xyflow/react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { NodeHandleId } from '../../constant';
import { ParserFormSchemaType } from '../../form/parser-form';
import { LabelCard } from './card';
import { CommonHandle } from './handle';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import NodeHeader from './node-header';
@ -12,7 +15,8 @@ function ParserNode({
data,
isConnectable = true,
selected,
}: NodeProps<IRagNode>) {
}: NodeProps<BaseNode<ParserFormSchemaType>>) {
const { t } = useTranslation();
return (
<NodeWrapper selected={selected}>
<CommonHandle
@ -33,6 +37,17 @@ function ParserNode({
isConnectableEnd={false}
></CommonHandle>
<NodeHeader id={id} name={data.name} label={data.label}></NodeHeader>
<section className="space-y-2">
{data.form?.setups.map((x, idx) => (
<LabelCard
key={idx}
className="flex justify-between text-text-primary"
>
<span className="text-text-secondary">Parser {idx + 1}</span>
{t(`dataflow.fileFormatOptions.${x.fileFormat}`)}
</LabelCard>
))}
</section>
</NodeWrapper>
);
}

View File

@ -1,7 +1,10 @@
import { IRagNode } from '@/interfaces/database/flow';
import { BaseNode } from '@/interfaces/database/agent';
import { NodeProps, Position } from '@xyflow/react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { NodeHandleId } from '../../constant';
import { TokenizerFormSchemaType } from '../../form/tokenizer-form';
import { LabelCard } from './card';
import { CommonHandle } from './handle';
import { LeftHandleStyle } from './handle-icon';
import NodeHeader from './node-header';
@ -13,7 +16,9 @@ function TokenizerNode({
data,
isConnectable = true,
selected,
}: NodeProps<IRagNode>) {
}: NodeProps<BaseNode<TokenizerFormSchemaType>>) {
const { t } = useTranslation();
return (
<ToolBar
selected={selected}
@ -32,6 +37,16 @@ function TokenizerNode({
nodeId={id}
></CommonHandle>
<NodeHeader id={id} name={data.name} label={data.label}></NodeHeader>
<LabelCard className="text-text-primary flex justify-between">
<span className="text-text-secondary">
{t('dataflow.searchMethod')}
</span>
<ul>
{data.form?.search_method.map((x) => (
<li key={x}>{t(`dataflow.tokenizerSearchMethodOptions.${x}`)}</li>
))}
</ul>
</LabelCard>
</NodeWrapper>
</ToolBar>
);

View File

@ -29,6 +29,8 @@ export const FormSchema = z.object({
fields: z.string(),
});
export type TokenizerFormSchemaType = z.infer<typeof FormSchema>;
const TokenizerForm = ({ node }: INextOperatorForm) => {
const { t } = useTranslation();
const defaultValues = useFormValues(initialTokenizerValues, node);
@ -44,7 +46,7 @@ const TokenizerForm = ({ node }: INextOperatorForm) => {
'dataflow.tokenizerFieldsOptions',
);
const form = useForm<z.infer<typeof FormSchema>>({
const form = useForm<TokenizerFormSchemaType>({
defaultValues,
resolver: zodResolver(FormSchema),
mode: 'onChange',