Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 136 additions & 1 deletion examples/app-showcase/src/system/translations/index.ts
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

/**
* English + Simplified Chinese labels for the core showcase objects.
* English + Simplified Chinese labels for the core showcase objects — and for
* the app shell those objects are read in.
*
* Covers EVERY field surfaced as a column on the showcase pages so a list never
* mixes locales (the prior bundle translated only a handful, leaving columns
* like Project / Assignee / Progress falling back to their English field label
* next to translated 状态 / 优先级 — an obvious inconsistency on a zh-CN session).
*
* The `apps.showcase_app` block carries the sidebar — navigation items and
* group headers — for that same reason one level up: the columns were
* translated under an English menu, and the sentence above, scoped to columns,
* is exactly why nothing caught it. This is a description of what this file
* CONTAINS, not a wider guarantee: it does not claim every declared surface of
* the showcase is translated. `scripts/i18n-coverage-baseline.json` is the
* measure of what still is not.
*/
export const ShowcaseTranslationBundle = {
en: {
Expand DownExpand Up@@ -650,6 +659,132 @@ export const ShowcaseTranslationBundle = {
},
},
},
// ── The app shell: sidebar navigation ────────────────────────────────
// A THIRD key space, addressed by the navigation node's stable `id`
// regardless of tree depth: `apps.<app>.navigation.<id>.label`, applied by
// `translateApp` (`@objectstack/spec/system/i18n-resolver`) at the `/meta`
// boundary in `@objectstack/rest`. Nothing under `objects.*` answers for
// it — a nav entry whose label was authored ('Projects', not the bare
// `showcase_project`) keeps that authored label, so the object's translated
// `pluralLabel` never reaches the sidebar. Which is why a zh-CN session
// showed translated view tabs, columns, field labels and option values
// under an English sidebar: the bundle carried no app keys at all.
//
// Every labelled node of `ui/apps/index.ts` is here — 49 items and the 8
// `grp_*` group headers, the exact set `os lint` reports for this app.
// `nav_sep_reports` is a separator: it declares no label, so there is
// nothing to translate and no key for it.
//
// Wording reuses the vocabulary this bundle already established rather than
// minting a second word per idea: 项目 / 任务 / 客户 / 联系人 / 发票 / 设置
// from the object blocks, 任务清单 · 工时按状态分布 · 活动时间线 ·
// 工作地点地图 · 看板 · 日历 from `showcase_task._views`, 排期 from its
// `_sections`, 分流 from `showcase_inquiry._views.triage`, 业务单元 from
// the platform bundle's `sys_business_unit`.
apps: {
showcase_app: {
// The app's own name, rendered at the top of the same sidebar
// (`apps.<name>.label`, objectui's `useObjectLabel().appLabel`). Left
// untranslated it reproduces the mixed shell one line above the tree
// this block fixes. Setup and Account translate theirs; Studio keeps
// its product name. This app is named for what it does, not branded,
// so it translates.
label: '功能展示',
navigation: {
// Landing + the page-authoring teaching index — the two ungrouped
// entries above every group.
nav_capability_map: { label: '能力地图' },
nav_start_here: { label: '页面搭建' },

// Workspace — the app working like a real product.
grp_workspace: { label: '工作区' },
nav_my_work: { label: '我的工作' },
// 审批 matches the platform bundle's `group_approvals`; the page is
// the reviewer's queue, not the request list.
nav_review_queue: { label: '审批' },
nav_new_project_wizard: { label: '新建项目(向导)' },
// The object's own `pluralLabel` above (showcase_preference).
nav_settings: { label: '设置' },

// Data Model — one entry per object list. Each reads the word this
// bundle already gives that object.
grp_data: { label: '数据模型' },
nav_projects: { label: '项目' },
nav_tasks: { label: '任务' },
nav_accounts: { label: '客户' },
nav_contacts: { label: '联系人' },
nav_invoices: { label: '发票' },
// `showcase_expense_report` has no translated object label (it sits
// inside check-i18n-coverage's frozen baseline), so this renders the
// nav label directly; 报销单 is the standard word for the document.
nav_expense_reports: { label: '报销单' },
nav_products: { label: '产品' },
nav_teams: { label: '团队' },
nav_categories: { label: '分类' },
nav_business_units: { label: '业务单元' },
nav_field_zoo: { label: '字段动物园' },
nav_cascade: { label: '级联选择' },

// Data slices — the same object under a pre-applied filter. Each
// reads the option label of the value it filters on, so the entry
// says the same word as the cells it lists (进行中 / 紧急 / 评审中,
// from `showcase_task.fields.status|priority.options`).
grp_slices: { label: '数据切片(筛选)' },
nav_slice_in_progress: { label: '进行中的任务' },
nav_slice_urgent: { label: '紧急任务' },
nav_slice_review: { label: '评审中的任务' },

// Analytics.
grp_analytics: { label: '数据分析' },
nav_command_center: { label: '指挥中心(大屏)' },
nav_ops: { label: '交付运营' },
nav_revenue_pulse: { label: '营收概览(带筛选)' },
nav_charts: { label: '图表画廊' },
// View-scoped and report entries whose surface this bundle already
// names: 任务清单 is `showcase_task._views.tabular`, 工时按状态分布
// is `_views.chart` — the same list under the same word.
nav_report_tabular: { label: '任务清单' },
nav_report_summary: { label: '工时按状态分布' },
nav_report_chart: { label: '工时按状态分布(图表)' },
nav_report_matrix: { label: '状态 × 优先级' },
nav_report_joined: { label: '任务总览' },

// The page-authoring gallery, split by authoring KIND. All four
// headers share one word with `nav_start_here` above, exactly as the
// English shares "Authoring" with "Page Authoring".
grp_auth_structured: { label: '页面搭建 · 结构化' },
nav_gallery: { label: '组件画廊' },
nav_styling_gallery: { label: '样式(ADR-0065)' },
nav_page_variables: { label: '页面变量' },
nav_contact_form: { label: '联系表单' },
nav_project_workspace: { label: '新建项目 + 任务' },
nav_task_workbench: { label: '任务工作台' },
nav_task_triage: { label: '任务分流(标签页)' },
// The page's base filter hides completed projects rather than
// matching `status = active`, so this says 进行中 rather than 活跃.
nav_active_projects: { label: '进行中的项目' },

grp_auth_viz: { label: '页面搭建 · 可视化' },
nav_task_all_views: { label: '全部视图' },
nav_task_board: { label: '任务看板' },
nav_task_calendar: { label: '任务日历' },
// 画廊 is objectui's own word for the gallery view type, shared here
// with 组件画廊 / 图表画廊 above.
nav_task_gallery: { label: '任务画廊' },
nav_task_schedule: { label: '团队排期' },
nav_task_timeline: { label: '活动时间线' },
nav_task_map: { label: '工作地点地图' },

grp_auth_html: { label: '页面搭建 · HTML' },
nav_command_center_jsx: { label: '指挥中心' },

grp_auth_react: { label: '页面搭建 · React' },
nav_crm_workbench: { label: 'CRM 工作台 · 主从视图' },
nav_task_desk: { label: '任务处理台 · 抽屉与弹窗' },
nav_renewals_pipeline: { label: '续约管道 · 汇总与区块' },
},
},
},
// See the `en` block: object-less actions resolve ONLY through
// `globalActions`. Translated at birth for the same reason as
// `showcase_action_param_gallery.params.p_assignee` above — this example is
Expand Down
2 changes: 1 addition & 1 deletion scripts/i18n-coverage-baseline.json
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
{
"examples/app-crm/objectstack.config.ts": 89,
"examples/app-showcase/objectstack.config.ts": 451,
"examples/app-showcase/objectstack.config.ts": 393,
"examples/app-todo/objectstack.config.ts": 120,
"packages/platform-objects/scripts/i18n-extract.config.ts": 0,
"packages/plugins/plugin-approvals/scripts/i18n-extract.config.ts": 0,
Expand Down
Loading