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

@@ -98,7 +98,7 @@ export const MockForm = React.forwardRef(
}));
useEffect(() => {
eventEmitter.on('change', (...args: any[]) => {
// 实际上都是假的咯 假设 args 第一个参数是 field 第二个参数是具体 value
// In fact, it is all false. Suppose the first argument of args is field and the second argument is a specific value.
valuesRef.current[args[0]] = args[1];
props.onValueChange(valuesRef.current, args[1]);
});

View File

@@ -59,7 +59,7 @@ export const StepFooter: FC = () => {
}
const res = await callbackResult;
// 返回 false 则直接 return
// If it returns false, it will be returned directly.
if (typeof res === 'boolean' && res === false) {
setSubmitButtonLoading(false);
return;
@@ -71,7 +71,7 @@ export const StepFooter: FC = () => {
// onSubmit
try {
// 判断传入的 submit 函数如果是异步,则按钮 loading
// Determine if the passed submit function is asynchronous, then the button loading
const callbackResult = onSubmit?.();
if (callbackResult instanceof Promise) {
setSubmitButtonLoading(true);
@@ -79,10 +79,10 @@ export const StepFooter: FC = () => {
await callbackResult;
if (isLastStep) {
//关闭
//close
onCancel?.();
} else {
// 下一步
// Next step
useStepStore.setState(state => ({
step: Math.min(state.step + 1, lastStep),
}));
@@ -95,10 +95,10 @@ export const StepFooter: FC = () => {
const handleClickPrev = () => {
getCallbacks()?.onPrevious?.();
if (isFirstStep) {
// 关闭
// close
onCancel?.();
} else {
// 上一步
// previous step
useStepStore.setState(state => ({
step: Math.max(state.step - 1, firstStep),
}));

View File

@@ -118,7 +118,7 @@ export const TablePreview: FC = () => {
});
let res: AddTableResponse;
try {
// TODO:此需求暂停,后端下线,后续待开放
// TODO: This demand is suspended, the backend is offline, and it will be opened later.
// res = await DataModelApi.AddTable({
// file: {
// tos_uri: fileList[0].response.upload_uri,

View File

@@ -121,7 +121,7 @@ export const TableStructure: FC = () => {
let res: PreviewTableFileResponse;
try {
// TODO:此需求暂停,后端下线,后续待开放
// TODO: This demand is suspended, the backend is offline, and it will be opened later.
// res = await DataModelApi.PreviewTableFile({
// file: {
// tos_uri: fileList[0].response.upload_uri,
@@ -168,7 +168,7 @@ export const TableStructure: FC = () => {
}
});
// 上一步保存当前状态
// Previous Save the current state
onPrevious(() => {
const tableBasicValue =
// @ts-expect-error -- linter-disable-autofix
@@ -265,7 +265,7 @@ export const TableStructure: FC = () => {
};
if (changedKeys.length === 1 && changedKeys.includes('sheetID')) {
// FIXME: 此处 semi 有 bug始终是 override 更新,所以需要也添加上 sheetID 属性
// FIXME: There is a bug in semi here, and it is always override update, so you need to add the sheetID attribute as well.
// @ts-expect-error -- linter-disable-autofix
excelInfoFormRef.current.formApi.setValues({
sheetID: changedValue.sheetID,
@@ -274,7 +274,7 @@ export const TableStructure: FC = () => {
});
}
// 切换 sheet
// Switch sheet
if (
changedKeys.length === 3 &&
changedKeys.includes('headerRow') &&
@@ -284,7 +284,7 @@ export const TableStructure: FC = () => {
await reloadTableValue({ updateTableName: true });
}
// 仅更新 headerRow
// Update headerRow only
if (changedKeys.length === 1 && changedKeys.includes('headerRow')) {
// @ts-expect-error -- linter-disable-autofix
if (changedValue.headerRow >= values.dataStartRow) {
@@ -299,7 +299,7 @@ export const TableStructure: FC = () => {
}
}
// 仅更新 dataStartRow
// Update dataStartRow only
if (
changedKeys.length === 1 &&
changedKeys.includes('dataStartRow')

View File

@@ -163,7 +163,7 @@ export const Upload: FC = () => {
}
try {
// 业务
// business
const { name, fileInstance } = file;
if (fileInstance) {
@@ -246,7 +246,7 @@ export const Upload: FC = () => {
setCurrentState({
fileList: fileList.filter((f, i) => index !== i),
});
// reset 配置
// Reset configuration
setTableStructure({
excelBasicInfo: undefined,
excelValue: undefined,
@@ -380,7 +380,7 @@ export const Upload: FC = () => {
style={{
height: '100%',
/**
* NOTE: 此处采取 css 隐藏是为了保持 upload 过程,否则会取消上传
* NOTE: css hiding is taken here to keep the upload process, otherwise the upload will be cancelled
*/
...(fileList.length > 0
? {
@@ -395,8 +395,8 @@ export const Upload: FC = () => {
});
}}
beforeUpload={fileInfo => {
// 不通过 maxSize 属性来限制的原因是
// 只有 beforeUpload 钩子能改 validateMessage
// The reason for not limiting by the maxSize property is
// Only the beforeUpload hook can change validateMessage
const res = {
fileInstance: fileInfo.file.fileInstance,
status: fileInfo.file.status,
@@ -438,7 +438,7 @@ export const Upload: FC = () => {
dragMainText={I18n.t('db_table_0126_016')}
dragSubText={I18n.t('db_table_0126_017')}
onChange={({ fileList: files }) => {
// 存在校验通过的才上传
// It will only be uploaded if the verification is passed.
if (files.some(f => f.shouldUpload)) {
setCurrentState({
fileList: files,

View File

@@ -14,6 +14,6 @@
* limitations under the License.
*/
// 20MB 限制
// 20MB limit
export const ACCEPT_FILE_MAX_SIZE = 20 * 1024 * 1024;
export const ACCEPT_FILE_TYPES = ['.xlsx', '.xls', '.csv'].join(',');

View File

@@ -62,7 +62,7 @@ export default class DatamodelService<T> {
*
* [jump to BAM]()
*
* Table Import】导入文件数据预检查
* [Table Import] Import file data pre-check
*/
PreviewTableFile(
req: table_import.PreviewTableFileRequest,
@@ -84,7 +84,7 @@ export default class DatamodelService<T> {
*
* [jump to BAM]()
*
* Table Import】导入文件数据任务信息查询
* [Table Import] Import file data task information query
*/
QueryTableFileTaskStatus(
req: table_import.QueryTableFileTaskStatusRequest,
@@ -107,7 +107,7 @@ export default class DatamodelService<T> {
*
* [jump to BAM]()
*
* Table Import】导入文件添加table
* [Table Import] Import file Add table
*/
AddTable(
req: table_import.AddTableRequest,

View File

@@ -22,33 +22,33 @@
export type Int64 = string | number;
export enum BotTableRWMode {
/** 单用户模式 */
/** single user mode */
LimitedReadWrite = 1,
/** 只读模式 */
/** read-only mode */
ReadOnly = 2,
/** 多用户模式 */
/** multi-user mode */
UnlimitedReadWrite = 3,
/** Max 边界值 */
/** Max boundary value */
RWModeMax = 4,
}
export enum BotTableStatus {
/** 初始化(不可用) */
/** Initialization (not available) */
Init = 0,
/** 已上线 */
/** It's online now. */
Online = 1,
/** 删除 */
/** delete */
Delete = 2,
/** 草稿态(未 publish */
/** Draft status (not published) */
Draft = 3,
}
export enum FieldItemType {
/** 文本 */
/** Text */
Text = 1,
/** 数字 */
/** number */
Number = 2,
/** 时间 */
/** time */
Date = 3,
/** float */
Float = 4,
@@ -56,13 +56,13 @@ export enum FieldItemType {
Boolean = 5,
}
/** Table model相关常量,结构体定义 */
/** Table model related constants, structure definitions */
export enum FieldType {
/** 文本 */
/** Text */
Text = 1,
/** 数字 */
/** number */
Number = 2,
/** 时间 */
/** time */
Date = 3,
/** float */
Float = 4,
@@ -71,49 +71,49 @@ export enum FieldType {
}
export enum ImportFileTaskStatus {
/** 任务初始化 */
/** task initialization */
Init = 1,
/** 任务处理中 */
/** Task in progress */
Enqueue = 2,
/** 任务成功 */
/** Mission successful */
Succeed = 3,
/** 任务失败 */
/** Mission failed */
Failed = 4,
}
export enum Language {
/** 中文 */
/** Chinese */
Chinese = 1,
/** 英文 */
/** English */
English = 2,
}
export enum TableType {
/** 草稿 */
/** draft */
DraftTable = 1,
/** 线上 */
/** online */
OnlineTable = 2,
}
export interface FieldItem {
/** 字段名称,用户自定义,可能为中文 */
/** Field name, user-defined, possibly in Chinese */
name: string;
desc?: string;
type: FieldItemType;
must_required?: boolean;
/** 字段Id服务端生成全局唯一新增为0 */
/** Field Id, server level generated, globally unique (added as 0) */
id?: Int64;
/** 字段名称语言类型 */
/** Field Name Language Type */
lang?: Language;
/** 物理字段名,服务端生成,单个table下唯一 */
/** Physical field name, server level generation, unique under a single table */
physics_name?: string;
/** 是否主键 */
/** Whether primary key */
primary_key?: boolean;
/** 字段可见性1:用户自定义2:业务定义对用户可见3:业务定义,对用户隐藏 */
/** Field visibility, 1: user-defined; 2: business definition, visible to users; 3: business definition, hidden from users */
visibility?: number;
/** 在excel文档中使用映射到excel中对应的列 */
/** Used in an excel document, map to the corresponding column in excel */
sequence?: string;
/** 业务自定义扩展field元数据 */
/** Business custom extension field metadata */
map_ext_meta?: Record<string, string>;
}
/* eslint-enable */

View File

@@ -33,15 +33,15 @@ export interface AddTableRequest {
}
export interface AddTableResponse {
/** 相关id. bot_id */
/** Related id bot_id */
bot_id: string;
/** table_id */
table_id: string;
/** 表名 */
/** table name */
table_name: string;
/** 上传 TableFile 的 task id用于后期查询使用.
DataModelService 使用 GID 保证 task_id 全局唯一,后续查询时只需要 task_id.
DataModel 服务会记录 table 的 lastTaskID, 查询时可以通过 table_id 查到唯一的
/** Upload the task id of TableFile for later query use.
DataModelService uses GID to ensure that task_id globally unique, and subsequent queries only require task_id.
The DataModel service will record the lastTaskID of the table, which can be found by table_id when querying
task_id */
task_id: Int64;
code: number;
@@ -51,24 +51,24 @@ task_id */
export interface FileInfo {
/** tos uri */
tos_uri: string;
/** Excel 行号 */
/** Excel line number */
header_row: Int64;
/** Excel 数据开始行 */
/** Excel data start line */
start_data_row: Int64;
/** Excel sheet id, 0 for default */
sheet_id?: number;
}
export interface ImportTableInfo {
/** table 所属的 bot_id */
/** Table belongs to bot_id */
bot_id: string;
/** 表名 */
/** table name */
table_name: string;
/** 表描述 */
/** table description */
table_desc?: string;
/** 字段信息 */
/** Field information */
table_meta: Array<table_base.FieldItem>;
/** 空间ID */
/** Space ID */
space_id: string;
}

View File

@@ -76,7 +76,7 @@ export const useUploadProgress = (params: {
try {
let res: QueryTableFileTaskStatusResponse;
try {
// TODO:此需求暂停,后端下线,后续待开放
// TODO: This demand is suspended, the backend is offline, and it will be opened later.
// res = await DataModelApi.QueryTableFileTaskStatus({
// table_id: tableID,
// bot_id: botID,
@@ -89,7 +89,7 @@ export const useUploadProgress = (params: {
throw error;
}
// 不在Processing则停止轮询
// Stop polling without Processing
// @ts-expect-error -- linter-disable-autofix
if (res?.status !== ImportFileTaskStatus.Enqueue) {
clearInterval(importResultRef.current);
@@ -97,8 +97,8 @@ export const useUploadProgress = (params: {
}
/**
* 成功后---写入localStorage
* 没有任务---写入localStorage
* After success --- write to localStorage
* No task --- write to localStorage
*/
if (
// @ts-expect-error -- linter-disable-autofix
@@ -129,7 +129,7 @@ export const useUploadProgress = (params: {
};
useEffect(() => {
// 读取localStorage,减少不必要的请求次数
// Read localStorage to reduce unnecessary requests
const lsMap = readFromLocalStorage();
const inLocaleStorage = (lsMap[botID] || []).includes(tableID);

View File

@@ -29,7 +29,7 @@ export interface initialConfigStore {
}) => Promise<void>;
}
// 用来存储静态状态,非初始化场景下,仅只读不可修改
// Used to store static state, in non-initialization scenarios, read-only and not modifiable
export const useInitialConfigStore = create<initialConfigStore>()(set => ({
onCancel: noop,
botId: '',

View File

@@ -131,7 +131,7 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
mapOfShouldHidingDatabaseTableStructureTips,
setMapOfShouldHidingDatabaseTableStructureTips,
] = useLocalStorageState<string | undefined>(
// FIXME: 此属性名意义不明确,处为了兼容,暂不修改此属性名,但后续需要使用更明确的命名
// FIXME: The meaning of this property name is unclear. For compatibility, this property name will not be modified for the time being, but a more explicit naming needs to be used in the future.
'use-local-storage-state-modify-tips',
{
defaultValue: '',
@@ -181,9 +181,9 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
const showEntry = isEntry && !isEdit && !NL2DBInfo;
const shouldShowAIGenerate =
/**
* 1. 入口不展示
* 2. 编辑态不展示
* 3. Excel导入时不展示
* 1. The entrance is not displayed
* 2. Editing status is not displayed
* 3. Excel is not displayed when importing
*/
!showEntry && !isEdit && createType !== CreateType.excel;
@@ -280,8 +280,8 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
})),
});
// data 是初始值,此处需要手动 setState 更新子组件状态
// Modal 已提前关闭,子组件卸载,则 ref 为空,需要加上可选链判断一下
// Data is the initial value, where you need to manually setState to update the subcomponent state
// If Modal has been closed early and the subassembly is uninstalled, the ref is empty. You need to add an optional chain to judge.
tableStructureRef.current?.setTableFieldsList(
// @ts-expect-error -- linter-disable-autofix
res.bot_table_list[0].field_list.map(i => ({
@@ -562,7 +562,7 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
onDeleteField={list => {
setIsDeletedField(
!database.tableMemoryList.every(i =>
// TODO: 当前field id生成规则有问题故暂时使用 nanoid 替换
// TODO: There is a problem with the current field id generation rule, so the nanoid is temporarily replaced
list.find(j => j.nanoid === i.nanoid),
),
);

View File

@@ -20,7 +20,7 @@ import { I18n } from '@coze-arch/i18n';
import { type MapperItem, type TriggerType, VerifyType } from '../../../types';
// 校验 Table Name Field Name
// Validation Table Name and Field Name
const namingRegexMapper = [
{
type: 1,
@@ -49,7 +49,7 @@ export const validateNaming = (str: string, errList: string[] = []) => {
return list;
};
// 校验 Table Fields
// Validation Table Fields
export const thMapper: MapperItem[] = [
{
label: I18n.t('db_add_table_field_name'),
@@ -120,7 +120,7 @@ export const validateFields = (
const msg = verifyItem.message;
switch (verifyItem.type) {
case VerifyType.Required: {
// 报错出现时机:点击保存按钮时,出现提示。表中某一行填写了数据,但是未填写必填字段时,需要报错
// When the error occurs: When clicking the Save button, a prompt appears. When a row in the table fills in the data, but the required fields are not filled in, an error needs to be reported.
if (
trigger === 'save' &&
!value &&
@@ -131,14 +131,14 @@ export const validateFields = (
) {
listItem.errorMapper[thKey].push(msg);
}
// 报错消失时机:必填输入框输入了内容后,报错立刻消失
// Error reporting and disappearance timing: Required text box After entering the content, the error will disappear immediately
if (trigger === 'change' && value) {
listItem.errorMapper[thKey] = errTarget.filter(i => i !== msg);
}
break;
}
case VerifyType.Unique: {
// 报错出现时机:点击保存按钮时,出现提示。
// When the error occurs: When you click the Save button, a prompt appears.
if (
trigger === 'save' &&
value &&
@@ -146,7 +146,7 @@ export const validateFields = (
) {
listItem.errorMapper[thKey].push(msg);
}
// 报错消失时机:必填输入框输入了内容后,报错立刻消失
// Error reporting and disappearance timing: Required text box After entering the content, the error will disappear immediately
if (
trigger === 'change' &&
value &&
@@ -157,7 +157,7 @@ export const validateFields = (
break;
}
case VerifyType.Naming: {
// 报错出现时机:命名格式有问题,失去焦点时,立刻校验格式
// Error timing: There is a problem with the naming format. When you lose focus, check the format immediately
if (
trigger === 'save' ||
trigger === 'blur' ||

View File

@@ -97,10 +97,10 @@ export interface DatabaseTableStructureProps {
loading?: boolean;
loadingTips?: string;
/**
* excel: 单用户模式|只读模式
* normal: 单用户模式|只读模式
* expert: 单用户模式|只读模式|多用户模式
* undefined: 不支持读写模式
* Excel: single user mode | read-only mode
* Normal: Single user mode | Read-only mode
* Expert: Single user mode | Read-only mode | Multi-user mode
* Undefined: Read and write modes are not supported
*/
readAndWriteModeOptions?: ReadAndWriteModeOptions;
enableAdd?: boolean;
@@ -219,11 +219,11 @@ export const DatabaseTableStructure = forwardRef<
};
const verifyAllBeforeSave = async (): Promise<boolean> => {
// 触发 tableFields 校验
// Trigger tableFields validation
const validatedTableFieldsList = validateFields(tableFieldsList, 'save');
setTableFieldsList(validatedTableFieldsList);
// 触发并校验 tableBasicInfo
// Trigger and validate tableBasicInfo
try {
// @ts-expect-error -- linter-disable-autofix
await tableBasicInfoFormRef.current.formApi.validate(['name']);
@@ -231,7 +231,7 @@ export const DatabaseTableStructure = forwardRef<
return false;
}
// 校验 tableFields
// Validation tableFields
if (
validatedTableFieldsList.find(i =>
Object.keys(i.errorMapper || {}).find(
@@ -242,7 +242,7 @@ export const DatabaseTableStructure = forwardRef<
return false;
}
// 校验 tableFields 是否为空
// Verify that tableFields is empty
if (isEmptyList) {
return false;
}
@@ -354,7 +354,7 @@ export const DatabaseTableStructure = forwardRef<
}
};
// 初始化 ref 属性
// Initialize ref attribute
useImperativeHandle<DatabaseTableStructureRef, DatabaseTableStructureRef>(
ref,
() => ({
@@ -374,7 +374,7 @@ export const DatabaseTableStructure = forwardRef<
[isReadonly, tableFieldsList, tableBasicInfoFormRef],
);
// 自定义表单项组件
// Custom form item component
const FormInputInner: FC<any> = useCallback(
p => {
const { onChange, value, onBlur, validateStatus } = p;
@@ -413,7 +413,7 @@ export const DatabaseTableStructure = forwardRef<
[],
);
// 校验是否 disable 下一步按钮
// Verify that the Next button is disabled
useComputingEnableGoToNextStep?.(tableFieldsList);
const dataSource = enableAdd

View File

@@ -103,7 +103,7 @@ export const DATABASE_CONTENT_CHECK_ERROR_CODE = 708024072;
export const DATABASE_CONTENT_CHECK_ERROR_CODE_NEW = 708334072;
/**
* 内置字段: uuid
* Built-in field: uuid
*/
export const USER_ID_FIELD: TableMemoryItem = {
name: 'uuid',
@@ -115,7 +115,7 @@ export const USER_ID_FIELD: TableMemoryItem = {
};
/**
* 内置字段: id
* Built-in field: id
*/
export const ID_FIELD: TableMemoryItem = {
name: 'id',
@@ -127,6 +127,6 @@ export const ID_FIELD: TableMemoryItem = {
};
/**
* 内置系统字段
* Built-in system fields
*/
export const SYSTEM_FIELDS = [USER_ID_FIELD, ID_FIELD];

View File

@@ -28,9 +28,9 @@ export enum CreateType {
custom = 'custom',
template = 'template',
excel = 'excel',
// 推荐建表
// recommended table
recommend = 'recommend',
// 输入自然语言建表
// Enter natural language to build a table
naturalLanguage = 'naturalLanguage',
}

View File

@@ -52,7 +52,7 @@ interface CreateTableModalExtraParams {
creatorId?: string;
}
// RenderGenerate属性类型定义
// RenderGenerate property type definition
export interface RenderGenerateProps {
tableStructureRef: RefObject<DatabaseTableStructureRef>;
onGenerateChange: (tableMemoryList: TableMemoryItem[]) => void;
@@ -181,7 +181,7 @@ export function DatabaseCreateTableModal({
setSaveBtnDisabled(true);
return;
}
// 系统字段不计入字段数量限制
// System fields do not count towards the number of fields limit
if (list.filter(i => !i.isSystemField).length > MAX_COLUMNS) {
setSaveBtnDisabled(true);
return;
@@ -204,8 +204,8 @@ export function DatabaseCreateTableModal({
const onSave: OnSave = async ({ response }) => {
/**
* DatabaseTableStructure 这个组件中,提交已经区分了 edit create 两种状态,
* 并且存在一个onSave的回调因此提交之后的逻辑全部收敛在这里
* In DatabaseTableStructure component, commit already distinguishes between edit and create states,
* And there is an onSave callback, so the logic after commit all converges here
*/
await onSubmit?.(response);
};
@@ -262,7 +262,7 @@ export function DatabaseCreateTableModal({
/>
</div>
</div>
{/* 编辑弹窗出现 Banner 提示 */}
{/* Banner prompt appears in the edit pop-up window */}
{isModify ? (
<DismissibleBanner
type="warning"

View File

@@ -24,7 +24,7 @@ import {
VerifyType,
} from '../../../types/database-field';
// 校验 Table Name Field Name
// Validation Table Name and Field Name
const namingRegexMapper = [
{
type: 1,
@@ -53,7 +53,7 @@ export const validateNaming = (str: string, errList: string[] = []) => {
return list;
};
// 校验 Table Fields
// Validation Table Fields
export const thMapper: MapperItem[] = [
{
label: I18n.t('db_add_table_field_name'),
@@ -124,7 +124,7 @@ export const validateFields = (
const msg = verifyItem.message;
switch (verifyItem.type) {
case VerifyType.Required: {
// 报错出现时机:点击保存按钮时,出现提示。表中某一行填写了数据,但是未填写必填字段时,需要报错
// When the error occurs: When clicking the Save button, a prompt appears. When a row in the table fills in the data, but the required fields are not filled in, an error needs to be reported.
if (
trigger === 'save' &&
!value &&
@@ -135,14 +135,14 @@ export const validateFields = (
) {
listItem.errorMapper[thKey].push(msg);
}
// 报错消失时机:必填输入框输入了内容后,报错立刻消失
// Error reporting and disappearance timing: Required text box After entering the content, the error will disappear immediately
if (trigger === 'change' && value) {
listItem.errorMapper[thKey] = errTarget.filter(i => i !== msg);
}
break;
}
case VerifyType.Unique: {
// 报错出现时机:点击保存按钮时,出现提示。
// When the error occurs: When you click the Save button, a prompt appears.
if (
trigger === 'save' &&
value &&
@@ -150,7 +150,7 @@ export const validateFields = (
) {
listItem.errorMapper[thKey].push(msg);
}
// 报错消失时机:必填输入框输入了内容后,报错立刻消失
// Error reporting and disappearance timing: Required text box After entering the content, the error will disappear immediately
if (
trigger === 'change' &&
value &&
@@ -161,7 +161,7 @@ export const validateFields = (
break;
}
case VerifyType.Naming: {
// 报错出现时机:命名格式有问题,失去焦点时,立刻校验格式
// Error timing: There is a problem with the naming format. When you lose focus, check the format immediately
if (
trigger === 'save' ||
trigger === 'blur' ||

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable max-lines */
import {
useRef,
@@ -89,19 +89,19 @@ export interface DatabaseTableStructureProps {
loadingTips?: string;
projectID?: string;
/**
* excel: 单用户模式|只读模式
* normal: 单用户模式|只读模式
* expert: 单用户模式|只读模式|多用户模式
* undefined: 不支持读写模式
* Excel: single user mode | read-only mode
* Normal: Single user mode | Read-only mode
* Expert: Single user mode | Read-only mode | Multi-user mode
* Undefined: Read and write modes are not supported
*/
readAndWriteModeOptions?: ReadAndWriteModeOptions;
/** databaseInfo中只显示 Mode 的UI */
/** Only display Mode UI in DatabaseInfo */
onlyShowDatabaseInfoRWMode?: boolean;
enableAdd?: boolean;
isReadonlyMode?: boolean;
maxColumnNum?: number;
/**
* 是否展示基本信息(表名、介绍)
* Whether to display basic information (table name, introduction)
*/
showDatabaseBaseInfo?: boolean;
hiddenTableBorder?: boolean;
@@ -138,7 +138,7 @@ export interface DatabaseTableStructureRef {
export const DatabaseTableStructure = forwardRef<
DatabaseTableStructureRef,
DatabaseTableStructureProps
// eslint-disable-next-line max-lines-per-function, @coze-arch/max-line-per-function, complexity -- 历史文件拷贝
// eslint-disable-next-line max-lines-per-function, @coze-arch/max-line-per-function, complexity -- historical file copy
>((props, ref) => {
const {
data: initialData,
@@ -156,7 +156,7 @@ export const DatabaseTableStructure = forwardRef<
enableAdd = true,
loading = false,
setContentCheckErrorMsg = noop,
// TODO AI generate loading tip 放到 table 里面
// TODO put AI generated loading tips into the table
// loadingTips,
createType,
showDatabaseBaseInfo,
@@ -177,7 +177,7 @@ export const DatabaseTableStructure = forwardRef<
const [isReadonly, { setTrue: enableReadonly, setFalse: disableReadonly }] =
useBoolean(false);
// 系统字段不计入字段数量限制
// System fields do not count towards the number of fields limit
const userFields = tableFieldsList.filter(i => !i.isSystemField);
const isRowMaxLimit = userFields.length >= maxColumnNum;
const isExceedRowMaxLimit = userFields.length > maxColumnNum;
@@ -233,11 +233,11 @@ export const DatabaseTableStructure = forwardRef<
};
const verifyAllBeforeSave = async (): Promise<boolean> => {
// 触发 tableFields 校验
// Trigger tableFields validation
const validatedTableFieldsList = validateFields(tableFieldsList, 'save');
setTableFieldsList(validatedTableFieldsList);
// 触发并校验 tableBasicInfo
// Trigger and validate tableBasicInfo
if (showDatabaseBaseInfo) {
try {
// @ts-expect-error -- linter-disable-autofix
@@ -247,7 +247,7 @@ export const DatabaseTableStructure = forwardRef<
}
}
// 校验 tableFields
// Validation tableFields
if (
validatedTableFieldsList.find(i =>
Object.keys(i.errorMapper || {}).find(
@@ -258,7 +258,7 @@ export const DatabaseTableStructure = forwardRef<
return false;
}
// 校验 tableFields 是否为空
// Verify that tableFields is empty
if (isEmptyList) {
return false;
}
@@ -382,7 +382,7 @@ export const DatabaseTableStructure = forwardRef<
return '';
};
// 初始化 ref 属性
// Initialize ref attribute
useImperativeHandle<DatabaseTableStructureRef, DatabaseTableStructureRef>(
ref,
() => ({
@@ -402,7 +402,7 @@ export const DatabaseTableStructure = forwardRef<
[isReadonly, tableFieldsList, tableBasicInfoFormRef],
);
// 校验是否 disable 下一步按钮
// Verify that the Next button is disabled
useComputingEnableGoToNextStep?.(tableFieldsList, isEmptyList);
const dataSource = enableAdd
@@ -759,7 +759,7 @@ export const DatabaseTableStructure = forwardRef<
}}
wrapperClassName={s['table-structure-table-wrapper']}
/>
{/* 表格为空时,底部的错误提示 */}
{/* Error message at the bottom when the table is empty */}
{isEmptyList && !loading ? (
<div className={s['table-empty-tips']}>
{I18n.t('db_table_save_exception_nofield')}

View File

@@ -54,7 +54,7 @@ export type SLInputProps = ComponentProps<typeof Input> & {
ellipsisPopoverProps?: PopoverProps;
onFocusPopoverProps?: PopoverProps;
tooltipProps?: TooltipProps;
// eslint-disable-next-line @typescript-eslint/naming-convention -- 历史逻辑
// eslint-disable-next-line @typescript-eslint/naming-convention -- historical logic
inputProps?: InputProps & { 'data-dtestid'?: string; 'data-testid'?: string };
errorMsg?: string;
errorMsgFloat?: boolean;
@@ -205,7 +205,7 @@ export const SLInput: React.FC<SLInputProps> = props => {
);
};
// Semi 不导出被 withField 包装的组件的 props 类型(甚至是 any ´_>`
// Semi does not export the props type (or even any ´_>`) of the component wrapped with the withField.
// https://github.com/DouyinFE/semi-design/blob/v2.69.2/packages/semi-ui/form/hoc/withField.tsx#L528
export const FormSLInput: React.FunctionComponent<
CommonFieldProps & Omit<SLInputProps, keyof CommonexcludeType>

View File

@@ -103,7 +103,7 @@ export const DATABASE_CONTENT_CHECK_ERROR_CODE = 708024072;
export const DATABASE_CONTENT_CHECK_ERROR_CODE_NEW = 708334072;
/**
* 内置字段: uuid
* Built-in field: uuid
* bstudio_connector_uid
*/
export const USER_ID_FIELD: TableMemoryItem = {
@@ -116,7 +116,7 @@ export const USER_ID_FIELD: TableMemoryItem = {
};
/**
* 内置字段: id
* Built-in field: id
*/
export const ID_FIELD: TableMemoryItem = {
name: 'id',
@@ -128,7 +128,7 @@ export const ID_FIELD: TableMemoryItem = {
};
/**
* 内置字段: sys_platform
* Built-in fields: sys_platform
* bstudio_connector_id
*/
export const PLATFORM_FIELD: TableMemoryItem = {
@@ -141,7 +141,7 @@ export const PLATFORM_FIELD: TableMemoryItem = {
};
/**
* 内置字段: connector_id
* Built-in fields: connector_id
* bstudio_create_time
*/
export const CREATE_TIME_FIELD: TableMemoryItem = {
@@ -154,7 +154,7 @@ export const CREATE_TIME_FIELD: TableMemoryItem = {
};
/**
* 内置系统字段
* Built-in system fields
*/
export const SYSTEM_FIELDS = [
ID_FIELD,

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { type DatabaseInfo } from '@coze-studio/bot-detail-store';
import {
type AlterBotTableResponse,
@@ -24,17 +24,17 @@ export type OnSave = (params: {
response: InsertBotTableResponse | AlterBotTableResponse;
}) => Promise<void>;
/* eslint-disable @typescript-eslint/naming-convention -- 历史文件拷贝 */
/* eslint-disable @typescript-eslint/naming-convention -- history file copy */
export enum CreateType {
custom = 'custom',
template = 'template',
excel = 'excel',
// 推荐建表
// recommended table
recommend = 'recommend',
// 输入自然语言建表
// Enter natural language to build a table
naturalLanguage = 'naturalLanguage',
}
/* eslint-enable @typescript-eslint/naming-convention -- 历史文件拷贝 */
/* eslint-enable @typescript-eslint/naming-convention -- history file copy */
export interface MapperItem {
label: string;
@@ -43,7 +43,7 @@ export interface MapperItem {
type: VerifyType;
message: string;
}[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 历史文件拷贝
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- historical file copy
defaultValue: any;
require: boolean;
}

View File

@@ -15,13 +15,13 @@
*/
/**
* 数据库详情页 tab
* Database details page tab
*/
export enum DatabaseTabs {
/** 表结构 */
/** table structure */
Structure = 'structure',
/** 测试数据 */
/** test data */
Draft = 'draft',
/** 线上数据 */
/** online data */
Online = 'online',
}

View File

@@ -65,7 +65,7 @@ export function StepConfig({
onTableSheetChange,
}: StepConfigProps) {
const [tableData, setTableData] = useState<TableSettingsData>();
// 默认值使用第1个数据表第1行是表头第2行开始是数据
// Default: Use the first data table, the first row is the header, and the second row starts with data
const [tableSettings, setTableSettings] = useState<TableSettings>({
sheet_id: 0,
header_line_idx: 0,
@@ -86,12 +86,12 @@ export function StepConfig({
onSuccess: res => {
setTableData({
sheet_list: res.sheet_list,
preview_data: {}, // TableSettingBar 并没有读取 preview_data但是在判断它非空
preview_data: {}, // TableSettingBar does not read preview_data, but it is not empty
});
if (res.table_meta) {
setTableStructure(
res.table_meta.map(column => {
// 表结构中有同名字段时,使用原本的类型及描述
// When there are fields with the same name in the table structure, use the original type and description
const matchedField = tableFields.find(
field => field.fieldName === column.column_name,
);

View File

@@ -64,13 +64,13 @@ export function StepProcess({
[fileItem],
);
const [progressProps, setProgressProps] = useState<ProcessProps>({
// 第一行文本(文件名)
// First line of text (file name)
mainText: fileItem.name,
// 第二行文本(文件大小)
// Second line of text (file size)
subText: fileSize,
// hover 时显示的第二行文本,与上面保持一致
// The second line of text displayed when hovering, consistent with the above
tipText: fileSize,
// 进度条百分比,初始 10% 与 @coze-data/knowledge-resource-processor-base/unit-progress 保持一致
// Progress bar percentage, initial 10% is consistent with @code-data/knowledge-resource-processor-base/unit-progress
percent: INIT_PERCENT,
status: ProcessStatus.Processing,
});
@@ -87,7 +87,7 @@ export function StepProcess({
onSuccess: res => {
const { data } = res;
if (data) {
// 有错误信息代表处理失败,展示错误信息,并停止轮询
// If there is an error message, it means the processing failed. Display the error message and stop polling.
if (data.status_descript) {
const msg = data.status_descript;
setProgressProps(props => ({
@@ -102,7 +102,7 @@ export function StepProcess({
...props,
percent: data.progress ?? 0,
}));
// 进度 100 代表处理完成,更新状态并停止轮询
// Progress 100 represents process completion, update status and stop polling
if (data.progress === COMPLETE_PERCENT) {
setProgressProps(props => ({
...props,
@@ -117,7 +117,7 @@ export function StepProcess({
},
);
// 提交任务,并开始轮询进度
// Submit the task and start polling progress
useEffect(() => {
MemoryApi.SubmitDatabaseInsertTask({
database_id: databaseId,

View File

@@ -130,7 +130,7 @@ export const DatabaseDetail = ({
}
};
// 需要一个 store后续改造
// Need a store, follow-up renovation
const isReadOnlyMode = databaseInfo.creator_id !== userId || !!version;
const tableInitData: DatabaseInitInfo = useMemo(
@@ -355,7 +355,7 @@ export const DatabaseDetail = ({
databaseId={databaseId}
tableType={TableType.DraftTable}
tableFields={databaseInfo.field_list || []}
// 测试数据无需控制权限,只要能看到的数据就能修改删除
// Test data does not require control rights, as long as the data can be seen, it can be modified and deleted
isReadonlyMode={false}
enterFrom={enterFrom}
onAfterEditRecords={onAfterEditRecords}

View File

@@ -90,7 +90,7 @@ export interface DatabaseModalProps {
botId: string;
spaceId: string;
readonly: boolean;
// eslint-disable-next-line @typescript-eslint/naming-convention -- 历史逻辑
// eslint-disable-next-line @typescript-eslint/naming-convention -- historical logic
NL2DBInfo: NL2DBInfo | null;
expertModeConfig?: ExpertModeConfig;
onSave?: OnSave;
@@ -138,7 +138,7 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
mapOfShouldHidingDatabaseTableStructureTips,
setMapOfShouldHidingDatabaseTableStructureTips,
] = useLocalStorageState<string | undefined>(
// FIXME: 此属性名意义不明确,处为了兼容,暂不修改此属性名,但后续需要使用更明确的命名
// FIXME: The meaning of this property name is unclear. For compatibility, this property name will not be modified for the time being, but a more explicit naming needs to be used in the future.
'use-local-storage-state-modify-tips',
{
defaultValue: '',
@@ -188,9 +188,9 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
const showEntry = isEntry && !isEdit && !NL2DBInfo;
const shouldShowAIGenerate =
/**
* 1. 入口不展示
* 2. 编辑态不展示
* 3. Excel导入时不展示
* 1. The entrance is not displayed
* 2. Editing status is not displayed
* 3. Excel is not displayed when importing
*/
!showEntry && !isEdit && createType !== CreateType.excel;
@@ -282,8 +282,8 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
})),
});
// data 是初始值,此处需要手动 setState 更新子组件状态
// Modal 已提前关闭,子组件卸载,则 ref 为空,需要加上可选链判断一下
// Data is the initial value, where you need to manually setState to update the subcomponent state
// If Modal has been closed early and the subassembly is uninstalled, the ref is empty. You need to add an optional chain to judge.
tableStructureRef.current?.setTableFieldsList(
// @ts-expect-error -- linter-disable-autofix
res.bot_table_list[0].field_list.map(i => ({
@@ -538,7 +538,7 @@ export const DatabaseModal: React.FC<DatabaseModalProps> = props => {
onDeleteField={list => {
setIsDeletedField(
!database.tableMemoryList.every(i =>
// TODO: 当前field id生成规则有问题故暂时使用 nanoid 替换
// TODO: There is a problem with the current field id generation rule, so the nanoid is temporarily replaced
list.find(j => j.nanoid === i.nanoid),
),
);

View File

@@ -56,7 +56,7 @@ export function formatTableDataRow(
dataRowFieldList.forEach(_key => {
const structItem = structList.find(i => i.fieldName === _key);
if (!structItem) {
// 系统字段
// System field
formattedDataRow[_key] = {
fieldName: _key,
type: FieldItemType.Text,
@@ -157,7 +157,7 @@ function DatabaseTableCell({ value }: DatabaseTableCellProps) {
}
/**
* 获取 Table Field 表头数据
* Get Table Field Header Data
*/
export const getTableColumns = ({
fieldList,
@@ -168,7 +168,7 @@ export const getTableColumns = ({
}: GetTableColumnsParams) => {
const columns: ColumnProps<TableRow>[] = [];
// 系统字段列
// System field column
columns.push(
...SYSTEM_FIELDS.map(item => ({
title: () => (
@@ -193,7 +193,7 @@ export const getTableColumns = ({
})),
);
// 用户字段列
// user field column
columns.push(
...fieldList.map(item => ({
title: () => (
@@ -210,7 +210,7 @@ export const getTableColumns = ({
})),
);
// 操作列
// action column
columns.push({
title: I18n.t('db_table_0126_021'),
width: 100,

View File

@@ -54,7 +54,7 @@
padding-bottom: 0;
}
/** table header样式 **/
/** Table header style **/
.semi-table-thead {
// 拖拽列宽度的图标样式
.semi-table-row {
@@ -90,7 +90,7 @@
}
}
/** table body部分样式 **/
/** Table body part style **/
.semi-table-tbody {
.semi-table-row {
>.semi-table-row-cell {

View File

@@ -153,7 +153,7 @@ export function DatabaseTableData({
database_id: databaseId,
table_type: tableType,
record_data_alter: [values],
// 编辑行时,要带上原始的 connector_id后端需要判断数据是否来自/目标为“豆包”渠道
// When editing the line, bring the original connector_id, and the backend needs to determine whether the data comes from/targets the "bean bag" channel
ori_connector_id: originalConnectorId,
});
}
@@ -230,7 +230,7 @@ export function DatabaseTableData({
},
rowKey: (record: TableRow) => record?.bstudio_id?.value as string,
scroll: {
// 128 = ToolButtonsBar(52) + 表头(28) + Pagination(48)
// 128 = ToolButtonsBar (52) + Header (28) + Pagination (48)
y: tableHeight > 128 ? tableHeight - 128 : 'auto',
},
pagination: {
@@ -259,7 +259,7 @@ export function DatabaseTableData({
),
}}
wrapperClassName={classNames(styles['table-wrapper'], {
// database 数据表格在 Project IDE 中要使用 coz-bg-max 白色背景
// Use coz-bg-max white background for database data tables in Project IDE
[styles['table-wrapper-project']]: enterFrom === 'project',
})}
empty={

View File

@@ -20,13 +20,13 @@ import { CSS } from '@dnd-kit/utilities';
import { useSortable } from '@dnd-kit/sortable';
/**
* 拆分自 packages/data/database-v2/src/components/database-table-data/index.tsx
* 原本实现基本是从 Semi 文档复制过来的排序后的数据也没有提交给服务端PM 似乎也不知道有这个功能,所以 ...
* Split from packages/data/database-v2/src/components/database-table-data/index.tsx
* The original implementation was basically copied from the Semi document, and the sorted data was not submitted to the server level. The PM did not seem to know about this function, so...
* @see
*/
export const SortableRow = (
// https://github.com/DouyinFE/semi-design/blob/v2.69.2/packages/semi-ui/table/Body/BaseRow.tsx#L396
// eslint-disable-next-line @typescript-eslint/naming-convention -- semi 没有导出 table row props 的类型
// eslint-disable-next-line @typescript-eslint/naming-convention -- semi does not export the type of table row props
sortProps: HTMLAttributes<HTMLTableRowElement> & { 'data-row-key': string },
) => {
const {

View File

@@ -17,7 +17,7 @@
import { type TableMemoryItem } from '@coze-studio/bot-detail-store';
import { type FieldItemType } from '@coze-arch/bot-api/memory';
// 期待的数据结构是什么样的?
// What is the expected data structure?
export interface TableRowCommonData {
fieldName: string;
required: boolean;

View File

@@ -30,7 +30,7 @@ import keyExample from '../../assets/key-example.png';
import s from './index.module.less';
function getTableStructureColumns(): ColumnProps<TableMemoryItem>[] {
// 字段表头内容来自 ../database-table-structure/index.tsx:578
// The field header content comes from../database-table-structure/index.tsx: 578
return [
{
title: (
@@ -140,7 +140,7 @@ export function DatabaseTableStructureReadonly({
columns,
dataSource,
scroll: {
// 表头的高度是 40px
// The height of the watch header is 40px.
y: tableHeight > 40 ? tableHeight - 40 : 'auto',
},
}}

View File

@@ -47,23 +47,23 @@ const formatValue = (dValue: string | Date | Date[] | string[] | undefined) => {
try {
if (dValue instanceof Date) {
// 单个Date对象
// Single Date Object
formattedValue = format(dValue, 'yyyy-MM-dd HH:mm:ss');
} else if (Array.isArray(dValue)) {
// Date[] string[]
// Date [] or string []
formattedValue = dValue
.map(item => {
if (item instanceof Date) {
return format(item, 'yyyy-MM-dd HH:mm:ss');
} else if (typeof item === 'string') {
// 假设字符串为有效日期格式
// Assume string is in valid date format
return format(new Date(item), 'yyyy-MM-dd HH:mm:ss');
}
return '';
})
.join(', '); // 使用逗号分隔不同的日期
.join(', '); // Use commas to separate different dates
} else if (typeof dValue === 'string') {
// 单个字符串
// Single string
formattedValue = format(new Date(dValue), 'yyyy-MM-dd HH:mm:ss');
}
} catch {

View File

@@ -56,7 +56,7 @@ const FormDatePicker = withField(
<DatePicker
{...props}
type="dateTime"
// Semi DatePicker 使用 date-fns 格式
// Semi DatePicker uses date-fns format
format="yyyy-MM-dd HH:mm:ss"
onChange={date =>
props.onChange?.(dayjs(date as Date).format('YYYY-MM-DD HH:mm:ss'))
@@ -149,7 +149,7 @@ export function RowEditModal({
>
<Form<Record<string, unknown>> allowEmpty ref={formRef}>
{tableType === TableType.OnlineTable ? (
// 只有“线上数据”支持修改“渠道”字段
// Only "Online Data" supports modifying the "Channel" field
<FormSelect
{...getSystemFieldCommonProps(PLATFORM_FIELD)}
optionList={connectorOptions}
@@ -274,7 +274,7 @@ function getUserFieldCommonProps(field: TableFieldData): FieldCommonProps {
required={field.required}
/>
),
// DatabaseFieldTitle 中已经显示 required * 符号
// The required * symbol is already displayed in DatabaseFieldTitle
required: false,
},
};

View File

@@ -156,7 +156,7 @@ export const useSelectDatabaseModal = ({
enterFrom === 'bot' ? TableType.DraftTable : TableType.OnlineTable,
table_name: key_word,
creator_id: filter_creator === 'all' ? '0' : filter_creator,
// 暂时不做分页加载
// Do not do paging loading for the time being
limit: 50,
offset: page_offset,
order_by: [
@@ -191,7 +191,7 @@ export const useSelectDatabaseModal = ({
},
);
// onScroll 判断 scrollRef 是否触底
// onScroll Determines whether scrollRef bottoms out
const handleScroll = () => {
if (!scrollRef.current) {
return;
@@ -364,7 +364,7 @@ export const useSelectDatabaseModal = ({
ref={scrollRef}
onScroll={handleScroll}
>
{/* FIXME: 这里需要根据实际做渲染 */}
{/* FIXME: This needs to be rendered according to the actual situation. */}
{data?.list.map((item, index) => (
<DatabaseListItem
icon={item.icon_url}

View File

@@ -21,25 +21,25 @@ import { type DynamicParams } from '@coze-arch/bot-typings/teamspace';
import { MemoryApi } from '@coze-arch/bot-api';
/**
* 已经迁移的旧渠道 id 到新渠道 id 的映射
* key(旧) -> value(新)
* Mapping of migrated old channel IDs to new channel IDs
* Key (old) - > value (new)
*/
const migratedConnectorIds: Record<string, string | undefined> = {
// 微信服务号
// WeChat service account
'10000114': '10000120',
// 微信订阅号
// WeChat subscribed account
'10000115': '10000121',
};
export interface ConnectorOption {
label: string;
value: string;
/** 该渠道 id 是否已经迁移 */
/** Has the channel ID been migrated? */
migrated?: boolean;
}
export interface UseConnectorOptionsParams {
/** 是否包含已迁移的旧渠道,默认不包含 */
/** Whether to include the old channels that have been migrated, not by default */
includeMigrated?: boolean;
}
@@ -47,7 +47,7 @@ export function useConnectorOptions({
includeMigrated = false,
}: UseConnectorOptionsParams = {}): ConnectorOption[] {
const { space_id } = useParams<DynamicParams>();
// 资源库 workflow 页面的 url 上没有 space_id 参数,需要从 searchParams 中获取
// There is no space_id parameter on the url of the library workflow page, you need to get it from searchParams
const [searchParams] = useSearchParams();
const spaceId = space_id ?? searchParams.get('space_id') ?? '';
const { data } = useRequest(
@@ -73,7 +73,7 @@ export function useConnectorOptions({
},
{
refreshDeps: [spaceId],
// 设置缓存 key, 防止重复请求
// Set cache key to prevent duplicate requests
cacheKey: `db_connector_name_${spaceId}`,
},
);

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useEffect, useState } from 'react';
import { DataNamespace, dataReporter } from '@coze-data/reporter';
@@ -55,7 +55,7 @@ export const useExpertModeConfig = (params: {
res = await MemoryApi.GetModeConfig({
bot_id: botId,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 复制历史文件
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Copy history file
} catch (error: any) {
dataReporter.errorEvent(DataNamespace.DATABASE, {
eventName: REPORT_EVENTS.DatabaseGetExpertConfig,

View File

@@ -19,7 +19,7 @@ import { useRef } from 'react';
import { type TableData } from '../components/database-table-data/type';
export const useGetTableInstantaneousData = (tableData: TableData) => {
// 缓存 Data 数据,用于在事件中获取数据
// Cache data for fetching data in events
const dataRef = useRef<TableData>(tableData);
dataRef.current = tableData;

View File

@@ -85,7 +85,7 @@ export const useLibraryCreateDatabaseModal = ({
const { id, draft_id } = createRes.database_info ?? {};
if (id && draft_id) {
if (onFinish) {
// bot 绑定数据库需要 draft_id ,其他场景一般只需要用 id
// Bot binding database needs draft_id, other scenarios generally only need to use id
onFinish(id, draft_id);
return;
} else {

View File

@@ -25,7 +25,7 @@ export const getDefaultValue = (type: FieldItemType) => {
} else if (type === FieldItemType.Text) {
return '';
} else if (type === FieldItemType.Date) {
// TODO: @liushuoyan 这里可能存在时区的问题,联调的时候请注意
// TODO: @liushuoyan There may be a time zone problem here, please pay attention when joint debugging
return format(new Date(), 'yyyy-MM-dd HH:mm:ss');
} else {
return undefined;

View File

@@ -13,6 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 符合预期
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- as expected
export const isEmptyValue = (value: any) => value === '' || value === undefined;

View File

@@ -13,17 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// int64 的最大值和最小值
// The maximum and minimum values of int64
export const INT64_MAX = BigInt('9223372036854775807');
export const INT64_MIN = BigInt('-9223372036854775808');
/**
* 检查数值是否在 int64 范围内
* @param value - 要检查的字符串
* Check if the value is in the int64 range
* @Param value - string to check
* @returns
* - 如果是有效的 int64 范围内的整数,返回 true
* - 如果无效或超出范围,返回 false
* If it is a valid integer in the int64 range, return true.
* If invalid or out of range, return false
*/
export const isInInt64Range = (value: string): boolean => {
if (
@@ -41,7 +41,7 @@ export const isInInt64Range = (value: string): boolean => {
return false;
}
return true;
// eslint-disable-next-line @coze-arch/use-error-in-catch -- 正常业务逻辑
// eslint-disable-next-line @coze-arch/use-error-in-catch -- normal business logic
} catch {
return false;
}

View File

@@ -21,14 +21,14 @@ import { type TableRow } from '../components/database-table-data/type';
const FIXED_COLUMN_WIDTH = 60;
const MIN_COLUMN_WIDTH = 100;
/**
* 表格列伸缩时的回调,用于限制伸缩边界
* Callbacks when table columns are scaled to limit the scaling boundaries
* @param column
* @returns
*/
export const resizeFn = (
column: ColumnProps<TableRow>,
): ColumnProps<TableRow> => {
// 多选框/序号列不可伸缩
// The checkbox/serial number column is not retractable
if (column.key === 'column-selection') {
return {
...column,
@@ -36,14 +36,14 @@ export const resizeFn = (
width: FIXED_COLUMN_WIDTH,
};
}
// 固定列(操作列)不可伸缩
// Fixed columns (action columns) are not scalable
if (column.fixed) {
return {
...column,
resizable: false,
};
}
// 其余字段列可伸缩,但需要限制最小宽度
// The remaining field columns are scalable, but the minimum width needs to be limited
return {
...column,
width:

View File

@@ -129,7 +129,7 @@ describe('MultiTable', () => {
/>,
);
// 第二个数据库应该被激活
// The second database should be activated
const tab = screen.getByText('Database 2').closest('div');
expect(tab).toHaveClass(s['tab-bar-item']);
});
@@ -137,10 +137,10 @@ describe('MultiTable', () => {
it('should handle database switching', () => {
render(<MultiTable botID="test-bot" databaseList={mockDatabaseList} />);
// 点击第二个数据库标签
// Click on the second database tab
fireEvent.click(screen.getByText('Database 2'));
// 验证切换是否成功
// Verify that the switch was successful
const tab = screen.getByText('Database 2').closest('div');
expect(tab).toHaveClass(s['tab-bar-item']);
});

View File

@@ -60,7 +60,7 @@ export const getColumns = (
const dataWidth = width ? width : initWidth;
const isLast = index === _list.length - 1;
switch (i.type) {
// 文本
// Text
case FieldItemType.Text:
res = {
// @ts-expect-error -- linter-disable-autofix
@@ -71,7 +71,7 @@ export const getColumns = (
width: isLast ? undefined : dataWidth,
};
break;
// 整数
// integer
case FieldItemType.Number:
res = {
// @ts-expect-error -- linter-disable-autofix
@@ -82,7 +82,7 @@ export const getColumns = (
width: isLast ? undefined : dataWidth,
};
break;
// 数字
// number
case FieldItemType.Float:
res = {
// @ts-expect-error -- linter-disable-autofix
@@ -93,7 +93,7 @@ export const getColumns = (
width: isLast ? undefined : dataWidth,
};
break;
// 时间
// time
case FieldItemType.Date:
res = {
// @ts-expect-error -- linter-disable-autofix
@@ -104,7 +104,7 @@ export const getColumns = (
width: isLast ? undefined : dataWidth,
};
break;
// 布尔
// Boolean
case FieldItemType.Boolean:
res = {
// @ts-expect-error -- linter-disable-autofix

View File

@@ -116,7 +116,7 @@ export const DataTable = forwardRef<DataTableRef, DatabaseTable>(
const resizeList = columns.list.filter(
item => item.dataIndex !== col.dataIndex,
);
// 计算拖拽列能拖拽的最小宽度,小于最小宽度则返回最小宽度
// Calculate the minimum width that the drag column can drag, and return the minimum width if it is less than the minimum width
const widthCount = resizeList.reduce(
(prev, cur) => Number(prev) + Number(cur.width),
0,

View File

@@ -75,7 +75,7 @@ const ResetBtn: React.FC<DatabaseTable> = props => {
close();
},
className: s['reset-confirm-modal'],
// ToolPane z-index 1000,所以此处需要加 1001 z-index,避免被 database 数据面板遮住
// ToolPane's z-index is 1000, so you need to add 1001 z-index here to avoid being obscured by the database data panel
zIndex: 1001,
});

View File

@@ -14,5 +14,5 @@
* limitations under the License.
*/
// Coze的渠道id在某些场景下需要写死传递给后端
// Coze's channel ID, in some scenarios, needs to be written dead and passed to the backend
export const COZE_CONNECTOR_ID = '10000010';

View File

@@ -53,7 +53,7 @@ export const useFileList = (
};
try {
const res = await fileboxApi.FileList({
// 前端从 1 开始计数,方便 Math.ceil 计算,传给后端时手动减 1
// The front end starts counting from 1, which is convenient for Math.ceil calculation. When passing to the back end, manually subtract 1.
page_num: page - 1,
page_size: pageSize,
bid: botId,

View File

@@ -61,15 +61,15 @@ export const useUploadModal = (params: UseUploadModalParams) => {
unitList.some(
i =>
/**
* 1. 未上传成功的
* 2. 校验失败的
* 3. 名字为空的(名字为空暂不影响 validateMessage所以需要单独判断
* 1. Unsuccessful upload
* 2. Validation failed
* 3. The name is empty (the name is empty will not affect the validateMessage for the time being, so it needs to be judged separately)
*/
i.status !== UploadStatus.SUCCESS || i.validateMessage || !i.name,
);
const handleUnitListUpdate = (data: UnitItem[]) => {
// 防止重命名后再上传被覆盖
// Prevent renaming and then uploading from being overwritten.
const newData = data.map(i => {
let resultName = i.name;
unitList.forEach(u => {

View File

@@ -42,7 +42,7 @@ export const ImageList: FC<ImageListProps> = props => {
<CardGroup spacing={12} className={s['card-group']}>
{images?.map(i => {
const {
// MainURL 加载太慢了,列表中使用 ThumbnailURL 进行缩略图展示
// MainURL is too slow to load, the list uses ThumbnailURL for thumbnail display
ThumbnailURL: url,
MainURL: previewUrl,
FileID: id,
@@ -68,7 +68,7 @@ export const ImageList: FC<ImageListProps> = props => {
cover={
<Image
src={url}
// 仅设置宽度,高度会按图片原比例自动缩放
// Only set the width, and the height will be automatically scaled according to the original scale of the picture.
width={209}
className={s['card-cover']}
preview={{

View File

@@ -52,12 +52,12 @@ export const FileBoxList: FC<FileBoxListProps> = props => {
},
);
// 手动控制 data 加载时机
// Manually control data loading timing
useEffect(() => {
if (botId) {
reloadAsync();
// 重新加载时,回到最顶部
// When reloading, return to the top
ref.current?.scrollTo?.({
top: 0,
behavior: 'smooth',
@@ -85,11 +85,11 @@ export const FileBoxList: FC<FileBoxListProps> = props => {
return (
<div className={s['filebox-list']}>
<div className={s.header}>
{/* 切换图片/文档 */}
{/* Switch images/documents */}
<FileBoxFilter />
<Space spacing={12}>
{/* 搜索框 */}
{/* search box */}
<UISearch
placeholder={I18n.t(
'card_builder_dataEditor_get_errormsg_please_enter',
@@ -97,7 +97,7 @@ export const FileBoxList: FC<FileBoxListProps> = props => {
onChange={debounceSearch}
/>
{/* 上传按钮 */}
{/* Upload button */}
<UIButton type="primary" theme="solid" onClick={open}>
{I18n.t('datasets_createFileModel_step2')}
</UIButton>
@@ -110,7 +110,7 @@ export const FileBoxList: FC<FileBoxListProps> = props => {
childStyle={{
height: '100%',
width: '100%',
// 防止切换 fileListType 时 items 数量不一致,导致 loading 闪烁
// Prevent inconsistent number of items when switching fileListType, causing loading to flicker
display: loading ? 'none' : 'block',
}}
>

View File

@@ -93,7 +93,7 @@ export const useMemoryDebugModal = ({
</span>
}
>
{/* 给 children 传递 onCancel 参数,用于从内部关闭弹窗 */}
{/* Pass the onCancel parameter to children to close the pop-up window from within */}
{React.isValidElement(item.component)
? React.cloneElement(item.component, {
onCancel: close,

View File

@@ -252,7 +252,7 @@ export const VariableDebug = () => {
{i.keyword}
</Paragraph>
</div>
{/* 是否为系统字段 */}
{/* Is it a system field? */}
{i.is_system ? (
<Paragraph
data-dtestid={`${BotE2e.BotVariableDebugModalValueInput}.${i.keyword}`}

View File

@@ -21,7 +21,7 @@ import { sendTeaEvent, EVENT_NAMES } from '@coze-arch/bot-tea';
export const useSendTeaEventForMemoryDebug = (p: { isStore: boolean }) => {
const { isStore = false } = p;
// TODO@XML 看起来在商店也用到了,先不改
// TODO@XML seems to be used in the store too, don't change it
const params = useParams<DynamicParams>();
const { bot_id = '', product_id = '' } = params;

View File

@@ -16,7 +16,7 @@
export const filterUnnecessaryContentFromSlice = (slice: string): string => {
let res = slice;
// 过滤img 标签
// Filter img tags
res = res.replaceAll(/<(\n)*img((?!(<(\n)*img))(.|\n))*>/g, '');
return res;
};

View File

@@ -104,7 +104,7 @@ function RecallSlice(props: { llmOutput: LLMOutput; index: number }) {
[meta.document],
);
// 后面改成 staring
// Change the back to staring.
const sliceTag = `Recall slice ${index + 1}`;
const filteredSlice = filterUnnecessaryContentFromSlice(slice);

View File

@@ -39,7 +39,7 @@ export const ParamName = (props: {
const { groups } = useVariableContext();
const formApi = useFormApi();
// 使用 ref 缓存最后一次的有效值, Tree组件隐藏的时候会销毁组件Form表单的Field字段会删除所以需要缓存
// Use ref to cache the last valid value. When the Tree component is hidden, the component will be destroyed, and the Field field of the Form will be deleted, so it needs to be cached.
useCacheField(data);
return (

View File

@@ -25,24 +25,24 @@ export const requiredRules = {
};
/**
* 检查变量名称是否重复
* 1、检查变量名称在同组&同层级是否重复
* 2、检查变量名称在不同组的Root节点名称是否重复
* Check if variable names are duplicate
* 1. Check whether the variable names are duplicated in the same group & level
* 2. Check whether the variable names are duplicated in the root node names of different groups
*/
export const duplicateRules = {
validate: (value: Variable, groups: VariableGroup[]): boolean => {
if (!value.name) {
return true;
} // 如果名称为空则跳过检查
} // Skip check if name is empty
// 1. 检查同组同层级是否重复
// 1. Check whether the same group and level are duplicated
const currentGroup = groups.find(group => group.groupId === value.groupId);
if (!currentGroup) {
return true;
}
// 获取当前节点所在的所有同层级节点(包括嵌套在其他节点children中的)
// Get all nodes at the same level as the current node (including those nested in other node children)
const findSiblings = (
variables: Variable[],
targetParentId: string | null,
@@ -50,14 +50,14 @@ export const duplicateRules = {
let result: Variable[] = [];
for (const variable of variables) {
// 如果当前变量的parentId与目标parentId相同且不是自身则添加到结果中
// If the parentId of the current variable is the same as the target parentId and is not itself, it is added to the result
if (
variable.parentId === targetParentId &&
variable.variableId !== value.variableId
) {
result.push(variable);
}
// 递归检查children
// Check children recursively
if (variable.children?.length) {
result = result.concat(
findSiblings(variable.children, targetParentId),
@@ -74,8 +74,8 @@ export const duplicateRules = {
return false;
}
// 2. 检查是否与其他组的根节点重名
// 只有当前节点是根节点时才需要检查
// 2. Check if it has the same name as the root node of other groups
// Check only if the current node is the root node
if (!value.parentId) {
const otherGroupsRootNodes = groups
.filter(group => group.groupId !== value.groupId)

View File

@@ -49,28 +49,28 @@ export default function ParamOperator({
}: ParamOperatorProps) {
const isLimited = level >= 3;
// 是否可以添加子项
// Is it possible to add children?
const canAddChild = !readonly && ObjectLikeTypes.includes(data.type);
// 子项按钮是否可用
// Is the child button available?
const enableAddChildButton =
!readonly && hasObjectLike && canAddChild && needRenderAppendChild;
// 是否显示删除按钮
// Whether to display the delete button
const showDeleteButton = !readonly;
// 是否显示开启/关闭按钮
// Whether to display the on/off button
const enabledSwitch = level === 0;
const { variablePageCanEdit } = useVariableContext();
return (
<div className="flex items-center h-[24px] flex-shrink-0 justify-start gap-x-2 w-[130px]">
{/* 开启/关闭 */}
{/* Open/close */}
<Switch
size="small"
disabled={!variablePageCanEdit || !enabledSwitch}
checked={data.enabled}
onChange={onEnabledChange}
/>
{/* 添加子项 */}
{/* Add child item */}
{needRenderAppendChild ? (
<div className="flex items-center justify-center">
<Tooltip
@@ -89,7 +89,7 @@ export default function ParamOperator({
</Tooltip>
</div>
) : null}
{/* 删除 */}
{/* delete */}
<IconButton
data-testid={VariableE2e.VariableTreeDeleteBtn}
color="secondary"

View File

@@ -33,15 +33,15 @@ export const generateVariableOption = (
});
export interface VariableTypeOption {
// 类型的值, 非叶子节点时可能为空
// Value of type, possibly empty when not a leaf node
value: number | string;
// 选项的展示名称
// The display name of the option
label: ReactNode;
// 回显的展示名称
// Echoed display name
display?: string;
// 类型是否禁用
// Is the type disabled?
disabled?: boolean;
// 子类型
// subtype
children?: VariableTypeOption[];
}
@@ -72,7 +72,7 @@ const filterTypes = (
}
/**
* 1. 到达层级限制时禁用 ObjectLike 类型,避免嵌套过深
* 1. Disable the ObjectLike type when reaching the level limit to avoid too deep nesting
*/
const disabled = Boolean(
level &&
@@ -98,7 +98,7 @@ export const getVariableTypeList = options =>
filterTypes(allVariableTypeList, options);
/**
* 获取类型在选项列表中的路径,作为 cascader value
* Get the path of the type in the options list as the cascader value
*/
export const getCascaderVal = (
originalVal: ViewVariableType,

View File

@@ -24,7 +24,7 @@ export enum ChangeMode {
Replace,
}
// JSON类型
// JSON type
// eslint-disable-next-line @typescript-eslint/naming-convention
export const JSONLikeTypes = [
ViewVariableType.Object,

View File

@@ -63,20 +63,20 @@ export default function CustomTreeNode(props: CustomTreeNodeProps) {
onCollapse,
validateExistKeyword = false,
} = props;
// 当前值
// current value
const value = cloneDeep(data) as Variable;
const treeNodeRef = useRef<HTMLDivElement>(null);
// 删除时
// When deleting
const onDelete = () => {
onChange(ChangeMode.Delete, value);
};
// 新增子项时
// When adding a child
const onAppend = () => {
onChange(ChangeMode.Append, value);
};
// 类型切换时
// When switching types
const onSelectChange = (
val?: string | number | Array<unknown> | Record<string, unknown>,
) => {
@@ -86,7 +86,7 @@ export default function CustomTreeNode(props: CustomTreeNodeProps) {
if (!isNumber(val)) {
return;
}
// 清除默认值
// Clear default
value.defaultValue = '';
value.children = [];
onChange(ChangeMode.Update, { ...value, type: val as ViewVariableType });

View File

@@ -143,7 +143,7 @@ export const JSONEditor: FC<JSONEditorProps> = props => {
const isValid = useMemo(() => validate(value), [value]);
// 同步 value schema
// Synchronizing values and schemas
useEffect(() => {
const _schema = convert(value);
setSchema(_schema);
@@ -185,7 +185,7 @@ export const JSONEditor: FC<JSONEditorProps> = props => {
key={id}
value={value}
defaultLanguage="json"
/** 通过 css 样式覆盖 icube-dark 主题 */
/** Override icube-dark theme with css style */
className={lightStyles.light}
options={{
fontSize: 13,

View File

@@ -47,19 +47,19 @@ export const JSONImport: FC<JSONImportProps> = props => {
const [jsonString, setJsonString] = useState('');
const handleImport = (data: SchemaNode[]) => {
const allowDepth = MAX_LEVEL; // 最大深度限制
const allowNameLength = MAX_NAME_LENGTH; // 名称长度限制
const maxVariableCount = MAX_JSON_VARIABLE_COUNT; // 最大变量数量限制
const allowDepth = MAX_LEVEL; // Maximum depth limit
const allowNameLength = MAX_NAME_LENGTH; // Name length limit
const maxVariableCount = MAX_JSON_VARIABLE_COUNT; // Maximum number of variables limit
const variables = exportVariableService(
data,
{
groupId: treeData.groupId,
channel: treeData.channel,
},
treeData, // 传入原始变量以保持variableId
treeData, // Pass in the original variable to maintain the variableId.
);
// 裁切非法数据
// Crop illegal data
const dataCutoff = cutOffInvalidData({
data: variables,
allowDepth,
@@ -67,12 +67,12 @@ export const JSONImport: FC<JSONImportProps> = props => {
maxVariableCount,
});
// 先深拷贝原始数据
// First deep copy the original data source
const clonedTreeData = cloneDeep(treeData);
// 合并新旧数据
// Merge old and new data
const mergedData = merge(clonedTreeData, dataCutoff[0]);
// 更新数据
// update data
return onOk(mergedData);
};

View File

@@ -65,14 +65,14 @@ export const getEditorViewVariableJson = (treeData: TreeNodeCustomData) => {
);
}
// 如果没有name,返回空对象
// If there is no name, return an empty object
if (!name) {
return '{}';
}
const isArray = isArrayType(type);
// 递归处理children
// Recursive processing of children
const processChildren = (
nodes?: TreeNodeCustomData[],
parentType?: ViewVariableType,
@@ -87,7 +87,7 @@ export const getEditorViewVariableJson = (treeData: TreeNodeCustomData) => {
return [];
}
// 如果是数组类型,根据第一个子元素的类型生成默认值
// If it is an array type, generate a default value based on the type of the first child element
const result = {};
if (firstChild.children && firstChild.children.length > 0) {
result[firstChild.name] = processChildren(
@@ -117,7 +117,7 @@ export const getEditorViewVariableJson = (treeData: TreeNodeCustomData) => {
);
};
// 生成最终的JSON结构
// Generate the final JSON structure
const result = {
[name]: processChildren(children),
};

View File

@@ -23,10 +23,10 @@ import { type Variable } from '@/store';
import { type SchemaNode } from '../../../json-editor/service/convert-schema-service';
/**
* 将转换后的数据转换为Variable
* @param data 转换后的数据
* @param baseInfo 基础信息
* @param originalVariable 原始变量,用于保持variableId
* Converting Converted Data to Variables
* @param data converted data
* @param baseInfo
* @param originalVariable to hold variableId
* @returns Variable[]
*/
export const exportVariableService = (
@@ -44,7 +44,7 @@ export const exportVariableService = (
parentId = '',
originalNode?: Variable,
): Variable => {
// 使用store中的createVariable方法创建基础变量
// Create the underlying variable using the createVariable method in the store
const baseVariable = store.createVariable({
variableType: node.type as ViewVariableType,
groupId: baseInfo.groupId,
@@ -52,17 +52,17 @@ export const exportVariableService = (
channel: baseInfo.channel,
});
// 如果存在原始节点,保持其variableId
// If the original node exists, keep its variableId.
if (originalNode) {
baseVariable.variableId = originalNode.variableId;
baseVariable.description = originalNode.description;
}
// 更新变量的基本信息
// Update basic information about variables
baseVariable.name = node.name;
baseVariable.defaultValue = node.defaultValue;
// 递归处理子节点,尝试匹配原始子节点
// Recursively process the sub-node and try to match the original sub-node.
if (node.children?.length) {
baseVariable.children = node.children.map((child, index) => {
const originalChild = originalNode?.children?.[index];
@@ -75,7 +75,7 @@ export const exportVariableService = (
const variables = data.map(node => convertNode(node, '', originalVariable));
// 使用store中的updateMeta方法更新meta信息
// Update meta information using the updateMeta method in the store
store.updateMeta({ variables });
return variables;

View File

@@ -19,7 +19,7 @@ import { nanoid } from 'nanoid';
import type { TreeNodeCustomData } from '../../../type';
import { traverse, type TraverseContext } from './traverse';
/** 计算路径 */
/** Compute Path */
const getTreePath = (context: TraverseContext): string => {
const parents = context
.getParents()
@@ -32,14 +32,14 @@ const getTreePath = (context: TraverseContext): string => {
return parents.map(node => node.value.name).join('/');
};
/** 新旧数据保留 key 防止变量系统引用失效 */
/** Old and new data keep keys to prevent variable system references from invalidating */
export const mergeData = (params: {
newData: TreeNodeCustomData;
oldData: TreeNodeCustomData;
}): TreeNodeCustomData => {
const { newData, oldData } = params;
// 计算旧数据中路径与key的映射
// Compute the mapping of paths and keys in old data
const treeDataPathKeyMap = new Map<
string,
{
@@ -60,7 +60,7 @@ export const mergeData = (params: {
});
});
// 新数据复用旧数据的key失败则重新生成
// The new data reuses the key of the old data, and if it fails, it is regenerated.
const newDataWithKey = traverse(newData, context => {
if (
typeof context.node.value !== 'object' ||

View File

@@ -37,9 +37,9 @@ export interface TraverseContext {
export type TraverseHandler = (context: TraverseContext) => void;
/**
* 深度遍历对象,对每个值做处理
* @param value 遍历对象
* @param handle 处理函数
* Traverse the object in depth, processing each value
* @param value over object
* @param handling function
*/
export const traverse = <T extends TraverseValue = TraverseValue>(
value: T,
@@ -56,9 +56,9 @@ export const traverse = <T extends TraverseValue = TraverseValue>(
namespace TraverseUtils {
/**
* 深度遍历对象,对每个值做处理
* @param node 遍历节点
* @param handle 处理函数
* Traverse the object in depth, processing each value
* @param node traverse node
* @param handling function
*/
export const traverseNodes = (
node: TraverseNode,
@@ -66,11 +66,11 @@ namespace TraverseUtils {
): void => {
const { value } = node;
if (!value) {
// 异常处理
// exception handling
return;
}
if (Object.prototype.toString.call(value) === '[object Object]') {
// 对象,遍历对象的每个属性
// Object, iterate through each property of the object
Object.entries(value).forEach(([key, item]) =>
traverseNodes(
{
@@ -83,8 +83,8 @@ namespace TraverseUtils {
),
);
} else if (Array.isArray(value)) {
// 数组,遍历数组的每个元素
// 从数组的末尾开始遍历,这样即使中途移除了某个元素,也不会影响到未处理的元素的索引
// Array, iterate through each element of the array
// The iteration starts at the end of the array, so that even if an element is removed halfway through, it will not affect the index of the unprocessed element
for (let index = value.length - 1; index >= 0; index--) {
const item: string = value[index];
traverseNodes(
@@ -116,14 +116,14 @@ namespace TraverseUtils {
});
const setValue = (node: TraverseNode, value: unknown) => {
// 设置值函数
// 引用类型,需要借助父元素修改值
// 由于是递归遍历所以需要根据node来判断是给对象的哪个属性赋值还是给数组的哪个元素赋值
// Set Value Function
// Reference type, you need to modify the value with the help of the parent element
// Since it is a recursive traversal, it is necessary to determine which property of the object to assign a value to, or which element of the array to assign a value to, according to node
if (!value || !node) {
return;
}
node.value = value;
// 从上级作用域node中取出containerkeyindex
// Remove container, key, index from upper scope node
const { container, key, index } = node;
if (key && container) {
container[key] = value;
@@ -161,7 +161,7 @@ namespace TraverseUtils {
if (typeof pathItem === 'string') {
const re = /\W/g;
if (re.test(pathItem)) {
// 包含特殊字符
// Contains special characters
return `${stringifyPath}["${pathItem}"]`;
}
return `${stringifyPath}.${pathItem}`;

View File

@@ -16,17 +16,17 @@
/* eslint-disable @typescript-eslint/naming-convention */
/** 每一级树缩进宽度 */
/** Indent width of each level of tree */
export const TreeIndentWidth = 30;
/** 树节点展开收起按钮宽度 */
/** Tree Node Expand Collapse Button Width */
export const TreeCollapseWidth = 24;
// 名称最长50字符
// Name Maximum 50 characters
export const MAX_NAME_LENGTH = 50;
// 最大深度限制
// Maximum depth limit
export const MAX_LEVEL = 3;
// 最大变量数量限制
// Maximum number of variables limit
export const MAX_JSON_VARIABLE_COUNT = 1;
// 最大JSON长度限制30kb
// Maximum JSON length limit 30kb
export const MAX_JSON_LENGTH = 30 * 1024;

View File

@@ -51,7 +51,7 @@ export interface VariableTreeProps {
className?: string;
style?: React.CSSProperties;
showAddButton?: boolean;
/** 默认变量类型 */
/** Default variable type */
defaultVariableType?: ViewVariableType;
defaultCollapse?: boolean;
children?: React.ReactNode;
@@ -172,7 +172,7 @@ export function Index(
});
};
// 树节点的 change 方法
// Tree node change method
const onTreeNodeChange = (mode: ChangeMode, param: TreeNodeCustomData) => {
const findResult = findAndModifyVariable(
groupId,
@@ -194,7 +194,7 @@ export function Index(
});
addChildVariable(childVariable);
// 当前节点下新增节点 展开当前节点
// Add a new node under the current node and expand the current node
if (findResult?.variableId) {
expandTreeNode(findResult.variableId);
}
@@ -231,13 +231,13 @@ export function Index(
}
case ChangeMode.UpdateEnabled: {
findResult.enabled = param.enabled;
// 一键关闭所有子节点
// Close all sub-nodes with one click
traverse<TreeNodeCustomData>(findResult, node => {
if (!param.enabled) {
node.enabled = param.enabled;
}
});
// 子点开启,父节点也开启
// The child point is turned on, and the parent node is also turned on.
if (findResult.parentId && findResult.enabled) {
const parentData = findAndModifyVariable(
groupId,
@@ -284,11 +284,11 @@ export function Index(
<VariableTreeContext.Provider value={{ groupId, variables: flatTreeData }}>
<div
className={classNames(
// 基础容器样式
// basic container style
'relative h-full',
// 交互状态
// interaction state
!readonly && 'cursor-default',
// 自定义类名
// custom class name
className,
)}
style={style}
@@ -301,20 +301,20 @@ export function Index(
}}
disabled={readonly}
className={classNames(
// 基础滚动行为
// basic scrolling behavior
'overflow-x-auto',
// Tree 列表基础样式
// Tree list base style
[
// 列表容器样式
// list container style
'[&_.semi-tree-option-list]:overflow-visible',
'[&_.semi-tree-option-list]:p-0',
'[&_.semi-tree-option-list>div:first-child]:mt-0',
// 选项样式
// Option style
'[&_.semi-tree-option]:!pl-2',
].join(' '),
// 交互状态样式
// interaction state style
readonly
? '[&_.semi-tree-option-list-block_.semi-tree-option:hover]:bg-inherit'
: [
@@ -371,5 +371,5 @@ export function Index(
);
}
// 导出可调用ref方法的组件
// Export components that can call the ref method
export const VariableTree = React.forwardRef(Index);

View File

@@ -22,7 +22,7 @@ import { type ChangeMode } from './components/custom-tree-node/constants';
export interface RecursedParamDefinition {
name?: string;
/** Tree 组件要求每一个节点都有 key而 key 不适合用名称(前后缀)等任何方式赋值,最终确定由接口转换层一次性提供随机 key */
/** The Tree component requires each node to have a key, and the key is not suitable for assignment in any way such as name (before and after). Finally, the interface conversion layer provides a random key at one time. */
fieldRandomKey?: string;
desc?: string;
type: ViewVariableType;
@@ -35,14 +35,14 @@ export interface CustomTreeNodeFuncRef {
data: TreeNodeCustomData;
level: number;
readonly: boolean;
// 通用change方法
// General change method
onChange: (mode: ChangeMode, param: TreeNodeCustomData) => void;
// 定制的类型改变的change方法主要用于自定义render使用
// 添加子项
// Customized type change method, mainly used for custom rendering
// Add child item
onAppend: () => void;
// 删除该项
// Delete this item
onDelete: () => void;
// 类型改变时内部的调用方法主要用于从类Object类型转为其他类型时需要删除所有子项
// The internal call method when the type changes, mainly used to delete all children when converting from the class Object type to other types
onSelectChange: (
val?: string | number | Array<unknown> | Record<string, unknown>,
) => void;

View File

@@ -32,7 +32,7 @@ interface ChildrenFindResult {
export type FindDataResult = RootFindResult | ChildrenFindResult | null;
/**
* 根据target数组找到key在该项的值和位置主要是获取位置方便操作parent的children
* According to the target array, find the value and position of the key in the item, mainly to obtain the position, which is convenient for operating the children of the parent.
*/
export function findCustomTreeNodeDataResult(
target: Array<TreeNodeCustomData>,
@@ -40,7 +40,7 @@ export function findCustomTreeNodeDataResult(
): FindDataResult {
const dataInRoot = target.find(item => item.variableId === variableId);
if (dataInRoot) {
// 如果是根节点
// If it is the root node
return {
isRoot: true,
parentData: null,
@@ -81,7 +81,7 @@ export function findCustomTreeNodeDataResult(
return findDataInChildrenLoop(target);
}
// groupVariableMeta打平为viewVariableTreeNode[]
// Flatten groupVariableMeta to viewVariableTreeNode []
export function flatGroupVariableMeta(
groupVariableMeta: VariableGroup[],
maxDepth = Infinity,

View File

@@ -37,7 +37,7 @@ export const VariablesPage = () => {
type="text"
className={classNames(
'h-full flex flex-col',
// 滚动条位置调整到 tab 内容中
// Scroll bar position is adjusted to tab content
'[&_.semi-tabs-content]:p-0 [&_.semi-tabs-content]:grow [&_.semi-tabs-content]:overflow-hidden',
'[&_.semi-tabs-pane-active]:h-full',
'[&_.semi-tabs-pane-motion-overlay]:h-full [&_.semi-tabs-pane-motion-overlay]:overflow-auto',

View File

@@ -20,7 +20,7 @@ import { Toast } from '@coze-arch/coze-design';
import { useVariableGroupsStore } from '../../store';
/**
* 提交变量
* commit variable
* @param projectID
* @returns
*/
@@ -38,9 +38,9 @@ export async function submit(projectID: string) {
}
/**
* 检查并确保 projectID 是非空字符串
* @param projectID 可能为空的项目ID
* @returns projectID 是否为非空字符串
* Check and make sure projectID is a non-empty string
* @param projectID possibly empty project ID
* @Returns whether projectID is a non-empty string
*/
export const checkProjectID = (projectID: unknown): projectID is string =>
typeof projectID === 'string' && projectID.length > 0;

View File

@@ -85,27 +85,27 @@ export interface VariableGroupsAction {
parentId: string;
channel: VariableChannel;
}) => Variable;
// 更新变量, 根据groupIdvariableId更新
// Update variables, according to groupId and variableId
updateVariable: (newVariable: Variable) => void;
// 更新变量的meta信息
// Update the meta information of the variable
updateMeta: (params: {
variables: Variable[];
level?: number;
parentId?: string;
}) => void;
// 新增根节点变量
// Add root node variable
addRootVariable: (variable: Omit<Variable, 'channel'>) => void;
// 新增子节点变量
// Add sub-node variable
addChildVariable: (variable: Variable) => void;
// 删除变量
// Delete variable
deleteVariable: (variable: Variable) => void;
// 保存后作为历史变量对待
// After being preserved, it is treated as a historical variable
saveHistory: () => void;
// 获取DTO variable
// Get DTO variable
getDtoVariable: (variable: Variable) => ProjectMemory.Variable;
// 获取groups下所有的变量
// Get all the variables under groups
getAllRootVariables: () => Variable[];
// 获取groups下所有的变量
// Get all the variables under groups
getAllVariables: () => Variable[];
transformDto2Vo: (data: ProjectMemory.GroupVariableInfo[]) => VariableGroup[];
initStore: (data: {
@@ -113,7 +113,7 @@ export interface VariableGroupsAction {
canEdit: boolean;
}) => void;
clear: () => void;
// 在变量树中查找变量,并可选地修改或删除
// Locate variables in the variable tree and optionally modify or delete them
findAndModifyVariable: (
groupId: string,
predicate: (variable: Variable) => boolean,
@@ -328,7 +328,7 @@ export const useVariableGroupsStore = create<
},
transformDto2Vo: data => {
const transformedData = getGroupListByDto(data);
// 在数据转换完成后立即更新meta信息
// After the data conversion is completed, update the meta information immediately
transformedData.forEach(group => {
get().updateMeta({ variables: group.varInfoList });
});

View File

@@ -104,7 +104,7 @@ const getSubGroupListByDto = ({
subGroupList?.map(subGroup => ({
...getBaseGroupInfoByDto({
...subGroup,
DefaultChannel: group.DefaultChannel, // 服务端返回的 subGroup 没有 DefaultChannel需要手动设置
DefaultChannel: group.DefaultChannel, // The subGroup returned by the server level has no DefaultChannel and needs to be set manually
}),
groupId,
varInfoList: getGroupVariableListByDto({

View File

@@ -24,7 +24,7 @@ import { type VariableSchemaDTO, VariableTypeDTO } from '../types';
import { type Variable } from '../store';
/**
* 前端变量类型
* Front-end variable type
*/
export enum ViewVariableType {
String = 1,
@@ -32,7 +32,7 @@ export enum ViewVariableType {
Boolean,
Number,
Object = 6,
// 上面是 api 中定义的 InputType。下面是整合后的。从 99 开始,避免和后端定义撞车
// The above is the InputType defined in the api. The following is the integrated one. Start from 99 to avoid collisions with the backend definition.
ArrayString = 99,
ArrayInteger,
ArrayBoolean,
@@ -101,7 +101,7 @@ export const getDtoVariable = (
schema: '',
};
// 处理数组类型
// Working with array types
if (type === VariableTypeDTO.List && arrayItemType) {
if (arrayItemType === VariableTypeDTO.Object) {
schema.schema = {
@@ -118,7 +118,7 @@ export const getDtoVariable = (
}
}
// 处理对象类型
// Handling object types
if (type === VariableTypeDTO.Object) {
schema.schema = viewVariable.children?.map(child => {
const childDTO = getDtoVariable(child);

View File

@@ -34,7 +34,7 @@ export interface VariableSchemaDTO {
}
/**
* 前端变量类型
* Front-end variable type
*/
export enum ViewVariableType {
String = 1,
@@ -42,7 +42,7 @@ export enum ViewVariableType {
Boolean,
Number,
Object = 6,
// 上面是 api 中定义的 InputType。下面是整合后的。从 99 开始,避免和后端定义撞车
// The above is the InputType defined in the api. The following is the integrated one. Start from 99 to avoid collisions with the backend definition.
ArrayString = 99,
ArrayInteger,
ArrayBoolean,
@@ -73,7 +73,7 @@ export const VARIABLE_TYPE_ALIAS_MAP: Record<ViewVariableType, string> = {
// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace ViewVariableType {
/**
* 获取所有变量类型的补集
* Get the complement of all variable types
* @param inputTypes
*/
export function getComplement(inputTypes: ViewVariableType[]) {