From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001 From: wwf <yearningwang@iqtogether.com> Date: 星期三, 04 六月 2025 15:17:49 +0800 Subject: [PATCH] 初始化 --- app/components/header/account-setting/model-provider-page/model-modal/Form.tsx | 338 +++++++++++++++----------------------------------------- 1 files changed, 92 insertions(+), 246 deletions(-) diff --git a/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index c5af4ed..c0a7be6 100644 --- a/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -1,5 +1,5 @@ -import { useCallback, useState } from 'react' -import type { ReactNode } from 'react' +import { useState } from 'react' +import type { FC } from 'react' import { ValidatingTip } from '../../key-validator/ValidateStatus' import type { CredentialFormSchema, @@ -17,48 +17,24 @@ import { SimpleSelect } from '@/app/components/base/select' import Tooltip from '@/app/components/base/tooltip' import Radio from '@/app/components/base/radio' -import ModelParameterModal from '@/app/components/plugins/plugin-detail-panel/model-selector' -import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-selector' -import MultipleToolSelector from '@/app/components/plugins/plugin-detail-panel/multiple-tool-selector' -import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-selector' -import RadioE from '@/app/components/base/radio/ui' -import type { - NodeOutPutVar, -} from '@/app/components/workflow/types' -import type { Node } from 'reactflow' - -type FormProps< - CustomFormSchema extends Omit<CredentialFormSchema, 'type'> & { type: string } = never, -> = { +type FormProps = { className?: string itemClassName?: string fieldLabelClassName?: string value: FormValue onChange: (val: FormValue) => void - formSchemas: Array<CredentialFormSchema | CustomFormSchema> + formSchemas: CredentialFormSchema[] validating: boolean validatedSuccess?: boolean showOnVariableMap: Record<string, string[]> isEditMode: boolean - isAgentStrategy?: boolean readonly?: boolean inputClassName?: string isShowDefaultValue?: boolean - fieldMoreInfo?: (payload: CredentialFormSchema | CustomFormSchema) => ReactNode - customRenderField?: ( - formSchema: CustomFormSchema, - props: Omit<FormProps<CustomFormSchema>, 'override' | 'customRenderField'> - ) => ReactNode - // If return falsy value, this field will fallback to default render - override?: [Array<FormTypeEnum>, (formSchema: CredentialFormSchema, props: Omit<FormProps<CustomFormSchema>, 'override' | 'customRenderField'>) => ReactNode] - nodeId?: string - nodeOutputVars?: NodeOutPutVar[], - availableNodes?: Node[], + fieldMoreInfo?: (payload: CredentialFormSchema) => JSX.Element | null } -function Form< - CustomFormSchema extends Omit<CredentialFormSchema, 'type'> & { type: string } = never, ->({ +const Form: FC<FormProps> = ({ className, itemClassName, fieldLabelClassName, @@ -69,35 +45,13 @@ validatedSuccess, showOnVariableMap, isEditMode, - isAgentStrategy = false, readonly, inputClassName, isShowDefaultValue = false, fieldMoreInfo, - customRenderField, - override, - nodeId, - nodeOutputVars, - availableNodes, -}: FormProps<CustomFormSchema>) { +}) => { const language = useLanguage() const [changeKey, setChangeKey] = useState('') - const filteredProps: Omit<FormProps<CustomFormSchema>, 'override' | 'customRenderField'> = { - className, - itemClassName, - fieldLabelClassName, - value, - onChange, - formSchemas, - validating, - validatedSuccess, - showOnVariableMap, - isEditMode, - readonly, - inputClassName, - isShowDefaultValue, - fieldMoreInfo, - } const handleFormChange = (key: string, val: string | boolean) => { if (isEditMode && (key === '__model_type' || key === '__model_name')) @@ -107,44 +61,31 @@ const shouldClearVariable: Record<string, string | undefined> = {} if (showOnVariableMap[key]?.length) { showOnVariableMap[key].forEach((clearVariable) => { - const schema = formSchemas.find(it => it.variable === clearVariable) - shouldClearVariable[clearVariable] = schema ? schema.default : undefined + shouldClearVariable[clearVariable] = undefined }) } onChange({ ...value, [key]: val, ...shouldClearVariable }) } - const handleModelChanged = useCallback((key: string, model: any) => { - const newValue = { - ...value[key], - ...model, - type: FormTypeEnum.modelSelector, - } - onChange({ ...value, [key]: newValue }) - }, [onChange, value]) - - const renderField = (formSchema: CredentialFormSchema | CustomFormSchema) => { + const renderField = (formSchema: CredentialFormSchema) => { const tooltip = formSchema.tooltip const tooltipContent = (tooltip && ( <Tooltip - popupContent={<div className='w-[200px]'> - {tooltip[language] || tooltip.en_US} - </div>} + popupContent={ + <div className='w-[200px]'> + {tooltip[language] || tooltip.en_US} + </div>} triggerClassName='ml-1 w-4 h-4' - asChild={false} /> + asChild={false} + /> )) - if (override) { - const [overrideTypes, overrideRender] = override - if (overrideTypes.includes(formSchema.type as FormTypeEnum)) { - const node = overrideRender(formSchema as CredentialFormSchema, filteredProps) - if (node) - return node - } - } - 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)) @@ -153,11 +94,13 @@ const disabled = readonly || (isEditMode && (variable === '__model_type' || variable === '__model_name')) return ( <div key={variable} className={cn(itemClassName, 'py-3')}> - <div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}> + <div className={cn(fieldLabelClassName, 'flex items-center py-2 text-sm text-gray-900')}> {label[language] || label.en_US} - {required && ( - <span className='ml-1 text-red-500'>*</span> - )} + { + required && ( + <span className='ml-1 text-red-500'>*</span> + ) + } {tooltipContent} </div> <Input @@ -167,10 +110,9 @@ validated={validatedSuccess} placeholder={placeholder?.[language] || placeholder?.en_US} disabled={disabled} - type={formSchema.type === FormTypeEnum.secretInput ? 'password' - : formSchema.type === FormTypeEnum.textNumber ? 'number' - : 'text'} - {...(formSchema.type === FormTypeEnum.textNumber ? { min: (formSchema as CredentialFormSchemaNumberInput).min, max: (formSchema as CredentialFormSchemaNumberInput).max } : {})} /> + type={formSchema.type === FormTypeEnum.textNumber ? 'number' : 'text'} + {...(formSchema.type === FormTypeEnum.textNumber ? { min: (formSchema as CredentialFormSchemaNumberInput).min, max: (formSchema as CredentialFormSchemaNumberInput).max } : {})} + /> {fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && <ValidatingTip />} </div> @@ -179,7 +121,11 @@ 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)) @@ -189,34 +135,40 @@ return ( <div key={variable} className={cn(itemClassName, 'py-3')}> - <div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}> + <div className={cn(fieldLabelClassName, 'flex items-center py-2 text-sm text-gray-900')}> {label[language] || label.en_US} - {required && ( - <span className='ml-1 text-red-500'>*</span> - )} + { + required && ( + <span className='ml-1 text-red-500'>*</span> + ) + } {tooltipContent} </div> - <div className={cn('grid gap-3', `grid-cols-${options?.length}`)}> - {options.filter((option) => { - if (option.show_on.length) - return option.show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value) + <div className={`grid grid-cols-${options?.length} gap-3`}> + { + options.filter((option) => { + if (option.show_on.length) + return option.show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value) - return true - }).map(option => ( - <div - className={` - flex cursor-pointer items-center gap-2 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg px-3 py-2 - ${value[variable] === option.value && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg shadow-sm'} + return true + }).map(option => ( + <div + className={` + flex items-center px-3 py-2 rounded-lg border border-gray-100 bg-gray-25 cursor-pointer + ${value[variable] === option.value && 'bg-white border-[1.5px] border-primary-400 shadow-sm'} ${disabled && '!cursor-not-allowed opacity-60'} `} - onClick={() => handleFormChange(variable, option.value)} - key={`${variable}-${option.value}`} - > - <RadioE isChecked={value[variable] === option.value} /> - - <div className='system-sm-regular text-text-secondary'>{option.label[language] || option.label.en_US}</div> - </div> - ))} + onClick={() => handleFormChange(variable, option.value)} + key={`${variable}-${option.value}`} + > + <div className={` + flex justify-center items-center mr-2 w-4 h-4 border border-gray-300 rounded-full + ${value[variable] === option.value && 'border-[5px] border-primary-600'} + `} /> + <div className='text-sm text-gray-900'>{option.label[language] || option.label.en_US}</div> + </div> + )) + } </div> {fieldMoreInfo?.(formSchema)} {validating && changeKey === variable && <ValidatingTip />} @@ -224,9 +176,14 @@ ) } - if (formSchema.type === FormTypeEnum.select) { + if (formSchema.type === '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)) @@ -234,16 +191,17 @@ return ( <div key={variable} className={cn(itemClassName, 'py-3')}> - <div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}> + <div className={cn(fieldLabelClassName, 'flex items-center py-2 text-sm text-gray-900')}> {label[language] || label.en_US} - {required && ( - <span className='ml-1 text-red-500'>*</span> - )} + { + required && ( + <span className='ml-1 text-red-500'>*</span> + ) + } {tooltipContent} </div> <SimpleSelect - wrapperClassName='h-8' className={cn(inputClassName)} disabled={readonly} defaultValue={(isShowDefaultValue && ((value[variable] as string) === '' || value[variable] === undefined || value[variable] === null)) ? formSchema.default : value[variable]} @@ -254,16 +212,20 @@ 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 && <ValidatingTip />} </div> ) } - if (formSchema.type === FormTypeEnum.boolean) { + if (formSchema.type === '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)) @@ -271,12 +233,14 @@ return ( <div key={variable} className={cn(itemClassName, 'py-3')}> - <div className='system-sm-semibold flex items-center justify-between py-2 text-text-secondary'> + <div className='flex items-center justify-between py-2 text-sm text-gray-900'> <div className='flex items-center space-x-2'> - <span className={cn(fieldLabelClassName, 'system-sm-regular flex items-center py-2 text-text-secondary')}>{label[language] || label.en_US}</span> - {required && ( - <span className='ml-1 text-red-500'>*</span> - )} + <span className={cn(fieldLabelClassName, 'flex items-center py-2 text-sm text-gray-900')}>{label[language] || label.en_US}</span> + { + required && ( + <span className='ml-1 text-red-500'>*</span> + ) + } {tooltipContent} </div> <Radio.Group @@ -292,131 +256,13 @@ </div> ) } - - if (formSchema.type === FormTypeEnum.modelSelector) { - const { - variable, label, required, scope, - } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) - return ( - <div key={variable} className={cn(itemClassName, 'py-3')}> - <div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}> - {label[language] || label.en_US} - {required && ( - <span className='ml-1 text-red-500'>*</span> - )} - {tooltipContent} - </div> - <ModelParameterModal - popupClassName='!w-[387px]' - isAdvancedMode - isInWorkflow - isAgentStrategy={isAgentStrategy} - value={value[variable]} - setModel={model => handleModelChanged(variable, model)} - readonly={readonly} - scope={scope} /> - {fieldMoreInfo?.(formSchema)} - {validating && changeKey === variable && <ValidatingTip />} - </div> - ) - } - - if (formSchema.type === FormTypeEnum.toolSelector) { - const { - variable, - label, - required, - scope, - } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) - return ( - <div key={variable} className={cn(itemClassName, 'py-3')}> - <div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}> - {label[language] || label.en_US} - {required && ( - <span className='ml-1 text-red-500'>*</span> - )} - {tooltipContent} - </div> - <ToolSelector - scope={scope} - nodeId={nodeId} - nodeOutputVars={nodeOutputVars || []} - availableNodes={availableNodes || []} - disabled={readonly} - value={value[variable]} - // selectedTools={value[variable] ? [value[variable]] : []} - onSelect={item => handleFormChange(variable, item as any)} - onDelete={() => handleFormChange(variable, null as any)} - /> - {fieldMoreInfo?.(formSchema)} - {validating && changeKey === variable && <ValidatingTip />} - </div> - ) - } - - if (formSchema.type === FormTypeEnum.multiToolSelector) { - const { - variable, - label, - tooltip, - required, - scope, - } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) - - return ( - <div key={variable} className={cn(itemClassName, 'py-3')}> - <MultipleToolSelector - disabled={readonly} - nodeId={nodeId} - nodeOutputVars={nodeOutputVars || []} - availableNodes={availableNodes || []} - scope={scope} - label={label[language] || label.en_US} - required={required} - tooltip={tooltip?.[language] || tooltip?.en_US} - value={value[variable] || []} - onChange={item => handleFormChange(variable, item as any)} - supportCollapse - /> - {fieldMoreInfo?.(formSchema)} - {validating && changeKey === variable && <ValidatingTip />} - </div> - ) - } - - if (formSchema.type === FormTypeEnum.appSelector) { - const { - variable, label, required, scope, - } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) - - return ( - <div key={variable} className={cn(itemClassName, 'py-3')}> - <div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}> - {label[language] || label.en_US} - {required && ( - <span className='ml-1 text-red-500'>*</span> - )} - {tooltipContent} - </div> - <AppSelector - disabled={readonly} - scope={scope} - value={value[variable]} - onSelect={item => handleFormChange(variable, { ...item, type: FormTypeEnum.appSelector } as any)} /> - {fieldMoreInfo?.(formSchema)} - {validating && changeKey === variable && <ValidatingTip />} - </div> - ) - } - - // @ts-expect-error it work - if (!Object.values(FormTypeEnum).includes(formSchema.type)) - return customRenderField?.(formSchema as CustomFormSchema, filteredProps) } return ( <div className={className}> - {formSchemas.map(formSchema => renderField(formSchema))} + { + formSchemas.map(formSchema => renderField(formSchema)) + } </div> ) } -- Gitblit v1.8.0