chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -33,22 +33,22 @@ export interface PromptConfiguratorModalProps extends ModalProps {
|
||||
workflowId?: string;
|
||||
defaultPrompt?: string;
|
||||
canEdit?: boolean;
|
||||
/** 用于埋点: 页面来源 */
|
||||
/** For event tracking: page source */
|
||||
source: string;
|
||||
enableDiff?: boolean;
|
||||
promptSectionConfig?: {
|
||||
/** 提示词输入框的 placeholder */
|
||||
/** Cue word text box placeholder */
|
||||
editorPlaceholder?: React.ReactNode;
|
||||
/** 提示词划词actions */
|
||||
/** Cue action */
|
||||
editorActions?: React.ReactNode;
|
||||
/** 头部 actions */
|
||||
/** Head actions */
|
||||
headerActions?: React.ReactNode;
|
||||
/** 提示词输入框的 active line placeholder */
|
||||
/** Cue text box active line placeholder */
|
||||
editorActiveLinePlaceholder?: React.ReactNode;
|
||||
/** 提示词输入框的 extensions */
|
||||
/** Tip text box extensions */
|
||||
editorExtensions?: React.ReactNode;
|
||||
};
|
||||
/** 最外层容器插槽 */
|
||||
/** outermost container slot */
|
||||
containerAppendSlot?: React.ReactNode;
|
||||
importPromptWhenEmpty?: string;
|
||||
getConversationId?: () => string | undefined;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { useCallback, useRef, useEffect, type ReactNode, useMemo } from 'react';
|
||||
|
||||
import { merge } from 'lodash-es';
|
||||
import { Renderer, Placeholder, useEditor } from '@coze-editor/editor/react';
|
||||
// promptPreset是针对Prompt提供了一系列内置扩展的集合
|
||||
// promptPreset is a collection of built-in extensions for Prompt
|
||||
import promptPreset, {
|
||||
type EditorAPI,
|
||||
} from '@coze-editor/editor/preset-prompt';
|
||||
@@ -29,7 +29,7 @@ import { LanguageSupport } from '@coze-common/editor-plugins/language-support';
|
||||
import { defaultTheme } from '@/theme/default';
|
||||
|
||||
export interface PromptEditorRenderProps {
|
||||
readonly?: boolean; // 所有插入编辑器相关操作禁用:action-bar
|
||||
readonly?: boolean; // All insert editor related operations are disabled: action-bar
|
||||
placeholder?: ReactNode;
|
||||
className?: string;
|
||||
dataTestID?: string;
|
||||
@@ -39,11 +39,11 @@ export interface PromptEditorRenderProps {
|
||||
onChange?: (value: string) => void;
|
||||
onFocus?: () => void;
|
||||
/**
|
||||
* 光标焦点丢失
|
||||
* Cursor focus lost
|
||||
*/
|
||||
onBlur?: () => void;
|
||||
options?: Record<string, string | number>;
|
||||
isControled?: boolean; // 是否受控
|
||||
isControled?: boolean; // Is it controlled
|
||||
getEditor?: (editor: EditorAPI) => void;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ export const PromptEditorRender: React.FC<PromptEditorRenderProps> = props => {
|
||||
};
|
||||
}, [editor, onFocus]);
|
||||
|
||||
// 值受控
|
||||
// value controlled
|
||||
useEffect(() => {
|
||||
const curEditor = apiRef.current;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import { type ModalHierarchyServiceConstructor } from './type';
|
||||
import { type FreeGrabModalHierarchyAction } from './store';
|
||||
|
||||
export class FreeGrabModalHierarchyService {
|
||||
/** Tip: semi modal zIndex 为 1000 */
|
||||
/** Tip: semi modal zIndex is 1000 */
|
||||
private baseZIndex = 1000;
|
||||
public registerModal: FreeGrabModalHierarchyAction['registerModal'];
|
||||
public removeModal: FreeGrabModalHierarchyAction['removeModal'];
|
||||
|
||||
@@ -19,7 +19,7 @@ import { create } from 'zustand';
|
||||
import { produce } from 'immer';
|
||||
|
||||
export interface FreeGrabModalHierarchyState {
|
||||
// modal 的 key list
|
||||
// Modal key list
|
||||
modalHierarchyList: string[];
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface FreeGrabModalHierarchyAction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 可自由拖拽的弹窗之间的层级关系
|
||||
* Hierarchical relationship between pop-ups that can be dragged and dropped freely
|
||||
*/
|
||||
export const createFreeGrabModalHierarchyStore = () =>
|
||||
create<FreeGrabModalHierarchyState & FreeGrabModalHierarchyAction>()(
|
||||
|
||||
@@ -45,14 +45,14 @@ export const insertToNewline = async ({
|
||||
selection,
|
||||
scrollIntoView: true,
|
||||
});
|
||||
// 等待下一个微任务周期,确保状态已更新
|
||||
// Wait for the next microtask cycle to ensure that the status has been updated
|
||||
await Promise.resolve();
|
||||
|
||||
// 使用更新后的state获取最新文档内容
|
||||
// Use the updated state to get the latest document content
|
||||
const newDoc = editor.$view.state.doc.toString();
|
||||
|
||||
// 插入到新一行
|
||||
// 注意:该操作提前会触发 chrome bug 导致崩溃问题
|
||||
// Insert to new line
|
||||
// Note: This operation will trigger a chrome bug in advance, resulting in a crash
|
||||
editor.focus();
|
||||
return newDoc;
|
||||
};
|
||||
|
||||
@@ -23,13 +23,13 @@ export const getSelectionBoundary = (editor: EditorAPI) => {
|
||||
return { left: 0, top: 0, width: 0, height: 0 };
|
||||
}
|
||||
|
||||
// 初始化最大矩形
|
||||
// Initialize the largest rectangle
|
||||
let maxLeft = Infinity;
|
||||
let maxTop = Infinity;
|
||||
let maxRight = -Infinity;
|
||||
let maxBottom = -Infinity;
|
||||
|
||||
// 遍历所有矩形,计算包围盒的边界
|
||||
// Iterate through all rectangles and calculate the bounding box boundary
|
||||
rects.forEach(rect => {
|
||||
maxLeft = Math.min(maxLeft, rect.left);
|
||||
maxTop = Math.min(maxTop, rect.top);
|
||||
@@ -37,18 +37,18 @@ export const getSelectionBoundary = (editor: EditorAPI) => {
|
||||
maxBottom = Math.max(maxBottom, rect.top + (rect.height ?? 0));
|
||||
});
|
||||
|
||||
// 计算最终的宽度和高度
|
||||
// Calculate the final width and height
|
||||
const width = maxRight - maxLeft;
|
||||
const height = maxBottom - maxTop;
|
||||
|
||||
// 获取编辑器的滚动位置
|
||||
// Get the scroll position of the editor
|
||||
const { scrollLeft } = editor.$view.scrollDOM;
|
||||
const { scrollTop } = editor.$view.scrollDOM;
|
||||
|
||||
// 获取编辑器容器的位置
|
||||
// Get the location of the editor container
|
||||
const editorRect = editor.$view.dom.getBoundingClientRect();
|
||||
|
||||
// 计算相对于视口的绝对位置
|
||||
// Calculate the absolute position relative to the viewport
|
||||
const absoluteLeft = editorRect.left + maxLeft - scrollLeft;
|
||||
const absoluteTop = editorRect.top + maxTop - scrollTop;
|
||||
const absoluteBottom = editorRect.top + maxBottom - scrollTop;
|
||||
|
||||
@@ -75,13 +75,13 @@ interface PromptLibraryProps extends ModalProps {
|
||||
importPromptWhenEmpty?: string;
|
||||
defaultActiveTab?: 'Recommended' | 'Team';
|
||||
tabs?: ('Recommended' | 'Team')[];
|
||||
/** 用于埋点: 页面来源 */
|
||||
/** For event tracking: page source */
|
||||
source: string;
|
||||
/** 用于埋点: bot_id */
|
||||
/** For event tracking: bot_id */
|
||||
botId?: string;
|
||||
/** 用于埋点: project_id */
|
||||
/** For event tracking: project_id */
|
||||
projectId?: string;
|
||||
/** 用于埋点: workflow_id */
|
||||
/** For event tracking: workflow_id */
|
||||
workflowId?: string;
|
||||
onInsertPrompt?: (prompt: string, selectedLibrary: ActionExtraInfo) => void;
|
||||
onUpdateSuccess?: (
|
||||
@@ -195,7 +195,7 @@ export const PromptLibrary = ({
|
||||
});
|
||||
}, [selectedLibraryId, dataList, isLoading]);
|
||||
|
||||
// 切换tab、无选中提示词,重置搜索词
|
||||
// Switch tab, no selected prompt word, reset search term
|
||||
useEffect(() => {
|
||||
setSelectedLibraryId('');
|
||||
setPrompt('');
|
||||
|
||||
@@ -77,7 +77,7 @@ function Index<T extends object>(
|
||||
return (
|
||||
<div className={cls(s['height-whole-100'], containerClassName)}>
|
||||
{!dataList?.length ? (
|
||||
/** 数据为空的时候,操作如何显示空页面 */
|
||||
/** How to display an empty page when the data is empty */
|
||||
<Empty
|
||||
isError={isLoadingError}
|
||||
isLoading={isLoading}
|
||||
@@ -95,7 +95,7 @@ function Index<T extends object>(
|
||||
className={
|
||||
typeof itemClassName === 'string'
|
||||
? itemClassName
|
||||
: itemClassName?.(item) // 支持动态行className
|
||||
: itemClassName?.(item) // Support dynamic row className
|
||||
}
|
||||
>
|
||||
{renderItem?.(item, number)}
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface EmptyProps {
|
||||
className?: string;
|
||||
isError?: boolean;
|
||||
isLoading?: boolean;
|
||||
loadRetry?: () => void; //重试加载
|
||||
loadRetry?: () => void; //retry loading
|
||||
size?: EmptyStateProps['size'];
|
||||
text?: {
|
||||
emptyTitle?: string;
|
||||
@@ -45,12 +45,12 @@ export interface EmptyProps {
|
||||
) => React.ReactNode | null;
|
||||
}
|
||||
export interface FooterProps {
|
||||
isError?: boolean; // 是否加载出错
|
||||
isLoading?: boolean; // 是否加载中
|
||||
noMore?: boolean; //没有更多数据
|
||||
isError?: boolean; // Whether loading error
|
||||
isLoading?: boolean; // Is it loading?
|
||||
noMore?: boolean; //No more data.
|
||||
isNeedBtnLoadMore?: boolean;
|
||||
dataNum?: number;
|
||||
loadRetry?: () => void; //重试加载
|
||||
loadRetry?: () => void; //retry loading
|
||||
renderFooter?: (
|
||||
footerProps: Omit<FooterProps, 'renderFooter'>,
|
||||
) => React.ReactNode | null;
|
||||
@@ -65,15 +65,15 @@ export interface InfiniteListDataProps<T> {
|
||||
}
|
||||
|
||||
export interface ScrollProps<T> {
|
||||
threshold?: number; //距离下方多长距离,开始加载数据
|
||||
targetRef?: RefObject<HTMLDivElement>; // 监听滚动的Dom 引用
|
||||
threshold?: number; //How far is it from below to start loading data?
|
||||
targetRef?: RefObject<HTMLDivElement>; // Listening for scrolling Dom references
|
||||
loadData: (
|
||||
current: InfiniteListDataProps<T>,
|
||||
) => Promise<InfiniteListDataProps<T>>; // 加载更多数据
|
||||
reloadDeps?: unknown[]; // 重新加载数据依赖
|
||||
) => Promise<InfiniteListDataProps<T>>; // Load more data
|
||||
reloadDeps?: unknown[]; // Reloading data dependencies
|
||||
isNeedBtnLoadMore?: boolean;
|
||||
isLoading?: boolean; // 是否加载中
|
||||
resetDataIfReload?: boolean; // 当reload时,是否先reset列表已存在数据,默认为true
|
||||
isLoading?: boolean; // Is it loading?
|
||||
resetDataIfReload?: boolean; // When reloading, whether to reset the existing data in the list first, the default is true
|
||||
}
|
||||
|
||||
export interface InfiniteListProps<T>
|
||||
@@ -81,8 +81,8 @@ export interface InfiniteListProps<T>
|
||||
Pick<ListProps<T>, 'className' | 'emptyContent' | 'grid' | 'renderItem'>
|
||||
> {
|
||||
containerClassName?: string;
|
||||
canShowData?: boolean; //是否能够显示数据了
|
||||
isSearching?: boolean; // 是否搜索中,主要是用于错误显示的时候,选择文案使用
|
||||
canShowData?: boolean; //Can the data be displayed?
|
||||
isSearching?: boolean; // Whether it is in the search, it is mainly used for error display, select Copy to use
|
||||
itemClassName?: string | ((item: T) => string);
|
||||
isNeedBtnLoadMore?: boolean;
|
||||
isResponsive?: boolean;
|
||||
@@ -103,5 +103,5 @@ export interface InfiniteListProps<T>
|
||||
|
||||
export interface InfiniteListRef<T> {
|
||||
reload: () => void;
|
||||
getDataList: () => T[]; // 获取当前列表数据
|
||||
getDataList: () => T[]; // Get current list data
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
import {
|
||||
useState,
|
||||
useRef,
|
||||
@@ -31,13 +31,13 @@ import {
|
||||
|
||||
import { type ScrollProps, type InfiniteListDataProps } from './type';
|
||||
|
||||
/* 滚动Hooks */
|
||||
/* Rolling Hooks */
|
||||
|
||||
function useForwardFunc<T>(
|
||||
dataInfo: InfiniteListDataProps<T>,
|
||||
mutate: Dispatch<SetStateAction<InfiniteListDataProps<T>>>,
|
||||
) {
|
||||
// 手动插入数据,不通过接口
|
||||
// Insert data manually, without going through the interface
|
||||
const insertData = (item: T, index: number) => {
|
||||
dataInfo.list.splice(index, 0, item);
|
||||
mutate({
|
||||
@@ -46,7 +46,7 @@ function useForwardFunc<T>(
|
||||
});
|
||||
};
|
||||
|
||||
// 手动删除数据,不通过接口
|
||||
// Delete data manually, without going through the interface
|
||||
const removeData = (index: number) => {
|
||||
dataInfo.list.splice(index, 1);
|
||||
mutate({
|
||||
@@ -60,7 +60,7 @@ function useForwardFunc<T>(
|
||||
return { insertData, removeData, getDataList };
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function, @coze-arch/max-line-per-function -- 看了下代码行数不太好优化
|
||||
// eslint-disable-next-line max-lines-per-function, @coze-arch/max-line-per-function -- the number of lines of code is not very good optimization
|
||||
function useScroll<T>(props: ScrollProps<T>) {
|
||||
const {
|
||||
targetRef,
|
||||
@@ -84,16 +84,16 @@ function useScroll<T>(props: ScrollProps<T>) {
|
||||
reload,
|
||||
} = useInfiniteScroll<InfiniteListDataProps<T>>(
|
||||
async current => {
|
||||
// 此处逻辑如此复杂,是解决Scroll中的bug。
|
||||
// useInfiniteScroll中的cancel只是取消了一次请求,但是数据会根据current重新设置一遍。
|
||||
// The logic here is so complex that it solves the bug in Scroll.
|
||||
// The cancel in useInfiniteScroll simply cancels a request, but the data is reset based on the current.
|
||||
const defaultData = {
|
||||
cursor: '0',
|
||||
list: [],
|
||||
};
|
||||
const fetchNo = refFetchNo.current;
|
||||
if (refResolve.current) {
|
||||
// 保证顺序执行,如果有当前方法,就取消上一次的请求,防止出现由于网络原因导致数据覆盖问题
|
||||
// 同时发出A1,A2,三次请求,但是A1先到达,然后请求了B1, 但是A1过慢,导致了A1覆盖了B1的请求。
|
||||
// Guaranteed sequential execution, if there is a current method, cancel the last request to prevent data overwriting problems due to network reasons
|
||||
// At the same time, A1, A2, and three requests were issued, but A1 arrived first, and then B1 was requested, but A1 was too slow, causing A1 to overwrite B1's request.
|
||||
refResolve.current({
|
||||
...defaultData,
|
||||
...(current || {}),
|
||||
@@ -110,7 +110,7 @@ function useScroll<T>(props: ScrollProps<T>) {
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
refResolve.current = null;
|
||||
|
||||
// 切换Tab的时候,如果此时正在请求,防止数据的残留界面显示
|
||||
// When switching tabs, if you are requesting at this time, prevent the residual interface display of the data
|
||||
if (refFetchNo.current !== fetchNo) {
|
||||
if (current) {
|
||||
current.list = [];
|
||||
@@ -123,7 +123,7 @@ function useScroll<T>(props: ScrollProps<T>) {
|
||||
return result as InfiniteListDataProps<T>;
|
||||
},
|
||||
{
|
||||
target: isLoadingError || isNeedBtnLoadMore ? null : targetRef, //失败的时候,通过去掉target的事件绑定,禁止滚动加载。
|
||||
target: isLoadingError || isNeedBtnLoadMore ? null : targetRef, //When it fails, scrolling loading is prohibited by removing the event binding of the target.
|
||||
threshold,
|
||||
onBefore: () => {
|
||||
//setIsLoadingError(false);
|
||||
@@ -135,8 +135,8 @@ function useScroll<T>(props: ScrollProps<T>) {
|
||||
}
|
||||
},
|
||||
onError: e => {
|
||||
// 如果在请求第一页数据时发生错误,并且当前列表不为空,则reset数据
|
||||
// 这个case只有当resetDataIfReload设置为false时才会发生
|
||||
// If an error occurs when requesting the first page of data and the current list is not empty, reset the data
|
||||
// This case only occurs when resetDataIfReload is set to false
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
if (dataInfo.cursor === '0' && (dataInfo?.list?.length ?? 0) > 0) {
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
@@ -205,7 +205,7 @@ function useScroll<T>(props: ScrollProps<T>) {
|
||||
isLoading,
|
||||
loadMore: () => {
|
||||
if (!isLoading) {
|
||||
//如果已经有数据加载中了,需要禁止重复加载。
|
||||
//If there is already data loading, you need to prohibit repeated loading.
|
||||
loadMore();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -72,7 +72,7 @@ export const Index = (
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [selectedLibraryId, setSelectedLibraryId] = useState<string>('');
|
||||
|
||||
// 切换tab,默认选中第一个
|
||||
// Switch tabs, the first one is selected by default
|
||||
useEffect(() => {
|
||||
if (!dataList.length || isLoading) {
|
||||
return;
|
||||
|
||||
@@ -65,15 +65,15 @@ interface RecommendPannelProps {
|
||||
cardClassName?: string;
|
||||
listContainerClassName?: string;
|
||||
tabs: TabType[];
|
||||
/** 用于埋点: 页面来源 */
|
||||
/** For event tracking: page source */
|
||||
source: string;
|
||||
importPromptWhenEmpty?: string;
|
||||
spaceId: string;
|
||||
/** 用于埋点: bot_id */
|
||||
/** For event tracking: bot_id */
|
||||
botId?: string;
|
||||
/** 用于埋点: project_id */
|
||||
/** For event tracking: project_id */
|
||||
projectId?: string;
|
||||
/** 用于埋点: workflow_id */
|
||||
/** For event tracking: workflow_id */
|
||||
workflowId?: string;
|
||||
isPersonal?: boolean;
|
||||
enableLibrary?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user