Skip to content

feat(i18n, app-shell): one word per state in Studio and Setup, and the permission matrix columns in Chinese - #29841

Merged
objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-4k3hr3
Nov 3, 2026
Merged

objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-4k3hr3

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread

Fixes #29729

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Studio 和 Setup 里同一个状态只用一个词。中文里“打开/关闭”统一为 启用/停用,“定制”这个动作统一为 定制(不再混用 自定义),环境里新建、非软件包带来的权限集标为 新增;权限矩阵的列头在中文下直接写 创建、读取……查看全部、修改全部,不再是 C/R/U/D 字母;“OWD”前缀改为 记录共享模型。英文里流程状态统一为 Switched on / Switched off。
  • 为什么改:同一件事在相邻两个界面叫不同的名字,用户会以为是两件不同的事;中文用户看不懂 C/R/U/D 和 OWD 这些英文缩写。另外修了一个缺陷:中文界面下 Setup 的权限矩阵如果在中文词表加载完成前就渲染,图例和列头提示会一直显示英文。
  • 风险与回滚:几乎只改文案和一处 React memo 的依赖,没有数据、接口或权限行为的变化。回滚就是还原这个 PR。英文有 7 条 Studio 自动化状态文案改了词,已按设计豁免登记在 en 漂移门禁的基线里。
  • 先看:ui/packages/i18n/src/namespaces/studio/zh.ts 的改动行,以及 PermissionMatrixEditor.tsx 里列头、图例和 OWD 标签的几处改动。
  • 两分钟验证:用中文打开 Setup 的某个权限集和 Studio 的“访问”页,看列头是中文词、没有字母图例、对象行的标签是“记录共享模型:私有(默认)”;打开 Studio 的自动化页,看软件包流程的开关写“本部署中已启用/已停用”。截图见下方“Screenshots”。
  • 需要你做的:确认 新增 / Added 这个权限集徽标用词(理由见下方 Acceptance notes),以及 Studio Access: a permission set the .custom pair added reads "Package" in its header, beside the rail's "Added" #29809 合入后是否需要跟进。

What changes

Strings, one legend gate, one chip and one memo. No data, API, permission or protocol behaviour changes.

  1. Switched on / switched off, one word.
    • zh: the packaged-flow ledger family (engine.studio.ledger.on/off/notRunning/hint/walled/switchedOn/switchedOff) moves from 开启 / 关闭 to 启用 / 停用. Console packagedAutomation.off moves from 已关闭 to 已停用, and actionsSubtitle from 关闭后 to 停用后.
    • en: engine.studio.ledger.on/off/notRunning read "Switched on/off for this deployment[, not running here]". engine.studio.auto.on/off/offTitle/enabled/disabled/enabledToast/disabledToast read "Switched on" / "Switched off" (they said On / Off and Enabled / Disabled). These are the words Studio: one vocabulary for an item's state across the pillars, All metadata and Access #29705 landed for the landing. The verbs (enableTitle / disableTitle) stay verbs.
  2. The Customize act reads 定制 (zh), in 12 rows: the button, its titles, the walled and no-version lines, the draft footer, the restore confirmations, the landing lines quoting the button, and the two form-editor notes. This matches 已定制 and 可定制. Nine rows where 自定义 means user-defined (a custom value, key, renderer, page or code) keep 自定义. The census in the stateVocabulary test lists both groups.
  3. perm.badge.custom reads 新增 / "Added" (it read 自定义 / "Custom"). See Acceptance notes for why it is not 已定制.
  4. Permission matrix columns.
    • zh: the object-action headers spell the words through a new perm.col.* family: 创建 读取 编辑 删除 导出 转移 查看全部 修改全部. The two long ones break between 查看/全部 and 修改/全部 (break-keep).
    • en: keeps C R U D E Tr VA MA.
    • The legend line that spells the letters out is drawn only where the headers are abbreviations (headersAbbreviate). So zh no longer repeats the words, and en keeps the legend.
  5. Setup's per-object chip reads through perm.owd.chip: en "OWD {value}", zh 记录共享模型:{value}. Before, it was a hard-coded OWD prefix.
  6. Fixed: lazy-catalogue memo. getObjectActions(locale) was memoised on the locale alone. A zh matrix whose first render ran before the lazily fetched studio catalogue was resident kept the en answer, so Setup's legend and every header tooltip read English in zh-CN. The deps now carry isStudioCatalogueLoaded(locale).
  7. check-i18n-en-drift accepts objectstack#N. ISSUE_PATTERN is now ^(?:objectui|objectstack)#\d+$, because the ui tree lives in this repo now. The 7 en auto.* rows above are designer waivers keyed to objectstack#29729, and the test's designer ceiling moves 0 → 7.

