Feat: Wrap DynamicVariableForm with Collapsible. #3221 (#5440)

### What problem does this PR solve?

Feat: Wrap DynamicVariableForm with Collapsible. #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-02-27 16:09:12 +08:00 committed by GitHub
parent 230865c4f7
commit 7a6e70d6b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 19 deletions

View File

@ -1,5 +1,7 @@
import { cn } from '@/lib/utils';
import Icon from '@ant-design/icons'; import Icon from '@ant-design/icons';
import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon';
import { ChevronDown } from 'lucide-react';
type IconComponentProps = CustomIconComponentProps; type IconComponentProps = CustomIconComponentProps;
const currentColor = 'currentColor'; const currentColor = 'currentColor';
@ -276,3 +278,14 @@ export const SemicolonIcon = (props: Partial<IconComponentProps>) => (
export const CommaIcon = (props: Partial<IconComponentProps>) => ( export const CommaIcon = (props: Partial<IconComponentProps>) => (
<Icon component={CommaSvg} {...props} /> <Icon component={CommaSvg} {...props} />
); );
export function SideDown({ className }: { className?: string }) {
return (
<ChevronDown
className={cn(
'transition-transform group-data-[state=open]/collapsible:rotate-180',
className,
)}
/>
);
}

View File

@ -190,7 +190,8 @@ type RAGFlowSelectProps = Partial<ControllerRenderProps> & {
FormControlComponent?: typeof FormControl; FormControlComponent?: typeof FormControl;
options?: (RAGFlowSelectOptionType | RAGFlowSelectGroupOptionType)[]; options?: (RAGFlowSelectOptionType | RAGFlowSelectGroupOptionType)[];
allowClear?: boolean; allowClear?: boolean;
}; placeholder?: React.ReactNode;
} & SelectPrimitive.SelectProps;
/** /**
* *
@ -218,6 +219,7 @@ export const RAGFlowSelect = forwardRef<
FormControlComponent, FormControlComponent,
options = [], options = [],
allowClear, allowClear,
placeholder,
}, },
ref, ref,
) { ) {
@ -260,7 +262,7 @@ export const RAGFlowSelect = forwardRef<
allowClear={allowClear} allowClear={allowClear}
ref={ref} ref={ref}
> >
<SelectValue placeholder="Select a verified email to display" /> <SelectValue placeholder={placeholder} />
</SelectTrigger> </SelectTrigger>
</FormControlWidget> </FormControlWidget>
<SelectContent> <SelectContent>
@ -292,3 +294,5 @@ export const RAGFlowSelect = forwardRef<
</Select> </Select>
); );
}); });
RAGFlowSelect.displayName = 'RAGFlowSelect';

View File

@ -1,3 +1,4 @@
import { SideDown } from '@/assets/icon/Icon';
import { Card, CardContent } from '@/components/ui/card'; import { Card, CardContent } from '@/components/ui/card';
import { import {
Collapsible, Collapsible,
@ -13,7 +14,6 @@ import {
SidebarHeader, SidebarHeader,
SidebarMenu, SidebarMenu,
} from '@/components/ui/sidebar'; } from '@/components/ui/sidebar';
import { ChevronDown } from 'lucide-react';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { import {
AgentOperatorList, AgentOperatorList,
@ -23,12 +23,6 @@ import {
} from './constant'; } from './constant';
import OperatorIcon from './operator-icon'; import OperatorIcon from './operator-icon';
function SideDown() {
return (
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
);
}
type OperatorItem = { type OperatorItem = {
name: Operator; name: Operator;
}; };
@ -59,7 +53,7 @@ function OperatorCollapsible({
<SidebarGroupLabel asChild className="mb-1"> <SidebarGroupLabel asChild className="mb-1">
<CollapsibleTrigger> <CollapsibleTrigger>
<span className="font-bold text-base">{title}</span> <span className="font-bold text-base">{title}</span>
<SideDown /> <SideDown className="ml-auto" />
</CollapsibleTrigger> </CollapsibleTrigger>
</SidebarGroupLabel> </SidebarGroupLabel>
<CollapsibleContent className="px-2"> <CollapsibleContent className="px-2">

View File

@ -87,7 +87,7 @@ const FormSheet = ({
}, [visible, form, node?.data?.form, node?.id, node, operatorName]); }, [visible, form, node?.data?.form, node?.id, node, operatorName]);
return ( return (
<Sheet onOpenChange={hideModal} open={visible} modal={false}> <Sheet open={visible} modal={false}>
<SheetContent className="bg-white top-20" closeIcon={false}> <SheetContent className="bg-white top-20" closeIcon={false}>
<SheetHeader> <SheetHeader>
<section className="flex-col border-b pb-2"> <section className="flex-col border-b pb-2">

View File

@ -1,6 +1,12 @@
'use client'; 'use client';
import { SideDown } from '@/assets/icon/Icon';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from '@/components/ui/collapsible';
import { import {
FormControl, FormControl,
FormDescription, FormDescription,
@ -11,7 +17,7 @@ import {
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { RAGFlowSelect } from '@/components/ui/select'; import { RAGFlowSelect } from '@/components/ui/select';
import { RAGFlowNodeType } from '@/interfaces/database/flow'; import { RAGFlowNodeType } from '@/interfaces/database/flow';
import { CircleMinus, Plus } from 'lucide-react'; import { Plus, Trash2 } from 'lucide-react';
import { useFieldArray, useFormContext } from 'react-hook-form'; import { useFieldArray, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
@ -61,9 +67,14 @@ export function DynamicVariableForm({ node }: IProps) {
<FormDescription /> <FormDescription />
<FormControl> <FormControl>
<RAGFlowSelect <RAGFlowSelect
// placeholder={t('common.pleaseSelect')}
{...field} {...field}
placeholder={t('common.pleaseSelect')}
options={options} options={options}
onChange={(val) => {
field.onChange(val);
form.resetField(`query.${index}.value`);
form.resetField(`query.${index}.component_id`);
}}
></RAGFlowSelect> ></RAGFlowSelect>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
@ -79,7 +90,7 @@ export function DynamicVariableForm({ node }: IProps) {
<FormControl> <FormControl>
{typeValue === VariableType.Reference ? ( {typeValue === VariableType.Reference ? (
<RAGFlowSelect <RAGFlowSelect
// placeholder={t('common.pleaseSelect')} placeholder={t('common.pleaseSelect')}
{...field} {...field}
options={valueOptions} options={valueOptions}
></RAGFlowSelect> ></RAGFlowSelect>
@ -91,17 +102,37 @@ export function DynamicVariableForm({ node }: IProps) {
</FormItem> </FormItem>
)} )}
/> />
<CircleMinus <Trash2
className="cursor-pointer" className="cursor-pointer mx-3 size-4 text-colors-text-functional-danger"
onClick={() => remove(index)} onClick={() => remove(index)}
/> />
</div> </div>
); );
})} })}
<Button onClick={append} className="w-full mt-4"> <Button onClick={append} className="mt-4" variant={'outline'} size={'sm'}>
<Plus /> <Plus />
{t('flow.addVariable')} {t('flow.addVariable')}
</Button> </Button>
</div> </div>
); );
} }
export function DynamicInputVariable({ node }: IProps) {
const { t } = useTranslation();
return (
<Collapsible defaultOpen className="group/collapsible pt-4">
<CollapsibleTrigger className="flex justify-between w-full pb-2">
<span className="font-bold text-2xl text-colors-text-neutral-strong">
{t('flow.input')}
</span>
<Button variant={'icon'} size={'icon'}>
<SideDown />
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
<DynamicVariableForm node={node}></DynamicVariableForm>
</CollapsibleContent>
</Collapsible>
);
}

View File

@ -13,7 +13,7 @@ import {
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { INextOperatorForm } from '../../interface'; import { INextOperatorForm } from '../../interface';
import { DynamicVariableForm } from '../components/next-dynamic-input-variable'; import { DynamicInputVariable } from '../components/next-dynamic-input-variable';
const RetrievalForm = ({ form, node }: INextOperatorForm) => { const RetrievalForm = ({ form, node }: INextOperatorForm) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -25,7 +25,7 @@ const RetrievalForm = ({ form, node }: INextOperatorForm) => {
e.preventDefault(); e.preventDefault();
}} }}
> >
<DynamicVariableForm></DynamicVariableForm> <DynamicInputVariable node={node}></DynamicInputVariable>
<SimilaritySliderFormField vectorSimilarityWeightName="keywords_similarity_weight"></SimilaritySliderFormField> <SimilaritySliderFormField vectorSimilarityWeightName="keywords_similarity_weight"></SimilaritySliderFormField>
<TopNFormField></TopNFormField> <TopNFormField></TopNFormField>
<RerankFormFields></RerankFormFields> <RerankFormFields></RerankFormFields>