Repository navigation
Commit 8c28972
fix(app-shell): zh-CN Studio first screens stop mixing English in the package form, flow rail groups and column picker (#29773)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9Ubb895hQJRzcYb4LCvShTxE6L)_
Fixes #29706
Clause-②: no
Metadata-protocol: none
The two lines are the amended claim's (comment on the card,
2026-11-03T02:55Z).
## 维护者速读
- 改了什么:中文 Studio
的三处首屏不再夹英文。新建软件包表单在中文词表加载后重建,标签和说明都是中文;自动化侧栏里尚未发布的对象,其流程分组显示对象标签(如「维修工单」),不再显示大写的机器名;列表视图的「添加字段」先列搭建者自己的字段,再列系统字段(创建时间、创建人、所有人等)。
-
为什么改:这些是中文用户最先看到的界面,中英混杂让人分不清哪些字可以忽略。卡上的第一行(「新建类似」复制流程后的提示句)要服务端先给出代码,已移到服务端车道的卡
#29727,本 PR 不动它。
- 风险与回滚:只改 app-shell 的三处读取与排序,不加不删 i18n 键,不动 spec 与
runtime。草稿对象多读一次草稿列表,失败时照旧只用已发布对象。回滚即撤销本 PR。
- 先看:`StudioDesignSurface.tsx` 的
`readObjectLabels`(合并草稿对象的标签);`PackageFormDialog.tsx` 的表单 memo
依赖;`ViewColumnPanes.tsx` 的 `AddFieldPopover` 排序。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/app-shell/src/views/metadata-admin/PackageFormDialog.lazyCatalogue-29706.test.tsx
packages/app-shell/src/views/studio-design/StudioDesignSurface.draftObjectFlowGroup-29706.test.tsx
packages/app-shell/src/views/metadata-admin/previews/FieldsListEditor.addFieldOrder-29706.test.tsx`,预期
3 个文件 6 个用例全过(任一修复撤回时对应用例转红)。
- 需要你做的:无,席位落地。
## What changes
The card's four rows were re-measured on `main` 7b55ea9 in zh-CN, and
all four reproduced. Rows 2 to 4 are fixed here. Row 1 moved to its own
card (below).
- **Row 1, the New similar clone notice: moved to #29727, not changed
here.** The flow clone answer is `{flow, packageId, notice}` with no
code, and the console prints `notice` as sent. The repo's pattern for a
server sentence a person reads is code-keyed: the console maps a code it
knows to an i18n key and keeps the wire text for any other code
(`translateFailureCode` in `CloudConnectionPanel.tsx`; the publish
refusal's `BATCH_ABORTED_CODE` line in `StudioDesignSurface.tsx`). The
notice has no code yet, so the first step is server-side
(`packages/runtime`), which is out of this card's surface. #29727 covers
the flow and permission-set clone notices and the console mapping that
follows the code.
- **Row 2, the New package form (`PackageFormDialog.tsx`).** Studio's
landing mounts the dialog closed, before the lazily fetched zh `studio`
catalogue is resident. The form spec (labels and help lines,
`getPackageForm`) was memoised on `[locale, mode]`, so the `en` answer
of the first render survived the catalogue's arrival, while the title,
read on every render, turned Chinese: 新建软件包 over "Display name" and
"Human-readable package name". The memo now also keys on
`isStudioCatalogueLoaded(locale)`, so the form is rebuilt once the
catalogue lands. Once rebuilt, zh no longer falls through to the spec's
`.describe()` text; en still does, by design (`add10d8f9`).
- **Row 3, the Automations rail (`StudioDesignSurface.tsx`,
`readObjectLabels` only).** The rail's object index read the published
objects only, so a flow started on an object not published yet was
grouped under the object's name, which the header's `uppercase` style
showed as REPAIRS_REPAIR_TICKET. The index now merges the package's
object drafts (`listDrafts({ packageId, type: 'object' })`, unscoped in
the package-less scope) with the label each `_drafts` row carries,
resolved in the designer locale. A published object keeps its published
label. A failed draft read adds nothing and leaves the published index
as it was.
- **Row 4, the column picker (`ViewColumnPanes.tsx`,
`AddFieldPopover`).** The served object puts the columns
`applySystemFields` injects ahead of the author's field map. Measured on
`@objectstack/objectql`'s `applySystemFields` for an object declaring
`title` and `priority`: `organization_id`, `created_at`, `created_by`,
`updated_at`, `updated_by`, `owner_id`, `owning_business_unit_id`,
`queue`, `title`, `priority`. The list-view inspector already drops the
hidden ones, but the audit four and `owner_id` stayed on top. The picker
now lists the builder's fields first and the `system` ones after, each
in served order. The same popover serves the report inspector's columns.
- No i18n key is added or removed, and nothing under `packages/spec` or
`packages/runtime` changes.
## Tests
Three new files, one per kept row, each over the real component, each
with a CONTROL case.
- **`PackageFormDialog.lazyCatalogue-29706.test.tsx`.** Mounts the real
`PackageFormDialog` closed under an `I18nProvider` in zh with the studio
catalogue NOT resident (asserted first; the `dom` project isolates each
file), lands the catalogue, then opens it, as Studio's landing does. The
labels and help read 显示名称 / 软件包的可读名称。 and neither "Display name" nor the
spec's `.describe()` text appears (read from the installed
`ManifestSchema`). CONTROL: an en console mounted the same way keeps the
spec's own English help.
- **`StudioDesignSurface.draftObjectFlowGroup-29706.test.tsx`.** The
whole surface at `/studio/PKG/automations` (harness of
`automationsRailOrder-12612`): one published object, one draft-only
object whose `_drafts` header carries 维修工单, one flow on each. The draft
object's group reads 维修工单 and not its machine name. CONTROL: the
published object's group reads its published label.
- **`FieldsListEditor.addFieldOrder-29706.test.tsx`.** The real
`FieldsListEditor` and its Add field popover over a catalog in the
measured served order (audit four and `owner_id` first). The picker
lists `title`, `priority`, then the system columns in served order.
CONTROL: a catalog with no system column keeps its served order.
- **Ablations, one per row** (`scripts/ablation-replace.mjs`, fix
committed first, each mutation counted on disk and restored to the HEAD
blob with `git diff HEAD` empty): memo deps back to `[locale, mode]`;
the draft read replaced by an empty answer; the picker order back to
`[...fields]`. Each turns exactly its row's case red and leaves the
CONTROL green.
## Acceptance notes
- **Row 1 went to #29727** (filed by the seat for the server lane). This
PR leaves the clone notice as it is.
- **Measured live, before and after, in zh-CN** (app-crm `--fresh`
backend plus the Vite console on source; before = the three
`origin/main` source files swapped in, restored to HEAD after): the rail
header read REPAIRS_REPAIR_TICKET before and 维修工单 after; the New package
form's first labels read "Display name", "Description", 软件包 ID, "Object
namespace" before and 显示名称, 描述, 软件包 ID, 对象命名空间 after; the column picker
read 创建时间, 创建人, 更新时间, 更新人, 负责人, 标题, 优先级 before and 标题, 优先级, then the
five system columns after. Screenshots are in the project's
`issue-29706/` folder (`before-row*.png`, `after-row*.png`). The harness
was temporary and nothing of it is committed.
- **Seen on the same screens, not changed here (outside this card's
surface):** the filter builder's "+ Add filter…" in the Interfaces
list-view panel renders in English in zh-CN; the package form's Type
select shows the raw value `app`; the dialog's screen-reader "Close"
label is English. Noted for triage.
- After merging `main` (the pinyin create-door card landed in
`PackageFormDialog.tsx` and `StudioDesignSurface.tsx`), the touched
suites, the app-shell type-check and the three new files were re-run on
the merged head.
## Verification
Final head `f9fd4b39` (merge of `origin/main` 3eeb81d); code head
a346e17.
<details><summary>Tests</summary>
- The 3 new files: 3 files, 6 tests passed (merged head).
- Every app-shell test naming `PackageFormDialog`, `ViewColumnPanes`,
`FieldsListEditor`, `AddFieldPopover`, `BuilderLanding` or the
Automations rail (125 files, code head a346e17's tree,
`--maxWorkers=2`, three batches): 125 files, 1080 tests passed. On the
merged head, the 36 that name the touched components plus the two rail
suites: 38 files, 304 tests passed.
- `pnpm exec turbo run type-check --filter=@object-ui/app-shell`: 65 of
65 tasks successful (merged head).
- `pnpm exec eslint` over the six touched ui files: 0 errors (existing
warnings only).
- `pnpm --dir ui exec vitest run scripts/`: 170 files passed, 2 skipped;
4977 tests passed.
- `pnpm --dir ui check:new-line-citations`: 0 new citations.
</details>
<details><summary>Gates</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: 35 derived families (unchanged by the
merge). The 34 non-vitest ones ran in one loop on a346e17 and all
exited 0, including `check-sdui-manifest.mjs` and its `--self-test`,
`check-changeset-no-major`, `check-adr-0087-registration`,
`check-empty-changeset`, `check:published-files`,
`check:type-check-debt` (locked) and `check:cross-package-test-inputs`;
the 35th, `pnpm --dir ui exec vitest run scripts/`, is the run above.
The body-reading gates were re-run on this body before opening.
- `scripts/pm/clause2-line.mjs` reads the changeset as `Clause-②: no`
and `Metadata-protocol: none`, matching the amended claim. No i18n key
and no export changes.
- Dogfood battery: n/a, because there is no `!` in the title and no
(narrowing) arm.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jRdVLGVEbfCX4asHX1)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 8d208a4 commit 8c28972
7 files changed
Lines changed: 357 additions & 5 deletions
File tree
- .changeset
- ui/packages/app-shell/src/views
- metadata-admin
- previews
- studio-design
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
59 | 60 | | |
60 | 61 | | |
61 | 62 | | |
| |||
383 | 384 | | |
384 | 385 | | |
385 | 386 | | |
386 | | - | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
387 | 397 | | |
388 | 398 | | |
389 | 399 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
303 | 303 | | |
304 | 304 | | |
305 | 305 | | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
306 | 314 | | |
307 | 315 | | |
308 | | - | |
309 | | - | |
| 316 | + | |
| 317 | + | |
310 | 318 | | |
311 | 319 | | |
312 | | - | |
| 320 | + | |
313 | 321 | | |
314 | 322 | | |
315 | 323 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
0 commit comments