refactor: playground params form

This commit is contained in:
jialin
2026-03-17 16:35:55 +08:00
committed by jialin
parent 9447088f89
commit d389b035b7
30 changed files with 1299 additions and 951 deletions
@@ -1,202 +0,0 @@
import FieldComponent from '@/components/seal-form/field-component';
import SealSelect from '@/components/seal-form/seal-select';
import { useIntl } from '@umijs/max';
import { Form } from 'antd';
import _ from 'lodash';
import React, {
forwardRef,
useCallback,
useEffect,
useId,
useImperativeHandle
} from 'react';
import { FormContext } from '../config/form-context';
import { ParamsSchema } from '../config/types';
type ParamsSettingsProps = {
ref?: any;
parametersTitle?: React.ReactNode;
showModelSelector?: boolean;
modelList?: Global.BaseOption<string>[];
onValuesChange?: (changeValues: any, value: Record<string, any>) => void;
onModelChange?: (model: string) => void;
paramsConfig?: ParamsSchema[];
initialValues?: Record<string, any>; // for initial values when switch model, aviod update values from setParams
extra?: React.ReactNode;
watchFields?: string[];
formFields?: string;
meta?: Record<string, any>;
};
const ParamsSettings: React.FC<ParamsSettingsProps> = forwardRef(
(
{
onValuesChange,
onModelChange,
parametersTitle,
initialValues,
paramsConfig,
modelList,
showModelSelector = true,
extra,
meta
},
ref
) => {
const intl = useIntl();
const [form] = Form.useForm();
const formId = useId();
useImperativeHandle(ref, () => ({
form
}));
useEffect(() => {
form.setFieldsValue({
...initialValues
});
}, [initialValues]);
const handleOnFinish = (values: any) => {
console.log('handleOnFinish', values);
};
const handleOnFinishFailed = (errorInfo: any) => {
console.log('handleOnFinishFailed', errorInfo);
};
const handleOnModelChange = (model: string) => {
onModelChange?.(model);
};
const handleValuesChange = useCallback(
(changedValues: any, allValues: any) => {
const normalizedValues = Object.fromEntries(
Object.entries(changedValues).map(([key, value]: [string, any]) => [
key,
value?.target?.checked ?? value?.target?.value ?? value
])
);
form.setFieldsValue(normalizedValues);
console.log('handleValuesChange', normalizedValues, allValues);
onValuesChange?.(normalizedValues, {
...allValues,
...normalizedValues
});
},
[onValuesChange]
);
const renderDescription = useCallback(
(description: any) => {
let desc = description?.text;
if (description?.isLocalized) {
desc = intl.formatMessage({ id: description?.text });
}
if (description?.html) {
return <div dangerouslySetInnerHTML={{ __html: desc }}></div>;
}
return desc;
},
[intl]
);
const renderFields = () => {
if (!paramsConfig?.length) {
return null;
}
const values = form.getFieldsValue();
const formValues = _.isEmpty(values) ? initialValues || {} : values;
return paramsConfig?.map((item: ParamsSchema) => {
return (
<Form.Item
name={item.name}
rules={item.rules}
key={item.name}
{...item.formItemAttrs}
>
<FieldComponent
disabled={
item.disabledConfig
? item.disabledConfig?.when?.(formValues)
: item.disabled
}
description={renderDescription(item.description)}
onChange={null}
{..._.omit(item, [
'name',
'rules',
'formItemAttrs',
'dependencies',
'disabledConfig',
'description'
])}
></FieldComponent>
</Form.Item>
);
});
};
return (
<FormContext.Provider
value={{ meta, onValuesChange: handleValuesChange }}
>
<Form
name={formId}
form={form}
onValuesChange={handleValuesChange}
onFinish={handleOnFinish}
onFinishFailed={handleOnFinishFailed}
initialValues={initialValues}
>
<div>
{
<>
<h3 className="m-b-20 font-size-14 line-24 font-500">
{parametersTitle || (
<span>
{intl.formatMessage({ id: 'playground.parameters' })}
</span>
)}
</h3>
{showModelSelector && (
<Form.Item
name="model"
rules={[
{
required: true,
message: intl.formatMessage(
{
id: 'common.form.rule.select'
},
{
name: intl.formatMessage({ id: 'playground.model' })
}
)
}
]}
>
<SealSelect
description={intl.formatMessage({
id: 'playground.model.noavailable.tips2'
})}
onChange={handleOnModelChange}
showSearch={true}
options={modelList}
label={intl.formatMessage({ id: 'playground.model' })}
></SealSelect>
</Form.Item>
)}
</>
}
{renderFields()}
{extra}
</div>
</Form>
</FormContext.Provider>
);
}
);
export default ParamsSettings;
@@ -0,0 +1,52 @@
import SealSelect from '@/components/seal-form/seal-select';
import { useIntl } from '@umijs/max';
import { Form } from 'antd';
import React from 'react';
import { useFormContext } from '../config/form-context';
const ModelSelect: React.FC<{
title?: React.ReactNode;
showModelSelector?: boolean;
}> = ({ title, showModelSelector = true }) => {
const intl = useIntl();
const { onModelChange, modelList } = useFormContext();
return (
<>
<h3 className="m-b-20 font-size-14 line-24 font-500">
{title || (
<span>{intl.formatMessage({ id: 'playground.parameters' })}</span>
)}
</h3>
{showModelSelector && (
<Form.Item
name="model"
rules={[
{
required: true,
message: intl.formatMessage(
{
id: 'common.form.rule.select'
},
{
name: intl.formatMessage({ id: 'playground.model' })
}
)
}
]}
>
<SealSelect
description={intl.formatMessage({
id: 'playground.model.noavailable.tips2'
})}
onChange={onModelChange}
showSearch={true}
options={modelList}
label={intl.formatMessage({ id: 'playground.model' })}
></SealSelect>
</Form.Item>
)}
</>
);
};
export default ModelSelect;
@@ -24,16 +24,16 @@ import React, {
} from 'react';
import 'simplebar-react/dist/simplebar.min.css';
import { CHAT_API } from '../../apis';
import DataForm from '../../chat/forms';
import { ChatParamsConfig } from '../../chat/params-config';
import { Roles, generateMessagesByListContent } from '../../config';
import CompareContext from '../../config/compare-context';
import { MessageItem, ModelSelectionItem } from '../../config/types';
import { LLM_METAKEYS, llmInitialValues } from '../../hooks/config';
import useChatCompletion from '../../hooks/use-chat-completion';
import { useInitLLmMeta } from '../../hooks/use-init-meta';
import { useInitLLmMeta } from '../../hooks/use-init-llm';
import '../../style/model-item.less';
import { generateLLMCode } from '../../view-code/llm';
import DynamicParams from '../dynamic-params';
import ReferenceParams from '../reference-params';
import ViewCommonCode from '../view-common-code';
import MessageContent from './message-content';
@@ -62,10 +62,8 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
handleOnValuesChange,
handleOnModelChange,
setParams,
setInitialValues,
formRef,
paramsConfig,
initialValues,
parameters
} = useInitLLmMeta(
{
@@ -73,10 +71,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
modelList: modelFullList
},
{
defaultValues: {
...llmInitialValues,
model: model
},
defaultValues: llmInitialValues,
defaultParamsConfig: ChatParamsConfig,
metaKeys: LLM_METAKEYS
}
@@ -87,6 +82,8 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
const [show, setShow] = useState(false);
const scroller = useRef<any>(null);
console.log('render model item', formRef);
const {
submitMessage,
handleAddNewMessage,
@@ -217,11 +214,8 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
...globalParams
};
});
setInitialValues((prev: any) => {
return {
...prev,
...globalParams
};
formRef.current?.setFieldsValue({
...globalParams
});
}, [globalParams]);
@@ -313,11 +307,11 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
style={{ paddingInline: '24px' }}
oppositeTheme={true}
>
<DynamicParams
<DataForm
ref={formRef}
onValuesChange={OnValuesChange}
paramsConfig={paramsConfig}
initialValues={initialValues}
initialValues={parameters}
showModelSelector={false}
parametersTitle={
<div className="flex-center flex-between">
@@ -0,0 +1,107 @@
import FieldComponent from '@/components/seal-form/field-component';
import { useIntl } from '@umijs/max';
import { Form } from 'antd';
import _ from 'lodash';
import React from 'react';
import { useFormContext } from '../config/form-context';
import { ParamsSchema } from '../config/types';
interface ParamsFieldsProps {
paramsConfig?: ParamsSchema[];
}
const ParamsFields: React.FC<ParamsFieldsProps> = ({ paramsConfig = [] }) => {
const intl = useIntl();
const form = Form.useFormInstance();
const { meta } = useFormContext();
const renderDescription = (description: any) => {
let desc = description?.text;
if (description?.isLocalized) {
desc = intl.formatMessage({ id: description?.text });
}
if (description?.html) {
return <div dangerouslySetInnerHTML={{ __html: desc }}></div>;
}
return desc;
};
return paramsConfig?.map((item: ParamsSchema) => {
const comProps = {
...item.attrs,
label: item.label.isLocalized
? intl.formatMessage({ id: item.label.text })
: item.label.text
};
// if no disabledConfig, render directly
if (!item.disabledConfig) {
return (
<Form.Item
name={item.name}
rules={item.rules}
key={item.name}
dependencies={item.dependencies}
{...item.formItemAttrs}
>
<FieldComponent
{...comProps}
disabled={item.disabled}
description={renderDescription(item.description)}
onChange={null}
{..._.omit(item, [
'name',
'rules',
'formItemAttrs',
'dependencies',
'disabledConfig',
'description'
])}
/>
</Form.Item>
);
}
// if has disabledConfig, wrap with another Form.Item to listen the dependencies change
return (
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => {
return (
item.disabledConfig?.depends.some(
(dep) => prevValues[dep] !== currentValues[dep]
) ?? false
);
}}
key={item.name}
>
{() => (
<Form.Item
name={item.name}
rules={item.rules}
dependencies={item.dependencies}
{...item.formItemAttrs}
>
<FieldComponent
{...comProps}
disabled={item.disabledConfig?.when(form.getFieldsValue())}
description={renderDescription(item.description)}
onChange={null}
{..._.omit(item, [
'name',
'rules',
'formItemAttrs',
'dependencies',
'disabledConfig',
'description'
])}
{...item.initAttrs?.(meta)}
/>
</Form.Item>
)}
</Form.Item>
);
});
};
export default ParamsFields;