feat: improve i18n for panel
This commit is contained in:
+7
-2
@@ -1,5 +1,10 @@
|
||||
import { type SupportedLanguage, locales } from './locales'
|
||||
import type { TranslationKey, TranslationParams, TranslationSchema } from './types'
|
||||
import {
|
||||
type SupportedLanguage,
|
||||
type TranslationKey,
|
||||
type TranslationParams,
|
||||
type TranslationSchema,
|
||||
locales,
|
||||
} from './locales'
|
||||
|
||||
export class I18n {
|
||||
private language: SupportedLanguage
|
||||
|
||||
+76
-48
@@ -1,7 +1,55 @@
|
||||
import type { TranslationSchema } from './types'
|
||||
// English translations (base/reference language)
|
||||
const enUS = {
|
||||
ui: {
|
||||
panel: {
|
||||
ready: 'Ready',
|
||||
thinking: 'Thinking...',
|
||||
paused: 'Paused',
|
||||
taskInput: 'Enter new task, describe steps in detail, press Enter to submit',
|
||||
userAnswerPrompt: 'Please answer the question above, press Enter to submit',
|
||||
taskTerminated: 'Task terminated',
|
||||
taskCompleted: 'Task completed',
|
||||
continueExecution: 'Continue execution',
|
||||
userAnswer: 'User answer: {{input}}',
|
||||
question: 'Question: {{question}}',
|
||||
waitingPlaceholder: 'Waiting for task to start...',
|
||||
pause: 'Pause',
|
||||
continue: 'Continue',
|
||||
stop: 'Stop',
|
||||
expand: 'Expand history',
|
||||
collapse: 'Collapse history',
|
||||
step: 'Step {{number}} · {{time}}{{duration}}',
|
||||
},
|
||||
tools: {
|
||||
clicking: 'Clicking element [{{index}}]...',
|
||||
inputting: 'Inputting text to element [{{index}}]...',
|
||||
selecting: 'Selecting option "{{text}}"...',
|
||||
scrolling: 'Scrolling page...',
|
||||
waiting: 'Waiting {{seconds}} seconds...',
|
||||
done: 'Task done',
|
||||
clicked: '🖱️ Clicked element [{{index}}]',
|
||||
inputted: '⌨️ Inputted text "{{text}}"',
|
||||
selected: '☑️ Selected option "{{text}}"',
|
||||
scrolled: '🛞 Page scrolled',
|
||||
waited: '⌛️ Wait completed',
|
||||
executing: 'Executing {{toolName}}...',
|
||||
resultSuccess: 'success',
|
||||
resultFailure: 'failed',
|
||||
resultError: 'error',
|
||||
},
|
||||
errors: {
|
||||
elementNotFound: 'No interactive element found at index {{index}}',
|
||||
taskRequired: 'Task description is required',
|
||||
executionFailed: 'Task execution failed',
|
||||
notInputElement: 'Element is not an input or textarea',
|
||||
notSelectElement: 'Element is not a select element',
|
||||
optionNotFound: 'Option "{{text}}" not found',
|
||||
},
|
||||
},
|
||||
} as const
|
||||
|
||||
// 中文翻译(作为基准)
|
||||
const zhCN: TranslationSchema = {
|
||||
// Chinese translations (must match the structure of enUS)
|
||||
const zhCN = {
|
||||
ui: {
|
||||
panel: {
|
||||
ready: '准备就绪',
|
||||
@@ -13,6 +61,8 @@ const zhCN: TranslationSchema = {
|
||||
taskCompleted: '任务结束',
|
||||
continueExecution: '继续执行',
|
||||
userAnswer: '用户回答: {{input}}',
|
||||
question: '询问: {{question}}',
|
||||
waitingPlaceholder: '等待任务开始...',
|
||||
pause: '暂停',
|
||||
continue: '继续',
|
||||
stop: '终止',
|
||||
@@ -33,6 +83,9 @@ const zhCN: TranslationSchema = {
|
||||
scrolled: '🛞 页面滚动完成',
|
||||
waited: '⌛️ 等待完成',
|
||||
executing: '正在执行 {{toolName}}...',
|
||||
resultSuccess: '成功',
|
||||
resultFailure: '失败',
|
||||
resultError: '错误',
|
||||
},
|
||||
errors: {
|
||||
elementNotFound: '未找到索引为 {{index}} 的交互元素',
|
||||
@@ -45,54 +98,29 @@ const zhCN: TranslationSchema = {
|
||||
},
|
||||
} as const
|
||||
|
||||
// 英文翻译(必须符合相同的结构)
|
||||
const enUS: TranslationSchema = {
|
||||
ui: {
|
||||
panel: {
|
||||
ready: 'Ready',
|
||||
thinking: 'Thinking...',
|
||||
paused: 'Paused',
|
||||
taskInput: 'Enter new task, describe steps in detail, press Enter to submit',
|
||||
userAnswerPrompt: 'Please answer the question above, press Enter to submit',
|
||||
taskTerminated: 'Task terminated',
|
||||
taskCompleted: 'Task completed',
|
||||
continueExecution: 'Continue execution',
|
||||
userAnswer: 'User answer: {{input}}',
|
||||
pause: 'Pause',
|
||||
continue: 'Continue',
|
||||
stop: 'Stop',
|
||||
expand: 'Expand history',
|
||||
collapse: 'Collapse history',
|
||||
step: 'Step {{number}} · {{time}}{{duration}}',
|
||||
},
|
||||
tools: {
|
||||
clicking: 'Clicking element [{{index}}]...',
|
||||
inputting: 'Inputting text to element [{{index}}]...',
|
||||
selecting: 'Selecting option "{{text}}"...',
|
||||
scrolling: 'Scrolling page...',
|
||||
waiting: 'Waiting {{seconds}} seconds...',
|
||||
done: 'Task done',
|
||||
clicked: '🖱️ Clicked element [{{index}}]',
|
||||
inputted: '⌨️ Inputted text "{{text}}"',
|
||||
selected: '☑️ Selected option "{{text}}"',
|
||||
scrolled: '🛞 Page scrolled',
|
||||
waited: '⌛️ Wait completed',
|
||||
executing: '正在执行 {{toolName}}...',
|
||||
},
|
||||
errors: {
|
||||
elementNotFound: 'No interactive element found at index {{index}}',
|
||||
taskRequired: 'Task description is required',
|
||||
executionFailed: 'Task execution failed',
|
||||
notInputElement: 'Element is not an input or textarea',
|
||||
notSelectElement: 'Element is not a select element',
|
||||
optionNotFound: 'Option "{{text}}" not found',
|
||||
},
|
||||
},
|
||||
} as const
|
||||
// Type definitions generated from English base structure (but with string values)
|
||||
type DeepStringify<T> = {
|
||||
[K in keyof T]: T[K] extends string ? string : T[K] extends object ? DeepStringify<T[K]> : T[K]
|
||||
}
|
||||
|
||||
export type TranslationSchema = DeepStringify<typeof enUS>
|
||||
|
||||
// Utility type: Extract all nested paths from translation object
|
||||
type NestedKeyOf<ObjectType extends object> = {
|
||||
[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object
|
||||
? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}`
|
||||
: `${Key}`
|
||||
}[keyof ObjectType & (string | number)]
|
||||
|
||||
// Extract all possible key paths from translation structure
|
||||
export type TranslationKey = NestedKeyOf<TranslationSchema>
|
||||
|
||||
// Parameterized translation types
|
||||
export type TranslationParams = Record<string, string | number>
|
||||
|
||||
export const locales = {
|
||||
'zh-CN': zhCN,
|
||||
'en-US': enUS,
|
||||
'zh-CN': zhCN,
|
||||
} as const
|
||||
|
||||
export type SupportedLanguage = keyof typeof locales
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
// 定义翻译数据的结构类型
|
||||
export interface TranslationSchema {
|
||||
ui: {
|
||||
panel: {
|
||||
ready: string
|
||||
thinking: string
|
||||
paused: string
|
||||
taskInput: string
|
||||
userAnswerPrompt: string
|
||||
taskTerminated: string
|
||||
taskCompleted: string
|
||||
continueExecution: string
|
||||
userAnswer: string
|
||||
pause: string
|
||||
continue: string
|
||||
stop: string
|
||||
expand: string
|
||||
collapse: string
|
||||
step: string
|
||||
}
|
||||
tools: {
|
||||
clicking: string
|
||||
inputting: string
|
||||
selecting: string
|
||||
scrolling: string
|
||||
waiting: string
|
||||
done: string
|
||||
clicked: string
|
||||
inputted: string
|
||||
selected: string
|
||||
scrolled: string
|
||||
waited: string
|
||||
executing: string
|
||||
}
|
||||
errors: {
|
||||
elementNotFound: string
|
||||
taskRequired: string
|
||||
executionFailed: string
|
||||
notInputElement: string
|
||||
notSelectElement: string
|
||||
optionNotFound: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 工具类型:提取嵌套对象的所有路径
|
||||
type NestedKeyOf<ObjectType extends object> = {
|
||||
[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object
|
||||
? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}`
|
||||
: `${Key}`
|
||||
}[keyof ObjectType & (string | number)]
|
||||
|
||||
// 从翻译结构中提取所有可能的key路径
|
||||
export type TranslationKey = NestedKeyOf<TranslationSchema>
|
||||
|
||||
// 参数化翻译的类型
|
||||
export type TranslationParams = Record<string, string | number>
|
||||
Reference in New Issue
Block a user