Acceptance notes

  • Why the badge says 新增 / Added, not 已定制. PermissionMatrixEditor.tsx L748 picks the badge with const shippedByPackage = !!packageId || codeIsArtifact;. The perm.badge.custom branch is therefore a permission set that no package ships and that has no code artifact: one this deployment added. Nothing on that branch checks whether a shipped base was changed, so 已定制 (customized) would claim something the editor does not know. 新增 / Added is the word engine.customizationMark.added already uses for an item added beside a base, and the census test pins the two to the same word.
  • Studio Access: a permission set the .custom pair added reads "Package" in its header, beside the rail's "Added" #29809 (open, seat 4) changes which branch a set added by a .custom pair takes. This PR does not touch that choice: only the word on the custom branch changes. If Studio Access: a permission set the .custom pair added reads "Package" in its header, beside the rail's "Added" #29809 lands first, the rationale above still holds for whatever reaches that branch.
  • Not changed here:
    • The en Console packagedAutomation On / Off: not ruled on this card.
    • From main, new since the card was written: the zh Console profile app lock (已开启 / 已关闭, a different surface), and engine.packages.detail.*Disableable (禁用并重新启用, a new 禁用 / 停用 split). These are left for a follow-up card.

Screenshots

On the merged tree, in /mnt/project-files/issue-29729/after/ (project files):

  • after-environment-{zh,en}-1304.png: Setup's matrix, zh words with no legend, en letters with the legend, and the chip.
  • after-studio-{zh,en}-1304.png: the Studio Access pillar.
  • rail-{en,zh}-1024.png: the automation rail at the narrowest Studio width. "Switched on" is 69 px in a 215 px legend with no overflow (scrollWidth equals width). The en legend grows from 3 lines to 4 (72 px high). zh is unchanged at 53 px.

Before shots and the legend options are in /mnt/project-files/issue-29729/legend/.

Tests

  • New PermissionMatrixEditor.columnHeaders-29729.test.tsx. It does not preload the catalogue and asserts the not-resident precondition first. It checks zh headers, tooltips and no legend in both renderings; an en CONTROL with letters and the legend; and the chip in zh and en.
  • DirectoryPage.stateVocabulary-29705.test.tsx: a second-pass census.
    • No 开启 / 关闭 in the switched-on/off rows.
    • No bare On / Off / Enabled / Disabled in the en rows.
    • The packaged actions in zh, with an en CONTROL.
    • The 12 Customize rows read 定制 and agree with the button and landing.
    • A 7-row 自定义 CONTROL.
    • The badge equals the customization mark's added word.
  • check-i18n-en-drift.test.ts: accepts objectstack#N. A CONTROL still refuses objectstack 29729, objectstack#, cloud#12, #29729, objectstack#29729x and objectui-3650. The ceiling ratchet moves to 7.
  • These tests are updated to the new words: the badge, provenanceBadge-7611, ledgerSwitch-28148, FlowStatusDot and customizeFlow-28570. customizeFlow now checks the header by its disable title, because "Switched on" also appears in the Status pill.
Verification
  • Nine ablations each turned red, with the tree restored after each:

    • the memo deps;
    • the Setup legend gate;
    • zh perm.col.create back to C;
    • the OWD prefix back;
    • zh ledger.off back to 已关闭;
    • zh customize.action back to 自定义;
    • zh badge back to 自定义;
    • zh packagedAutomation.off back to 已关闭;
    • en auto.off back to Off.

    The gate script is pinned by its CONTROL test, not by ablation.

  • 184 neighbour test files are green, in three chunks. After the main merge, the 13 touched test files (220 tests) are green.

  • dispatch-gates: all 35 derived gates exit 0. check-i18n-en-drift (run by hand, not derived) is green with 7 waived.

  • Type-check passes for @object-ui/i18n and @object-ui/app-shell. ESLint: 0 errors.

  • These gates exit 0 after the merge: sdui-manifest, changeset-no-major, empty-changeset, adr-0087, nul-bytes, type-check-debt.

  • Deviation: the refusal text and the help-text examples in check-i18n-en-drift.mjs now spell objectstack#1234, beyond the one-line pattern change.


Generated by Claude Code

…zh-CN

The switch-off confirm (title, body, button) and the switched-on/off toasts
still read 开启 / 关闭 on the page whose column reads 已停用. Five zh rows move
to 启用 / 停用, pinned by a census over every zh packagedAutomation row.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jR2PhzeUkFuXHiwpdp
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#2 · zhuangjianguo · session_01QsR2jRFuJz9QBZqPVHYVhJ

维护者速读

  • 改了什么:Studio 与设置里同一个状态只用一个词。中文:开关状态统一为「启用 / 停用」(打包流程的账本开关、设置 › 打包动作的状态列、停用确认框和两条提示);「定制」动作统一为「定制」,表示用户自定义内容的「自定义」保持不变;不来自任何软件包的权限集标为「新增」。权限矩阵中文表头直接写动作词(创建 … 查看 全部),不再需要缩写图例;英文保留 C … MA 和图例。英文的流程状态改为 "Switched on / Switched off"。
  • 为什么改:Studio zh-CN: one word left per state after #29705 — 已关闭 vs 已停用, 自定义 vs 定制, and Access's perm.badge.custom #29729 实测同一状态在相邻界面里出现「开启 / 启用 / 关闭 / 停用」「自定义 / 定制」两套说法,用户无法判断是不是同一件事。另实测:中文环境下设置页的矩阵图例和每个列提示显示英文,原因是矩阵在 Studio 中文词条懒加载完成前就缓存了列定义。
  • 风险与回滚:只改词条、一处表头渲染和一个缓存依赖,无服务端、无数据改动。en 改了 7 行而其余语言包未跟进,按门禁规则登记为 7 条 objectstack#29729 豁免(这些行的中文本来就对)。回滚即 revert 本 PR。
  • 先看:ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx(getObjectActions 的缓存依赖与图例开关)、ui/packages/i18n/src/namespaces/studio/zh.ts、ui/scripts/check-i18n-en-drift.mjs。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.columnHeaders-29729.test.tsx packages/app-shell/src/views/setup/DirectoryPage.stateVocabulary-29705.test.tsx scripts/__tests__/check-i18n-en-drift.test.ts,预期全绿。
  • 需要你做的:无。席位验收后进合并队列。

