From b7e56a23a07bbcfbe7cd28c6e185348737e86731 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Thu, 26 Dec 2024 14:32:21 +0800 Subject: [PATCH] feat: custom credential form --- .../model-provider-page/model-modal/Form.tsx | 194 ++++++++---------- .../nodes/_base/components/agent-strategy.tsx | 51 ++++- .../components/workflow/nodes/agent/panel.tsx | 21 -- 3 files changed, 135 insertions(+), 131 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index d08a72adc9..fdb7aece0f 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -1,5 +1,5 @@ import { useCallback, useState } from 'react' -import type { FC } from 'react' +import type { ReactNode } from 'react' import { ValidatingTip } from '../../key-validator/ValidateStatus' import type { CredentialFormSchema, @@ -22,13 +22,15 @@ import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-sele import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-selector' import RadioE from '@/app/components/base/radio/ui' -type FormProps = { +type FormProps< + CustomFormSchema extends Omit & { type: string } = never, +> = { className?: string itemClassName?: string fieldLabelClassName?: string value: FormValue onChange: (val: FormValue) => void - formSchemas: CredentialFormSchema[] + formSchemas: Array validating: boolean validatedSuccess?: boolean showOnVariableMap: Record @@ -36,10 +38,13 @@ type FormProps = { readonly?: boolean inputClassName?: string isShowDefaultValue?: boolean - fieldMoreInfo?: (payload: CredentialFormSchema) => JSX.Element | null + fieldMoreInfo?: (payload: CredentialFormSchema | CustomFormSchema) => ReactNode + customRenderField?: (formSchema: CustomFormSchema, props: FormProps) => ReactNode } -const Form: FC = ({ +function Form< + CustomFormSchema extends Omit & { type: string } = never, +>({ className, itemClassName, fieldLabelClassName, @@ -54,7 +59,8 @@ const Form: FC = ({ inputClassName, isShowDefaultValue = false, fieldMoreInfo, -}) => { + customRenderField, +}: FormProps) { const language = useLanguage() const [changeKey, setChangeKey] = useState('') @@ -81,25 +87,19 @@ const Form: FC = ({ onChange({ ...value, [key]: newValue }) }, [onChange, value]) - const renderField = (formSchema: CredentialFormSchema) => { + const renderField = (formSchema: CredentialFormSchema | CustomFormSchema) => { const tooltip = formSchema.tooltip const tooltipContent = (tooltip && ( - {tooltip[language] || tooltip.en_US} - } + popupContent={
+ {tooltip[language] || tooltip.en_US} +
} triggerClassName='ml-1 w-4 h-4' - asChild={false} - /> + asChild={false} /> )) if (formSchema.type === FormTypeEnum.textInput || formSchema.type === FormTypeEnum.secretInput || formSchema.type === FormTypeEnum.textNumber) { const { - variable, - label, - placeholder, - required, - show_on, + variable, label, placeholder, required, show_on, } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) if (show_on.length && !show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)) @@ -110,11 +110,9 @@ const Form: FC = ({
{label[language] || label.en_US} - { - required && ( - * - ) - } + {required && ( + * + )} {tooltipContent}
= ({ placeholder={placeholder?.[language] || placeholder?.en_US} disabled={disabled} type={formSchema.type === FormTypeEnum.textNumber ? 'number' : 'text'} - {...(formSchema.type === FormTypeEnum.textNumber ? { min: (formSchema as CredentialFormSchemaNumberInput).min, max: (formSchema as CredentialFormSchemaNumberInput).max } : {})} - /> + {...(formSchema.type === FormTypeEnum.textNumber ? { min: (formSchema as CredentialFormSchemaNumberInput).min, max: (formSchema as CredentialFormSchemaNumberInput).max } : {})} /> {fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && }
@@ -135,11 +132,7 @@ const Form: FC = ({ if (formSchema.type === FormTypeEnum.radio) { const { - options, - variable, - label, - show_on, - required, + options, variable, label, show_on, required, } = formSchema as CredentialFormSchemaRadio if (show_on.length && !show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)) @@ -151,36 +144,32 @@ const Form: FC = ({
{label[language] || label.en_US} - { - required && ( - * - ) - } + {required && ( + * + )} {tooltipContent}
- { - options.filter((option) => { - if (option.show_on.length) - return option.show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value) + {options.filter((option) => { + if (option.show_on.length) + return option.show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value) - return true - }).map(option => ( -
( +
handleFormChange(variable, option.value)} - key={`${variable}-${option.value}`} - > - + onClick={() => handleFormChange(variable, option.value)} + key={`${variable}-${option.value}`} + > + -
{option.label[language] || option.label.en_US}
-
- )) - } +
{option.label[language] || option.label.en_US}
+
+ ))}
{fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && } @@ -190,12 +179,7 @@ const Form: FC = ({ if (formSchema.type === FormTypeEnum.select) { const { - options, - variable, - label, - show_on, - required, - placeholder, + options, variable, label, show_on, required, placeholder, } = formSchema as CredentialFormSchemaSelect if (show_on.length && !show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)) @@ -206,11 +190,9 @@ const Form: FC = ({
{label[language] || label.en_US} - { - required && ( - * - ) - } + {required && ( + * + )} {tooltipContent}
= ({ return true }).map(option => ({ value: option.value, name: option.label[language] || option.label.en_US }))} onSelect={item => handleFormChange(variable, item.value as string)} - placeholder={placeholder?.[language] || placeholder?.en_US} - /> + placeholder={placeholder?.[language] || placeholder?.en_US} /> {fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && }
@@ -235,10 +216,7 @@ const Form: FC = ({ if (formSchema.type === FormTypeEnum.boolean) { const { - variable, - label, - show_on, - required, + variable, label, show_on, required, } = formSchema as CredentialFormSchemaRadio if (show_on.length && !show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)) @@ -249,11 +227,9 @@ const Form: FC = ({
{label[language] || label.en_US} - { - required && ( - * - ) - } + {required && ( + * + )} {tooltipContent}
= ({ if (formSchema.type === FormTypeEnum.modelSelector) { const { - variable, - label, - required, - scope, + variable, label, required, scope, } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) return (
{label[language] || label.en_US} - { - required && ( - * - ) - } + {required && ( + * + )} {tooltipContent}
= ({ value={value[variable]} setModel={model => handleModelChanged(variable, model)} readonly={readonly} - scope={scope} - /> + scope={scope} /> {fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && }
@@ -305,27 +275,22 @@ const Form: FC = ({ if (formSchema.type === FormTypeEnum.toolSelector) { const { - variable, - label, - required, + variable, label, required, } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) return (
{label[language] || label.en_US} - { - required && ( - * - ) - } + {required && ( + * + )} {tooltipContent}
handleFormChange(variable, item as any)} - /> + onSelect={item => handleFormChange(variable, item as any)} /> {fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && }
@@ -334,41 +299,54 @@ const Form: FC = ({ if (formSchema.type === FormTypeEnum.appSelector) { const { - variable, - label, - required, - scope, + variable, label, required, scope, } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) return (
{label[language] || label.en_US} - { - required && ( - * - ) - } + {required && ( + * + )} {tooltipContent}
handleFormChange(variable, { ...item, type: FormTypeEnum.appSelector } as any)} - /> + onSelect={item => handleFormChange(variable, { ...item, type: FormTypeEnum.appSelector } as any)} /> {fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && }
) } + + // @ts-expect-error it work + if (!Object.values(FormTypeEnum).includes(formSchema.type)) { + return customRenderField?.(formSchema as CustomFormSchema, { + className, + itemClassName, + fieldLabelClassName, + value, + onChange, + formSchemas, + validating, + validatedSuccess, + showOnVariableMap, + isEditMode, + readonly, + inputClassName, + isShowDefaultValue, + fieldMoreInfo, + customRenderField, + }) + } } return (
- { - formSchemas.map(formSchema => renderField(formSchema)) - } + {formSchemas.map(formSchema => renderField(formSchema))}
) } diff --git a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx index fbd9463582..d21190b1ff 100644 --- a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx +++ b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx @@ -6,6 +6,10 @@ import Link from 'next/link' import { useTranslation } from 'react-i18next' import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' import { Agent } from '@/app/components/base/icons/src/vender/workflow' +import { InputNumber } from '@/app/components/base/input-number' +import Slider from '@/app/components/base/slider' +import Field from './field' +import type { ComponentProps } from 'react' export type Strategy = { agent_strategy_provider_name: string @@ -22,22 +26,65 @@ export type AgentStrategyProps = { onFormValueChange: (value: ToolVarInputs) => void } +type MaxIterFormSchema = Omit & { type: 'max-iter' } + export const AgentStrategy = (props: AgentStrategyProps) => { const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange } = props const { t } = useTranslation() + const renderField: ComponentProps>['customRenderField'] = (schema, props) => { + switch (schema.type) { + case 'max-iter': { + const value = props.value[schema.variable] + const onChange = (value: number) => { + props.onChange({ ...props.value, [schema.variable]: value }) + } + return +
+ + +
+
+ } + } + } + console.log(formSchema) return
{ strategy ?
-
+ formSchemas={[ + ...formSchema, + { + type: 'max-iter', + variable: 'max_iterations', + label: { + en_US: 'Max Iterations', + zh_Hans: '最大迭代次数', + }, + name: 'max iter', + required: true, + show_on: [], + } as MaxIterFormSchema, + ]} value={formValue} onChange={onFormValueChange} validating={false} showOnVariableMap={{}} isEditMode={true} fieldLabelClassName='uppercase' + customRenderField={renderField} />
: > = (props) => { })} /> - - - - -
- - -
-
}