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

@@ -23,5 +23,5 @@ export enum FileItemStatus {
Wait = 'wait',
}
// 支持预览的图片类型
// Image types that support preview
export const PREVIEW_IMAGE_TYPE = ['jpg', 'jpeg', 'png', 'webp', 'svg'];

View File

@@ -119,7 +119,7 @@ export const getIconByExtension = (extension: string) => {
return fileIcon;
};
/** 获取文件名后缀 */
/** Get filename suffix */
export function getFileExtension(name?: string) {
if (!name) {
return '';

View File

@@ -155,13 +155,13 @@ export const FileUpload: React.FC<FileUploadProps> = props => {
const handleChange = useMemoizedFn(val => onChange?.(val));
// 当fileList更新时触发onChange
// When the fileList is updated, onChange is triggered.
useUpdateEffect(() => {
const newVal = getSubmitValue();
handleChange?.(newVal);
}, [fileList]);
// 当表单值更新时,同步到fileList
// When the form value is updated, sync to fileList
useEffect(() => {
const val = getSubmitValue();
if (val !== value) {

View File

@@ -17,13 +17,13 @@
import type { FileItemStatus } from '../file-icon';
export interface FileItem extends File {
// 唯一标识
// unique identifier
uid?: string;
// 文件地址
// File address
url?: string;
// 上传进度
// upload progress
percent?: number;
// 校验信息
// verification information
validateMessage?: string;
status?: FileItemStatus;
[key: string]: any;

View File

@@ -99,10 +99,10 @@ export const useUpload = (props?: UploadConfig) => {
throw new CustomError('normal_error', 'no uri');
}
// 上传完成,清空超时计时器
// Upload complete, clear timeout timer
clearTimeout(progressTimer);
// 加签uri获得url
// Add uri and get the url.
const { url } = await workflowApi.SignImageURL(
{
uri,

View File

@@ -30,9 +30,9 @@ interface UploadValidateRule {
}
/**
* 格式化文件大小
* @param bytes 文件大小
* @param decimals 小数位数, 默认 2 位
* Format file size
* @param bytes file size
* @Param decimals, default 2 digits
* @example
* formatBytes(1024); // 1KB
* formatBytes('1024'); // 1KB
@@ -50,7 +50,7 @@ export function formatBytes(bytes: number, decimals = 2) {
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))}${sizes[i]}`;
}
/** 文件大小校验 */
/** file size verification */
export const sizeValidate = (
size: number,
maxSize: number = MAX_FILE_SIZE,
@@ -71,7 +71,7 @@ export interface ImageSizeRule {
}
/**
* 获取图片的宽高
* Get the width and height of the image
*/
export async function getImageSize(
file: FileItem,
@@ -93,7 +93,7 @@ export async function getImageSize(
});
}
/** 图像宽高校验 */
/** image width check */
// eslint-disable-next-line complexity
export const imageSizeValidate = async (
file: FileItem,
@@ -101,7 +101,7 @@ export const imageSizeValidate = async (
): Promise<string | undefined> => {
const { maxWidth, minWidth, maxHeight, minHeight, aspectRatio } = rule || {};
// 未定义时不校验
// No validation when undefined
if (isNil(maxWidth || minWidth || maxHeight || minHeight || aspectRatio)) {
return;
}
@@ -145,7 +145,7 @@ export const acceptValidate = (fileName: string, accept?: string) => {
const fileExtension = getFileExtension(fileName);
const mimeType = mime.lookup(fileExtension);
// image/* 匹配所有的图片类型
// Image/* matches all image types
if (acceptList.includes('image/*') && mimeType?.startsWith?.('image/')) {
return undefined;
}

View File

@@ -15,7 +15,7 @@
*/
/**
* test run test form 布局的 FormItem
* Test run test form layout FormItem
*/
import React, { type FC, type ReactNode, type PropsWithChildren } from 'react';

View File

@@ -33,7 +33,7 @@ import css from './full-input.module.less';
export interface InnerFullInputProps {
value?: string;
disabled?: boolean;
/** 是否可以展开,默认 true */
/** Whether it can be expanded, the default is true. */
expand?: boolean;
className?: string;
onChange: (v?: string) => void;
@@ -66,7 +66,7 @@ const InnerFullInputAdapter: React.FC<FullInputProps> = ({
const content = editorRef.current.getContent();
const { markdown } = delta2md(content.deltas[0], content.deltas);
/**
* change 可能来自用户输入或者初始化,做一下 diff 来保证性能
* Changes may come from user input or initialization, do a diff to ensure performance
*/
if (markdown !== innerValueRef.current) {
innerValueRef.current = markdown;

View File

@@ -36,11 +36,11 @@ export interface InputNumberV2Props {
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);
@@ -73,18 +73,18 @@ export const InputNumberV2Adapter: React.FC<InputNumberV2Props> = ({
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 === '') {
// 如果是空字符串需要主动转换为 undefined
// If it is an empty string, it needs to be actively converted to undefined.
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;
@@ -116,7 +116,7 @@ export const InputNumberV2Adapter: React.FC<InputNumberV2Props> = ({
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

@@ -22,7 +22,7 @@ export { FormPanelLayout } from './form-panel';
export { TraceIconButton, BaseTestButton } from './test-button';
export { ResizablePanel } from './resizable-panel';
export { BasePanel } from './resizable-panel/base-panel';
// 禁止直接导出 form-engine 避免 formily 包被打到首屏
// Prohibit direct export of form-engine to avoid formily packages being hit to the first screen
// export { FormCore } from './form-engine';
export { NodeEventInfo } from './node-event-info';

View File

@@ -37,7 +37,7 @@ export default function useGetCurrentResult({
const isNodeLogNeedAsync = true;
const { batch, isBatch } = result || {};
// 反序列化获取所有遍历数组
// Deserialize to get all iterated arrays
const batchData: NodeResult[] = useMemo(() => {
if (!isBatch) {
return [];
@@ -49,13 +49,13 @@ export default function useGetCurrentResult({
}
return {
...i,
/** batch 数据里面不包含该标记,手动增加 */
/** The tag is not included in the batch data, and it is added manually. */
isBatch: true,
};
});
}, [isBatch, batch]);
// 当前执行日志(同步获取完整日志)
// Current execution log (get full log synchronously)
const current: NodeResult | undefined = useMemo(() => {
if (!isBatch) {
return result;

View File

@@ -15,6 +15,6 @@
*/
/**
* 解析运行结果的组件
* Components that parse run results
*/
export { LogDetail } from './log-detail';

View File

@@ -52,9 +52,9 @@ export const LogDetail: React.FC<LogDetailProps> = ({
onOpenWorkflowLink,
}) => {
const { isBatch, nodeId } = result;
/** 从 0 开始 */
/** Start from 0 */
const [paging, setPaging] = useState(0);
/** 只看错误 */
/** Just look at the error. */
const [onlyShowError, setOnlyShowError] = useState(false);
const { current, batchData } = useGetCurrentResult({
@@ -73,14 +73,14 @@ export const LogDetail: React.FC<LogDetailProps> = ({
const { modal, open } = useMarkdownModal();
// 当分页数据发生变化,重新选中第一项
// When the paging data changes, re-select the first item
useLayoutEffect(() => {
setPaging(0);
}, [batchData]);
return (
<div className={css['log-detail']}>
{/* 分页 */}
{/* paging */}
{isBatch ? (
<LogDetailPagination
paging={paging}

View File

@@ -17,7 +17,7 @@
import { type NodeResult } from '@coze-workflow/base';
/**
* log images 业务逻辑太重了,本期暂不抽
* Log images business logic is too heavy, this period will not draw
*/
export type LogImages = React.FC<{
testRunResult: NodeResult;

View File

@@ -15,7 +15,7 @@
*/
/**
* 批处理的分页器
* Batch pager
*/
import React, { useMemo } from 'react';

View File

@@ -37,17 +37,17 @@ import s from './more-selector.module.less';
interface MoreSelectorProps {
/**
* 运行结果数组
* Run result array
*/
data: (NodeResult | null)[];
/** 当前选择索引 */
/** current selection index */
paging: number;
fixedCount: number;
/** placeholder */
placeholder: string;
/** 选择索引变更事件 */
/** Select index change event */
onChange: (p: number) => void;
}

View File

@@ -39,14 +39,14 @@ export const PageSelector: React.FC<PageSelectorProps> = ({
data,
onChange,
}) => {
// 固定展示的条目,最大为 10 条,不到 10 条按实际展示
// Fixed display items, the maximum is 10, less than 10 items are displayed according to the actual display
const fixedItems = useMemo(
() => data.slice(0, fixedCount),
[fixedCount, data],
);
const moreItems = useMemo(() => data.slice(fixedCount), [data]);
// 是否需要通过下拉框展示更多
// Do you need to show more through the drop-down box?
const hasMore = useMemo(() => data.length > fixedCount, [data, fixedCount]);
return (

View File

@@ -28,19 +28,19 @@ import styles from './base-panel.module.less';
interface BasePanelProps {
className?: string;
/**
* 面板头,不传不渲染
* Panel header, no pass and no render
*/
header?: React.ReactNode;
/**
* 面板脚,不传不渲染
* Panel foot, do not pass and do not render
*/
footer?: React.ReactNode;
/**
* 默认初始高度,不支持响应式
* Default initial height, does not support responsive
*/
height?: number;
/**
* 是否可拖拽改变高度
* Can you drag and drop to change the height?
*/
resizable?:
| boolean
@@ -49,7 +49,7 @@ interface BasePanelProps {
max?: number;
};
/**
* 点击关闭事件,仅当渲染面板头时可能触发
* Click to close the event, which may only be triggered when rendering the panel header
*/
onClose?: () => void;
}

View File

@@ -56,7 +56,7 @@ export interface ResizablePanelRef {
const MIN_HEIGHT = 156;
/**
* TODO: 这里的核心伸缩能力后面想换成 semi Resizable,这里先临时写一些逻辑适配
* TODO: The core telescopic ability here wants to be replaced by semi Resizable later. Here are some temporary logical adaptations.
*/
export const ResizablePanel = forwardRef<
ResizablePanelRef,
@@ -95,7 +95,7 @@ export const ResizablePanel = forwardRef<
const handleMouseMove = useCallback(
e => {
if (isResizing.current) {
const newHeight = startHeight.current - (e.clientY - startY.current); // 计算新的高度
const newHeight = startHeight.current - (e.clientY - startY.current); // Calculate the new height
setHeight(newHeight > MIN_HEIGHT ? newHeight : MIN_HEIGHT);
}
},
@@ -103,17 +103,17 @@ export const ResizablePanel = forwardRef<
);
const handleMouseUp = useCallback(() => {
isResizing.current = false;
document.removeEventListener('mousemove', handleMouseMove); // 取消监听
document.removeEventListener('mouseup', handleMouseUp); // 取消监听
document.removeEventListener('mousemove', handleMouseMove); // Cancel listening
document.removeEventListener('mouseup', handleMouseUp); // Cancel listening
}, [handleMouseMove]);
const handleMouseDown = useCallback(
e => {
isResizing.current = true;
startY.current = e.clientY; // 记录鼠标开始拖拽时的 Y 轴坐标
startY.current = e.clientY; // Record the Y-axis coordinates when the mouse starts dragging
startHeight.current = innerRef.current?.offsetHeight || 0;
document.addEventListener('mousemove', handleMouseMove); // 监听鼠标移动事件
document.addEventListener('mouseup', handleMouseUp); // 监听鼠标抬起事件
document.addEventListener('mousemove', handleMouseMove); // Monitor mouse movement events
document.addEventListener('mouseup', handleMouseUp); // Monitor mouse lift events
},
[handleMouseMove, handleMouseUp],
);

View File

@@ -72,7 +72,7 @@
.resizable-panel-slide {
position: absolute;
bottom: 0;
right: -100%; /* 初始位置在容器的右外侧 */
right: -100%; /* The initial position is on the right outside of the container */
overflow: hidden;

View File

@@ -25,26 +25,26 @@ interface Config {
}
/**
* 目前仅支持高度可变
* Currently only highly variable is supported
*/
export const useResize = (config: Config) => {
const [dragging, setDragging] = useState(false);
const [height, setHeight] = useState(config.default);
const ref = useRef<HTMLDivElement>(null);
/**
* 拖拽过程中
* Dragging process
*/
const resizing = useRef(false);
/**
* y 轴变化
* Y-axis variation
*/
const startY = useRef(0);
/** 开始位置 */
/** starting position */
const start = useRef(0);
const handleMouseMove = useMemoizedFn(e => {
if (resizing.current) {
const newHeight = start.current - (e.clientY - startY.current); // 计算新的高度
const newHeight = start.current - (e.clientY - startY.current); // Calculate the new height
if (config.max && newHeight > config.max) {
setHeight(config.max);
} else if (config.min && newHeight < config.min) {
@@ -57,17 +57,17 @@ export const useResize = (config: Config) => {
const handleMouseUp = useCallback(() => {
resizing.current = false;
setDragging(false);
document.removeEventListener('mousemove', handleMouseMove); // 取消监听
document.removeEventListener('mouseup', handleMouseUp); // 取消监听
document.removeEventListener('mousemove', handleMouseMove); // Cancel listening
document.removeEventListener('mouseup', handleMouseUp); // Cancel listening
}, [handleMouseMove]);
const handleMouseDown = useMemoizedFn(e => {
resizing.current = true;
setDragging(true);
startY.current = e.clientY; // 记录鼠标开始拖拽时的 Y 轴坐标
startY.current = e.clientY; // Record the Y-axis coordinates when the mouse starts dragging
start.current = ref.current?.offsetHeight || 0;
document.addEventListener('mousemove', handleMouseMove); // 监听鼠标移动事件
document.addEventListener('mouseup', handleMouseUp); // 监听鼠标抬起事件
document.addEventListener('mousemove', handleMouseMove); // Monitor mouse movement events
document.addEventListener('mouseup', handleMouseUp); // Monitor mouse lift events
});
return {

View File

@@ -132,7 +132,7 @@ export const ChatFlowTestsetEditForm: React.FC<TestsetEditFormProps> = ({
ipt.value = val;
}
// 清除 object/array的空值,包括空字符串
// Clears null values of objects/arrays, including empty strings
if (
!val &&
(ipt.type === FormItemSchemaType.LIST ||
@@ -141,7 +141,7 @@ export const ChatFlowTestsetEditForm: React.FC<TestsetEditFormProps> = ({
ipt.value = undefined;
}
// bool 类型 需要将枚举转为布尔值
// Bool type, you need to convert the enumeration to a boolean
if (ipt.type === FormItemSchemaType.BOOLEAN) {
ipt.value = transTestsetBoolSelect2Bool(
ipt.value as TestsetFormValuesForBoolSelect,
@@ -184,7 +184,7 @@ export const ChatFlowTestsetEditForm: React.FC<TestsetEditFormProps> = ({
// });
// formRef.current?.setValues(formValues);
// // 设置值之后再校验一次
// //Check again after setting the value
// formRef.current?.validate(validateFields);
// },
// [formRef],

View File

@@ -48,10 +48,10 @@ import {
import styles from './edit-form-section.module.less';
/** 整数类型表单精度 */
/** integer type form precision */
const INTEGER_PRECISION = 0.1;
/** bot field name 固定值 */
/** Bot field name fixed value */
const BOT_FIELD_NAME = `${TESTSET_BOT_NAME}_${ComponentType.CozeVariableBot}`;
interface EditFormSectionTitleProps {
@@ -62,7 +62,7 @@ const EditFormSectionTitle: React.FC<EditFormSectionTitleProps> = ({
schema,
}) => {
const title = useMemo(() => {
// 目前只有start和variable两种节点
// Currently only two nodes are start and variable
switch (schema.component_type) {
case ComponentType.CozeStartNode:
return I18n.t('workflow_testset_start_node');
@@ -255,8 +255,8 @@ export const EditFormSection: React.FC<EditFormSectionProps> = ({
const botFieldValue = useFieldState(BOT_FIELD_NAME);
// 判断是否选择到了应用,只有选中应用才会回显对话组件。
// 应用内直接默认选中应用,可以回显对话组件。
// Determine whether the application is selected, and only the selected application will echo the dialog component.
// The application is directly selected by default in the application, and the dialog component can be echoed.
const isBotSelectProject =
(botFieldValue?.value?.id &&
botFieldValue?.value?.type === IntelligenceType.Project) ||
@@ -272,7 +272,7 @@ export const EditFormSection: React.FC<EditFormSectionProps> = ({
if (projectId && i.type === FormItemSchemaType.BOT) {
return false;
}
// 对话组件只会在应用内存在
// The dialog component will only exist within the app
if (!isBotSelectProject && i.type === FormItemSchemaType.CHAT) {
return false;
}

View File

@@ -149,7 +149,7 @@ export const TestsetEditForm: React.FC<TestsetEditFormProps> = ({ data }) => {
ipt.value = val;
}
// 清除 object/array的空值,包括空字符串
// Clears null values of objects/arrays, including empty strings
if (
!val &&
(ipt.type === FormItemSchemaType.LIST ||
@@ -158,7 +158,7 @@ export const TestsetEditForm: React.FC<TestsetEditFormProps> = ({ data }) => {
ipt.value = undefined;
}
// bool 类型 需要将枚举转为布尔值
// Bool type, you need to convert the enumeration to a boolean
if (ipt.type === FormItemSchemaType.BOOLEAN) {
ipt.value = transTestsetBoolSelect2Bool(
ipt.value as TestsetFormValuesForBoolSelect,
@@ -201,7 +201,7 @@ export const TestsetEditForm: React.FC<TestsetEditFormProps> = ({ data }) => {
});
formRef.current?.setValues(formValues);
// 设置值之后再校验一次
// Check again after setting the value
formRef.current?.validate(validateFields);
},
[formRef],

View File

@@ -31,7 +31,7 @@ function count(val: unknown) {
return val ? `${val}`.length : 0;
}
/** 需要后缀 & blur trim,扩展下原始的input */
/** The suffix & blur trim is required to expand the original input */
function InnerInput(props: InputProps) {
const onBlur = (evt: FocusEvent<HTMLInputElement>) => {
props.onChange?.(

View File

@@ -46,7 +46,7 @@ export const useEditFormSchemas = (testset?: CaseDataDetail | null) => {
[]) as NodeFormSchema[];
if (localSchemas.length) {
// 编辑模式比对本地和远程schema并尝试赋值
// Edit schema: compare local and remote schemas and try to assign values
const localSchemaMap: Record<string, FormItemSchema | undefined> = {};
traverseTestsetNodeFormSchemas(
localSchemas,
@@ -66,7 +66,7 @@ export const useEditFormSchemas = (testset?: CaseDataDetail | null) => {
}
});
} else {
// 创建模式:赋默认值
// Creation mode: assigns default values
traverseTestsetNodeFormSchemas(remoteSchemas, (schema, ipt) => {
assignTestsetFormDefaultValue(ipt);
});

View File

@@ -39,12 +39,12 @@ export interface TestsetManageState {
projectId?: string;
/**
* 校验缓存
* check cache
*/
validateCache: ValidateSchemaResult;
/**
* 编辑面板状态
* Edit Panel Status
*/
editPanelVisible: boolean;
editData: CaseDataDetail | null;
@@ -52,28 +52,28 @@ export interface TestsetManageState {
editPanelCloseState: boolean;
/**
* 自动填充状态
* autofill status
*/
generating: boolean;
/**
* 自定义渲染组件,暂时从外部传入,后续不要了
* Custom rendering component, temporarily passed in from the outside, no more in the future
*/
formRenders: Partial<Record<FormItemSchemaType, NodeFormItem>>;
}
export interface TestsetManageAction {
/** 更新状态 */
/** update status */
patch: (s: Partial<TestsetManageState>) => void;
/**
* 校验 schema
* Validation schema
*/
validateSchema: () => Promise<ValidateSchemaResult>;
/**
* 打开编辑面板
* Open the editing panel
*/
openEditPanel: (data?: CaseDataDetail) => void;
/**
* 关闭编辑面板
* Close the edit panel
*/
closeEditPanel: () => void;
@@ -164,7 +164,7 @@ export const TestsetManageProvider: React.FC<
formRenders,
children,
}) => {
// 只初始化一次
// Initialize only once
const storeRef = useRef<TestsetManageStore>(
createTestsetManageState({
bizCtx: {

View File

@@ -68,7 +68,7 @@ export interface TestsetSelectAPI {
const DEBOUNCE_DELAY = 200;
/** option key, 更新 nameincompatibleinput时都要重新渲染 */
/** Option key, re-render when updating name, incompatible, input */
function getOptionKey({ caseBase, schemaIncompatible }: CaseDataDetail) {
return `${caseBase?.caseID}_${caseBase?.name}_${caseBase?.input}_${
schemaIncompatible ? 0 : 1
@@ -139,7 +139,7 @@ export const TestsetSelect = forwardRef<TestsetSelectAPI, TestsetSelectProps>(
}
const selectedTestset = optionsCacheRef.current.get(val);
// 不兼容的不可选中
// Incompatible unselectable
if (!selectedTestset || selectedTestset.schemaIncompatible) {
return;
}

View File

@@ -37,9 +37,9 @@ export function useTestsetOptions() {
const [loadingMore, setLoadingMore] = useState(false);
const [optionsData, setOptionsData] = useState<OptionsData>({ list: [] });
// options 实时
// Options in real time
const optionsDataRef = useRef(optionsData);
// options 缓存
// Options cache
const optionsCacheRef = useRef(new Map<Int64, CaseDataDetail>());
const setOptionsDataWithCache = useCallback(