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

@@ -69,7 +69,7 @@ export const createBatchFunctionJSON = (
const transform = node.getData<FlowNodeTransformData>(
FlowNodeTransformData,
);
// 鼠标开始时所在位置不包括当前节点时才可选中
// The mouse can only be selected when the starting position does not include the current node
return !transform.bounds.contains(mousePos.x, mousePos.y);
},
renderSubCanvas: () => ({

View File

@@ -17,13 +17,13 @@
import type { WorkflowDocument } from '@flowgram-adapter/free-layout-editor';
import { delay } from '@flowgram-adapter/common';
/** 生成连线 */
/** connect generation */
export const createBatchFunctionLines = async (params: {
document: WorkflowDocument;
batchId: string;
batchFunctionId: string;
}) => {
await delay(30); // 等待节点创建完毕
await delay(30); // Wait for the node to be created
const { document, batchId, batchFunctionId } = params;
document.linesManager.createLine({
from: batchId,

View File

@@ -19,7 +19,7 @@ import { type NodeData, WorkflowNodeData } from '@coze-workflow/nodes';
import type { BasicStandardNodeTypes } from '@coze-workflow/base';
import { I18n } from '@coze-arch/i18n';
/** 同步节点模版数据 */
/** Synchronize node template data */
export const createBatchFunctionTemplateData = (
batchNode: WorkflowNodeEntity,
batchFunctionNode: WorkflowNodeEntity,

View File

@@ -26,7 +26,7 @@ import { createBatchFunctionTemplateData } from './create-batch-function-templat
import { createBatchFunctionLines } from './create-batch-function-lines';
import { createBatchFunctionJSON } from './create-batch-function-json';
/** 创建 Batch 循环体节点 */
/** Create Batch loop body node */
export const createBatchFunction = async (
batchNode: WorkflowNodeEntity,
batchJson: WorkflowNodeJSON,

View File

@@ -20,7 +20,7 @@ import { variableUtils } from '@coze-workflow/variable';
import { type NodeDataDTO } from '@coze-workflow/base';
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (formData: any, ctx: any) => {
const inputParameters = formData?.inputs?.inputParameters;
@@ -71,7 +71,7 @@ export const transformOnInit = (formData: any, ctx: any) => {
};
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/
@@ -88,7 +88,7 @@ export const transformOnSubmit = (formData: any, ctx: any): NodeDataDTO => {
{ node: ctx.node },
);
// 定制逻辑:如果选择了循环体内的变量,则输出变量的类型套一层 list
// Custom logic: If a variable inside the loop is selected, a list of the type of the output variable is set
if (
outputValue?.input?.content?.keyPath?.[0] !== ctx.node.id &&
dto?.input

View File

@@ -37,13 +37,13 @@ import { transformOnInit, transformOnSubmit } from './data-transformer';
import { BatchPath } from './constants';
export const BATCH_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <BatchFormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
[`${BatchPath.Inputs}.*.name`]: BatchInputNameValidator,
@@ -52,16 +52,16 @@ export const BATCH_FORM_META: FormMetaV2<FormData> = {
[`${BatchPath.Outputs}.*.input`]: BatchInputValueValidator,
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
inputs: provideLoopInputsVariablesEffect,
outputs: provideLoopOutputsVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -45,7 +45,7 @@ export const BATCH_NODE_REGISTRY: WorkflowNodeRegistry<NodeTestMeta> = {
size: BatchSize,
nodeMetaPath: DEFAULT_NODE_META_PATH,
outputsPath: DEFAULT_OUTPUTS_PATH,
inputParametersPath: BatchPath.Inputs, // 入参路径,试运行等功能依赖该路径提取参数
inputParametersPath: BatchPath.Inputs, // Imported parameter path, practice running and other functions rely on this path to extract parameters
useDynamicPort: true,
defaultPorts: [
{ type: 'input' },
@@ -73,7 +73,7 @@ export const BATCH_NODE_REGISTRY: WorkflowNodeRegistry<NodeTestMeta> = {
outputsPathList: [],
inputsPathList: [
BatchPath.Inputs,
// 'outputs', // WARNING: 加上 outputs 会导致这一数据清空
// 'Outputs',//WARNING: Adding outputs will cause this data to be cleared
],
},
formMeta: BATCH_FORM_META,

View File

@@ -19,12 +19,12 @@ import { type NodeDataDTO } from '@coze-workflow/base';
import { type FormData } from './types';
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (value: NodeDataDTO) => value;
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/

View File

@@ -27,25 +27,25 @@ import { FormRender } from './form';
import { transformOnInit, transformOnSubmit } from './data-transformer';
export const BREAK_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -33,5 +33,5 @@ export const BREAK_NODE_REGISTRY: WorkflowNodeRegistry = {
nodeMetaPath: DEFAULT_NODE_META_PATH,
},
formMeta: BREAK_FORM_META,
getOutputPoints: () => [], // Break 节点没有输出
getOutputPoints: () => [], // Broken node has no output
};

View File

@@ -17,12 +17,12 @@
import { nanoid } from 'nanoid';
import { ViewVariableType } from '@coze-workflow/variable';
// 路径
// path
export const INPUT_PATH = 'inputParameters';
export const CODE_PATH = 'codeParams';
export const OUTPUT_PATH = 'outputs';
// 默认值
// default value
export const DEFAULT_OUTPUTS = [
{
key: nanoid(),

View File

@@ -23,7 +23,7 @@ import { type FormData } from './types';
import { DEFAULT_INPUTS, DEFAULT_OUTPUTS } from './constants';
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (
value: NodeDataDTO | undefined,
@@ -32,7 +32,7 @@ export const transformOnInit = (
const { globalState } = context.playgroundContext;
const { isBindDouyin } = globalState;
const defaultCodeParams = getDefaultValue({ isBindDouyin });
// 初始值设置
// initial value setting
const initValue = value || {
inputs: {
inputParameters: DEFAULT_INPUTS,
@@ -54,7 +54,7 @@ export const transformOnInit = (
};
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/

View File

@@ -34,13 +34,13 @@ import { transformOnInit, transformOnSubmit } from './data-transformer';
import { CODE_PATH, OUTPUT_PATH } from './constants';
export const CODE_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
...createCodeInputsValidator(),
@@ -48,15 +48,15 @@ export const CODE_FORM_META: FormMetaV2<FormData> = {
[OUTPUT_PATH]: outputTreeMetaValidator,
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
outputs: provideNodeOutputVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -41,7 +41,7 @@ export const CODE_NODE_REGISTRY: WorkflowNodeRegistry<NodeTestMeta> = {
test,
nodeMetaPath: DEFAULT_NODE_META_PATH,
outputsPath: DEFAULT_OUTPUTS_PATH,
inputParametersPath: INPUT_PATH, // 入参路径,试运行等功能依赖该路径提取参数
inputParametersPath: INPUT_PATH, // Imported parameter path, practice running and other functions rely on this path to extract parameters
enableCopilotGenerateTestNodeForm: true,
helpLink: '/open/docs/guides/code_node',
},

View File

@@ -15,13 +15,13 @@
*/
/* eslint-disable @typescript-eslint/naming-convention -- todo */
/** 备注默认尺寸 */
/** Remarks Default size */
export const CommentDefaultSize = {
width: 240,
height: 150,
};
/** 备注默认值 */
/** Remarks Default value */
export const CommentDefaultNote = JSON.stringify([
{
type: 'paragraph',

View File

@@ -49,7 +49,7 @@ export const COMMENT_NODE_REGISTRY: WorkflowNodeRegistry = {
const { inputs, ...rest } = value;
return {
...rest,
schemaType: inputs?.schemaType ?? CommentDefaultSchemaType, // 默认使用 slate 格式,后续考虑支持其他格式
schemaType: inputs?.schemaType ?? CommentDefaultSchemaType, // The default is to use the slate format, and other formats will be considered later.
note: inputs?.note ?? CommentDefaultNote,
size: value.size ?? CommentDefaultSize,
};
@@ -59,13 +59,13 @@ export const COMMENT_NODE_REGISTRY: WorkflowNodeRegistry = {
return {
...rest,
inputs: {
schemaType: schemaType ?? CommentDefaultSchemaType, // 默认使用 slate 格式,后续考虑支持其他格式
schemaType: schemaType ?? CommentDefaultSchemaType, // The default is to use the slate format, and other formats will be considered later.
note: note ?? CommentDefaultNote,
},
size: value.size ?? CommentDefaultSize,
};
},
},
getInputPoints: () => [], // Comment 节点没有输入
getOutputPoints: () => [], // Comment 节点没有输出
getInputPoints: () => [], // Comment node no input
getOutputPoints: () => [], // Comment node has no output
};

View File

@@ -119,8 +119,8 @@ const createCron = (schedule: TaskSchedule) => {
return cronGenerator.every(day).days().atHour(hour).atMinute(0).toString();
};
export const parseCron: (cron: string) => TaskSchedule = cronExpr => {
// 目前需求只有 5 位 分、时、day of month、月、day of week
// bytescheduler 只支持 6 位 秒、分、时、day of month、月、day of week
// The current demand is only 5, minutes, hours, day of month, month, day of week
// Bytescheduler only supports 6 bits, seconds, minutes, hours, day of month, month, day of week
const cronUnits = cronExpr?.split?.(' ').slice?.(1);
const hour = cronUnits?.at(1);
const dayOfMonthIndex = 2;
@@ -128,7 +128,7 @@ export const parseCron: (cron: string) => TaskSchedule = cronExpr => {
const dayOfWeek = cronExpr?.at(-1);
const numberHour = Number(hour);
// 通配符
// wild-card
const wildcard = '*';
if (dayOfWeek !== wildcard) {
return ['weekly', Number(dayOfWeek), numberHour];
@@ -142,7 +142,7 @@ export const parseCron: (cron: string) => TaskSchedule = cronExpr => {
return ['daily', numberHour];
};
// 将key转化为对应文案
// Convert key to corresponding copy
// export const getOptionNodeText = (val: TaskSchedule): string[] => {
// let resultData = treeData();
// const nodeList = val?.map(item => {
@@ -205,7 +205,7 @@ interface FixCronjobSelectProps {
hasError?: boolean;
}
/** 选择时间和时区组件 */
/** Select time and time zone components */
export const FixCronjobSelect: React.FC<FixCronjobSelectProps> = ({
value: _value,
onChange: _onChange,
@@ -237,7 +237,7 @@ export const FixCronjobSelect: React.FC<FixCronjobSelectProps> = ({
value={value ? parseCron(value) : void 0}
onChange={v => {
if (Array.isArray(v) && v.length) {
// 生成的 cron 表达式是 5 位 但需要 6 位
// The resulting cron expression is 5 bits, but 6 bits are required
const cronExpr = `0 ${createCron(v as TaskSchedule)}`;
onChange?.(cronExpr);
return;

View File

@@ -25,7 +25,7 @@ export interface DynamicFormProps {
name: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
components: Record<string, FC<DynamicComponentProps<any>>>;
// 禁用做触发
// Disable trigger
onChange?: () => void;
}

View File

@@ -29,8 +29,8 @@ export interface FormItemMeta {
export type FormMeta = FormItemMeta[];
export interface DynamicComponentProps<T> {
value?: T; // 字段值
readonly?: boolean; // 是否只读
disabled?: boolean; // 是否禁用
value?: T; // field value
readonly?: boolean; // Is it read-only?
disabled?: boolean; // Whether to disable
onChange: (newValue?: T) => void;
}

View File

@@ -32,7 +32,7 @@ export const ExpressionEditorField = withField<
maxLength,
disableSuggestion,
disableCounter,
// 旧版逻辑是用name作为testID后缀 新版节点name路径可能会变(如xxx -> inputs.xxx) 需要从外部指定
// The old logic used name as the testID suffix, the new version of the node name path may change (such as xxx - > inputs.xxx) need to be specified externally
testIDSuffix = name,
} = props;

View File

@@ -26,7 +26,7 @@ type ImageModelSelectProps = Omit<
>;
/**
* 图像模型选择器
* Image model selector
*/
export const ImageModelSelectField = withField<ImageModelSelectProps>(props => {
const { value, readonly, onChange, errors } = useField<number>();

View File

@@ -14,5 +14,5 @@
* limitations under the License.
*/
// TODO 源码待迁移。 开发 cli ,依赖引用路径
// TODO source code to be migrated. Develop cli, rely on the reference path
export { InputParameters } from '@/components/node-render/node-render-new/fields/input-parameters';

View File

@@ -33,9 +33,9 @@ type NodeConfigFormProps = PropsWithChildren<{
}>;
/**
* NodeConfigForm组件
* 用于展示节点配置表单
* @param children - 子组件,用于渲染表单内容
* NodeConfigForm component
* Used to display node configuration forms
* @Param children - child component for rendering form content
*/
export function NodeConfigForm({
children,

View File

@@ -14,5 +14,5 @@
* limitations under the License.
*/
// TODO 源码待迁移。 开发 cli ,依赖引用路径
// TODO source code to be migrated. Develop cli, rely on the reference path
export { Outputs } from '@/components/node-render/node-render-new/fields/outputs';

View File

@@ -15,12 +15,12 @@
*/
/**
* 默认时区,目前用于 task 模块
* Default time zone, currently used by the task module
*
* 国内UTC+8
* 海外UTC+0
* Domestic: UTC + 8
* Overseas: UTC + 0
*/
export const DEFAULT_TIME_ZONE = IS_OVERSEA ? 'Etc/GMT+0' : 'Asia/Shanghai';
export const DEFAULT_TIME_ZONE_OFFSET = IS_OVERSEA ? 'UTC+00:00' : 'UTC+08:00';
// 未知时区,用于兼容
// Unknown time zone for compatibility
export const UNKNOWN_TIME_ZONE_OFFSET = 'Others';

View File

@@ -37,8 +37,8 @@ import styles from './index.module.less';
type TimezoneProps = DynamicComponentProps<string> & {
className?: string;
showClear?: boolean; // 是否可清空
defaultValue?: string; // 默认值
showClear?: boolean; // Can it be emptied?
defaultValue?: string; // default value
};
export const Timezone: FC<TimezoneProps> = ({
@@ -53,15 +53,15 @@ export const Timezone: FC<TimezoneProps> = ({
_value ??
defaultValue) as string;
// 时区列表
// time zone list
const { timezoneOptions: TIME_ZONE_OPTIONS, timezoneMap: TIME_ZOME_MAP } =
useMemo(() => generatedTimezones(), []);
// 时区选择器选项生成逻辑
// Time zone selector option generation logic
const [timezoneOptions, timezoneMap] = useMemo(() => {
const timezoneOptionsBase = cloneDeep(TIME_ZONE_OPTIONS);
const timezoneMapBase = cloneDeep(TIME_ZOME_MAP);
// 用户已选择时区,但当前环境不支持兼容对应时区时,在选项末尾插入未知时区选项兼容
// When the user has selected a time zone, but the current environment does not support compatibility with the corresponding time zone, insert the unknown time zone option Compatible at the end of the option
if (value && timezoneMapBase.every(e => e.value !== value)) {
timezoneOptionsBase.push({
value: UNKNOWN_TIME_ZONE_OFFSET,
@@ -85,7 +85,7 @@ export const Timezone: FC<TimezoneProps> = ({
}
}, [value, timezoneMap]);
// 遍历查询时区偏移量
// Traverse query time zone offset
const findTimezoneValue = (nodes: string[], key: string) => {
if (Array.isArray(nodes) && nodes.length > 1) {
const [offsetValue, timezoneLabel] = nodes;
@@ -133,10 +133,10 @@ export const Timezone: FC<TimezoneProps> = ({
return 0;
};
// 自定义高亮逻辑
// custom highlighting logic
const filterRender = (filterRenderProps: FilterRenderProps) => {
const { className: cls, inputValue, data, onClick } = filterRenderProps;
// 把多级选项的文案拼起来
// Put together the copy of the multi-level options
const labelString = data.map(e => e.label).join(' / ');
return (
<li

View File

@@ -28,7 +28,7 @@ import { type CascaderData } from '@coze-arch/bot-semi/Cascader';
import { DEFAULT_TIME_ZONE, DEFAULT_TIME_ZONE_OFFSET } from '../const';
// dependent on utc plugin
dayjs.extend(isoWeek); // 注意:这里插件的注册顺序不能随意改变,此外重复注册插件可能会有 bug。
dayjs.extend(isoWeek); // Attention: The registration order of plugins here cannot be changed at will, and repeated registration of plugins may have bugs.
dayjs.extend(quartersOfYear);
dayjs.extend(dayjsUTC);
dayjs.extend(dayjsTimezone);
@@ -42,16 +42,16 @@ export interface ITimezoneItem {
utcOffset?: number;
}
// 获取时区列表
// Get a list of time zones
export const generatedTimezones = () => {
let timezoneOptions: CascaderData[] = [];
let timezoneMap: ITimezoneItem[] = [];
try {
// 当前国际化环境
// The current international environment
const locale = I18n.language ?? 'en-US';
/**
* 所有时区列表
* (Intl as any) 项目的typescript版本不含有supportedValuesOf方法编译会报错
* List of all time zones
* (Intl as any) The typescript version of the project does not contain the supportedValuesOf method, and an error will be reported when compiled
*/
const options = (Intl as any)
.supportedValuesOf('timeZone')
@@ -99,7 +99,7 @@ export const generatedTimezones = () => {
timezoneMap = [
{ value: DEFAULT_TIME_ZONE, offset: DEFAULT_TIME_ZONE_OFFSET },
];
// 如果出现无法获取时区信息的情况上报异常到 slardar
// If the time zone information cannot be obtained, report the exception to slardar.
logger.persist.error({
message: 'Custom Error: Unable to obtain accurate time zone list',
error,

View File

@@ -62,7 +62,7 @@ export const NodeInputName = ({
const variableService = useService(WorkflowVariableFacadeService);
const { getNodeSetterId } = useNodeTestId();
// text 状态受控(删除节点时联动 text 的值)
// The text state is controlled (the value of the linked text when deleting a node)
useEffect(() => {
if (value !== text) {
setText(value);
@@ -91,7 +91,7 @@ export const NodeInputName = ({
useEffect(() => {
if (initValidate) {
// 初始化写值触发校验
// Initialize write value to trigger verification
onChange(value as string);
}
if (value) {

View File

@@ -32,15 +32,15 @@ export interface NodeInputNameProps {
initValidate?: boolean;
isPureText?: boolean;
style?: CSSProperties;
/** 同一层的变量表达式 */
/** Variable expressions at the same level */
input: ValueExpression;
/** 当前输入列表中所有输入项 */
/** All input items in the current input list */
inputParameters: Array<InputValueVO>;
/** 前缀 */
/** prefix */
prefix?: string;
/** 后缀 */
/** suffix */
suffix?: string;
/** 名称自定义格式化 */
/** Name custom formatting */
format?: NodeInputNameFormat;
tooltip?: string;
isError?: boolean;

View File

@@ -20,11 +20,11 @@ import { get } from 'lodash-es';
import { I18n } from '@coze-arch/i18n';
import { type Validate } from '@flowgram-adapter/free-layout-editor';
/** 变量命名校验规则 */
/** Variable Naming Validation Rules */
const outputTreeValidationRule =
/^(?!.*\b(true|false|and|AND|or|OR|not|NOT|null|nil|If|Switch)\b)[a-zA-Z_][a-zA-Z_$0-9]*$/;
/** 校验逻辑 */
/** check logic */
// eslint-disable-next-line @typescript-eslint/naming-convention
const OutputTreeMetaSchema = z.lazy(() =>
z
@@ -44,26 +44,26 @@ const OutputTreeMetaSchema = z.lazy(() =>
);
const omitErrorBody = (value, isBatch) => {
// 批量,去除 children 中的 errorBody
// Batch, remove errorBody from children
if (isBatch) {
return value?.map(v => ({
...v,
children: v?.children?.filter(c => c?.name !== 'errorBody'),
}));
}
// 单次,去除 value 中的 errorBody
// Single, remove errorBody from value
return value?.filter(v => v?.name !== 'errorBody');
};
export const outputTreeMetaValidator: Validate = ({ value, formValues }) => {
/**
* 判断错误异常处理是否打开,如果打开需要过滤掉 errorBody 后做校验
* Determine whether the error exception handling is turned on. If it is turned on, you need to filter out the errorBody and check it.
*/
const { settingOnErrorIsOpen = false } = (get(formValues, 'settingOnError') ??
{}) as { settingOnErrorIsOpen?: boolean };
/**
* 根据 batch 数据判断,当前是否处于批处理状态
* According to the batch data, whether it is currently in the batch state
*/
const batchValue = get(formValues, 'batchMode');
const isBatch = batchValue === 'batch';

View File

@@ -43,15 +43,15 @@ export interface OutputsProps {
batchMode?: string;
needAppendChildWhenNodeIsPreset?: boolean;
/**
* 是否可以配置默认值
* Can the default value be configured?
*/
withDefaultValue?: boolean;
/**
* 默认展开的参数名
* Default expanded parameter name
*/
defaultExpandParams?: string[];
/**
* 列宽比 如 6:4 代表名称占6份类型占4份
* Column widths such as 6:4 represent 6 copies of the name and 4 copies of the type
*/
columnsRatio?: string;
maxLimit?: number;
@@ -85,7 +85,7 @@ export const OutputsField = withField<OutputsProps>(
value={value}
onChange={v => {
onChange?.(v);
// 保证 blur 时触发校验, 直接传 onBlur 不生效
// Guarantee that the verification is triggered when blur, and directly passing onBlur does not take effect
onBlur?.();
}}
title={title}

View File

@@ -38,9 +38,9 @@ import styles from './index.module.less';
interface ParamTypeProps {
level: number;
disabled?: boolean;
/** 不支持使用的类型 */
/** Types not supported */
disabledTypes?: ViewVariableType[];
/** 隐藏类型 */
/** hidden type */
hiddenTypes?: ViewVariableType[];
}

View File

@@ -47,7 +47,7 @@ interface ParametersInputGroupFieldProps
hiddenTypes?: boolean;
hiddenTypeTag?: boolean;
/**
* 输入框默认类型,但不限制可选变量类型
* Text box default type, but does not restrict optional variable types
*/
inputType?: ViewVariableType;
disabledTypes?: ViewVariableType[];

View File

@@ -18,11 +18,11 @@
import { NodeConfigForm } from '../components';
/**
* 高阶组件,用于为组件添加节点配置表单的包装
* 这个 HOC 为工作流节点提供配置表单的包装器
* Higher order component to add wrapper for node configuration form to component
* This HOC provides a wrapper for the configuration form for the workflow node
*
* @param Component - 需要被配置表单包装的组件
* @returns 返回一个被 NodeConfigForm 包装后的新组件
* @Param Component - Component that needs to be wrapped by the configuration form
* Returns a new component wrapped in NodeConfigForm
*/
export function withNodeConfigForm<
ComponentProps extends React.JSX.IntrinsicAttributes = {},

View File

@@ -24,14 +24,14 @@ import {
} from '@coze-workflow/base';
/**
* 获取自定义 setter 的值
* Get the value of a custom setter
* @param value
* @param field
* @returns
*/
export const getCustomVal = (
value: ValueExpression,
// 通过 number 提取单个输入项的类型
// Extracting the type of a single input item by number
field: ApiNodeDetailDTO['inputs'][number],
) => {
if (!field?.type) {
@@ -58,7 +58,7 @@ export const getCustomVal = (
};
/**
* 根据plugin扩展协议 获取自定义setter的属性
* Get the properties of the custom setter according to the plugin extension protocol
*/
export const getCustomSetterProps = (
input: ApiNodeDetailDTO['inputs'][number],
@@ -77,7 +77,7 @@ export const getCustomSetterProps = (
const isEnum = !!inputEnum;
const isSlider = !isNil(minimum) && !isNil(maximum);
// 例如这个插件cutout智能抠图store/plugin/7438917083918024738
// For example, this plugin: cutout: store/plugin/7438917083918024738
if (isEnum) {
return {
key: 'Select',
@@ -89,7 +89,7 @@ export const getCustomSetterProps = (
};
}
// 例如这个插件:change(调整):store/plugin/7438921446090637312
// For example, this plugin: change: store/plugin/7438921446090637312
if (isSlider) {
let step = 1;
try {

View File

@@ -44,7 +44,7 @@ const updateNodePorts = (node: WorkflowNodeRegistry) => {
const meta = node.meta || {};
// 需要改造成动态通道
// It needs to be transformed into a dynamic channel.
if (!meta.useDynamicPort) {
set(node, 'meta', {
...meta,
@@ -66,7 +66,7 @@ const updateNodeFormat = (node: WorkflowNodeRegistry) => {
set(node, 'formMeta.formatOnInit', (value, context: NodeContext) => {
const formated = formatOnInit ? formatOnInit(value, context) : value;
// 空值直接返回
// Null value returned directly
if (!formated) {
return formated;
}

View File

@@ -18,7 +18,7 @@ import { type Validate } from '@flowgram-adapter/free-layout-editor';
import { inputTreeValidator } from '@coze-workflow/nodes';
/**
* 树形输入校验器
* tree input validator
* @param param0
* @returns
*/

View File

@@ -19,12 +19,12 @@ import { type NodeDataDTO } from '@coze-workflow/base';
import { type FormData } from './types';
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (value: NodeDataDTO) => value;
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/

View File

@@ -27,25 +27,25 @@ import { FormRender } from './form';
import { transformOnInit, transformOnSubmit } from './data-transformer';
export const CONTINUE_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -33,5 +33,5 @@ export const CONTINUE_NODE_REGISTRY: WorkflowNodeRegistry = {
nodeMetaPath: DEFAULT_NODE_META_PATH,
},
formMeta: CONTINUE_FORM_META,
getOutputPoints: () => [], // Continue 节点没有输出
getOutputPoints: () => [], // Continue node has no output
};

View File

@@ -56,7 +56,7 @@ export const ConditionItemField = withField(
useCleanupRightValueOnOperatorChange();
// 属于、不属于操作符情况下,右值的类型是左值的数组类型
// In the case of belonging to or not belonging to the operator, the type of the rvalue is the array type of the lvalue
const rightFieldDataType = useMemo(
() =>
['IN', 'NOT_IN'].includes(operator || '')

View File

@@ -24,7 +24,7 @@ export function useResetCondition(conditionFieldName: string) {
const { data: currentDatabase } = useCurrentDatabaseQuery();
return () => {
// 当前有选中的数据库 需要有一个空条件
// There is currently a selected database, and an empty condition is required.
if (currentDatabase) {
form.setFieldValue(conditionFieldName, {
conditionList: [

View File

@@ -39,7 +39,7 @@ export const createConditionValidator = (conditionFieldPath: string) => ({
ValueExpressionService,
);
// 如果是不需要右值就跳过校验
// If no rvalue is required, skip the verification
if (
databaseNodeService.checkConditionOperatorNoNeedRight(condition?.operator)
) {
@@ -50,7 +50,7 @@ export const createConditionValidator = (conditionFieldPath: string) => ({
return I18n.t('workflow_detail_node_error_empty');
}
// 检验引用变量被删除的情况
// Check if the reference variable is deleted
if (
valueExpressionService.isRefExpression(value) &&
!valueExpressionService.isRefExpressionVariableExists(value, context.node)

View File

@@ -25,7 +25,7 @@ export function createSelectAndSetFieldsValidator() {
ValueExpressionService,
);
// 检查引用变量是否被删除
// Check if the reference variable has been deleted
if (
valueExpressionService.isRefExpression(value) &&
!valueExpressionService.isRefExpressionVariableExists(

View File

@@ -31,13 +31,13 @@ import FormRender from './form';
import { transformOnInit, transformOnSubmit } from './data-transformer';
export const DATABASE_NODE_FORM_META: WorkflowNodeRegistry['formMeta'] = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
'inputParameters.*.name': createNodeInputNameValidate({
@@ -56,21 +56,21 @@ export const DATABASE_NODE_FORM_META: WorkflowNodeRegistry['formMeta'] = {
},
},
// 默认值
// default value
defaultValues: {
inputParameters: [{ name: 'input' }],
databaseInfoList: [],
outputs: getOutputsDefaultValue(),
},
// 副作用
// side effect
effect: {
outputs: provideNodeOutputVariablesEffect,
},
// 初始化数据转换
// Initialize data conversion
formatOnInit: transformOnInit,
// 提交数据转换
// commit data conversion
formatOnSubmit: transformOnSubmit,
};

View File

@@ -16,7 +16,7 @@
import { useQueryFieldIDs } from './use-query-field-ids';
// 当前如果查询字段为空 则排序字段不显示
// Currently, if the query field is empty, the sorting field is not displayed
export function useOrderByVisible() {
const queryFieldIDs = useQueryFieldIDs();

View File

@@ -21,7 +21,7 @@ import { useFieldArray } from '@/form';
import { useQueryFieldIDs } from './use-query-field-ids';
import { type OrderByFieldSchema } from './types';
// 监听查询字段 当查询字段发生变化时 检查排序字段是否存在于查询字段中 不存在则移除
// Listen to the query field. When the query field changes, check whether the sorting field exists in the query field. If it does not exist, remove it.
export const useValidateOrderFields = () => {
const { value, onChange } = useFieldArray<OrderByFieldSchema>();
const queryFieldIDs = useQueryFieldIDs();

View File

@@ -29,7 +29,7 @@ export function QueryFieldsColumnTitles() {
},
},
// {
// label: I18n.t('workflow_query_fields_remove_duplicates', {}, '去重'),
// Label: I18n.t ('workflow_query_fields_remove_duplicates ', {}, ' deduplicate'),
// },
]}
/>

View File

@@ -19,7 +19,7 @@ import { isNil, set } from 'lodash-es';
import { BlockInput, ViewVariableType } from '@coze-workflow/base';
export function transformOnInit(value) {
// 新拖入节点初始化
// New drag-in node initialization
if (!value) {
return {
nodeMeta: undefined,
@@ -66,7 +66,7 @@ export function transformOnInit(value) {
);
formData.inputs.datasetParameters.datasetParam = datasetParam[0]?.input.value
.content as string[];
// 初始创建 / 存量数据的场景下,top_k min_score 为空,在 dataset-setting 组件内处理初始默认值
// In the case of initial creation/stock data, the top_k and min_score are empty, and the initial default value is processed in the dataset-settings component
formData.inputs.datasetParameters.datasetSetting = {
top_k: datasetParam.find(item => item.name === 'topK')?.input.value
.content as number,
@@ -144,14 +144,14 @@ export function transformOnSubmit(value) {
),
]);
// 没有表格知识库则不传 use_nl2sql 字段
// No fields are passed without a table knowledge base use_nl2sql
if (!isNil(datasetSetting?.use_nl2sql)) {
actualData.inputs.datasetParam.push(
BlockInput.createBoolean('useNl2sql', datasetSetting?.use_nl2sql),
);
}
// strategy 可能为 fulltext
// Strategy may be fulltext
if (datasetSetting?.min_score) {
actualData.inputs.datasetParam.push({
name: 'minScore',
@@ -165,8 +165,8 @@ export function transformOnSubmit(value) {
});
}
// 新增检索策略配置, 不在灰度中的可能没有 strategy 数据
// strategy 有可能会为 0
// Added search policy configuration, there may be no strategy data not in grey release
// Strategy may be 0
if (!isNil(datasetSetting?.strategy)) {
actualData.inputs.datasetParam.push({
name: 'strategy',

View File

@@ -31,13 +31,13 @@ import { transformOnInit, transformOnSubmit } from './data-transformer';
const datasetParamFieldName = 'inputs.datasetParameters.datasetParam';
export const DATASET_NODE_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onBlur,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
'inputs.inputParameters.Query': createValueExpressionInputValidate({
@@ -51,15 +51,15 @@ export const DATASET_NODE_FORM_META: FormMetaV2<FormData> = {
},
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
outputs: provideNodeOutputVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -93,12 +93,12 @@ export const DatasetWriteSetting = () => {
label: I18n.t('kl_write_012'),
tooltip: I18n.t('kl_write_013'),
},
// 一期不支持按层级分段
// Phase 1 does not support hierarchical segmentation
// {
// value: 'layer',
// label: '按层级分段',
// Labels: 'Segmented by hierarchy',
// tooltip:
// '按照文档层级结构分段,适用按层级结构来组织的文档,如论文、书籍、说明书等',
// 'Segmented according to the document hierarchy, suitable for documents organized according to the hierarchy, such as papers, books, manuals, etc. ',
// },
{
value: 'custom',

View File

@@ -25,7 +25,7 @@ const TEST_RUN_FILE_NAME_KEY = 'x-wf-file_name';
export function transformOnInit(
value: DatasetNodeActualData,
): DatasetNodeFormData {
// 新拖入节点初始化
// New drag-in node initialization
if (!value) {
return {
nodeMeta: undefined,

View File

@@ -68,9 +68,9 @@ export const DATASET_WRITE_FORM_META: FormMetaV2<FormData> = {
outputs: provideNodeOutputVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -17,7 +17,7 @@
import { I18n } from '@coze-arch/i18n';
import { TerminatePlan } from './types';
// 入参路径,试运行等功能依赖该路径提取参数
// Imported parameter path, practice running and other functions rely on this path to extract parameters
export const INPUT_PATH = 'inputs.inputParameters';
export const TERMINATE_PLAN_PATH = 'inputs.terminatePlan';
export const ANSWER_CONTENT_PATH = 'inputs.content';

View File

@@ -21,7 +21,7 @@ import { VariableTypeDTO } from '@coze-workflow/base';
import { type FormData, type NodeDataDTO, TerminatePlan } from './types';
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (
value: NodeDataDTO,
@@ -36,7 +36,7 @@ export const transformOnInit = (
content: get(value, 'inputs.content.value.content') as string | undefined,
},
};
// 设置各字段初始值
// Set the initial value of each field
if (typeof finalValue.inputs.inputParameters === 'undefined') {
set(finalValue, 'inputs.inputParameters', [{ name: 'output' }]);
}
@@ -56,7 +56,7 @@ export const transformOnInit = (
};
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/

View File

@@ -29,13 +29,13 @@ import { type FormData, TerminatePlan } from './types';
import { FormRender } from './form';
import { transformOnInit, transformOnSubmit } from './data-transformer';
export const END_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
...createInputsValidator(true),
@@ -47,14 +47,14 @@ export const END_FORM_META: FormMetaV2<FormData> = {
}),
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -55,7 +55,7 @@ export const FormRender = withNodeConfigForm(() => {
enableStreamingOutput
switchLabel={I18n.t('workflow_message_streaming_name')}
switchTooltip={I18n.t('workflow_message_streaming_tooltips')}
// 适配旧的 testId 格式
// Adapt to the old testId format
testId={`/${ANSWER_CONTENT_PATH.split('.').join('/')}`}
switchTestId={STREAMING_OUTPUT_PATH.split('.')?.at(-1)}
inputParameters={inputParameters}

View File

@@ -33,7 +33,7 @@ export const END_NODE_REGISTRY: WorkflowNodeRegistry = {
nodeDTOType: StandardNodeType.End,
size: { width: 360, height: 78.2 },
nodeMetaPath: DEFAULT_NODE_META_PATH,
inputParametersPath: INPUT_PATH, // 入参路径,试运行等功能依赖该路径提取参数
inputParametersPath: INPUT_PATH, // Imported parameter path, practice running and other functions rely on this path to extract parameters
defaultPorts: [{ type: 'input' }],
helpLink: '/open/docs/guides/start_end_node',
},

View File

@@ -61,7 +61,7 @@ export const BaseBashEditor = (props: BaseBashEditorProps) => {
[onChange],
);
// 值受控;
// Value controlled;
useEffect(() => {
const editor = apiRef.current;

View File

@@ -121,7 +121,7 @@ export const BaseJsonEditor = React.forwardRef(
apiRef.current?.updateASTDecorations();
}, [isDarkTheme]);
// 值受控;
// Value controlled;
useEffect(() => {
const editor = apiRef.current;

View File

@@ -46,7 +46,7 @@ export const BaseRawTextEditor = forwardRef<HTMLDivElement, RawTextEditorProps>(
[onChange],
);
// 值受控;
// Value controlled;
useEffect(() => {
const editor = apiRef.current;

View File

@@ -32,7 +32,7 @@ export const expressionStringValidator = (
const { required = true, emptyMessage, invalidMessage } = options;
const doubleBracedPattern = /{{([^}]+)}}/g;
const matches = expressionStr?.match(doubleBracedPattern);
// 去除字符串里的 {{}}
// Remove {{}} from string
const matchesContent = matches?.map((varStr: string) =>
varStr.replace(/^{{|}}$/g, ''),
);

View File

@@ -21,11 +21,11 @@ export enum MenuType {
export enum DropdownType {
/**
* 用户输入唤起
* user input evocation
*/
Input = 'Input',
/**
* 点击变量唤起
* click variable arousal
*/
Update = 'Update',
}

View File

@@ -43,9 +43,9 @@ export const useKeyboardActions = ({
);
/**
* 推荐面板出现时,禁用 ArrowUp/ArrowDown/Enter 的默认行为
* 改为上下键切换推荐项
* 左键关闭变量列表,右键打开变量列表,回车插入
* Disable the default behavior of ArrowUp/ArrowDown/Enter when the recommendation panel appears
* Change up and down keys to switch recommendations
* Left-click to close the variable list, right-click to open the variable list, and press Enter to insert.
*/
useEffect(() => {
if (!editor) {
@@ -61,7 +61,7 @@ export const useKeyboardActions = ({
]);
}
// 检测到变量列表存在时,再禁用回车
// When the variable list is detected, disable carriage return
if (isOptionsVisible) {
editor.disableKeybindings([
'Enter',
@@ -90,7 +90,7 @@ export const useKeyboardActions = ({
applyNode,
});
// 上下键切换推荐项,回车填入
// Press the up and down keys to switch the recommended items, and press Enter to fill in.
useKeyboard(dropDownVisible, {
ArrowUp: prev,
ArrowDown: next,
@@ -99,7 +99,7 @@ export const useKeyboardActions = ({
Enter: apply,
});
// ESC 关闭
// ESC Close
useKeyboard(dropDownVisible, {
// eslint-disable-next-line @typescript-eslint/naming-convention
Escape() {

View File

@@ -31,7 +31,7 @@ function useOptionsOperations(props: UseOptionsOperationsProps) {
return useMemo(() => {
function prev() {
if (variableMenuRef.current) {
// 操作变量菜单
// operation variable menu
const optionsInfo = getOptionInfoFromDOM(
variableMenuRef.current?.treeContainerRef,
'.semi-tree-option-list .semi-tree-option',
@@ -70,7 +70,7 @@ function useOptionsOperations(props: UseOptionsOperationsProps) {
function next() {
if (variableMenuRef.current) {
// 操作变量菜单
// operation variable menu
const optionsInfo = getOptionInfoFromDOM(
variableMenuRef.current?.treeContainerRef,
'.semi-tree-option-list .semi-tree-option',
@@ -101,7 +101,7 @@ function useOptionsOperations(props: UseOptionsOperationsProps) {
}
function left() {
// 只要按左键 变量面板就应该关闭
// As soon as you press the left button, the variables panel should close
setTreeVisible(false);
const optionsInfo = getOptionInfoFromDOM(dropdownRef.current);
if (!optionsInfo) {
@@ -111,7 +111,7 @@ function useOptionsOperations(props: UseOptionsOperationsProps) {
}
/**
* 变量面板关闭时直接打开
* Open directly when the variable panel is closed
*/
function right() {
if (!variableMenuRef.current) {

View File

@@ -56,7 +56,7 @@ function useSelection(editor: EditorAPI | undefined) {
const view = editor.$view;
function updateSelection(update?: ViewUpdate) {
// 忽略 replaceTextByRange 导致的 selection change(效果:不触发 selection 变更,进而不显示推荐面板)
// Ignore the selection change caused by replaceTextByRange (effect: no selection change is triggered, and the recommendation panel is not displayed)
if (update?.transactions.some(tr => isSkipSelectionChangeUserEvent(tr))) {
setSelection(undefined);
return;

View File

@@ -40,7 +40,7 @@ import type { RangeType, InputVariableInfo } from '../types';
import s from '../index.module.less';
/**
* 变量文本替换为自定义样式
* Variable text is replaced with a custom style
*/
export const useVariableInjector = ({
availableVariables,
@@ -111,7 +111,7 @@ export const useVariableInjector = ({
varibaleInfoRef.current = varaibleInfo;
// 变量不存在
// Variable does not exist
if (!varaibleInfo?.isVariableExist) {
const variableDeleteWidget = new VariableDeleteWidget(
{
@@ -121,7 +121,7 @@ export const useVariableInjector = ({
(range: RangeType) => {
openUpdateDropdownRef.current();
updateRange.current = range;
// 点击变量时,设置弹窗位置
// When clicking on a variable, set the pop-up position
setPos(from);
},
);
@@ -140,7 +140,7 @@ export const useVariableInjector = ({
(range: RangeType) => {
openUpdateDropdownRef.current();
updateRange.current = range;
// 点击变量时,设置弹窗位置
// When clicking on a variable, set the pop-up position
setPos(from);
},
{
@@ -165,7 +165,7 @@ export const useVariableInjector = ({
(range: RangeType) => {
openUpdateDropdownRef.current();
updateRange.current = range;
// 点击变量时,设置弹窗位置
// When clicking on a variable, set the pop-up position
setPos(from);
},
);
@@ -191,7 +191,7 @@ export const useVariableInjector = ({
type: 'replace',
from: from + nodeNameWithDotLength,
to,
// 全局变量场景 不可编辑变量字段
// Global variable scene, non-editable variable fields
widget: variableSubfixWidget,
atomicRange: true,
}

View File

@@ -41,11 +41,11 @@ export function findInputVariable(
nodePart: string;
globalVariableKey: string;
/**
* 流程变量字段名
* Process variable field name
*/
fieldPart: string;
/**
* 全局变量字段名
* Global variable field name
*/
parsedKeyPath: string[];
},
@@ -137,12 +137,12 @@ export function getVariableRanges(state: EditorState) {
}
/**
* 将字符串路径转换为键路径数组
* - 输入: `["Ob+.\".j"]["child"]`
* - 输出: ['Ob+.".j', 'child']
* Convert string path to key path array
* - Enter: '["Ob +.\" .j "] [" child "]'
* - Output: ['Ob +. ".j', 'child']
*/
export function convertStrPathToKeyPath(str: string): string[] {
// 去除字符串两端的方括号
// Remove square brackets at both ends of string
str = str.slice(2, -2);
const parts = str.split('"]["');
@@ -163,7 +163,7 @@ export function getOptionInfoFromDOM(
return;
}
// 获取所有的选项元素
// Get all option elements
const foundNodes = root.querySelectorAll(classNames ?? '.semi-list-item');
if (foundNodes.length === 0) {
@@ -172,7 +172,7 @@ export function getOptionInfoFromDOM(
const optionElements = [...foundNodes];
// 找到当前高亮的选项
// Find the currently highlighted option
const selectedIndex = optionElements.findIndex(element =>
element.classList.contains(SELECTED_OPTION_CLASSNAME),
);
@@ -223,7 +223,7 @@ export function getVariableInfoFromExpression(expression: string): {
nodeId: string;
nodeName: string;
/**
* 包含 . 的变量名,仅用于流程变量
* Variable names containing., used only for process variables
*/
nodeNameWithDot: string;
fieldPart: string;
@@ -239,11 +239,11 @@ export function getVariableInfoFromExpression(expression: string): {
let fieldKeyPath;
let parsedKeyPath;
// block_output_ 为流程变量特化前缀,由 block-output_ 转换来
// block_output_ specialised prefix for process variables, converted from block-output_
let matches = expression.match(
`^(${TRANS_WORKFLOW_VARIABLE_SOURCE}\\d+)\\.?`,
);
// 全局变量格式 {{global_variable_app["aaa"]["bbb"]}}
// Global variable format {{global_variable_app ["aaa"] ["bbb"]}}
allGlobalVariableKeys?.forEach((varKey: string) => {
const globalVariableRegexStr = `^(${varKey})`;
const curMatch = expression.match(globalVariableRegexStr);

View File

@@ -30,7 +30,7 @@ export class VariableDeleteWidget extends WidgetType {
super();
}
// 插入 editor 中的变量块 dom
// Insert variable block dom in editor
toDOM() {
const wrapper = document.createElement('span');
wrapper.classList.add(s['deleted-variable']);

View File

@@ -62,8 +62,8 @@ interface VariableExtensionProps {
const DROPDOWN_CLASS = 'tree-variable-selector-dropdown';
/**
* wrokflow 变量扩展插件
* - 支持流程变量 + 全局变量
* Wrokflow variable extension
* - Support process variables + global variables
*/
export function VariableExtension({
readonly,
@@ -75,7 +75,7 @@ export function VariableExtension({
languageId,
}: VariableExtensionProps) {
const editor = useEditor<EditorAPI>();
const [pos, setPos] = useState(-1); // 当前光标位置
const [pos, setPos] = useState(-1); // Current cursor position
const [posKey, setPosKey] = useState('');
const inputDropdownRef = useRef(null);
@@ -94,11 +94,11 @@ export function VariableExtension({
selection?.anchor,
);
// 控制输入提示框的显隐
// Control the visibility of input prompt boxes
const [inputDropdownOpen, setInputOpen] = useState(false);
// 控制编辑变量提示框的显隐
// Controls the visibility of the edit variable prompt box
const [updateDropdownOpen, setUpdateOpen] = useState(false);
// 当前提示面板的打开方式
// How to open the current prompt panel
const [dropdownType, setDropdownType] = useState(DropdownType.Input);
const isInputDropdownOpen = dropdownType === DropdownType.Input;
const updateRange = useRef({
@@ -108,12 +108,12 @@ export function VariableExtension({
const dropDownVisible = updateDropdownOpen || inputDropdownOpen;
// 变量插入逻辑
// variable insertion logic
useVariableInjector({
availableVariables,
openUpdateDropdown: () => {
if (variableDataSource?.length && !readonly) {
// 变量为空时不打开
// Do not open when variable is empty
setUpdateOpen(true);
}
setDropdownType(DropdownType.Update);
@@ -134,7 +134,7 @@ export function VariableExtension({
}
}, [dropDownVisible]);
// 替换选中变量
// Replace selected variable
const handleSelect: ApplyNodeType = (
data,
{ type, customRange },
@@ -155,7 +155,7 @@ export function VariableExtension({
curExpressionPath.source !== WORKFLOW_VARIABLE_SOURCE;
let textContent = '';
if (globalVariableKey) {
// keyPath 已经包含了 source
// KeyPath already includes the source.
textContent =
curExpressionPath.keyPath?.reduce((pre, cur) => {
if (pre) {
@@ -169,7 +169,7 @@ export function VariableExtension({
(curExpressionPath.keyPath?.join('.') ?? '');
}
// 下次打开菜单,变量面板不应该自动展开
// Next time you open the menu, the Variables panel should not automatically expand
setTreeVisible(false);
if (type === 'input') {
const range =
@@ -245,7 +245,7 @@ export function VariableExtension({
return;
}
setUpdateOpen(false);
// 意外关闭后,下次变量面板不应该自动展开
// After an unexpected shutdown, the next variable panel should not automatically expand
setTreeVisible(false);
};
@@ -338,7 +338,7 @@ export function VariableExtension({
{
type: 'input',
customRange: {
// 补充双花括号位置
// Supplementary double braces position
from: context.from - 2,
to: context.to + 2,
},
@@ -359,7 +359,7 @@ export function VariableExtension({
}) => {
const curPos = state.selection.main.head;
if (variableDataSource?.length && !readonly) {
// 变量为空时不打开
// Do not open when variable is empty
setInputOpen(value);
}
setPos(curPos);

View File

@@ -39,7 +39,7 @@ export class VariablePrefixWidget extends WidgetType {
super();
}
// 插入 editor 中的变量块 dom
// Insert variable block dom in editor
toDOM() {
const { range, varaibleInfo, nodeName, isDarkTheme, languageId } =
this.variableContext;

View File

@@ -33,11 +33,11 @@ export class VariableSubfixWidget extends WidgetType {
super();
}
// 插入 editor 中的变量块 dom
// Insert variable block dom in editor
toDOM() {
const node = document.createElement('span');
node.classList.add(s.content);
// 全局变量光标样式
// Global variable cursor style
if (this.variableContext.varaibleInfo.globalVariableKey) {
node.classList.add(s['pointer-content']);
}

View File

@@ -64,7 +64,7 @@ export enum DTOFieldType {
}
/**
* 后端数据类型 -> 前端数据类型
* Backend Data Types - > Frontend Data Types
*/
export const fileTypeDTOToVO = {
[DTOFieldType.File]: ViewVariableType.File,
@@ -72,7 +72,7 @@ export const fileTypeDTOToVO = {
};
/**
* 前端数据类型 -> 后端数据类型
* Front-end data types - > Back-end data types
*/
export const fileTypeVOToDTO = {
[ViewVariableType.File]: DTOFieldType.File,

View File

@@ -44,7 +44,7 @@ interface FormData {
}
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (
value: NodeDataDTO,
@@ -76,7 +76,7 @@ export const transformOnInit = (
},
},
setting: {
timeout: 120, //单位秒
timeout: 120, //unit second
retryTimes: 3,
},
},
@@ -206,8 +206,8 @@ export const transformOnInit = (
const basicTypeDTO = get(parsedTypeMapping, `${param.name}.basicType`);
let type = fileTypeDTOToVO[basicTypeDTO];
/*
* 兼容复杂数据类型
* rawMeta.type 存储的是 ViewVariableType
* Compatible with complex data types
* rawMeta.type stores ViewVariableType
*/
if (param.input?.value?.rawMeta?.type) {
type = param.input?.value?.rawMeta?.type;
@@ -248,7 +248,7 @@ export const transformOnInit = (
};
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
*/
export const transformOnSubmit = (
value: FormData,
@@ -272,7 +272,7 @@ export const transformOnSubmit = (
},
)
.map(param => ({
// 后端不需要 type
// Backend does not require type
name: param.name,
input: param.input,
}));
@@ -290,7 +290,7 @@ export const transformOnSubmit = (
},
)
.map(param => ({
// 后端不需要 type
// Backend does not require type
name: param.name,
input: param.input,
}));
@@ -335,7 +335,7 @@ export const transformOnSubmit = (
},
)
.map(param => ({
// 后端不需要 type
// Backend does not require type
name: param.name,
input: param.input,
}));

View File

@@ -30,7 +30,7 @@ export const useVariableTree = ({
}): ExpressionEditorTreeNode[] => {
const availableVariables: ExpressionEditorTreeHelper.AvailableVariable[] =
variables.map((variable: WorkflowVariableFacade) => ({
// 流程变量特化逻辑,因为 block-output 不是一个合法的变量名
// Process variable specialization logic because block-output is not a valid variable name
name: variable.globalVariableKey
? variable.expressionPath?.source
: TRANS_WORKFLOW_VARIABLE_SOURCE +

View File

@@ -51,12 +51,12 @@ export function useVariableWithNodeInfo(
let nodeTitle = variable.groupInfo.label;
const iconUrl = variable.groupInfo.icon;
if (!variable.globalVariableKey) {
// 这里获取到的节点名是最新的
// The node name obtained here is the latest
const variableMeta = getNodeInfoInVariableMeta(nodeEntity);
nodeTitle = variableMeta?.nodeTitle ?? '';
}
// 流程变量特化逻辑,因为 block-output 不是一个合法的变量名
// Process variable specialization logic because block-output is not a valid variable name
const source = variable.globalVariableKey
? variable.expressionPath.source
: TRANS_WORKFLOW_VARIABLE_SOURCE +

View File

@@ -68,7 +68,7 @@ interface InnerEditorProps {
}
/**
* 全局变量提示逻辑层
* Global variable hint logic layer
*/
export const InnerEditor = React.forwardRef(
(props: InnerEditorProps, editorRef) => {
@@ -94,7 +94,7 @@ export const InnerEditor = React.forwardRef(
allVariables,
getNodeInfoInVariableMeta,
);
/** 默认兜底的可选择变量数据 */
/** Selectable variable data with default backstop */
const defaultVariableDataSource = useFormatVariableDataSource({
disabledTypes: [],
});
@@ -103,7 +103,7 @@ export const InnerEditor = React.forwardRef(
defaultVariableDataSource,
);
// 处理 DataSource 数据,添加部分字段 / 渲染
// Process DataSource data, add partial fields/renders
const variableDataSource = processDataSourceLabelRender({
dataSource: dataSourceWithGlobal,
icon: node =>

View File

@@ -42,7 +42,7 @@ export const JsonExtensionEditorField = withField(() => {
placeholder={I18n.t('node_http_json_input')}
value={value as string}
minHeight={78}
// 表单内禁止编辑
// Forbid editing in the form
readonly={true}
borderRadius={8}
isDarkTheme={isDarkTheme}

View File

@@ -49,7 +49,7 @@ export const RawTextEditorField = withField(
value={value as string}
onChange={onChange}
minHeight={minHeight}
// 表单内禁止编辑
// Forbid editing in the form
readonly={readonly}
/>
</EditorProvider>

View File

@@ -59,7 +59,7 @@ interface RawTextEditorContainerProps {
}
/**
* 全局变量提示逻辑层
* Global variable hint logic layer
*/
export const InnerEditor: FC<RawTextEditorContainerProps> = props => {
const { value, onChange, placeholder, minHeight, readonly = false } = props;
@@ -74,7 +74,7 @@ export const InnerEditor: FC<RawTextEditorContainerProps> = props => {
allVariables,
getNodeInfoInVariableMeta,
);
/** 默认兜底的可选择变量数据 */
/** Selectable variable data with default backstop */
const defaultVariableDataSource = useFormatVariableDataSource({
disabledTypes: [],
});
@@ -83,7 +83,7 @@ export const InnerEditor: FC<RawTextEditorContainerProps> = props => {
defaultVariableDataSource,
);
// 处理 DataSource 数据,添加部分字段 / 渲染
// Process DataSource data, add partial fields/renders
const variableDataSource = processDataSourceLabelRender({
dataSource: dataSourceWithGlobal,
icon: node =>

View File

@@ -58,13 +58,13 @@ interface Match {
}
export const HTTP_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onBlur,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
[urlPathName]: ({ value, context }) => {
@@ -225,15 +225,15 @@ export const HTTP_FORM_META: FormMetaV2<FormData> = {
...createAuthValidator(),
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
outputs: provideNodeOutputVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -34,11 +34,11 @@ const generateExpressionString = (
{
node,
/**
* label 前缀,用于表单展示
* Label prefix for form display
*/
labelPrefix = '',
/**
* name 前缀,用于区分变量
* Name prefix, used to distinguish variables
*/
namePrefix = '',
}: {
@@ -52,7 +52,7 @@ const generateExpressionString = (
}
const doubleBracedPattern = /{{([^}]+)}}/g;
const matches = expressionStr.match(doubleBracedPattern);
// 去除字符串里的 {{}}
// Remove {{}} from string
const matchesContent = matches?.map((varStr: string) =>
varStr.replace(/^{{|}}$/g, ''),
);
@@ -71,7 +71,7 @@ const generateExpressionString = (
node.context.variableService.getWorkflowVariableByKeyPath(fieldKeyPath, {
node,
});
// 重复变量只展示一次
// Duplicate variables are displayed only once
if (
!cache[fieldName] &&
workflowVariable &&

View File

@@ -51,7 +51,7 @@ export const ApiSetter = () => {
),
);
const curlHeaders = {};
// 特化逻辑,过滤 content-type 字段,由后端发送请求时生成
// Specialized logic, filtering content-type fields, generated by the backend when sending a request
for (const key in parsedCurl?.headers) {
if (key.toLowerCase() !== 'content-type') {
curlHeaders[key] = parsedCurl?.headers[key];
@@ -72,7 +72,7 @@ export const ApiSetter = () => {
}
let bodyData;
if (
// Binary 类型 body 参数为文件路径,前端不处理,直接置空
// The body parameter of the Binary type is the file path, which is not processed by the front end and is directly set empty.
bodyType === BodyType.Binary
) {
bodyData = {

View File

@@ -85,9 +85,9 @@ export function MultiCondition(props: ConditionProps): JSX.Element {
initValidateResultsWithBranches(value || []);
}, []);
// TODO 补充 Validate
// TODO Supplement Validated
// useEffect(() => {
// // 监听画布保存表单提交时,进行一次整体校验
// //Monitor the canvas to save the form submission and perform an overall verification
// const disposable = onFormValidate(() => {
// validateAllBranches(branches);
// });
@@ -110,8 +110,8 @@ export function MultiCondition(props: ConditionProps): JSX.Element {
}, [branches, draggingBranchUid]);
useEffect(() => {
// 这里需要判断下外部的value 是否与 state里的 branches 一致
// 只有在不一致的时候才更新 branches避免死循环
// Here we need to determine whether the external value is consistent with the branches in the state
// Update branches only when they are inconsistent to avoid endless loops
if (
!isEqual(
value,
@@ -181,7 +181,7 @@ export function MultiCondition(props: ConditionProps): JSX.Element {
};
const handleDeleteBranch = index => () => {
// 将要被删除的端口移动到最后,这样删除时不会对其他连线顺序产生影响
// Move the port to be deleted to the end so that the deletion does not affect other connection sequences
updateSortedPortLines(index, value.length);
setBranches(branches.filter((item, innerIndex) => innerIndex !== index));
};
@@ -202,7 +202,7 @@ export function MultiCondition(props: ConditionProps): JSX.Element {
const handleDragEnd = (startIndex: number, endIndex: number) => {
setDraggingBranchUid(undefined);
// 连线服务重新计算端口的时候dom 可能还没更新完成所以这里加上延迟确保重新计算的时候dom已经更新完成了
// When the connection service recalculates the port, the dom may not have been updated yet, so add a delay here to ensure that the dom has been updated when the recalculation is completed
setTimeout(() => {
updateSortedPortLines(startIndex, endIndex);
}, 0);

View File

@@ -20,7 +20,7 @@ import { ViewVariableType } from '@coze-workflow/variable';
export const CONDITION_PATH = 'condition';
export const ELSE_PATH = 'else';
// 定义固定出参
// Define fixed exported parameters
export const OUTPUTS = [
{
key: nanoid(),

View File

@@ -22,7 +22,7 @@ import { type NodeDataDTO, type ValueExpression } from '@coze-workflow/base';
import { type FormData } from './types';
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (value: FormData, context: NodeContext) => {
if (!value) {
@@ -78,7 +78,7 @@ export const transformOnInit = (value: FormData, context: NodeContext) => {
};
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/

View File

@@ -33,13 +33,13 @@ import { transformOnInit, transformOnSubmit } from './data-transformer';
import { CONDITION_PATH } from './constants';
export const IF_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
[CONDITION_PATH]: ({ value, context }) => {
@@ -74,15 +74,15 @@ export const IF_FORM_META: FormMetaV2<FormData> = {
},
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
outputs: provideNodeOutputVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -97,7 +97,7 @@ export const Canvas: FC<{ variables?: InputVariable[] }> = ({
setFullscreenPanel(fabricEditor);
}, [setFullscreenPanel]);
// 更新节点
// update node
useEffect(() => {
if (fabricEditor && fullscreenPanelVisible) {
setFullscreenPanel(fabricEditor);

View File

@@ -28,9 +28,9 @@ const CanvasLazy = lazy(async () => {
export const Canvas = withField(props => {
/**
* useInputVariables 内部使用了 useContext
* lazyLoad 会导致 监听不到 context 的变化
* 所以提前获取 variables
* useInputVariables internally uses useContext
* lazyLoad will cause context changes that cannot be monitored
* Get the variables in advance
*/
const variables = useInputVariables({
needNullType: true,

View File

@@ -17,10 +17,10 @@
import { nanoid } from 'nanoid';
import { ViewVariableType } from '@coze-workflow/variable';
// 入参路径,试运行等功能依赖该路径提取参数
// Imported parameter path, practice running and other functions rely on this path to extract parameters
export const INPUT_PATH = 'inputs.inputParameters';
// 定义固定出参
// Define fixed exported parameters
export const OUTPUTS = [
{
key: nanoid(),

View File

@@ -40,7 +40,7 @@ export const initialValue = {
};
/**
* 节点后端数据 -> 前端表单数据
* Node Backend Data - > Frontend Form Data
*/
export const transformOnInit = (
value: NodeDataDTO,
@@ -76,7 +76,7 @@ export const transformOnInit = (
};
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/

View File

@@ -31,30 +31,30 @@ import { FormRender } from './form';
import { transformOnInit, transformOnSubmit } from './data-transformer';
export const IMAGE_CANVAS_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
// 必填
// Required
'inputs.inputParameters.*.input': createValueExpressionInputValidate({
required: true,
}),
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
outputs: provideNodeOutputVariablesEffect,
},
// 节点后端数据 -> 前端表单数据
// Node Backend Data - > Frontend Form Data
formatOnInit: transformOnInit,
// 前端表单数据 -> 节点后端数据
// Front-end form data - > node back-end data
formatOnSubmit: transformOnSubmit,
};

View File

@@ -36,7 +36,7 @@ export const IMAGE_CANVAS_NODE_REGISTRY: WorkflowNodeRegistry<NodeTestMeta> = {
size: { width: 360, height: 130.7 },
nodeMetaPath: DEFAULT_NODE_META_PATH,
outputsPath: DEFAULT_OUTPUTS_PATH,
inputParametersPath: INPUT_PATH, // 入参路径,试运行等功能依赖该路径提取参数
inputParametersPath: INPUT_PATH, // Imported parameter path, practice running and other functions rely on this path to extract parameters
test,
helpLink: '/open/docs/guides/canvas_node',
},

View File

@@ -24,7 +24,7 @@ export const PromptField = withField(
const { name } = useField();
const promptName = `${name}.prompt`;
const negativePromptName = `${name}.negative_prompt`;
// 保障和之前节点testID不变
// Guarantee that the testID of the previous node remains unchanged
const promptTestIDSuffix = name.replace('inputs.', '');
const negativePromptTestIDSuffix = name.replace('inputs.', '');

View File

@@ -69,7 +69,7 @@ function isPreprocessorDisabled({
}) {
let disabled = false;
// 如果当前选项的预处理器已经被当前项选中 从allSelectedPreprocessor中移除
// If the preprocessor for the current option is already selected by the current item, remove it from the allSelectedPreprocessor
allSelectedPreprocessor = allSelectedPreprocessor.filter(
item =>
!(
@@ -78,12 +78,12 @@ function isPreprocessorDisabled({
),
);
// 不能添加相同的模型
// The same model cannot be added
if (allSelectedPreprocessor.includes(currentOptionPreprocessor)) {
disabled = true;
}
// 1到4编号最多只能出现两个 4以上编号的模型不做限制
// Numbers 1 to 4 can only appear at most two models with numbers above 4, and there is no limit.
const group = [1, 2, 3, 4];
if (group.includes(currentOptionPreprocessor)) {
const isPreprocessorGroup =

View File

@@ -34,13 +34,13 @@ import { type FormData } from './types';
import { FormRender } from './form';
export const IMAGE_GENERATE_FORM_META: FormMetaV2<FormData> = {
// 节点表单渲染
// Node form rendering
render: () => <FormRender />,
// 验证触发时机
// verification trigger timing
validateTrigger: ValidateTrigger.onChange,
// 验证规则
// validation rules
validate: {
nodeMeta: nodeMetaValidate,
['inputs.modelSetting.model']: ({ value, formValues }) => {
@@ -51,13 +51,13 @@ export const IMAGE_GENERATE_FORM_META: FormMetaV2<FormData> = {
6: [6, 7],
};
// 获取references字段
// Get references field
const references = formValues?.inputs?.references || [];
// 获取value对应的无效preprocessor值数组
// Gets an array of invalid preprocessor values corresponding to the value
const invalidValues = invalidPreprocessors[value] || [];
// 检查references中的preprocessor是否包含无效值
// Check if the preprocessor in the references contains invalid values
for (const reference of references) {
if (invalidValues.includes(reference?.preprocessor)) {
return I18n.t('Imageflow_not_support');
@@ -71,13 +71,13 @@ export const IMAGE_GENERATE_FORM_META: FormMetaV2<FormData> = {
},
},
// 副作用管理
// Side effect management
effect: {
nodeMeta: fireNodeTitleChange,
outputs: provideNodeOutputVariablesEffect,
},
// 默认值
// default value
defaultValues: () => ({
inputs: {
modelSetting: {

View File

@@ -42,8 +42,8 @@ export const FormRender = withNodeConfigForm(() => {
);
});
// 监听引用参考的模型变化触发模型设置的模型校验
// useWatch目前无法监听引用模型 先监听整个表单值
// Listening to referenced model changes triggers model validation for model settings
// With useWatch, you can't currently listen to the reference model. Instead, listen to the entire form value first
function useReferenceModelChangeEffect(callback: () => void) {
const form = useForm<FormData>();
const { values } = form;

View File

@@ -48,4 +48,4 @@ export { PLUGIN_NODE_REGISTRY } from './plugin';
export { SUB_WORKFLOW_NODE_REGISTRY } from './sub-workflow';
export { VARIABLE_NODE_REGISTRY } from './variable';
export { JSON_STRINGIFY_NODE_REGISTRY } from './json-stringify';
// cli 脚本插入标识registry请勿修改/删除此行注释
// The cli script inserts the identifier (registry), do not modify/delete this line comment

View File

@@ -17,7 +17,7 @@
import { nanoid } from '@flowgram-adapter/free-layout-editor';
import { ViewVariableType } from '@coze-workflow/variable';
// 定义固定出参
// Define fixed exported parameters
export const OUTPUTS = [
{
key: nanoid(),

View File

@@ -19,7 +19,7 @@ import { variableUtils } from '@coze-workflow/variable';
import { type FormData, type NodeDataDTO } from './types';
/**
* 前端表单数据 -> 节点后端数据
* Front-end form data - > node back-end data
* @param value
* @returns
*/

Some files were not shown because too many files have changed in this diff Show More