diff --git a/.changeset/page-block-inspector-curated-label-i18n-3913.md b/.changeset/page-block-inspector-curated-label-i18n-3913.md new file mode 100644 index 000000000..5ef3d668e --- /dev/null +++ b/.changeset/page-block-inspector-curated-label-i18n-3913.md @@ -0,0 +1,41 @@ +--- +"@object-ui/app-shell": patch +--- + +Page block inspector: the PROPERTIES panel's curated field labels now follow the session locale instead of always rendering English + +`PageBlockInspector`'s chrome went through the translation table from the start — +`t('engine.inspector.pageBlock.properties')` and its siblings — while the panel's +CONTENTS did not. Every `label` in `previews/block-config.ts` was an English +literal handed straight to the field components, so a zh-CN admin opening any +page block read 「属性」 over a stack of English field names: two languages in one +panel, reproducible on any block with no special data. + +All 157 label literals (152 field/option labels + 5 `addLabel`s) are now +translation keys resolved through `t(key, locale)` at render, with 154 distinct +keys added to both the `en-US` and `zh-CN` sides of +`views/metadata-admin/i18n.ts`. The English text is unchanged: every key's `en` +value is the literal it replaced, verified by substituting all 157 keys back and +diffing the result byte-for-byte against the pre-change file. + +The key is a function of the label's POSITION in `BLOCK_CONFIG` +(`engine.inspector.pageBlock.field..`, `.add..`, +`.option..`), and a test re-derives all three shapes from the +table's own structure. That is what makes the realistic mistake visible: these +keys differ by one segment, so adding a block by copy-pasting a neighbour's key +yields a key that EXISTS in both locales and renders a plausible label belonging +to a different property — an existence-only check is green for it. Positional +keys also let one English word take different Chinese per block, which the panel +needs: `element:button.label` is a button caption 「按钮文字」 while +`page:tabs.items.label` is a tab title 「标签」, and `Add section` is 「添加分区」 +here but stays 「添加分组」 in the form-layout canvas. + +`addLabel` is now REQUIRED on the `array` field variant. It was optional and the +inspector fell back to a bare English `'Add'` — an untranslatable literal no +locale table could reach. Requiring it deletes the fallback instead of +translating it, so a new array field cannot compile without naming its +add-button key. + +Option labels are translated too, including the ones `ColorVariantPicker` renders +only as `aria-label`/`title`, where an untranslated string is invisible to a text +query. diff --git a/packages/app-shell/src/views/metadata-admin/i18n.ts b/packages/app-shell/src/views/metadata-admin/i18n.ts index a35116697..257e0566d 100644 --- a/packages/app-shell/src/views/metadata-admin/i18n.ts +++ b/packages/app-shell/src/views/metadata-admin/i18n.ts @@ -478,6 +478,166 @@ const ENGINE_STRINGS_EN: Record = { 'engine.inspector.pageBlock.advanced': 'Advanced', 'engine.inspector.pageBlock.remove': 'Remove block', 'engine.inspector.pageBlock.outlineLabel': 'Blocks', + // Page block inspector — curated property labels (#3913). + // These are the `label` / `addLabel` / option-label values of + // `previews/block-config.ts`; that file stores the KEY and the inspector + // resolves it through `t()` at render. Key shape is derived from the label's + // position in BLOCK_CONFIG and pinned by + // `previews/__tests__/block-config-i18n.test.ts` — see that file's header. + 'engine.inspector.pageBlock.field.object-grid.objectName': 'Object', + 'engine.inspector.pageBlock.field.object-grid.columns': 'Columns', + 'engine.inspector.pageBlock.field.object-grid.pageSize': 'Page size', + 'engine.inspector.pageBlock.field.object-grid.striped': 'Striped rows', + 'engine.inspector.pageBlock.field.object-grid.bordered': 'Bordered', + 'engine.inspector.pageBlock.field.object-form.objectName': 'Object', + 'engine.inspector.pageBlock.field.object-form.mode': 'Mode', + 'engine.inspector.pageBlock.option.mode.create': 'Create', + 'engine.inspector.pageBlock.option.mode.edit': 'Edit', + 'engine.inspector.pageBlock.option.mode.view': 'View', + 'engine.inspector.pageBlock.field.object-form.formType': 'Form type', + 'engine.inspector.pageBlock.option.formType.simple': 'Simple', + 'engine.inspector.pageBlock.option.formType.tabbed': 'Tabbed', + 'engine.inspector.pageBlock.option.formType.wizard': 'Wizard', + 'engine.inspector.pageBlock.option.formType.split': 'Split', + 'engine.inspector.pageBlock.option.formType.drawer': 'Drawer', + 'engine.inspector.pageBlock.option.formType.modal': 'Modal', + 'engine.inspector.pageBlock.field.object-form.layout': 'Layout', + 'engine.inspector.pageBlock.option.layout.vertical': 'Vertical', + 'engine.inspector.pageBlock.option.layout.horizontal': 'Horizontal', + 'engine.inspector.pageBlock.option.layout.inline': 'Inline', + 'engine.inspector.pageBlock.option.layout.grid': 'Grid', + 'engine.inspector.pageBlock.field.object-form.columns': 'Columns (grid layout)', + 'engine.inspector.pageBlock.field.object-form.fields': 'Fields', + 'engine.inspector.pageBlock.field.object-form.title': 'Title', + 'engine.inspector.pageBlock.field.object-form.description': 'Description', + 'engine.inspector.pageBlock.field.object-metric.objectName': 'Object', + 'engine.inspector.pageBlock.field.object-metric.label': 'Label', + 'engine.inspector.pageBlock.field.object-metric.description': 'Description', + 'engine.inspector.pageBlock.field.object-metric.icon': 'Icon', + 'engine.inspector.pageBlock.field.object-metric.colorVariant': 'Color', + 'engine.inspector.pageBlock.option.colorVariant.default': 'Default', + 'engine.inspector.pageBlock.option.colorVariant.blue': 'Blue', + 'engine.inspector.pageBlock.option.colorVariant.teal': 'Teal', + 'engine.inspector.pageBlock.option.colorVariant.orange': 'Orange', + 'engine.inspector.pageBlock.option.colorVariant.purple': 'Purple', + 'engine.inspector.pageBlock.option.colorVariant.success': 'Success', + 'engine.inspector.pageBlock.option.colorVariant.warning': 'Warning', + 'engine.inspector.pageBlock.option.colorVariant.danger': 'Danger', + 'engine.inspector.pageBlock.field.object-metric.format': 'Format', + 'engine.inspector.pageBlock.option.format.number': 'Number', + 'engine.inspector.pageBlock.option.format.currency': 'Currency', + 'engine.inspector.pageBlock.option.format.percent': 'Percent', + 'engine.inspector.pageBlock.field.object-metric.prefix': 'Prefix', + 'engine.inspector.pageBlock.field.object-metric.suffix': 'Suffix', + 'engine.inspector.pageBlock.field.object-kanban.objectName': 'Object', + 'engine.inspector.pageBlock.field.object-kanban.groupField': 'Group by field', + 'engine.inspector.pageBlock.field.object-kanban.titleField': 'Title field', + 'engine.inspector.pageBlock.field.object-kanban.cardFields': 'Card fields', + 'engine.inspector.pageBlock.field.grid.columns': 'Columns', + 'engine.inspector.pageBlock.field.grid.gap': 'Gap', + 'engine.inspector.pageBlock.field.element:text.content': 'Content', + 'engine.inspector.pageBlock.field.element:text.variant': 'Variant', + 'engine.inspector.pageBlock.option.variant.heading': 'Heading', + 'engine.inspector.pageBlock.option.variant.subheading': 'Subheading', + 'engine.inspector.pageBlock.option.variant.body': 'Body', + 'engine.inspector.pageBlock.option.variant.caption': 'Caption', + 'engine.inspector.pageBlock.field.element:text.align': 'Align', + 'engine.inspector.pageBlock.option.align.left': 'Left', + 'engine.inspector.pageBlock.option.align.center': 'Center', + 'engine.inspector.pageBlock.option.align.right': 'Right', + 'engine.inspector.pageBlock.field.element:image.src': 'Source URL', + 'engine.inspector.pageBlock.field.element:image.alt': 'Alt text', + 'engine.inspector.pageBlock.field.element:image.fit': 'Fit', + 'engine.inspector.pageBlock.option.fit.cover': 'Cover', + 'engine.inspector.pageBlock.option.fit.contain': 'Contain', + 'engine.inspector.pageBlock.option.fit.fill': 'Fill', + 'engine.inspector.pageBlock.field.element:definition-list.items': 'Items', + 'engine.inspector.pageBlock.add.element:definition-list.items': 'Add item', + 'engine.inspector.pageBlock.field.element:definition-list.items.label': 'Label', + 'engine.inspector.pageBlock.field.element:definition-list.items.value': 'Value', + 'engine.inspector.pageBlock.field.element:definition-list.columns': 'Columns (1 or 2)', + 'engine.inspector.pageBlock.field.element:definition-list.inline': 'Inline (label · value)', + 'engine.inspector.pageBlock.field.element:repeater.object': 'Object', + 'engine.inspector.pageBlock.field.element:repeater.titleField': 'Title field', + 'engine.inspector.pageBlock.field.element:repeater.fields': 'Fields', + 'engine.inspector.pageBlock.field.element:repeater.limit': 'Limit', + 'engine.inspector.pageBlock.field.element:repeater.emptyText': 'Empty text', + 'engine.inspector.pageBlock.field.element:repeater.divided': 'Dividers between rows', + 'engine.inspector.pageBlock.field.element:number.object': 'Object', + 'engine.inspector.pageBlock.field.element:number.field': 'Field', + 'engine.inspector.pageBlock.field.element:number.aggregate': 'Aggregate', + 'engine.inspector.pageBlock.option.aggregate.count': 'Count', + 'engine.inspector.pageBlock.option.aggregate.sum': 'Sum', + 'engine.inspector.pageBlock.option.aggregate.avg': 'Average', + 'engine.inspector.pageBlock.option.aggregate.min': 'Min', + 'engine.inspector.pageBlock.option.aggregate.max': 'Max', + 'engine.inspector.pageBlock.field.element:number.format': 'Format', + 'engine.inspector.pageBlock.field.element:number.prefix': 'Prefix', + 'engine.inspector.pageBlock.field.element:number.suffix': 'Suffix', + 'engine.inspector.pageBlock.field.element:button.label': 'Label', + 'engine.inspector.pageBlock.field.element:button.variant': 'Variant', + 'engine.inspector.pageBlock.option.variant.primary': 'Primary', + 'engine.inspector.pageBlock.option.variant.secondary': 'Secondary', + 'engine.inspector.pageBlock.option.variant.danger': 'Danger', + 'engine.inspector.pageBlock.option.variant.ghost': 'Ghost', + 'engine.inspector.pageBlock.option.variant.link': 'Link', + 'engine.inspector.pageBlock.field.element:button.size': 'Size', + 'engine.inspector.pageBlock.option.size.small': 'Small', + 'engine.inspector.pageBlock.option.size.medium': 'Medium', + 'engine.inspector.pageBlock.option.size.large': 'Large', + 'engine.inspector.pageBlock.field.element:button.icon': 'Icon', + 'engine.inspector.pageBlock.field.element:button.action': 'Action', + 'engine.inspector.pageBlock.field.page:header.title': 'Title', + 'engine.inspector.pageBlock.field.page:header.subtitle': 'Subtitle', + 'engine.inspector.pageBlock.field.page:header.icon': 'Icon', + 'engine.inspector.pageBlock.field.page:header.breadcrumb': 'Show breadcrumb', + 'engine.inspector.pageBlock.field.page:card.title': 'Title', + 'engine.inspector.pageBlock.field.page:card.bordered': 'Bordered', + 'engine.inspector.pageBlock.field.page:tabs.items': 'Tabs', + 'engine.inspector.pageBlock.add.page:tabs.items': 'Add tab', + 'engine.inspector.pageBlock.field.page:tabs.items.key': 'Key', + 'engine.inspector.pageBlock.field.page:tabs.items.label': 'Label', + 'engine.inspector.pageBlock.field.page:accordion.title': 'Title', + 'engine.inspector.pageBlock.field.page:accordion.items': 'Sections', + 'engine.inspector.pageBlock.add.page:accordion.items': 'Add section', + 'engine.inspector.pageBlock.field.page:accordion.items.value': 'Key', + 'engine.inspector.pageBlock.field.page:accordion.items.label': 'Label', + 'engine.inspector.pageBlock.field.record:related_list.objectName': 'Object', + 'engine.inspector.pageBlock.field.record:related_list.relationshipField': 'Relationship field', + 'engine.inspector.pageBlock.field.record:related_list.title': 'Title', + 'engine.inspector.pageBlock.field.record:related_list.limit': 'Limit', + 'engine.inspector.pageBlock.field.record:highlights.fields': 'Fields', + 'engine.inspector.pageBlock.field.record:details.sections': 'Sections', + 'engine.inspector.pageBlock.add.record:details.sections': 'Add section', + 'engine.inspector.pageBlock.field.record:details.sections.name': 'Name (i18n key)', + 'engine.inspector.pageBlock.field.record:details.sections.label': 'Label', + 'engine.inspector.pageBlock.field.record:details.sections.columns': 'Columns', + 'engine.inspector.pageBlock.field.record:details.sections.fields': 'Fields', + 'engine.inspector.pageBlock.field.record:alert.severity': 'Severity', + 'engine.inspector.pageBlock.option.severity.info': 'Info', + 'engine.inspector.pageBlock.option.severity.warning': 'Warning', + 'engine.inspector.pageBlock.option.severity.error': 'Error', + 'engine.inspector.pageBlock.option.severity.success': 'Success', + 'engine.inspector.pageBlock.field.record:alert.title': 'Title', + 'engine.inspector.pageBlock.field.record:alert.body': 'Body', + 'engine.inspector.pageBlock.field.record:alert.icon': 'Icon', + 'engine.inspector.pageBlock.field.record:alert.dismissible': 'Dismissible', + 'engine.inspector.pageBlock.field.record:path.statusField': 'Status field', + 'engine.inspector.pageBlock.field.record:path.stages': 'Stages', + 'engine.inspector.pageBlock.add.record:path.stages': 'Add stage', + 'engine.inspector.pageBlock.field.record:path.stages.value': 'Value', + 'engine.inspector.pageBlock.field.record:path.stages.label': 'Label', + 'engine.inspector.pageBlock.field.record:quick_actions.actionNames': 'Action names', + 'engine.inspector.pageBlock.field.record:quick_actions.location': 'Location', + 'engine.inspector.pageBlock.option.location.record_header': 'Record header', + 'engine.inspector.pageBlock.option.location.record_more': 'Record more menu', + 'engine.inspector.pageBlock.option.location.record_section': 'Record section', + 'engine.inspector.pageBlock.option.location.record_related': 'Record related', + 'engine.inspector.pageBlock.option.location.list_toolbar': 'List toolbar', + 'engine.inspector.pageBlock.option.location.list_item': 'List item', + 'engine.inspector.pageBlock.option.location.global_nav': 'Global nav', + 'engine.inspector.pageBlock.field.ai:input.agentName': 'Agent', + 'engine.inspector.pageBlock.field.ai:input.placeholder': 'Input placeholder', // Report default ("home") inspector 'engine.inspector.report.kind': 'Report', 'engine.inspector.report.close': 'Close report', @@ -2037,6 +2197,163 @@ const ENGINE_STRINGS_ZH: Record = { 'engine.inspector.pageBlock.advanced': '高级属性', 'engine.inspector.pageBlock.remove': '删除区块', 'engine.inspector.pageBlock.outlineLabel': '区块', + // 页面区块检查器 —— curated 属性 label(#3913)。 + // 键形状与 en 侧一一对应,由 `previews/__tests__/block-config-i18n.test.ts` + // 按 BLOCK_CONFIG 的结构重新推导并断言两语齐备。 + 'engine.inspector.pageBlock.field.object-grid.objectName': '对象', + 'engine.inspector.pageBlock.field.object-grid.columns': '列', + 'engine.inspector.pageBlock.field.object-grid.pageSize': '每页条数', + 'engine.inspector.pageBlock.field.object-grid.striped': '斑马纹行', + 'engine.inspector.pageBlock.field.object-grid.bordered': '显示边框', + 'engine.inspector.pageBlock.field.object-form.objectName': '对象', + 'engine.inspector.pageBlock.field.object-form.mode': '模式', + 'engine.inspector.pageBlock.option.mode.create': '新建', + 'engine.inspector.pageBlock.option.mode.edit': '编辑', + 'engine.inspector.pageBlock.option.mode.view': '查看', + 'engine.inspector.pageBlock.field.object-form.formType': '表单类型', + 'engine.inspector.pageBlock.option.formType.simple': '简单', + 'engine.inspector.pageBlock.option.formType.tabbed': '标签页', + 'engine.inspector.pageBlock.option.formType.wizard': '向导', + 'engine.inspector.pageBlock.option.formType.split': '分栏', + 'engine.inspector.pageBlock.option.formType.drawer': '抽屉', + 'engine.inspector.pageBlock.option.formType.modal': '弹窗', + 'engine.inspector.pageBlock.field.object-form.layout': '布局', + 'engine.inspector.pageBlock.option.layout.vertical': '纵向', + 'engine.inspector.pageBlock.option.layout.horizontal': '横向', + 'engine.inspector.pageBlock.option.layout.inline': '行内', + 'engine.inspector.pageBlock.option.layout.grid': '网格', + 'engine.inspector.pageBlock.field.object-form.columns': '列数(网格布局)', + 'engine.inspector.pageBlock.field.object-form.fields': '字段', + 'engine.inspector.pageBlock.field.object-form.title': '标题', + 'engine.inspector.pageBlock.field.object-form.description': '描述', + 'engine.inspector.pageBlock.field.object-metric.objectName': '对象', + 'engine.inspector.pageBlock.field.object-metric.label': '标签', + 'engine.inspector.pageBlock.field.object-metric.description': '描述', + 'engine.inspector.pageBlock.field.object-metric.icon': '图标', + 'engine.inspector.pageBlock.field.object-metric.colorVariant': '颜色', + 'engine.inspector.pageBlock.option.colorVariant.default': '默认', + 'engine.inspector.pageBlock.option.colorVariant.blue': '蓝色', + 'engine.inspector.pageBlock.option.colorVariant.teal': '青色', + 'engine.inspector.pageBlock.option.colorVariant.orange': '橙色', + 'engine.inspector.pageBlock.option.colorVariant.purple': '紫色', + 'engine.inspector.pageBlock.option.colorVariant.success': '成功', + 'engine.inspector.pageBlock.option.colorVariant.warning': '警告', + 'engine.inspector.pageBlock.option.colorVariant.danger': '危险', + 'engine.inspector.pageBlock.field.object-metric.format': '格式', + 'engine.inspector.pageBlock.option.format.number': '数字', + 'engine.inspector.pageBlock.option.format.currency': '货币', + 'engine.inspector.pageBlock.option.format.percent': '百分比', + 'engine.inspector.pageBlock.field.object-metric.prefix': '前缀', + 'engine.inspector.pageBlock.field.object-metric.suffix': '后缀', + 'engine.inspector.pageBlock.field.object-kanban.objectName': '对象', + 'engine.inspector.pageBlock.field.object-kanban.groupField': '分组字段', + 'engine.inspector.pageBlock.field.object-kanban.titleField': '标题字段', + 'engine.inspector.pageBlock.field.object-kanban.cardFields': '卡片字段', + 'engine.inspector.pageBlock.field.grid.columns': '列数', + 'engine.inspector.pageBlock.field.grid.gap': '间距', + 'engine.inspector.pageBlock.field.element:text.content': '内容', + 'engine.inspector.pageBlock.field.element:text.variant': '样式', + 'engine.inspector.pageBlock.option.variant.heading': '标题', + 'engine.inspector.pageBlock.option.variant.subheading': '副标题', + 'engine.inspector.pageBlock.option.variant.body': '正文', + 'engine.inspector.pageBlock.option.variant.caption': '说明文字', + 'engine.inspector.pageBlock.field.element:text.align': '对齐', + 'engine.inspector.pageBlock.option.align.left': '左对齐', + 'engine.inspector.pageBlock.option.align.center': '居中', + 'engine.inspector.pageBlock.option.align.right': '右对齐', + 'engine.inspector.pageBlock.field.element:image.src': '图片地址', + 'engine.inspector.pageBlock.field.element:image.alt': '替代文本', + 'engine.inspector.pageBlock.field.element:image.fit': '填充方式', + 'engine.inspector.pageBlock.option.fit.cover': '覆盖', + 'engine.inspector.pageBlock.option.fit.contain': '包含', + 'engine.inspector.pageBlock.option.fit.fill': '拉伸', + 'engine.inspector.pageBlock.field.element:definition-list.items': '条目', + 'engine.inspector.pageBlock.add.element:definition-list.items': '添加条目', + 'engine.inspector.pageBlock.field.element:definition-list.items.label': '标签', + 'engine.inspector.pageBlock.field.element:definition-list.items.value': '值', + 'engine.inspector.pageBlock.field.element:definition-list.columns': '列数(1 或 2)', + 'engine.inspector.pageBlock.field.element:definition-list.inline': '行内(标签 · 值)', + 'engine.inspector.pageBlock.field.element:repeater.object': '对象', + 'engine.inspector.pageBlock.field.element:repeater.titleField': '标题字段', + 'engine.inspector.pageBlock.field.element:repeater.fields': '字段', + 'engine.inspector.pageBlock.field.element:repeater.limit': '条数上限', + 'engine.inspector.pageBlock.field.element:repeater.emptyText': '空数据提示', + 'engine.inspector.pageBlock.field.element:repeater.divided': '行间分隔线', + 'engine.inspector.pageBlock.field.element:number.object': '对象', + 'engine.inspector.pageBlock.field.element:number.field': '字段', + 'engine.inspector.pageBlock.field.element:number.aggregate': '聚合方式', + 'engine.inspector.pageBlock.option.aggregate.count': '计数', + 'engine.inspector.pageBlock.option.aggregate.sum': '求和', + 'engine.inspector.pageBlock.option.aggregate.avg': '平均值', + 'engine.inspector.pageBlock.option.aggregate.min': '最小值', + 'engine.inspector.pageBlock.option.aggregate.max': '最大值', + 'engine.inspector.pageBlock.field.element:number.format': '格式', + 'engine.inspector.pageBlock.field.element:number.prefix': '前缀', + 'engine.inspector.pageBlock.field.element:number.suffix': '后缀', + 'engine.inspector.pageBlock.field.element:button.label': '按钮文字', + 'engine.inspector.pageBlock.field.element:button.variant': '样式', + 'engine.inspector.pageBlock.option.variant.primary': '主要', + 'engine.inspector.pageBlock.option.variant.secondary': '次要', + 'engine.inspector.pageBlock.option.variant.danger': '危险', + 'engine.inspector.pageBlock.option.variant.ghost': '幽灵', + 'engine.inspector.pageBlock.option.variant.link': '链接', + 'engine.inspector.pageBlock.field.element:button.size': '尺寸', + 'engine.inspector.pageBlock.option.size.small': '小', + 'engine.inspector.pageBlock.option.size.medium': '中', + 'engine.inspector.pageBlock.option.size.large': '大', + 'engine.inspector.pageBlock.field.element:button.icon': '图标', + 'engine.inspector.pageBlock.field.element:button.action': '动作', + 'engine.inspector.pageBlock.field.page:header.title': '标题', + 'engine.inspector.pageBlock.field.page:header.subtitle': '副标题', + 'engine.inspector.pageBlock.field.page:header.icon': '图标', + 'engine.inspector.pageBlock.field.page:header.breadcrumb': '显示面包屑', + 'engine.inspector.pageBlock.field.page:card.title': '标题', + 'engine.inspector.pageBlock.field.page:card.bordered': '显示边框', + 'engine.inspector.pageBlock.field.page:tabs.items': '标签页', + 'engine.inspector.pageBlock.add.page:tabs.items': '添加标签页', + 'engine.inspector.pageBlock.field.page:tabs.items.key': '键', + 'engine.inspector.pageBlock.field.page:tabs.items.label': '标签', + 'engine.inspector.pageBlock.field.page:accordion.title': '标题', + 'engine.inspector.pageBlock.field.page:accordion.items': '分区', + 'engine.inspector.pageBlock.add.page:accordion.items': '添加分区', + 'engine.inspector.pageBlock.field.page:accordion.items.value': '键', + 'engine.inspector.pageBlock.field.page:accordion.items.label': '标签', + 'engine.inspector.pageBlock.field.record:related_list.objectName': '对象', + 'engine.inspector.pageBlock.field.record:related_list.relationshipField': '关联字段', + 'engine.inspector.pageBlock.field.record:related_list.title': '标题', + 'engine.inspector.pageBlock.field.record:related_list.limit': '条数上限', + 'engine.inspector.pageBlock.field.record:highlights.fields': '字段', + 'engine.inspector.pageBlock.field.record:details.sections': '分区', + 'engine.inspector.pageBlock.add.record:details.sections': '添加分区', + 'engine.inspector.pageBlock.field.record:details.sections.name': '名称(i18n 键)', + 'engine.inspector.pageBlock.field.record:details.sections.label': '标签', + 'engine.inspector.pageBlock.field.record:details.sections.columns': '列数', + 'engine.inspector.pageBlock.field.record:details.sections.fields': '字段', + 'engine.inspector.pageBlock.field.record:alert.severity': '严重度', + 'engine.inspector.pageBlock.option.severity.info': '信息', + 'engine.inspector.pageBlock.option.severity.warning': '警告', + 'engine.inspector.pageBlock.option.severity.error': '错误', + 'engine.inspector.pageBlock.option.severity.success': '成功', + 'engine.inspector.pageBlock.field.record:alert.title': '标题', + 'engine.inspector.pageBlock.field.record:alert.body': '正文', + 'engine.inspector.pageBlock.field.record:alert.icon': '图标', + 'engine.inspector.pageBlock.field.record:alert.dismissible': '可关闭', + 'engine.inspector.pageBlock.field.record:path.statusField': '状态字段', + 'engine.inspector.pageBlock.field.record:path.stages': '阶段', + 'engine.inspector.pageBlock.add.record:path.stages': '添加阶段', + 'engine.inspector.pageBlock.field.record:path.stages.value': '值', + 'engine.inspector.pageBlock.field.record:path.stages.label': '标签', + 'engine.inspector.pageBlock.field.record:quick_actions.actionNames': '动作名称', + 'engine.inspector.pageBlock.field.record:quick_actions.location': '位置', + 'engine.inspector.pageBlock.option.location.record_header': '记录头部', + 'engine.inspector.pageBlock.option.location.record_more': '记录更多菜单', + 'engine.inspector.pageBlock.option.location.record_section': '记录分区', + 'engine.inspector.pageBlock.option.location.record_related': '记录关联列表', + 'engine.inspector.pageBlock.option.location.list_toolbar': '列表工具栏', + 'engine.inspector.pageBlock.option.location.list_item': '列表行', + 'engine.inspector.pageBlock.option.location.global_nav': '全局导航', + 'engine.inspector.pageBlock.field.ai:input.agentName': '智能体', + 'engine.inspector.pageBlock.field.ai:input.placeholder': '输入框占位提示', // Report default ("home") inspector 'engine.inspector.report.kind': '报表', 'engine.inspector.report.close': '关闭报表', diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/PageBlockInspector.i18n.test.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/PageBlockInspector.i18n.test.tsx new file mode 100644 index 000000000..3d1b48aca --- /dev/null +++ b/packages/app-shell/src/views/metadata-admin/inspectors/PageBlockInspector.i18n.test.tsx @@ -0,0 +1,172 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * objectui#3913 — the PROPERTIES panel renders in the session's language. + * + * The sibling `previews/__tests__/block-config-i18n.test.ts` pins the TABLE + * (every label is a key its position implies, and both locales define it). That + * is a fact about data. This file pins the fact about the screen, and they are + * different: `renderField` reaches `f.label` from eleven places — eight as a + * `label=` prop, three as `