@object-ui/i18n 3.1.4 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/locales/ar.d.ts +202 -1
- package/dist/locales/ar.js +202 -1
- package/dist/locales/de.d.ts +202 -1
- package/dist/locales/de.js +211 -1
- package/dist/locales/en.d.ts +201 -0
- package/dist/locales/en.js +211 -0
- package/dist/locales/es.d.ts +202 -1
- package/dist/locales/es.js +202 -1
- package/dist/locales/fr.d.ts +202 -1
- package/dist/locales/fr.js +211 -1
- package/dist/locales/index.d.ts +2041 -9
- package/dist/locales/ja.d.ts +213 -1
- package/dist/locales/ja.js +213 -1
- package/dist/locales/ko.d.ts +202 -1
- package/dist/locales/ko.js +202 -1
- package/dist/locales/pt.d.ts +202 -1
- package/dist/locales/pt.js +202 -1
- package/dist/locales/ru.d.ts +213 -1
- package/dist/locales/ru.js +222 -1
- package/dist/locales/zh.d.ts +202 -1
- package/dist/locales/zh.js +212 -1
- package/dist/useSafeTranslation.d.ts +5 -0
- package/dist/useSafeTranslation.js +46 -0
- package/package.json +6 -6
- package/src/__tests__/i18n.test.ts +27 -0
- package/src/index.ts +3 -0
- package/src/locales/ar.ts +202 -1
- package/src/locales/de.ts +211 -1
- package/src/locales/en.ts +211 -0
- package/src/locales/es.ts +202 -1
- package/src/locales/fr.ts +211 -1
- package/src/locales/ja.ts +213 -1
- package/src/locales/ko.ts +202 -1
- package/src/locales/pt.ts +202 -1
- package/src/locales/ru.ts +222 -1
- package/src/locales/zh.ts +212 -1
- package/src/useSafeTranslation.ts +49 -0
- package/tsconfig.tsbuildinfo +1 -1
package/dist/locales/zh.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ declare const zh: {
|
|
|
32
32
|
readonly noResults: "未找到结果";
|
|
33
33
|
readonly required: "必填";
|
|
34
34
|
readonly optional: "选填";
|
|
35
|
+
readonly selectOption: "请选择";
|
|
36
|
+
readonly select: "选择...";
|
|
35
37
|
};
|
|
36
38
|
readonly validation: {
|
|
37
39
|
readonly required: "{{field}}不能为空";
|
|
@@ -54,6 +56,11 @@ declare const zh: {
|
|
|
54
56
|
readonly saveError: "保存失败";
|
|
55
57
|
readonly unsavedChanges: "您有未保存的更改,确定要离开吗?";
|
|
56
58
|
readonly stepOf: "第{{current}}步,共{{total}}步";
|
|
59
|
+
readonly createTitle: "新建{{object}}";
|
|
60
|
+
readonly editTitle: "编辑{{object}}";
|
|
61
|
+
readonly createDescription: "向数据库添加新的{{object}}。";
|
|
62
|
+
readonly editDescription: "更新{{object}}的详情";
|
|
63
|
+
readonly saveRecord: "保存记录";
|
|
57
64
|
};
|
|
58
65
|
readonly table: {
|
|
59
66
|
readonly rowsPerPage: "每页行数";
|
|
@@ -146,6 +153,22 @@ declare const zh: {
|
|
|
146
153
|
readonly deleteCard: "删除卡片";
|
|
147
154
|
readonly deleteColumn: "删除列";
|
|
148
155
|
};
|
|
156
|
+
readonly view: {
|
|
157
|
+
readonly rename: "重命名";
|
|
158
|
+
readonly duplicateView: "复制视图";
|
|
159
|
+
readonly shareView: "共享视图";
|
|
160
|
+
readonly setAsDefault: "设为默认";
|
|
161
|
+
readonly pinView: "固定视图";
|
|
162
|
+
readonly unpinView: "取消固定";
|
|
163
|
+
readonly changeViewType: "更改视图类型";
|
|
164
|
+
readonly deleteView: "删除视图";
|
|
165
|
+
readonly addView: "添加视图";
|
|
166
|
+
readonly unsavedChanges: "未保存的更改";
|
|
167
|
+
readonly saveAsView: "另存为视图";
|
|
168
|
+
readonly moreViews: "还有 {{count}} 个";
|
|
169
|
+
readonly activeFilters: "筛选条件生效中";
|
|
170
|
+
readonly activeSort: "排序生效中";
|
|
171
|
+
};
|
|
149
172
|
readonly detail: {
|
|
150
173
|
readonly back: "返回";
|
|
151
174
|
readonly edit: "编辑";
|
|
@@ -191,11 +214,137 @@ declare const zh: {
|
|
|
191
214
|
readonly sortBy: "排序";
|
|
192
215
|
readonly filterPlaceholder: "筛选...";
|
|
193
216
|
readonly highlightFields: "关键字段";
|
|
217
|
+
readonly comments: "评论";
|
|
218
|
+
readonly searchComments: "搜索评论…";
|
|
219
|
+
readonly addCommentPlaceholder: "添加评论… (Ctrl+Enter 提交)";
|
|
220
|
+
readonly noMatchingComments: "没有匹配的评论";
|
|
221
|
+
readonly noCommentsYet: "暂无评论";
|
|
222
|
+
readonly pinned: "已置顶";
|
|
223
|
+
readonly pin: "置顶";
|
|
224
|
+
readonly unpin: "取消置顶";
|
|
225
|
+
readonly justNow: "刚刚";
|
|
226
|
+
readonly minutesAgo: "{{count}}分钟前";
|
|
227
|
+
readonly hoursAgo: "{{count}}小时前";
|
|
228
|
+
readonly daysAgo: "{{count}}天前";
|
|
229
|
+
readonly dropFilesToUpload: "拖拽文件到此处或点击上传";
|
|
230
|
+
readonly attachmentCount: "{{count}} 个附件";
|
|
231
|
+
readonly attachmentCountPlural: "{{count}} 个附件";
|
|
232
|
+
readonly removeAttachment: "移除附件";
|
|
233
|
+
readonly unifiedDiff: "统一视图";
|
|
234
|
+
readonly sideBySideDiff: "并排视图";
|
|
235
|
+
readonly noChanges: "无变更";
|
|
236
|
+
readonly previousVersion: "旧版本";
|
|
237
|
+
readonly currentVersion: "新版本";
|
|
238
|
+
readonly discussion: "讨论";
|
|
239
|
+
readonly showDiscussion: "显示讨论 ({{count}})";
|
|
240
|
+
readonly hideDiscussion: "隐藏讨论";
|
|
241
|
+
readonly bold: "粗体 (Ctrl+B)";
|
|
242
|
+
readonly italic: "斜体 (Ctrl+I)";
|
|
243
|
+
readonly listFormat: "列表";
|
|
244
|
+
readonly inlineCode: "行内代码";
|
|
245
|
+
readonly mentionSomeone: "提及某人";
|
|
246
|
+
readonly preview: "预览";
|
|
247
|
+
readonly submitComment: "提交 (Ctrl+Enter)";
|
|
248
|
+
readonly writeComment: "写评论…";
|
|
249
|
+
readonly subscribedTooltip: "已订阅 — 点击取消订阅";
|
|
250
|
+
readonly unsubscribedTooltip: "订阅通知";
|
|
251
|
+
readonly firstRecord: "第一条记录 (Home)";
|
|
252
|
+
readonly previousRecordKey: "上一条记录 (←)";
|
|
253
|
+
readonly nextRecordKey: "下一条记录 (→)";
|
|
254
|
+
readonly lastRecord: "最后一条记录 (End)";
|
|
255
|
+
readonly noRecords: "无记录";
|
|
256
|
+
readonly searchWhileNavigating: "导航时搜索";
|
|
257
|
+
readonly searchRecords: "搜索记录…";
|
|
258
|
+
readonly allActivity: "全部动态";
|
|
259
|
+
readonly commentsOnly: "仅评论";
|
|
260
|
+
readonly fieldChangesFilter: "字段变更";
|
|
261
|
+
readonly tasksOnly: "仅任务";
|
|
262
|
+
readonly leaveCommentPlaceholder: "留下评论… (Ctrl+Enter 提交)";
|
|
263
|
+
readonly noActivity: "暂无活动记录";
|
|
264
|
+
readonly loadMore: "加载更多";
|
|
265
|
+
readonly edited: "(已编辑)";
|
|
266
|
+
readonly via: "通过 {{source}}";
|
|
267
|
+
readonly replyCount: "{{count}} 条回复";
|
|
268
|
+
readonly replyCountPlural: "{{count}} 条回复";
|
|
269
|
+
readonly replyPlaceholder: "回复…";
|
|
270
|
+
readonly filterActivity: "筛选活动";
|
|
271
|
+
readonly openDiscussion: "打开讨论面板";
|
|
272
|
+
readonly closeDiscussion: "关闭讨论面板";
|
|
273
|
+
readonly subscribeAriaLabel: "订阅通知";
|
|
274
|
+
readonly unsubscribeAriaLabel: "取消订阅通知";
|
|
275
|
+
readonly clearSearch: "清除搜索";
|
|
194
276
|
};
|
|
195
277
|
readonly chart: {
|
|
196
278
|
readonly noData: "暂无图表数据";
|
|
197
279
|
readonly loading: "图表加载中...";
|
|
198
280
|
};
|
|
281
|
+
readonly map: {
|
|
282
|
+
readonly searchLocations: "搜索位置…";
|
|
283
|
+
readonly locationDetails: "位置详情";
|
|
284
|
+
readonly markersCount: "{{count}} 个标记";
|
|
285
|
+
readonly invalidCoordinates: "{{count}} 条记录因坐标缺失或无效已从地图中排除。";
|
|
286
|
+
readonly invalidCoordinatesPlural: "{{count}} 条记录因坐标缺失或无效已从地图中排除。";
|
|
287
|
+
};
|
|
288
|
+
readonly workflow: {
|
|
289
|
+
readonly draft: "草稿";
|
|
290
|
+
readonly active: "活跃";
|
|
291
|
+
readonly paused: "已暂停";
|
|
292
|
+
readonly completed: "已完成";
|
|
293
|
+
readonly cancelled: "已取消";
|
|
294
|
+
readonly save: "保存";
|
|
295
|
+
readonly publish: "发布";
|
|
296
|
+
readonly addNode: "添加节点";
|
|
297
|
+
readonly workflowFlow: "工作流程";
|
|
298
|
+
readonly properties: "属性";
|
|
299
|
+
readonly connections: "连接";
|
|
300
|
+
readonly quickConnect: "快速连接";
|
|
301
|
+
readonly fromPlaceholder: "从...";
|
|
302
|
+
readonly toPlaceholder: "到...";
|
|
303
|
+
readonly connect: "连接";
|
|
304
|
+
readonly label: "标签";
|
|
305
|
+
readonly type: "类型";
|
|
306
|
+
readonly description: "描述";
|
|
307
|
+
readonly assignee: "负责人";
|
|
308
|
+
readonly assigneeType: "负责人类型";
|
|
309
|
+
readonly user: "用户";
|
|
310
|
+
readonly role: "角色";
|
|
311
|
+
readonly group: "组";
|
|
312
|
+
readonly expression: "表达式";
|
|
313
|
+
readonly timeoutMinutes: "超时时间(分钟)";
|
|
314
|
+
readonly selectNodeToEdit: "选择节点以编辑其属性";
|
|
315
|
+
readonly workflowTitle: "工作流标题";
|
|
316
|
+
readonly newWorkflow: "新工作流";
|
|
317
|
+
readonly outConnections: "{{count}} 个输出";
|
|
318
|
+
readonly start: "开始";
|
|
319
|
+
readonly end: "结束";
|
|
320
|
+
readonly task: "任务";
|
|
321
|
+
readonly userTask: "用户任务";
|
|
322
|
+
readonly serviceTask: "服务任务";
|
|
323
|
+
readonly scriptTask: "脚本任务";
|
|
324
|
+
readonly approval: "审批";
|
|
325
|
+
readonly condition: "条件";
|
|
326
|
+
readonly parallelGateway: "并行网关";
|
|
327
|
+
readonly joinGateway: "合并网关";
|
|
328
|
+
readonly boundaryEvent: "边界事件";
|
|
329
|
+
readonly delay: "延迟";
|
|
330
|
+
readonly notification: "通知";
|
|
331
|
+
readonly webhook: "Webhook";
|
|
332
|
+
readonly allowConcurrency: "允许(并发执行)";
|
|
333
|
+
readonly forbidConcurrency: "禁止(跳过新任务)";
|
|
334
|
+
readonly replaceConcurrency: "替换(取消现有任务)";
|
|
335
|
+
readonly queueConcurrency: "排队(等待当前完成)";
|
|
336
|
+
readonly conditionEvent: "条件";
|
|
337
|
+
readonly manualEvent: "手动";
|
|
338
|
+
readonly webhookEvent: "Webhook";
|
|
339
|
+
readonly timerEvent: "定时器";
|
|
340
|
+
readonly signalEvent: "信号";
|
|
341
|
+
readonly versionHistory: "版本历史";
|
|
342
|
+
readonly importBpmn: "导入 BPMN";
|
|
343
|
+
readonly exportBpmn: "导出 BPMN";
|
|
344
|
+
readonly undo: "撤销";
|
|
345
|
+
readonly redo: "重做";
|
|
346
|
+
readonly resetZoom: "重置缩放";
|
|
347
|
+
};
|
|
199
348
|
readonly dashboard: {
|
|
200
349
|
readonly addWidget: "添加组件";
|
|
201
350
|
readonly removeWidget: "移除组件";
|
|
@@ -349,6 +498,58 @@ declare const zh: {
|
|
|
349
498
|
readonly modeLight: "浅色";
|
|
350
499
|
readonly modeDark: "深色";
|
|
351
500
|
readonly mobilePreview: "移动端预览";
|
|
501
|
+
readonly objectManager: {
|
|
502
|
+
readonly title: "对象管理器";
|
|
503
|
+
readonly addObject: "新建对象";
|
|
504
|
+
readonly searchPlaceholder: "搜索对象…";
|
|
505
|
+
readonly noObjects: "未找到对象。";
|
|
506
|
+
readonly objectName: "API 名称";
|
|
507
|
+
readonly objectLabel: "标签";
|
|
508
|
+
readonly pluralLabel: "复数标签";
|
|
509
|
+
readonly icon: "图标";
|
|
510
|
+
readonly selectIcon: "选择图标…";
|
|
511
|
+
readonly group: "分组";
|
|
512
|
+
readonly noGroup: "无分组";
|
|
513
|
+
readonly sortOrder: "排序";
|
|
514
|
+
readonly enabled: "启用";
|
|
515
|
+
readonly relationships: "关系";
|
|
516
|
+
readonly systemBadge: "系统";
|
|
517
|
+
readonly fieldCount: "{{count}} 个字段";
|
|
518
|
+
readonly ungrouped: "未分组";
|
|
519
|
+
readonly deleteConfirmTitle: "删除对象?";
|
|
520
|
+
readonly deleteConfirmMessage: "这将永久删除该对象及其所有字段。此操作无法撤销。";
|
|
521
|
+
};
|
|
522
|
+
readonly fieldDesigner: {
|
|
523
|
+
readonly title: "字段设计器";
|
|
524
|
+
readonly addField: "新建字段";
|
|
525
|
+
readonly searchPlaceholder: "搜索字段…";
|
|
526
|
+
readonly allTypes: "所有类型";
|
|
527
|
+
readonly noFields: "未找到字段。";
|
|
528
|
+
readonly fieldName: "API 名称";
|
|
529
|
+
readonly fieldLabel: "标签";
|
|
530
|
+
readonly fieldType: "类型";
|
|
531
|
+
readonly fieldGroup: "分组";
|
|
532
|
+
readonly description: "描述";
|
|
533
|
+
readonly required: "必填";
|
|
534
|
+
readonly unique: "唯一";
|
|
535
|
+
readonly readOnly: "只读";
|
|
536
|
+
readonly hidden: "隐藏";
|
|
537
|
+
readonly indexed: "索引";
|
|
538
|
+
readonly externalId: "外部 ID";
|
|
539
|
+
readonly trackHistory: "追踪历史";
|
|
540
|
+
readonly defaultValue: "默认值";
|
|
541
|
+
readonly placeholder: "占位文本";
|
|
542
|
+
readonly referenceTo: "引用对象";
|
|
543
|
+
readonly formula: "公式";
|
|
544
|
+
readonly options: "选项";
|
|
545
|
+
readonly addOption: "添加选项";
|
|
546
|
+
readonly validationRules: "验证规则";
|
|
547
|
+
readonly addRule: "添加规则";
|
|
548
|
+
readonly systemBadge: "系统";
|
|
549
|
+
readonly ungrouped: "通用";
|
|
550
|
+
readonly deleteConfirmTitle: "删除字段?";
|
|
551
|
+
readonly deleteConfirmMessage: "这将永久删除该字段。此字段中的现有数据将丢失。";
|
|
552
|
+
};
|
|
352
553
|
};
|
|
353
554
|
readonly console: {
|
|
354
555
|
readonly title: "ObjectStack 控制台";
|
|
@@ -434,7 +635,7 @@ declare const zh: {
|
|
|
434
635
|
readonly generalHint: "视图标题、描述和类型";
|
|
435
636
|
readonly toolbar: "工具栏";
|
|
436
637
|
readonly toolbarHint: "搜索、筛选、排序、分组和密度切换";
|
|
437
|
-
readonly toolbarEnabledCount: "{{count}}
|
|
638
|
+
readonly toolbarEnabledCount: "已启用 {{count}}/{{total}} 项";
|
|
438
639
|
readonly navigationSection: "导航";
|
|
439
640
|
readonly navigationHint: "行点击行为和详情视图设置";
|
|
440
641
|
readonly records: "记录";
|
package/dist/locales/zh.js
CHANGED
|
@@ -32,6 +32,8 @@ const zh = {
|
|
|
32
32
|
noResults: '未找到结果',
|
|
33
33
|
required: '必填',
|
|
34
34
|
optional: '选填',
|
|
35
|
+
selectOption: '请选择',
|
|
36
|
+
select: '选择...',
|
|
35
37
|
},
|
|
36
38
|
validation: {
|
|
37
39
|
required: '{{field}}不能为空',
|
|
@@ -54,6 +56,11 @@ const zh = {
|
|
|
54
56
|
saveError: '保存失败',
|
|
55
57
|
unsavedChanges: '您有未保存的更改,确定要离开吗?',
|
|
56
58
|
stepOf: '第{{current}}步,共{{total}}步',
|
|
59
|
+
createTitle: '新建{{object}}',
|
|
60
|
+
editTitle: '编辑{{object}}',
|
|
61
|
+
createDescription: '向数据库添加新的{{object}}。',
|
|
62
|
+
editDescription: '更新{{object}}的详情',
|
|
63
|
+
saveRecord: '保存记录',
|
|
57
64
|
},
|
|
58
65
|
table: {
|
|
59
66
|
rowsPerPage: '每页行数',
|
|
@@ -146,6 +153,22 @@ const zh = {
|
|
|
146
153
|
deleteCard: '删除卡片',
|
|
147
154
|
deleteColumn: '删除列',
|
|
148
155
|
},
|
|
156
|
+
view: {
|
|
157
|
+
rename: '重命名',
|
|
158
|
+
duplicateView: '复制视图',
|
|
159
|
+
shareView: '共享视图',
|
|
160
|
+
setAsDefault: '设为默认',
|
|
161
|
+
pinView: '固定视图',
|
|
162
|
+
unpinView: '取消固定',
|
|
163
|
+
changeViewType: '更改视图类型',
|
|
164
|
+
deleteView: '删除视图',
|
|
165
|
+
addView: '添加视图',
|
|
166
|
+
unsavedChanges: '未保存的更改',
|
|
167
|
+
saveAsView: '另存为视图',
|
|
168
|
+
moreViews: '还有 {{count}} 个',
|
|
169
|
+
activeFilters: '筛选条件生效中',
|
|
170
|
+
activeSort: '排序生效中',
|
|
171
|
+
},
|
|
149
172
|
detail: {
|
|
150
173
|
back: '返回',
|
|
151
174
|
edit: '编辑',
|
|
@@ -191,11 +214,147 @@ const zh = {
|
|
|
191
214
|
sortBy: '排序',
|
|
192
215
|
filterPlaceholder: '筛选...',
|
|
193
216
|
highlightFields: '关键字段',
|
|
217
|
+
// Comments
|
|
218
|
+
comments: '评论',
|
|
219
|
+
searchComments: '搜索评论…',
|
|
220
|
+
addCommentPlaceholder: '添加评论… (Ctrl+Enter 提交)',
|
|
221
|
+
noMatchingComments: '没有匹配的评论',
|
|
222
|
+
noCommentsYet: '暂无评论',
|
|
223
|
+
pinned: '已置顶',
|
|
224
|
+
pin: '置顶',
|
|
225
|
+
unpin: '取消置顶',
|
|
226
|
+
justNow: '刚刚',
|
|
227
|
+
minutesAgo: '{{count}}分钟前',
|
|
228
|
+
hoursAgo: '{{count}}小时前',
|
|
229
|
+
daysAgo: '{{count}}天前',
|
|
230
|
+
// Attachments
|
|
231
|
+
dropFilesToUpload: '拖拽文件到此处或点击上传',
|
|
232
|
+
attachmentCount: '{{count}} 个附件',
|
|
233
|
+
attachmentCountPlural: '{{count}} 个附件',
|
|
234
|
+
removeAttachment: '移除附件',
|
|
235
|
+
// Diff
|
|
236
|
+
unifiedDiff: '统一视图',
|
|
237
|
+
sideBySideDiff: '并排视图',
|
|
238
|
+
noChanges: '无变更',
|
|
239
|
+
previousVersion: '旧版本',
|
|
240
|
+
currentVersion: '新版本',
|
|
241
|
+
// Discussion
|
|
242
|
+
discussion: '讨论',
|
|
243
|
+
showDiscussion: '显示讨论 ({{count}})',
|
|
244
|
+
hideDiscussion: '隐藏讨论',
|
|
245
|
+
// Rich text editor
|
|
246
|
+
bold: '粗体 (Ctrl+B)',
|
|
247
|
+
italic: '斜体 (Ctrl+I)',
|
|
248
|
+
listFormat: '列表',
|
|
249
|
+
inlineCode: '行内代码',
|
|
250
|
+
mentionSomeone: '提及某人',
|
|
251
|
+
preview: '预览',
|
|
252
|
+
submitComment: '提交 (Ctrl+Enter)',
|
|
253
|
+
writeComment: '写评论…',
|
|
254
|
+
// Subscription
|
|
255
|
+
subscribedTooltip: '已订阅 — 点击取消订阅',
|
|
256
|
+
unsubscribedTooltip: '订阅通知',
|
|
257
|
+
// Navigation
|
|
258
|
+
firstRecord: '第一条记录 (Home)',
|
|
259
|
+
previousRecordKey: '上一条记录 (←)',
|
|
260
|
+
nextRecordKey: '下一条记录 (→)',
|
|
261
|
+
lastRecord: '最后一条记录 (End)',
|
|
262
|
+
noRecords: '无记录',
|
|
263
|
+
searchWhileNavigating: '导航时搜索',
|
|
264
|
+
searchRecords: '搜索记录…',
|
|
265
|
+
// Activity timeline
|
|
266
|
+
allActivity: '全部动态',
|
|
267
|
+
commentsOnly: '仅评论',
|
|
268
|
+
fieldChangesFilter: '字段变更',
|
|
269
|
+
tasksOnly: '仅任务',
|
|
270
|
+
leaveCommentPlaceholder: '留下评论… (Ctrl+Enter 提交)',
|
|
271
|
+
noActivity: '暂无活动记录',
|
|
272
|
+
loadMore: '加载更多',
|
|
273
|
+
edited: '(已编辑)',
|
|
274
|
+
via: '通过 {{source}}',
|
|
275
|
+
// Replies
|
|
276
|
+
replyCount: '{{count}} 条回复',
|
|
277
|
+
replyCountPlural: '{{count}} 条回复',
|
|
278
|
+
replyPlaceholder: '回复…',
|
|
279
|
+
// 无障碍标签
|
|
280
|
+
filterActivity: '筛选活动',
|
|
281
|
+
openDiscussion: '打开讨论面板',
|
|
282
|
+
closeDiscussion: '关闭讨论面板',
|
|
283
|
+
subscribeAriaLabel: '订阅通知',
|
|
284
|
+
unsubscribeAriaLabel: '取消订阅通知',
|
|
285
|
+
clearSearch: '清除搜索',
|
|
194
286
|
},
|
|
195
287
|
chart: {
|
|
196
288
|
noData: '暂无图表数据',
|
|
197
289
|
loading: '图表加载中...',
|
|
198
290
|
},
|
|
291
|
+
map: {
|
|
292
|
+
searchLocations: '搜索位置…',
|
|
293
|
+
locationDetails: '位置详情',
|
|
294
|
+
markersCount: '{{count}} 个标记',
|
|
295
|
+
invalidCoordinates: '{{count}} 条记录因坐标缺失或无效已从地图中排除。',
|
|
296
|
+
invalidCoordinatesPlural: '{{count}} 条记录因坐标缺失或无效已从地图中排除。',
|
|
297
|
+
},
|
|
298
|
+
workflow: {
|
|
299
|
+
draft: '草稿',
|
|
300
|
+
active: '活跃',
|
|
301
|
+
paused: '已暂停',
|
|
302
|
+
completed: '已完成',
|
|
303
|
+
cancelled: '已取消',
|
|
304
|
+
save: '保存',
|
|
305
|
+
publish: '发布',
|
|
306
|
+
addNode: '添加节点',
|
|
307
|
+
workflowFlow: '工作流程',
|
|
308
|
+
properties: '属性',
|
|
309
|
+
connections: '连接',
|
|
310
|
+
quickConnect: '快速连接',
|
|
311
|
+
fromPlaceholder: '从...',
|
|
312
|
+
toPlaceholder: '到...',
|
|
313
|
+
connect: '连接',
|
|
314
|
+
label: '标签',
|
|
315
|
+
type: '类型',
|
|
316
|
+
description: '描述',
|
|
317
|
+
assignee: '负责人',
|
|
318
|
+
assigneeType: '负责人类型',
|
|
319
|
+
user: '用户',
|
|
320
|
+
role: '角色',
|
|
321
|
+
group: '组',
|
|
322
|
+
expression: '表达式',
|
|
323
|
+
timeoutMinutes: '超时时间(分钟)',
|
|
324
|
+
selectNodeToEdit: '选择节点以编辑其属性',
|
|
325
|
+
workflowTitle: '工作流标题',
|
|
326
|
+
newWorkflow: '新工作流',
|
|
327
|
+
outConnections: '{{count}} 个输出',
|
|
328
|
+
start: '开始',
|
|
329
|
+
end: '结束',
|
|
330
|
+
task: '任务',
|
|
331
|
+
userTask: '用户任务',
|
|
332
|
+
serviceTask: '服务任务',
|
|
333
|
+
scriptTask: '脚本任务',
|
|
334
|
+
approval: '审批',
|
|
335
|
+
condition: '条件',
|
|
336
|
+
parallelGateway: '并行网关',
|
|
337
|
+
joinGateway: '合并网关',
|
|
338
|
+
boundaryEvent: '边界事件',
|
|
339
|
+
delay: '延迟',
|
|
340
|
+
notification: '通知',
|
|
341
|
+
webhook: 'Webhook',
|
|
342
|
+
allowConcurrency: '允许(并发执行)',
|
|
343
|
+
forbidConcurrency: '禁止(跳过新任务)',
|
|
344
|
+
replaceConcurrency: '替换(取消现有任务)',
|
|
345
|
+
queueConcurrency: '排队(等待当前完成)',
|
|
346
|
+
conditionEvent: '条件',
|
|
347
|
+
manualEvent: '手动',
|
|
348
|
+
webhookEvent: 'Webhook',
|
|
349
|
+
timerEvent: '定时器',
|
|
350
|
+
signalEvent: '信号',
|
|
351
|
+
versionHistory: '版本历史',
|
|
352
|
+
importBpmn: '导入 BPMN',
|
|
353
|
+
exportBpmn: '导出 BPMN',
|
|
354
|
+
undo: '撤销',
|
|
355
|
+
redo: '重做',
|
|
356
|
+
resetZoom: '重置缩放',
|
|
357
|
+
},
|
|
199
358
|
dashboard: {
|
|
200
359
|
addWidget: '添加组件',
|
|
201
360
|
removeWidget: '移除组件',
|
|
@@ -349,6 +508,58 @@ const zh = {
|
|
|
349
508
|
modeLight: '浅色',
|
|
350
509
|
modeDark: '深色',
|
|
351
510
|
mobilePreview: '移动端预览',
|
|
511
|
+
objectManager: {
|
|
512
|
+
title: '对象管理器',
|
|
513
|
+
addObject: '新建对象',
|
|
514
|
+
searchPlaceholder: '搜索对象…',
|
|
515
|
+
noObjects: '未找到对象。',
|
|
516
|
+
objectName: 'API 名称',
|
|
517
|
+
objectLabel: '标签',
|
|
518
|
+
pluralLabel: '复数标签',
|
|
519
|
+
icon: '图标',
|
|
520
|
+
selectIcon: '选择图标…',
|
|
521
|
+
group: '分组',
|
|
522
|
+
noGroup: '无分组',
|
|
523
|
+
sortOrder: '排序',
|
|
524
|
+
enabled: '启用',
|
|
525
|
+
relationships: '关系',
|
|
526
|
+
systemBadge: '系统',
|
|
527
|
+
fieldCount: '{{count}} 个字段',
|
|
528
|
+
ungrouped: '未分组',
|
|
529
|
+
deleteConfirmTitle: '删除对象?',
|
|
530
|
+
deleteConfirmMessage: '这将永久删除该对象及其所有字段。此操作无法撤销。',
|
|
531
|
+
},
|
|
532
|
+
fieldDesigner: {
|
|
533
|
+
title: '字段设计器',
|
|
534
|
+
addField: '新建字段',
|
|
535
|
+
searchPlaceholder: '搜索字段…',
|
|
536
|
+
allTypes: '所有类型',
|
|
537
|
+
noFields: '未找到字段。',
|
|
538
|
+
fieldName: 'API 名称',
|
|
539
|
+
fieldLabel: '标签',
|
|
540
|
+
fieldType: '类型',
|
|
541
|
+
fieldGroup: '分组',
|
|
542
|
+
description: '描述',
|
|
543
|
+
required: '必填',
|
|
544
|
+
unique: '唯一',
|
|
545
|
+
readOnly: '只读',
|
|
546
|
+
hidden: '隐藏',
|
|
547
|
+
indexed: '索引',
|
|
548
|
+
externalId: '外部 ID',
|
|
549
|
+
trackHistory: '追踪历史',
|
|
550
|
+
defaultValue: '默认值',
|
|
551
|
+
placeholder: '占位文本',
|
|
552
|
+
referenceTo: '引用对象',
|
|
553
|
+
formula: '公式',
|
|
554
|
+
options: '选项',
|
|
555
|
+
addOption: '添加选项',
|
|
556
|
+
validationRules: '验证规则',
|
|
557
|
+
addRule: '添加规则',
|
|
558
|
+
systemBadge: '系统',
|
|
559
|
+
ungrouped: '通用',
|
|
560
|
+
deleteConfirmTitle: '删除字段?',
|
|
561
|
+
deleteConfirmMessage: '这将永久删除该字段。此字段中的现有数据将丢失。',
|
|
562
|
+
},
|
|
352
563
|
},
|
|
353
564
|
console: {
|
|
354
565
|
title: 'ObjectStack 控制台',
|
|
@@ -434,7 +645,7 @@ const zh = {
|
|
|
434
645
|
generalHint: '视图标题、描述和类型',
|
|
435
646
|
toolbar: '工具栏',
|
|
436
647
|
toolbarHint: '搜索、筛选、排序、分组和密度切换',
|
|
437
|
-
toolbarEnabledCount: '{{count}}
|
|
648
|
+
toolbarEnabledCount: '已启用 {{count}}/{{total}} 项',
|
|
438
649
|
navigationSection: '导航',
|
|
439
650
|
navigationHint: '行点击行为和详情视图设置',
|
|
440
651
|
records: '记录',
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe translation hook with fallback to default strings.
|
|
3
|
+
*
|
|
4
|
+
* When no I18nProvider is available (e.g., in tests or standalone usage),
|
|
5
|
+
* this hook falls back to the provided default translations instead of
|
|
6
|
+
* returning raw i18n keys.
|
|
7
|
+
*
|
|
8
|
+
* @param defaults - Fallback English translations keyed by i18n key
|
|
9
|
+
* @param testKey - A key to test if i18n is properly configured (must be in defaults)
|
|
10
|
+
*/
|
|
11
|
+
import { useObjectTranslation } from './provider';
|
|
12
|
+
export function createSafeTranslation(defaults, testKey) {
|
|
13
|
+
return function useSafeTranslation() {
|
|
14
|
+
try {
|
|
15
|
+
const result = useObjectTranslation();
|
|
16
|
+
const testValue = result.t(testKey);
|
|
17
|
+
if (testValue === testKey) {
|
|
18
|
+
return {
|
|
19
|
+
t: (key, options) => {
|
|
20
|
+
let value = defaults[key] || key;
|
|
21
|
+
if (options) {
|
|
22
|
+
for (const [k, v] of Object.entries(options)) {
|
|
23
|
+
value = value.replace(`{{${k}}}`, String(v));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return { t: result.t };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return {
|
|
34
|
+
t: (key, options) => {
|
|
35
|
+
let value = defaults[key] || key;
|
|
36
|
+
if (options) {
|
|
37
|
+
for (const [k, v] of Object.entries(options)) {
|
|
38
|
+
value = value.replace(`{{${k}}}`, String(v));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/i18n",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,17 +30,17 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"i18next": "^
|
|
34
|
-
"react-i18next": "^
|
|
33
|
+
"i18next": "^26.0.4",
|
|
34
|
+
"react-i18next": "^17.0.2"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"react": "^18.0.0 || ^19.0.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/react": "19.2.14",
|
|
41
|
-
"react": "19.2.
|
|
42
|
-
"typescript": "^
|
|
43
|
-
"vitest": "^4.1.
|
|
41
|
+
"react": "19.2.5",
|
|
42
|
+
"typescript": "^6.0.2",
|
|
43
|
+
"vitest": "^4.1.4"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsc",
|
|
@@ -47,6 +47,17 @@ describe('@object-ui/i18n', () => {
|
|
|
47
47
|
expect(i18n.t('common.cancel')).toBe('Cancel');
|
|
48
48
|
expect(i18n.t('common.delete')).toBe('Delete');
|
|
49
49
|
expect(i18n.t('common.loading')).toBe('Loading...');
|
|
50
|
+
expect(i18n.t('common.selectOption')).toBe('Select an option');
|
|
51
|
+
expect(i18n.t('common.select')).toBe('Select...');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('translates new form keys in English', () => {
|
|
55
|
+
const i18n = createI18n({ defaultLanguage: 'en', detectBrowserLanguage: false });
|
|
56
|
+
expect(i18n.t('form.createTitle', { object: 'Contact' })).toBe('Create Contact');
|
|
57
|
+
expect(i18n.t('form.editTitle', { object: 'Contact' })).toBe('Edit Contact');
|
|
58
|
+
expect(i18n.t('form.createDescription', { object: 'Contact' })).toBe('Add a new Contact to your database.');
|
|
59
|
+
expect(i18n.t('form.editDescription', { object: 'Contact' })).toBe('Update details for Contact');
|
|
60
|
+
expect(i18n.t('form.saveRecord')).toBe('Save Record');
|
|
50
61
|
});
|
|
51
62
|
|
|
52
63
|
it('translates common keys in Chinese', () => {
|
|
@@ -55,6 +66,22 @@ describe('@object-ui/i18n', () => {
|
|
|
55
66
|
expect(i18n.t('common.cancel')).toBe('取消');
|
|
56
67
|
expect(i18n.t('common.delete')).toBe('删除');
|
|
57
68
|
expect(i18n.t('common.loading')).toBe('加载中...');
|
|
69
|
+
expect(i18n.t('common.selectOption')).toBe('请选择');
|
|
70
|
+
expect(i18n.t('common.select')).toBe('选择...');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('translates new form keys in Chinese', () => {
|
|
74
|
+
const i18n = createI18n({ defaultLanguage: 'zh', detectBrowserLanguage: false });
|
|
75
|
+
expect(i18n.t('form.createTitle', { object: '联系人' })).toBe('新建联系人');
|
|
76
|
+
expect(i18n.t('form.editTitle', { object: '联系人' })).toBe('编辑联系人');
|
|
77
|
+
expect(i18n.t('form.createDescription', { object: '联系人' })).toBe('向数据库添加新的联系人。');
|
|
78
|
+
expect(i18n.t('form.editDescription', { object: '联系人' })).toBe('更新联系人的详情');
|
|
79
|
+
expect(i18n.t('form.saveRecord')).toBe('保存记录');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('translates toolbarEnabledCount in Chinese (not English fallback)', () => {
|
|
83
|
+
const i18n = createI18n({ defaultLanguage: 'zh', detectBrowserLanguage: false });
|
|
84
|
+
expect(i18n.t('console.objectView.toolbarEnabledCount', { count: 3, total: 5 })).toBe('已启用 3/5 项');
|
|
58
85
|
});
|
|
59
86
|
|
|
60
87
|
it('translates common keys in Japanese', () => {
|
package/src/index.ts
CHANGED
|
@@ -37,6 +37,9 @@ export { createI18n, getDirection, getAvailableLanguages, type I18nConfig, type
|
|
|
37
37
|
// React integration
|
|
38
38
|
export { I18nProvider, useObjectTranslation, useI18nContext, type I18nProviderProps } from './provider';
|
|
39
39
|
|
|
40
|
+
// Safe translation hook factory
|
|
41
|
+
export { createSafeTranslation } from './useSafeTranslation';
|
|
42
|
+
|
|
40
43
|
// Convention-based object/field label i18n
|
|
41
44
|
export { useObjectLabel, useSafeFieldLabel } from './useObjectLabel';
|
|
42
45
|
|