chore: replace all cn comments of fe to en version by volc api (#320)

This commit is contained in:
tecvan
2025-07-31 10:32:15 +08:00
committed by GitHub
parent 716ec0cba8
commit 71f6245a01
2960 changed files with 15545 additions and 15545 deletions

View File

@@ -22,7 +22,7 @@ import { render, screen } from '@testing-library/react';
import { FieldItem } from '../../../src/components/base-form-materials/field-item';
describe('FieldItem', () => {
// 测试基本渲染
// Test basic rendering
it('should render title', () => {
const title = 'Test Title';
render(<FieldItem title={title} />);
@@ -30,14 +30,14 @@ describe('FieldItem', () => {
expect(titleElement).toBeInTheDocument();
});
// 测试必填标记渲染
// Test required tag rendering
it('should render required marker', () => {
render(<FieldItem title="Test" required />);
const requiredMarker = screen.getByText('*');
expect(requiredMarker).toBeInTheDocument();
});
// 测试提示信息渲染
// Test prompt information rendering
it('should render tooltip', () => {
const tooltipText = 'This is a tooltip';
const el = render(<FieldItem title="Test" tooltip={tooltipText} />);
@@ -47,7 +47,7 @@ describe('FieldItem', () => {
expect(tooltipIcon).toBeInTheDocument();
});
// 测试标签渲染
// test label rendering
it('should render tag', () => {
const tagText = 'New';
render(<FieldItem title="Test" tag={tagText} />);
@@ -55,7 +55,7 @@ describe('FieldItem', () => {
expect(tagElement).toBeInTheDocument();
});
// 测试描述信息渲染
// Test description information rendering
it('should render description', () => {
const descriptionText = 'This is a description';
render(<FieldItem title="Test" description={descriptionText} />);
@@ -63,7 +63,7 @@ describe('FieldItem', () => {
expect(descriptionElement).toBeInTheDocument();
});
// 测试反馈信息渲染
// Test feedback rendering
it('should render feedback', () => {
const feedbackText = 'This is a feedback';
render(<FieldItem title="Test" feedback={feedbackText} />);
@@ -71,7 +71,7 @@ describe('FieldItem', () => {
expect(feedbackElement).toBeInTheDocument();
});
// 测试子元素渲染
// Test child element rendering
it('should render children', () => {
const childText = 'Child Content';
render(<FieldItem title="Test">{childText}</FieldItem>);

View File

@@ -23,7 +23,7 @@ import { render, screen, fireEvent } from '@testing-library/react';
import { GroupCollapse } from '../../../src/components/base-form-materials/group-collapse/collapse';
describe('GroupCollapse', () => {
// 测试基本渲染
// Test basic rendering
it('should render label and initial content', () => {
const label = 'Test Label';
const childContent = 'Child Content';
@@ -36,7 +36,7 @@ describe('GroupCollapse', () => {
expect(childElement).toBeInTheDocument();
});
// 测试提示信息渲染
// Test prompt information rendering
it('should render tooltip', () => {
const tooltipText = 'This is a tooltip';
const el = render(
@@ -51,7 +51,7 @@ describe('GroupCollapse', () => {
expect(tooltipIcon).toBeInTheDocument();
});
// 测试额外内容渲染
// Test Extra Content Rendering
it('should render extra content', () => {
const extraText = 'Extra Content';
render(
@@ -64,26 +64,26 @@ describe('GroupCollapse', () => {
expect(extraElement).toBeInTheDocument();
});
// 测试点击标题展开/折叠功能
// Test click title to expand/collapse function
it('should toggle content when clicking the title', () => {
const childContent = 'Child Content';
const { getByText, queryByText } = render(
<GroupCollapse label="Test">{childContent}</GroupCollapse>,
);
// 初始状态下内容应该可见
// The content should be visible in the initial state
expect(queryByText(childContent)).toBeInTheDocument();
// 点击标题
// Click on the title
act(() => {
fireEvent.click(getByText('Test'));
});
// 点击后内容应该隐藏
// Content should be hidden after clicking
expect(queryByText(childContent)).toBeNull();
});
// 测试粘性状态样式
// Test sticky state style
it('should apply sticky class when out of viewport or closed', async () => {
const { useInViewport } = await vi.importMock('ahooks');
(useInViewport as any).mockReturnValue([false]);

View File

@@ -19,19 +19,19 @@ import { describe, it, expect } from 'vitest';
import { isFormSchemaPropertyEmpty } from '../../src/utils/is-property-empty';
describe('isFormSchemaPropertyEmpty', () => {
// 测试空对象
// Test an empty object
it('should return true for an empty object', () => {
const emptyObject = {};
expect(isFormSchemaPropertyEmpty(emptyObject)).toBe(true);
});
// 测试非空对象
// Testing non-empty objects
it('should return false for a non-empty object', () => {
const nonEmptyObject = { key: 'value' };
expect(isFormSchemaPropertyEmpty(nonEmptyObject)).toBe(false);
});
// 测试非对象值
// Testing non-object values
it('should return true for non-object values', () => {
const values = [null, undefined, 123, 'string', true, false, []];
values.forEach(value => {

View File

@@ -19,13 +19,13 @@ import { describe, it, expect } from 'vitest';
import { stringifyFormValuesFromBacked } from '../../src/utils/stringify-form-values-from-backed';
describe('stringifyFormValuesFromBacked', () => {
// 测试输入为空的情况
// When the test input is empty
it('should return undefined when input is null or undefined', () => {
expect(stringifyFormValuesFromBacked(null as any)).toBeUndefined();
expect(stringifyFormValuesFromBacked(undefined as any)).toBeUndefined();
});
// 测试输入包含字符串和布尔值的情况
// Test if the input contains strings and boolean values
it('should return the same string and boolean values', () => {
const input = {
str: 'hello',
@@ -38,7 +38,7 @@ describe('stringifyFormValuesFromBacked', () => {
});
});
// 测试输入包含对象和数组的情况
// Test if the input contains objects and arrays
it('should stringify objects and arrays', () => {
const input = {
obj: { key: 'value' },
@@ -51,7 +51,7 @@ describe('stringifyFormValuesFromBacked', () => {
});
});
// 测试输入包含 null undefined 的情况
// Test if the input contains null and undefined
it('should set null and undefined values to undefined in the result', () => {
const input = {
nullValue: null,

View File

@@ -40,12 +40,12 @@ export const GroupCollapse: React.FC<
const [isOpen, setIsOpen] = useState(true);
const ref = useRef(null);
/**
* 探测标题是否处于 sticky 状态
* Detect if the title is sticky
*/
const [inViewport] = useInViewport(ref);
return (
<div>
{/* 探测元素 */}
{/* probe element */}
<div ref={ref} />
{/* header */}
<div

View File

@@ -15,7 +15,7 @@
*/
/**
* 基础表单物料
* basic form material
*/
export { InputNumber, InputNumberProps } from './input-number';
export { InputString, type InputStringProps } from './input-string';

View File

@@ -35,11 +35,11 @@ export interface InputNumberProps {
onChange: (v?: string) => void;
onBlur: () => void;
onFocus: () => void;
/** 整型 */
/** integer */
int?: boolean;
}
/** 是否是合法的数字字符串 */
/** Is it a legal numeric string? */
function isValidNumber(str: string) {
try {
const value = new BigNumber(str);
@@ -71,17 +71,17 @@ export const InputNumber: React.FC<InputNumberProps> = ({
const handleBlur = () => {
if (props.value === '' || props.value === undefined) {
/** 失焦时若值为空,则同时清空验证值 */
/** If the value is empty when out of focus, the verification value is also cleared */
verifiedRef.current = undefined;
if (props.value === '') {
onChange(undefined);
}
} else {
/** 失焦时若值不为空,则需要验证值的合法性 */
/** If the value is not empty when out of focus, you need to verify the legitimacy of the value */
/**
* 1. 若值本身合法,则对值做格式化
* 2. 若值不合法,则采纳最近一次的合法值
* 3. 若都没有,则返回 undefined
* 1. If the value itself is legal, format the value
* 2. If the value is not legal, the most recent legal value is adopted
* 3. If none, return undefined
*/
let next: undefined | string;
const nextBig = normalizeNumber(props.value) || verifiedRef.current;
@@ -113,7 +113,7 @@ export const InputNumber: React.FC<InputNumberProps> = ({
onChange(next);
};
/** 当值发生变化,需要把值同步到合法数字 */
/** When the value changes, you need to synchronize the value to a legal number */
useEffect(() => {
if (props.value === '' || props.value === undefined) {
verifiedRef.current = undefined;

View File

@@ -32,7 +32,7 @@ export const FieldItem: React.FC<React.PropsWithChildren<FieldItemProps>> = ({
const schema = useFieldSchema();
const isBatchField = schema.path.includes(TestFormFieldName.Batch);
/** 批处理变量 tag 增加额外描述 */
/** Batch variable tag adds extra description */
const currentTag =
tag && isBatchField
? `${tag} - ${I18n.t('workflow_detail_node_batch')}`

View File

@@ -15,7 +15,7 @@
*/
/**
* 表单物料
* form material
*/
export { InputString } from './input-string';
export { FieldItem } from './field-item';

View File

@@ -15,7 +15,7 @@
*/
/**
* 固定的内部 field name
* Fixed internal field name
*/
export enum TestFormFieldName {
Node = '_node',
@@ -23,7 +23,7 @@ export enum TestFormFieldName {
Input = '_input',
Setting = '_setting',
JSON = '_json',
/** 关联内容 */
/** Linked Content */
Related = '_related',
Bot = '_bot',
Conversation = '_conversation',

View File

@@ -26,7 +26,7 @@ import { type StoreApi } from 'zustand';
import { type IFormSchema } from '../form-engine';
/**
* 单一表单内的全局性质状态集中管理
* Global nature state centralized management within a single form
*/
export interface TestRunFormState {
schema: IFormSchema | null;

View File

@@ -31,7 +31,7 @@ interface ReactiveFieldProps {
}
/**
* 接入响应式的 Field
* Access Responsive Fields
*/
const ReactiveField: React.FC<ReactiveFieldProps> = ({ parentUIState }) => {
const components = useComponents();
@@ -41,7 +41,7 @@ const ReactiveField: React.FC<ReactiveFieldProps> = ({ parentUIState }) => {
const formUIState = useFormUIState();
const fieldState = useCurrentFieldState();
/**
* 自生的 disabled 态由父亲和自身一起控制
* The autologous disabled state is controlled by the father along with the self
*/
const disabled =
parentUIState?.disabled || uiState.disabled || formUIState.disabled;

View File

@@ -27,7 +27,7 @@ const computePath = (path?: string[], name?: string) =>
[...(path || []), name].filter((i): i is string => Boolean(i));
/**
* 递归 Field
* Recursive Field
*/
const RecursionField: React.FC<RecursionFieldProps> = ({ name, schema }) => {
const renderProperties = () => {

View File

@@ -15,7 +15,7 @@
*/
/**
* 表单引擎
* form engine
*/
export { createSchemaField } from './fields';
export { FormSchema } from './shared';

View File

@@ -26,7 +26,7 @@ interface PropertyWithKey {
}
export class FormSchema implements IFormSchema {
/** IFormSchema 透传属性 */
/** IFormSchema pass-through properties */
type?: string | undefined;
title?: ReactNode;
description?: ReactNode;
@@ -34,7 +34,7 @@ export class FormSchema implements IFormSchema {
properties?: Record<string, IFormSchema>;
defaultValue?: any;
/** 模型属性 */
/** Model Properties */
uiState = new ReactiveState<FormSchemaUIState>({ disabled: false });
path: string[] = [];
@@ -64,7 +64,7 @@ export class FormSchema implements IFormSchema {
}
/**
* 获得有序的 properties
* Obtain ordered properties
*/
static getProperties(schema: FormSchema | IFormSchema) {
const orderProperties: PropertyWithKey[] = [];

View File

@@ -33,65 +33,65 @@ export interface FormSchemaUIState {
export interface IFormSchema<FrameworkComponent = React.ReactNode> {
/*******************************************************
* 核心属性
* core attributes
*/
version?: string;
name?: string;
type?: FormSchemaTypes;
/** 默认值“default” 是 jsonSchema 标准字段,但其为 js 关键字,遂使用 defaultValue */
/** Default value, "default" is the jsonSchema standard field, but it is the js keyword, so defaultValue is used */
defaultValue?: any;
/*******************************************************
* 下钻属性
* drill down properties
*/
properties?: Record<string, IFormSchema<FrameworkComponent>>;
items?: IFormSchema<FrameworkComponent>[];
/*******************************************************
* ui 属性
* UI attribute
*/
title?: FrameworkComponent | string;
description?: FrameworkComponent | string;
/** 顺序 */
/** order */
['x-index']?: number;
['x-visible']?: boolean;
['x-hidden']?: boolean;
['x-disabled']?: boolean;
/** 渲染的组件 */
/** Rendered components */
['x-component']?: string;
['x-component-props']?: Record<string, unknown>;
/** 装饰器 */
/** decorator */
['x-decorator']?: string;
['x-decorator-props']?: Record<string, unknown>;
/*******************************************************
* 合法性属性
* Legitimacy Attribute
*/
required?: boolean;
['x-validator']?: IFormSchemaValidate;
/*******************************************************
* 不常用或实现成本较高
* Less commonly used or more expensive to implement
*/
['x-reactions']?: any;
['x-content']?: FrameworkComponent;
/** 通配符字段 */
/** wild-card field */
patternProperties?: Record<string, IFormSchema<FrameworkComponent>>;
/** 定义之外的字段 */
/** Fields outside the definition */
additionalProperties?: IFormSchema<FrameworkComponent>;
/** 定义之外的项 */
/** Items outside the definition */
additionalItems?: IFormSchema<FrameworkComponent>;
/*******************************************************
* 业务自定义字段
* business custom field
*/
/** 节点 id */
/** Node ID */
['x-node-id']?: string;
/** 节点类型 */
/** Node type */
['x-node-type']?: string;
/** 表单模式 */
/** form mode */
['x-form-mode']?: 'form' | 'json';
/** 字段对应变量原始类型 */
/** Field corresponding variable primitive type */
['x-origin-type']?: string;
[key: string]: any;
}

View File

@@ -25,13 +25,13 @@ export const generateFieldComponent = (
options: GenerateFieldComponentOptions,
) => {
const { type, validateJsonSchema } = options;
/** 音色类型 */
/** timbre type */
if (ViewVariableType.Voice === type) {
return {
['x-component']: 'SelectVoice',
};
}
/** 文件类型 */
/** file type */
if (ViewVariableType.isFileType(type)) {
const fileType = [
ViewVariableType.Image,
@@ -42,14 +42,14 @@ export const generateFieldComponent = (
return {
['x-component']: 'TypedFileInput',
['x-component-props']: {
// 如果是数组类型,则表明是多选的文件选择器
// If it is an array type, it indicates that it is a multi-selected file selector
multiple: ViewVariableType.isArrayType(type),
accept: getFileAccept(type),
fileType,
},
};
}
/** 排除文件类型的对象类型、数组类型 */
/** Exclude object types and array types for file types */
if (ViewVariableType.isArrayType(type) || ViewVariableType.Object === type) {
return {
['x-component']: 'InputJson',
@@ -80,7 +80,7 @@ export const generateFieldComponent = (
['x-component']: 'InputTime',
};
}
/** string 类型和其它未知类型都渲染普通输入框 */
/** String type and other unknown types all render normal text boxes */
return {
['x-component']: 'InputString',
};

View File

@@ -29,8 +29,8 @@ interface GenerateFieldValidatorOptions {
}
/**
* ajv 实例缓存
* 无需导入创建或者多次创建,优化内存开销
* AJV instance cache
* No need to import or create multiple times, optimizing memory overhead
*/
let ajvCache: undefined | Ajv;
@@ -45,7 +45,7 @@ export const generateFieldValidator = (
param_name: title || name,
});
}
// 如果有结构化描述,还需要对值进行反序列化校验
// If there is a structured description, the value also needs to be deserialized
if (validateJsonSchema && value !== undefined) {
if (!ajvCache) {
ajvCache = new Ajv();
@@ -57,9 +57,9 @@ export const generateFieldValidator = (
return valid ? undefined : I18n.t('workflow_debug_wrong_json');
} catch {
/**
* 报错有多种可能,预期结果都是校验不通过
* 1. 值反序列化失败
* 2. 反序列化的值不合法
* There are many possibilities for error reporting, and the expected result is that the verification fails.
* 1. Value deserialization failed
* 2. The deserialized value is not legal
*/
return I18n.t('workflow_debug_wrong_json');
}

View File

@@ -32,7 +32,7 @@ interface GenerateFieldOptions {
}
/**
* 表单 Field Schema 计算
* Form Field Schema Calculation
*/
export const generateField = (options: GenerateFieldOptions): IFormSchema => {
const {
@@ -57,9 +57,9 @@ export const generateField = (options: GenerateFieldOptions): IFormSchema => {
},
['x-origin-type']: type as unknown as string,
...generateFieldValidator(options),
// 渲染组件相关
// rendering component related
...generateFieldComponent({ type, validateJsonSchema }),
// component 也自带默认值,入参的默认值优先级更高
// Component also comes with default values, and the default values of imported parameters have higher priority
defaultValue,
...extra,
};

View File

@@ -17,7 +17,7 @@
import { isObject } from 'lodash-es';
/**
* 是否是空的 properties
* Is it an empty property?
*/
export const isFormSchemaPropertyEmpty = (properties: unknown) =>
isObject(properties) ? !Object.keys(properties).length : true;