Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update form handling and configuration structure #227

Open
wants to merge 1 commit into
base: 0.2.x-dev
Choose a base branch
from

Conversation

MrWindlike
Copy link
Collaborator

背景

之前 formConfig 中把 RefineForm 和 YAMLForm 的配置字段混杂在一起,不容易分清哪些字段分别是针对哪种表单类型生效的。

解决方案

表单配置调整

现在在 formConfig 需明确声明表单类型,然后根据表单类型的不同填写不同的配置。

export type DefaultFormConfig<Model extends ResourceModel = ResourceModel> = {
  formType: FormType.FORM;
  /**
 * 表单字段配置函数
 * @param props 包含记录和动作类型的配置对象
 * @returns 表单字段配置数组
 */
  fields?: (props: {
    record?: Model;
    records: Model[];
    action: 'create' | 'edit';
  }) => RefineFormField[];
  /** Refine Core 的表单属性 */
  refineCoreProps?: UseFormProps['refineCoreProps'];
  /** React Hook Form 的配置属性 */
  useFormProps?: UseFormProps;
  /** 是否禁用切换表单模式(在 YAML 和表单之间切换) */
  isDisabledChangeMode?: boolean;
  /** 表单标签的宽度
   * 默认是 216px
   */
  labelWidth?: string;
  /**
 * 自定义表单渲染函数
 * @returns React节点
 */
  renderForm?: () => React.ReactNode;
};

export type YamlFormConfig = {
  formType: FormType.YAML;
};

export type CommonFormConfig<Model extends ResourceModel = ResourceModel> = {
  /** 自定义表单模态框组件 */
  CustomFormModal?: React.FC<FormModalProps>;
  /**
   * 初始值转换函数
   * @param values 原始值
   * @returns 转换后的值
   */
  transformInitValues?: (values: Record<string, unknown>) => Record<string, unknown>;
  /**
   * 提交值转换函数,转换为 YAML 格式
   * @param values 表单值
   * @returns YAML格式的数据
   */
  transformApplyValues?: (values: Record<string, unknown>) => Model['_rawYaml'];
  /** 表单容器类型:页面形式或模态框形式
   * PAGE 或者 MODAL
  */
  formContainerType?: FormContainerType;
  /**
   * 表单标题,可以是字符串或根据操作类型返回不同标题的函数
   * @param action 操作类型:create 或 edit
   */
  formTitle?: string | ((action: 'create' | 'edit') => string);
  /**
   * 表单描述,可以是字符串或根据操作类型返回不同描述的函数
   * @param action 操作类型:create 或 edit
   */
  formDesc?: string | ((action: 'create' | 'edit') => string);
  /** 保存按钮文本 */
  saveButtonText?: string;
  /**
   * 错误信息格式化函数,待完善
   * @param errorBody 错误信息体
   * @returns 格式化后的错误信息
   */
  formatError?: (errorBody: unknown) => string;
};

FormModal 调整

现在将表单的渲染逻辑拆分到 RefineFormContainer 和 YamlFormContainer 内部,并将对应的 formConfig 通过参数传入,这样在 RefineFormContainer 和 YamlFormContainer 不用先判断表单类型再获取配置字段。

  const formEle = useMemo(() => {
    if (config.formConfig && (config.formConfig?.formType === FormType.FORM || 'fields' in config.formConfig)) {
      return <RefineFormContainer
        id={id as string}
        isYamlMode={isYamlMode}
        config={config}
        yamlFormProps={customYamlFormProps}
        formConfig={config.formConfig as DefaultFormConfig & CommonFormConfig}
        onSaveButtonPropsChange={setSaveButtonProps}
        onError={() => {
          setIsError(true);
        }}
        onSuccess={() => {
          setIsError(false);
          popModal();
        }}
      />;

    }

    return <YamlFormContainer
      id={id as string}
      customYamlFormProps={customYamlFormProps}
      config={config}
      formConfig={config.formConfig}
      onSuccess={() => {
        setIsError(false);
        popModal();
      }}
      onError={() => {
        setIsError(true);
      }}
    />;
  }, [id, customYamlFormProps, config, isYamlMode, popModal, setSaveButtonProps]);

config 改为通过参数传入

由于 FormModal 支持传入 resource 来定义当前是哪个资源的表单,用来在当前资源页面打开其他资源的表单,所以 FormModal 内部使用的 config 都改为通过参数传入,而不是通过 useContextuseResource 进行获取。

@MrWindlike MrWindlike changed the base branch from main to 0.2.x-dev March 19, 2025 07:31
* @param errorBody 错误信息体
* @returns 格式化后的错误信息
*/
formatError?: (errorBody: unknown) => string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

errorBody 有可能给出实际的类型定义吗?

export type WithId<T> = T & { id: string };

export type DefaultFormConfig<Model extends ResourceModel = ResourceModel> = {
Copy link
Member

@tanbowensg tanbowensg Mar 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

叫Default感觉和下面的Common不太好区分,他们关系是什么?

@@ -230,6 +153,40 @@ export function FormModal(props: FormModalProps) {
}
return '';
}, [action, config.formConfig]);
const formEle = useMemo(() => {
if (config.formConfig && (config.formConfig?.formType === FormType.FORM || 'fields' in config.formConfig)) {
return <RefineFormContainer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

两种表单的参数共同的部分可以提取出来,维护起来更清晰一点

- Refactored form configuration to use `FormContainerType` and `FormType` enums for better clarity.
- Introduced `RefineFormContainer` and `YamlFormContainer` components to streamline form rendering logic.
- Updated various components to utilize the new form configuration structure, ensuring consistent form behavior across the application.
- Enhanced type safety by integrating `CommonFormConfig` and `DefaultFormConfig` into resource configurations.
- Adjusted form handling in `useRefineForm` and `useFieldsConfig` to accommodate the new structure.
- Updated resource pages to pass the correct configuration to forms, ensuring proper initialization and rendering.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants