|
1 | 1 | // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. |
2 | 2 |
|
3 | 3 | /** |
4 | | - * English + Simplified Chinese labels for the core showcase objects. |
| 4 | + * English + Simplified Chinese labels for the core showcase objects — and for |
| 5 | + * the app shell those objects are read in. |
5 | 6 | * |
6 | 7 | * Covers EVERY field surfaced as a column on the showcase pages so a list never |
7 | 8 | * mixes locales (the prior bundle translated only a handful, leaving columns |
8 | 9 | * like Project / Assignee / Progress falling back to their English field label |
9 | 10 | * next to translated 状态 / 优先级 — an obvious inconsistency on a zh-CN session). |
| 11 | + * |
| 12 | + * The `apps.showcase_app` block carries the sidebar — navigation items and |
| 13 | + * group headers — for that same reason one level up: the columns were |
| 14 | + * translated under an English menu, and the sentence above, scoped to columns, |
| 15 | + * is exactly why nothing caught it. This is a description of what this file |
| 16 | + * CONTAINS, not a wider guarantee: it does not claim every declared surface of |
| 17 | + * the showcase is translated. `scripts/i18n-coverage-baseline.json` is the |
| 18 | + * measure of what still is not. |
10 | 19 | */ |
11 | 20 | export const ShowcaseTranslationBundle = { |
12 | 21 | en: { |
@@ -650,6 +659,132 @@ export const ShowcaseTranslationBundle = { |
650 | 659 | }, |
651 | 660 | }, |
652 | 661 | }, |
| 662 | + // ── The app shell: sidebar navigation ──────────────────────────────── |
| 663 | + // A THIRD key space, addressed by the navigation node's stable `id` |
| 664 | + // regardless of tree depth: `apps.<app>.navigation.<id>.label`, applied by |
| 665 | + // `translateApp` (`@objectstack/spec/system/i18n-resolver`) at the `/meta` |
| 666 | + // boundary in `@objectstack/rest`. Nothing under `objects.*` answers for |
| 667 | + // it — a nav entry whose label was authored ('Projects', not the bare |
| 668 | + // `showcase_project`) keeps that authored label, so the object's translated |
| 669 | + // `pluralLabel` never reaches the sidebar. Which is why a zh-CN session |
| 670 | + // showed translated view tabs, columns, field labels and option values |
| 671 | + // under an English sidebar: the bundle carried no app keys at all. |
| 672 | + // |
| 673 | + // Every labelled node of `ui/apps/index.ts` is here — 49 items and the 8 |
| 674 | + // `grp_*` group headers, the exact set `os lint` reports for this app. |
| 675 | + // `nav_sep_reports` is a separator: it declares no label, so there is |
| 676 | + // nothing to translate and no key for it. |
| 677 | + // |
| 678 | + // Wording reuses the vocabulary this bundle already established rather than |
| 679 | + // minting a second word per idea: 项目 / 任务 / 客户 / 联系人 / 发票 / 设置 |
| 680 | + // from the object blocks, 任务清单 · 工时按状态分布 · 活动时间线 · |
| 681 | + // 工作地点地图 · 看板 · 日历 from `showcase_task._views`, 排期 from its |
| 682 | + // `_sections`, 分流 from `showcase_inquiry._views.triage`, 业务单元 from |
| 683 | + // the platform bundle's `sys_business_unit`. |
| 684 | + apps: { |
| 685 | + showcase_app: { |
| 686 | + // The app's own name, rendered at the top of the same sidebar |
| 687 | + // (`apps.<name>.label`, objectui's `useObjectLabel().appLabel`). Left |
| 688 | + // untranslated it reproduces the mixed shell one line above the tree |
| 689 | + // this block fixes. Setup and Account translate theirs; Studio keeps |
| 690 | + // its product name. This app is named for what it does, not branded, |
| 691 | + // so it translates. |
| 692 | + label: '功能展示', |
| 693 | + navigation: { |
| 694 | + // Landing + the page-authoring teaching index — the two ungrouped |
| 695 | + // entries above every group. |
| 696 | + nav_capability_map: { label: '能力地图' }, |
| 697 | + nav_start_here: { label: '页面搭建' }, |
| 698 | + |
| 699 | + // Workspace — the app working like a real product. |
| 700 | + grp_workspace: { label: '工作区' }, |
| 701 | + nav_my_work: { label: '我的工作' }, |
| 702 | + // 审批 matches the platform bundle's `group_approvals`; the page is |
| 703 | + // the reviewer's queue, not the request list. |
| 704 | + nav_review_queue: { label: '审批' }, |
| 705 | + nav_new_project_wizard: { label: '新建项目(向导)' }, |
| 706 | + // The object's own `pluralLabel` above (showcase_preference). |
| 707 | + nav_settings: { label: '设置' }, |
| 708 | + |
| 709 | + // Data Model — one entry per object list. Each reads the word this |
| 710 | + // bundle already gives that object. |
| 711 | + grp_data: { label: '数据模型' }, |
| 712 | + nav_projects: { label: '项目' }, |
| 713 | + nav_tasks: { label: '任务' }, |
| 714 | + nav_accounts: { label: '客户' }, |
| 715 | + nav_contacts: { label: '联系人' }, |
| 716 | + nav_invoices: { label: '发票' }, |
| 717 | + // `showcase_expense_report` has no translated object label (it sits |
| 718 | + // inside check-i18n-coverage's frozen baseline), so this renders the |
| 719 | + // nav label directly; 报销单 is the standard word for the document. |
| 720 | + nav_expense_reports: { label: '报销单' }, |
| 721 | + nav_products: { label: '产品' }, |
| 722 | + nav_teams: { label: '团队' }, |
| 723 | + nav_categories: { label: '分类' }, |
| 724 | + nav_business_units: { label: '业务单元' }, |
| 725 | + nav_field_zoo: { label: '字段动物园' }, |
| 726 | + nav_cascade: { label: '级联选择' }, |
| 727 | + |
| 728 | + // Data slices — the same object under a pre-applied filter. Each |
| 729 | + // reads the option label of the value it filters on, so the entry |
| 730 | + // says the same word as the cells it lists (进行中 / 紧急 / 评审中, |
| 731 | + // from `showcase_task.fields.status|priority.options`). |
| 732 | + grp_slices: { label: '数据切片(筛选)' }, |
| 733 | + nav_slice_in_progress: { label: '进行中的任务' }, |
| 734 | + nav_slice_urgent: { label: '紧急任务' }, |
| 735 | + nav_slice_review: { label: '评审中的任务' }, |
| 736 | + |
| 737 | + // Analytics. |
| 738 | + grp_analytics: { label: '数据分析' }, |
| 739 | + nav_command_center: { label: '指挥中心(大屏)' }, |
| 740 | + nav_ops: { label: '交付运营' }, |
| 741 | + nav_revenue_pulse: { label: '营收概览(带筛选)' }, |
| 742 | + nav_charts: { label: '图表画廊' }, |
| 743 | + // View-scoped and report entries whose surface this bundle already |
| 744 | + // names: 任务清单 is `showcase_task._views.tabular`, 工时按状态分布 |
| 745 | + // is `_views.chart` — the same list under the same word. |
| 746 | + nav_report_tabular: { label: '任务清单' }, |
| 747 | + nav_report_summary: { label: '工时按状态分布' }, |
| 748 | + nav_report_chart: { label: '工时按状态分布(图表)' }, |
| 749 | + nav_report_matrix: { label: '状态 × 优先级' }, |
| 750 | + nav_report_joined: { label: '任务总览' }, |
| 751 | + |
| 752 | + // The page-authoring gallery, split by authoring KIND. All four |
| 753 | + // headers share one word with `nav_start_here` above, exactly as the |
| 754 | + // English shares "Authoring" with "Page Authoring". |
| 755 | + grp_auth_structured: { label: '页面搭建 · 结构化' }, |
| 756 | + nav_gallery: { label: '组件画廊' }, |
| 757 | + nav_styling_gallery: { label: '样式(ADR-0065)' }, |
| 758 | + nav_page_variables: { label: '页面变量' }, |
| 759 | + nav_contact_form: { label: '联系表单' }, |
| 760 | + nav_project_workspace: { label: '新建项目 + 任务' }, |
| 761 | + nav_task_workbench: { label: '任务工作台' }, |
| 762 | + nav_task_triage: { label: '任务分流(标签页)' }, |
| 763 | + // The page's base filter hides completed projects rather than |
| 764 | + // matching `status = active`, so this says 进行中 rather than 活跃. |
| 765 | + nav_active_projects: { label: '进行中的项目' }, |
| 766 | + |
| 767 | + grp_auth_viz: { label: '页面搭建 · 可视化' }, |
| 768 | + nav_task_all_views: { label: '全部视图' }, |
| 769 | + nav_task_board: { label: '任务看板' }, |
| 770 | + nav_task_calendar: { label: '任务日历' }, |
| 771 | + // 画廊 is objectui's own word for the gallery view type, shared here |
| 772 | + // with 组件画廊 / 图表画廊 above. |
| 773 | + nav_task_gallery: { label: '任务画廊' }, |
| 774 | + nav_task_schedule: { label: '团队排期' }, |
| 775 | + nav_task_timeline: { label: '活动时间线' }, |
| 776 | + nav_task_map: { label: '工作地点地图' }, |
| 777 | + |
| 778 | + grp_auth_html: { label: '页面搭建 · HTML' }, |
| 779 | + nav_command_center_jsx: { label: '指挥中心' }, |
| 780 | + |
| 781 | + grp_auth_react: { label: '页面搭建 · React' }, |
| 782 | + nav_crm_workbench: { label: 'CRM 工作台 · 主从视图' }, |
| 783 | + nav_task_desk: { label: '任务处理台 · 抽屉与弹窗' }, |
| 784 | + nav_renewals_pipeline: { label: '续约管道 · 汇总与区块' }, |
| 785 | + }, |
| 786 | + }, |
| 787 | + }, |
653 | 788 | // See the `en` block: object-less actions resolve ONLY through |
654 | 789 | // `globalActions`. Translated at birth for the same reason as |
655 | 790 | // `showcase_action_param_gallery.params.p_assignee` above — this example is |
|
0 commit comments