席位意见: 用词按本席 05:25Z 的裁定落实,没有扩大。评审时发现设置 › 打包动作的停用确认框和两条提示仍是「开启 / 关闭」,与同页状态列的「已停用」不一致,已退回补齐(3368fa75),并加了「打包动作中文词条不含 开启/关闭」的普查测试。缓存修复有不预加载中文词条的测试钉住。

席位核对 — ACCEPT · domain:ui#2 · head 3368fa75 · 2026-11-03T07:28Z

  • 形态: draft PR on main, Fixes #29729 on its own line. 15 files, +519/−108. Tier S: check-governed-merges --pr 29841 says not governed (0 of 15 paths hit the register), under 3000 lines. The surface matches claim and amendment 6596167429: studio en/zh, locales/zh.ts (packagedAutomation), PermissionMatrixEditor.tsx, the drift script, its test and baseline, the touched tests, and one changeset.
  • 前提实测: on main, the packaged-flow ledger read 本部署中已开启/已关闭 beside Setup's 已启用 column; 12 Customize-sense rows read 自定义 beside 已定制; perm.badge.custom read 自定义 on a set no package ships. In zh-CN the Setup legend and header tooltips read English because getObjectActions(locale) was memoized on [locale] before the lazy studio catalogue arrived.
  • 门禁 check-runs (pinned to head 3368fa7542385420bc39bd53c3caababfb70c531): 55 runs: 44 success, 11 path-skipped, none failed or cancelled, including Lint & Repo Gates, Type Check UI, Test UI (16/16), Build & E2E UI, Live E2E UI, Lint UI, Check Changeset, Governed Surface Queue Guard and PR-body guards. Mergeable state clean. The two reds on the superseded head 46bc7f8b are runs cancelled by the push of 3368fa75, not failures. Dev local: the vocabulary test file 96/96, ui/packages/i18n 95 files / 1443 tests, check-i18n-en-drift, sdui-manifest and empty-changeset all exit 0.
  • Code read: the memo now keys on [locale, catalogueResident] (catalogueResident = isStudioCatalogueLoaded(locale), imported from the exported @object-ui/i18n/namespaces/studio subpath), so the columns are rebuilt once the catalogue lands; the new test renders without preloading it. headersAbbreviate(actions, locale) draws the legend only when a header is an abbreviation, so en keeps it and zh drops it; headers sit in break-keep spans, and the zh four-character words carry a space as their only break point (查看 / 全部 in the 52 px column). The OWD chip reads perm.owd.chip with {value} instead of a hard-coded OWD prefix. ISSUE_PATTERN accepts objectui#N and objectstack#N, pinned both ways plus a malformed-id CONTROL. The designer-waiver ceiling moves 0 → 7, one entry per en row that changed while its zh was already right; each is a reviewed edit in this PR. After review, 3368fa75 moved Setup's switch-off confirm and its two toasts to 启用/停用, with a census pin over every zh packagedAutomation key and an exact-value pin; the dev ablated actionOffConfirm back to 关闭 and both pins went red.
  • 接受的偏差: en tooltips engine.studio.auto.onBound / onUnbound still begin "Enabled ·", and the en action verbs (enableTitle, "Enable this automation") stay verbs; the ruling named the state words only. The PR body's item 1 lists only packagedAutomation.off and actionsSubtitle for Setup; the changeset's first bullet is the complete account, including the confirm and toasts.
  • 范围外去向: recorded here, not filed (word choices outside the ruled families, no defect): en Setup packagedAutomation.on/off stay "On"/"Off" in the column cell; zh engine.packages.detail.*Disableable say 禁用 for disabling a whole package (a different act from switching one item); the Console app lock settings read 已开启/已关闭 (a device setting, not a Studio item state). No Skills-docs: line is owed.
  • 落地条款: Clause-②: no (@object-ui/i18n keys and the private @object-ui/app-shell publish no contract surface), Metadata-protocol: none, patch. No contract review is owed. Land by pr_ready + automerge_enable once every check is green on this head.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 3, 2026 07:29
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 3, 2026 07:29
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 4985dde Nov 3, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-4k3hr3 branch November 3, 2026 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Studio zh-CN: one word left per state after #29705 — 已关闭 vs 已停用, 自定义 vs 定制, and Access's perm.badge.custom

1 participant