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

@@ -48,7 +48,7 @@ const leftPanelResourceType = [
];
/**
* IDE 全局逻辑处理
* IDE global logic processing
*/
export const GlobalHandler = ({
spaceId,
@@ -99,7 +99,7 @@ export const GlobalHandler = ({
useWsListener((props: WsMessageProps) => {
if (
// 即将支持,敬请期待
// Support soon, so stay tuned.
!FLAGS['bot.automation.project_multi_tab'] ||
!leftPanelResourceType.includes(props.bizType)
) {
@@ -114,9 +114,9 @@ export const GlobalHandler = ({
}
const isCreateOperate = props.operateType === MessageOperateType.Create;
// 只是创建 workflow 则刷新资源列表
// Just create workflow and refresh the resource list
const isCreateWorkflow = props?.extra?.methodName === 'CreateWorkflow';
// 封装解封场景需要刷新资源列表
// The encapsulation and unsealing scene needs to refresh the resource list.
const isEncapsulateWorkflow =
props?.extra?.methodName === 'EncapsulateWorkflow';

View File

@@ -48,23 +48,23 @@ export const CloseConfirmModal = () => {
}, []);
useEffect(() => {
// 浏览器维度的 dispose 监听
// Dispose listening in the browser dimension
const chromeDispose = windowService.onBeforeUnload(e => {
// 路由判断
// route judgment
const titles = viewService.getOpenTitles();
const hasUnsaved = titles.some(title => title.saving);
// 当存在未保存的项的时候,需要阻止
// When there are unsaved items, they need to be blocked
if (hasUnsaved) {
// 每次浏览器关闭之前都打开阻止关闭的弹窗
// 兼容不同浏览器的行为
// Open the pop-up window that prevents closing before each browser is closed.
// Compatible with the behavior of different browsers
e.preventDefault();
e.stopPropagation();
e.returnValue = '';
return '';
}
});
// 资源维度的 dispose 监听
// Dispose monitoring of the resource dimension
const resourceDisposable = modalService.onModalVisibleChange(opt => {
const { type, options, visible: vis = true } = opt;
if (type === ModalType.CLOSE_CONFIRM) {

View File

@@ -22,9 +22,9 @@ import { CloseConfirmModal } from './close-confirm-modal';
export const GlobalModals = () => (
// do something
<>
{/* 移动资源库全局弹窗 */}
{/* Mobile resource library global pop-up window */}
<ResourceModal />
{/* 保存中资源关闭弹窗 */}
{/* Saving resource closes pop-up window */}
<CloseConfirmModal />
</>
);

View File

@@ -65,7 +65,7 @@ const PrimarySidebarCore = ({
>
<div className={styles.title}>
{I18n.t('project_resource_sidebar_title')}
{/* 即将支持,敬请期待 */}
{/* Support soon, so stay tuned. */}
{FLAGS['bot.automation.dependency_tree'] ? (
<>
<Button

View File

@@ -97,14 +97,14 @@ export const ResourceList = ({
spaceId,
);
// 存在版本信息,预览状态无法创建资源
// Version information exists, preview status cannot create resource
if (commitVersion) {
canCreate = false;
}
const projectRoles = useProjectRole(projectId);
const hideMoreBtn = useMemo(
// 没有任何权限,或者存在版本信息,需要隐藏操作按钮
// There is no permission, or there is version information, you need to hide the operation button.
() => (projectRoles?.length ?? 0) === 0 || !!commitVersion,
[projectRoles, commitVersion],
);
@@ -135,7 +135,7 @@ export const ResourceList = ({
resourceTree={pluginResource}
canCreate={canCreate}
initLoaded={initLoaded}
// 业务实现
// business realization
onChangeName={changeNamePlugin}
onCustomCreate={createPlugin}
onDelete={deletePlugin}
@@ -170,9 +170,9 @@ export const ResourceList = ({
<div className="flex items-center">
{datasetIconMap[resource.biz_extend?.format_type]}
{/**
* 1: 启用
* 2: 删除,一般没有
* 3: 禁用
* 1: Enable
* 2: Delete, generally not
* 3: Disable
*/}
{resource.biz_res_status === 3 ? (
<span className="ml-[3px]"></span>

View File

@@ -91,7 +91,7 @@ export const ResourceTreeModal = ({
project_version: version ? version : undefined,
},
});
// 兼容先请求后返回场景
// Compatibility Request first and then return to the scene
if (selectedWorkflowId === id) {
setData(res?.data || DEFAULT_DATA);
}

View File

@@ -83,7 +83,7 @@ export const SidebarExpand = () => {
}, [pathname]);
useEffect(() => {
// 侧边栏显隐状态切换时,更新按钮状态
// Update button status when sidebar hidden status switch
const disposable = projectIDEServices.view.onSidebarVisibleChange(vis => {
setVisible(vis);
});
@@ -97,7 +97,7 @@ export const SidebarExpand = () => {
setPopoverVisible(false);
}, []);
// 右边分屏不展示 hover icon
// The split screen on the right does not show the hover icon.
if (direction === 'right') {
return null;
}

View File

@@ -78,7 +78,7 @@ export const FullScreenButton = () => {
[fullScreen, keybinding],
);
// 左边分屏不展示全屏按钮
// The left split screen does not display the full screen button.
if (direction === 'left') {
return null;
}
@@ -91,7 +91,7 @@ export const FullScreenButton = () => {
<Tooltip
content={content}
position="bottom"
// 点击后布局变化tooltip 需要手动控制消失
// After clicking, the layout changes, and the tooltip needs to be manually controlled to disappear.
trigger="custom"
visible={tooltipVisible}
>

View File

@@ -51,7 +51,7 @@ export const ReloadButton = ({ widget }: { widget: ProjectIDEWidget }) => {
<Tooltip
content={content}
position="bottom"
// 点击后布局变化tooltip 需要手动控制消失
// After clicking, the layout changes, and the tooltip needs to be manually controlled to disappear.
trigger="custom"
visible={tooltipVisible}
>

View File

@@ -29,12 +29,12 @@ export const TopBar = () => (
<div className={styles.container}>
<Row className={styles['top-bar']}>
<Col span={8} className={styles['left-col']}>
{/* 返回按钮 */}
{/* Back button */}
<GoBackButton />
{/* 项目标题 */}
{/* Project title */}
<ProjectInfo />
</Col>
{/* 海外版暂时不上 uibuilder 切换功能 */}
{/* The overseas version does not have the uibuilder switching function for the time being. */}
<Col span={8} className={styles['middle-col']}>
{IS_OVERSEA ? null : <ModeTab />}
</Col>

View File

@@ -122,7 +122,7 @@ export const Operators = () => {
>
{I18n.t('project_ide_duplicate')}
</Menu.Item>
{/* Tooltip disableFocusListener 失效,等待后续修复完成 */}
{/* Tooltip disableFocusListener failed, waiting for subsequent repairs to complete */}
{canDelete ? (
<Menu.Item
className="min-w-[190px] h-[32px] rounded-[4px]"
@@ -160,8 +160,8 @@ export const Operators = () => {
};
/**
* 为了给左侧一个容器用于计算整体宽度以便实现宽度不够时自动隐藏付费配置文案
* 同时还要兼顾左侧没有任何内容时自动隐藏 divider 的 first:hidden 写法
* In order to give the left side a container for calculating the overall width, in order to automatically hide the paid configuration copy when the width is not enough
* Also take into account the first: hidden writing method that automatically hides the divider when there is no content on the left
*/
function LeftContent({ children }: PropsWithChildren) {
return IS_OVERSEA ? (

View File

@@ -60,7 +60,7 @@ export function MonetizeConfig() {
},
);
/** loading 时展示为激活态(默认值) */
/** Show as active when loading (default) */
const btnDisplayOn = loading ? true : monetizeConfig.isOn;
return (

View File

@@ -59,7 +59,7 @@ export const ProjectInfo = () => {
const { modalContextHolder, openModal } = useUpdateProjectModal({
onSuccess: () => {
updateProjectInfo();
// 更新 info 信息
// Update info
Toast.success(I18n.t('project_ide_toast_edit_success'));
},
});
@@ -71,13 +71,13 @@ export const ProjectInfo = () => {
);
/**
* 可编辑判断:
* 1. 有编辑权限
* 2. 非预览态
* Editable judgment:
* 1. Have editing permission
* 2. Non-preview state
*/
const canEdit = canAuthEdit && !version;
// 打开 project 编辑弹窗
// Open the project editing pop-up
const handleEditProject = useCallback(() => {
openModal({
initialValue,
@@ -119,7 +119,7 @@ export const ProjectInfo = () => {
>
{projectInfo?.name}
</COZTitle>
{/* 权限判断 */}
{/* permission judgment */}
{canEdit ? (
<IconButton
color="secondary"

View File

@@ -39,8 +39,8 @@ import { ShortcutItem } from './shortcut-item';
import styles from './styles.module.less';
// coze 快捷键需要绑定 starling 文案。没有绑定文案的暂时不展示
// 避免添加快捷键导致新增误展示
// Coze shortcut needs to bind starling copy. If there is no bound copy, it will not be displayed for the time being.
// Avoid adding shortcuts to cause new wrong display
const SHOW_SHORTCUTS: string[] = [
Command.Default.VIEW_CLOSE_ALL_WIDGET,
Command.Default.VIEW_CLOSE_CURRENT_WIDGET,

View File

@@ -62,7 +62,7 @@ export const WidgetTitle: React.FC<TitlePropsType> = ({
/>
);
}
// 没有标题还在骨架屏阶段
// No title, still in the skeleton screen stage.
if (!title) {
return null;
} else if (uiState === 'saving') {

View File

@@ -2,7 +2,7 @@
/* stylelint-disable no-descending-specificity */
/* stylelint-disable selector-class-pattern */
/** 覆盖 flowide 默认样式 **/
/** Override flowide default style **/
body {
overscroll-behavior: none;

View File

@@ -106,7 +106,7 @@ const ProjectIDE: React.FC<ProjectIDEProps> = memo(
[spaceId, projectId, version, navigate],
);
if (!canView) {
// 无法查看跳转到兜底报错页
// Unable to view Jump to the bottom cover error page
throw new Error('can not view');
}

View File

@@ -33,7 +33,7 @@ const ProjectIDEContainer = ({
}) => {
useDestoryProject(projectId);
// 初始化Project角色数据
// Initializing Project Role Data
const isCompleted = useInitProjectRole(spaceId, projectId);
return isCompleted ? (

View File

@@ -15,7 +15,7 @@
*/
/**
* project ide app 的生命周期
* Project ide app life cycle
*/
import { injectable, inject } from 'inversify';
import {
@@ -45,15 +45,15 @@ export class AppContribution implements LifecycleContribution {
onStartedEmitter = new Emitter<void>();
onStarted = this.onStartedEmitter.event;
// ide 初始化完成,可执行业务逻辑的时机
// When IDE initialization is complete and business logic can be executed
onStart() {
// 更新项目信息
// Update project information
this.projectInfoService.init();
// // 打开 url 上携带的资源
// Open the resources carried on the URL
this.openURIResourceService.open();
this.openURIResourceService.listen();
// 订阅变化事件
// Subscribe to change events
this.widgetEventService.listen();
// listen layout store
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -63,7 +63,7 @@ export class AppContribution implements LifecycleContribution {
}
onDispose() {
// 销毁所有的订阅
// Destroy all subscriptions
this.widgetEventService.dispose();
this.openURIResourceService.dispose();
this.onStartedEmitter.dispose();

View File

@@ -15,7 +15,7 @@
*/
/**
* 承载 project ide app 业务逻辑的插件
* Plugin to host the business logic of the project ide app
*/
import { type NavigateFunction } from 'react-router-dom';

View File

@@ -15,7 +15,7 @@
*/
/**
* 业务层数据持久化
* Business layer data persistence
*/
import { isPlainObject } from 'lodash-es';
import { inject, injectable } from 'inversify';
@@ -34,7 +34,7 @@ import {
import { saveLayoutData, readLayoutData } from './utils/layout-store';
/**
* 被持久化的 widget 可能是普通的 widget 也可能是 project 特定的 widget
* The persistent widget may be a normal widget or a project-specific widget.
*/
type LayoutWidget = ReactWidget | ProjectIDEWidget;
@@ -45,7 +45,7 @@ interface LayoutWidgetData {
}
/**
* 判断是否是 ProjectIDEWidget
* Determine if it is a ProjectIDEWidget
*/
const isProjectIDEWidget = (w: LayoutWidget): w is ProjectIDEWidget =>
!!(w as ProjectIDEWidget).context;
@@ -63,13 +63,13 @@ export class LayoutRestoreService {
private optionsService: OptionsService;
/**
* 本地数据是否生效
* Is the local data valid?
*/
private _openFirstWorkflow = false;
/**
* 是否启用持久化,暂时不可配置,若开发过程中出现问题,可以关闭
* 此开关只会开关是否在初始化时恢复布局数据
* Whether to enable persistence is temporarily unconfigurable. If there is a problem during development, it can be turned off.
* This switch only switches whether to restore layout data during initialization
*/
private enabled = true;
// private enabled = false;
@@ -93,7 +93,7 @@ export class LayoutRestoreService {
);
}
async restoreLayout() {
// 无论是否需要持久化,这一步必须要做
// This step must be done whether persistence is required or not
await this.addSidebarWidget();
if (this.enabled) {
const data = await readLayoutData(
@@ -111,15 +111,15 @@ export class LayoutRestoreService {
}
/**
* 生成当前 ide 的布局数据
* Generate layout data for the current IDE
*/
getLayoutData() {
const data: Record<string, any> = {};
const { primarySidebar, mainPanel } = this.applicationShell;
/**
* primarySidebar 数据
* 在当前特化业务下primarySidebar 只可能打开特定的 widget所以这里无需存储通用的 widgets 数据
* Primary Sidebar Data
* In the current specialized business, primarySidebar can only open specific widgets, so there is no need to store general widgets data here
*/
data.primarySidebar = {
isHidden: !!primarySidebar?.isHidden,
@@ -134,10 +134,10 @@ export class LayoutRestoreService {
const { primarySidebar, mainPanel } = data || {};
/**
* primarySidebar 面板初始化
* 1. 数据不存在时,说明没有本地数据,需要默认打开
* 2. 数据存在,且 hidden 为假,默认打开
* 3. 其他情况不打开
* PrimarySidebar panel initialization
* 1. When the data does not exist, it means that there is no local data and needs to be opened by default.
* 2. The data exists, and hidden is false, open by default
* 3. Do not open in other cases
*/
if (!primarySidebar || !primarySidebar.isHidden) {
this.applicationShell.primarySidebar.show();
@@ -147,21 +147,21 @@ export class LayoutRestoreService {
if (mainPanel) {
const mainPanelData = await this.widgetsParseBFS(mainPanel);
// 如果初始化的时候没有 widget 打开,默认打开一个。
// If no widget is opened when initializing, one is opened by default.
// widget: tab
// children: 分屏
// Children: split screen
const { main } = mainPanelData || {};
if (!main?.widgets?.length && !main?.children?.length) {
this._openFirstWorkflow = true;
}
this.applicationShell.mainPanel.restoreLayout(mainPanelData);
// FlowDockPanel 需要挂载监听
// FlowDockPanel requires a monitor to be mounted
this.applicationShell.mainPanel.initWidgets();
}
}
/**
* 挂载默认的 sidebar widget
* Mount the default sidebar widget
*/
async addSidebarWidget() {
const widget = await this.widgetParse({

View File

@@ -15,7 +15,7 @@
*/
/**
* project ide app 初始化时打开 url 上携带的资源
* Open resources carried on the url when the project ide app is initialized
*/
import { inject, injectable } from 'inversify';
import {
@@ -47,20 +47,20 @@ export class OpenURIResourceService {
private disposable = new DisposableCollection();
/**
* 针对 1.直接打开2.外部系统跳转的场景,请勿在此添加其他副作用逻辑
* For scenarios where 1. Open directly; 2. External system jumps, please do not add other side effect logic here.
*/
open() {
const { resourceType } = getResourceByPathname(window.location.pathname);
// ui-builder
if (resourceType === UI_BUILDER_URI.displayName) {
this.openDesign();
// 展示默认页
// Show default page
this.tryOpenDefault();
} else {
const path = getURIPathByPathname(window.location.pathname);
if (!path || path.startsWith(MAIN_PANEL_DEFAULT_URI.displayName)) {
this.tryOpenDefault();
// 路由不匹配时需要手动激活 currentWidget
// When the routes do not match, you need to manually activate currentWidget.
if (this.applicationShell.mainPanel.currentTitle?.owner) {
this.applicationShell.setCurrentWidget(
this.applicationShell.mainPanel?.currentTitle?.owner as ReactWidget,

View File

@@ -66,7 +66,7 @@ export class ProjectInfoService {
init() {
this.updateProjectInfo().catch(() => {
// project 信息接口报错跳转到兜底页
// Project information interface error Jump to default page
this.errorService.toErrorPage();
});
if (!IS_OPEN_SOURCE) {
@@ -80,12 +80,12 @@ export class ProjectInfoService {
const res = await intelligenceApi.DraftProjectInnerTaskList({
project_id: this.optionsService.projectId,
});
// 和后端确认,默认 task_list 长度为 1.
// 如果有长度为 2 没有都住的场景,用户刷新后也可以获取到下一个。
// And backend confirmation, the default task_list length is 1.
// If there is a scene with a length of 2 that is not lived, the user can also get the next one after refreshing.
const { task_list } = res.data || {};
const taskId = task_list?.[0]?.task_id;
if (taskId) {
// 请求轮询接口获取基础信息
// Request polling interface to obtain basic information
const { task_detail } = await PluginDevelopApi.ResourceCopyDetail({
task_id: taskId,
});
@@ -99,7 +99,7 @@ export class ProjectInfoService {
}
/**
* 打开 project 页面需要上报,后端才能筛选出最近打开
* To open the project page, you need to report it, and the backend can filter out the most recently opened.
*/
reportUserBehavior() {
PlaygroundApi.ReportUserBehavior({
@@ -111,8 +111,8 @@ export class ProjectInfoService {
}
/**
* 单向请求接口
* 提前唤醒 ide 插件,无需消费返回值
* one-way request interface
* Wake up the ide plugin in advance, no need to consume the return value
*/
wakeUpPlugin() {
PluginDevelopApi.WakeupIdePlugin({

View File

@@ -17,31 +17,31 @@
import { Dexie, type EntityTable } from 'dexie';
/**
* 布局数据
* layout data
*/
interface DBLayoutRow {
/**
* 自增 id
* autoincrement id
*/
id: number;
/**
* 空间 id
* Space ID
*/
spaceId: string;
/**
* 项目 id
* Project ID
*/
projectId: string;
/**
* 时间戳
* timestamp
*/
timestamp: number;
/**
* 数据版本
* data version
*/
version: number;
/**
* 数据
* data
*/
data: string;
}
@@ -51,20 +51,20 @@ type DBLayout = Dexie & {
};
/**
* 持久化储存形式的版本号
* Version number of persistent storage form
*/
const VERSION = 3;
/**
* 数据库名称
* database name
*/
const DB_NAME = 'CozProjectIDELayoutData';
/**
* 数据库版本
* database version
*/
const DB_VERSION = 1;
/**
* 数据有效期
* Data valid period
*/
const DB_EXPIRE = 1000 * 60 * 60 * 24 * 30;
@@ -74,7 +74,7 @@ const isExpired = (row: DBLayoutRow) =>
row.timestamp < Date.now() - DB_EXPIRE || row.version !== VERSION;
/**
* 获取数据库实例
* Get the database instance
*/
const getDB = () => {
if (!cache) {
@@ -155,12 +155,12 @@ const deleteDataLS = (spaceId: string, projectId: string) => {
};
/**
* 保存布局数据
* 注:调用时机为组件销毁或浏览器关闭时,故不可用异步函数
* Save layout data
* Note: The calling time is when the component is destroyed or the browser is closed, so asynchronous functions cannot be used
*/
const saveLayoutData = (spaceId: string, projectId: string, data: any) => {
try {
// 无论是什么值都需要序列化成字符串
// No matter what the value is, it needs to be serialized into a string.
const str = JSON.stringify(data);
const row = {
data: str,
@@ -175,13 +175,13 @@ const saveLayoutData = (spaceId: string, projectId: string, data: any) => {
};
/**
* 读取布局数据
* 会同时从 indexedDB localStorage 中读取数据,会有以下几种情况:
* 1. localStorage 无数据,返回 indexedDB 数据
* 2. localStorage 有数据
* 2.1. indexedDB 无数据,更新 indexedDB 数据,删除 localStorage 数据,返回 indexedDB 数据
* 2.2. indexedDB 有数据,比较时间戳。返回最近的数据,删除 localStorage 数据
* 2.2.1. localStorage 数据较新,则更新到 indexedDB
* Read layout data
* Data will be read from indexedDB and localStorage simultaneously, in the following cases:
* 1. localStorage no data, return indexedDB data
* 2. localStorage has data
* 2.1. indexedDB no data, update indexedDB data, delete localStorage data, return indexedDB data
* 2.2. IndexedDB has data, compare timestamps. Return recent data, delete localStorage data
* 2.2.1. If localStorage data is new, update to indexedDB
*/
const readLayoutData = async (spaceId: string, projectId: string) => {
let str;

View File

@@ -15,7 +15,7 @@
*/
/**
* 监听 widget 事件而需要执行的业务逻辑
* Business logic that needs to be executed to listen for widget events
*/
import { inject, injectable } from 'inversify';
import {
@@ -58,14 +58,14 @@ export class WidgetEventService {
}
/**
* 1. 有 widget 打开时需要关闭默认页
* 2. 关闭所有 widget 时需要打开默认页
* 1. You need to close the default page when a widget is opened
* 2. When closing all widgets, you need to open the default page
*/
toggleDefaultWidget(widget) {
if ((widget as ReactWidget)?.uri) {
const widgetUri = widget?.uri;
if (widgetUri.displayName !== 'default') {
// 关闭默认的 widget
// Close the default widget
const defaultWidget = this.widgetManager.getWidgetFromURI(
MAIN_PANEL_DEFAULT_URI,
);
@@ -78,12 +78,12 @@ export class WidgetEventService {
}
/**
* 同步切换资源 tab 时的 url 变化
* Synchronize url changes when switching resource tabs
*/
syncURL(widget) {
if (widget) {
const widgetUri = widget?.uri;
// 默认页无需同步 url
// Default page does not need to synchronize URLs
if (compareURI(widgetUri, MAIN_PANEL_DEFAULT_URI)) {
return;
}