You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 69dbb3c
Browse filesBrowse the repository at this point in the historyBrowse files
feat(app-shell): the publish sheet speaks the console's language, and a load error the server answered shows its code and sentence (#29780)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbCxgU8qhkxkTtKmg6Wwh1hY)_Fixes#29704
Clause-②: yes (widening)
Metadata-protocol: none
## 维护者速读
- 改了什么:发布前的「待发布变更」面板改用使用者的语言说明改动。更新项按检查器里的字段名列出改动(如「显示名称」「列数」),不再列出
`overrides`
声明。新增项不再列出属性清单和「平台生成」分组,对象扩展分组显示中文名「对象扩展」。列表页、记录页、应用页和相关列表在加载失败时,如果服务器有回复,就显示它给出的原因和错误码(如
404 `OBJECT_NOT_FOUND`)。只有请求完全没有得到回复时,才提示「请检查网络连接后重试」。
- 为什么改:发布面板是使用者决定是否上线改动的地方,原来显示的是 `+ overrides`、`+ isDefault`
这类内部键名,看不懂。#29673 中对象注册失败时,服务器已经明确回复了原因,页面却让人去查网络,排查方向完全错误。
- 风险与回滚:只改界面文案和显示逻辑,不改发布内容、接口和元数据协议。十个语言包各新增两个键,没有删除键。回滚只需还原本 PR。
- 先看:`ui/packages/app-shell/src/preview/DraftChangesPanel.tsx` 的
`EntryDetail`,以及 `ui/packages/react/src/utils/error-message.ts` 新增的
`answeredLoadFailure`(四个页面共用的唯一判断规则)。
- 两分钟验证:中文界面下,在 Studio 中定制一个基础包的仪表板并改名,打开「变更」面板展开它,应看到「~ 显示名称」而没有
overrides。再打开一个对象列表,让数据接口返回 404
`OBJECT_NOT_FOUND`,应看到服务器的原句和错误码,而不是网络提示。下方 Verification 附有前后截图。
- 需要你做的:无,席位落地。
## What changes
**Publish sheet (`DraftChangesPanel`)**
- An updated item's top-level keys are named by the inspector's existing
label catalog, in the console's language: the spec form rows, the zh
overlay `localizeMetadataForm`, then `translateSchemaFieldLabel`. The
machine-name chip is still judged on the spec's source label
(objectui#8231). To keep the studio namespace off the console's eager
graph, `isZhLocale` and the schema-field label tables moved verbatim
into a new import-free leaf,
`views/metadata-admin/schema-field-label.ts`, and `i18n.ts` re-exports
them.
- The ADR-0146 D2 override declaration
(`Object.keys(OverrideDeclarationFields)`, i.e. `overrides`) is dropped
where the protection envelope is dropped, so a customized item no longer
lists `+ overrides`.
- A new item is added whole. It lists the fields and flow nodes it
brings under "Includes:", or one sentence, "Publishing adds this item."
(`preview.changes.detailNewItem`). It lists no key rows and no 平台生成
group. Updates keep both.
- `object_extension` has a count family in all ten packs
(`preview.changes.typeCount.object_extension`), so its group reads 「对象扩展
N」 / "N object extensions".
- No new diff capability.
**Load errors**
- New `answeredLoadFailure(err)` in `@object-ui/react`, beside
`classifyLoadError`, exported with its type. It returns the server's `{
code, message }` when a server answered, and `null` otherwise. A server
answered when the error has a numeric `httpStatus`, `status` or
`statusCode`, or `HTTP` plus three digits in its message. The sentence
comes from `extractWriteErrorMessage`, or from a wrapped `{ error: {
code, message } }` body parked under `details`. RelatedList's local
`serverSentence` rule is lifted into it.
- ListView: kind `network` with an answer shows the server's sentence
and a `list-error-code` chip. The network sentence stays for no answer.
Refused, unauthorized, rejected and api-disabled kinds keep their own
fixed copy.
- RecordDetailView `failed` and PageView's record scope `failed` follow
the same rule (`record-load-failed-code`,
`page-record-load-failed-code`). RelatedList now reads the shared helper
and shows the code too.
- Out of scope: the route-level read failure in `console/AppContent.tsx`
(`RouteObjectReadFailed`, with `MetadataProvider` and `appObjectScope`)
is filed as #29728.
## Tests
- `DraftChangesPanel.namedChanges-27835`:
- a customized dashboard update in zh-CN lists `~ 列数` and `~ 显示名称`, with
no `overrides` and no English label;
- an English control;
- `computeChangeDetail` drops the declaration;
- a new view in zh-CN shows `draft-entry-new` and no key rows, with no
`viewKind`, `isDefault` or "Includes:".
- This replaces the "heads a NEW view…" pin.
- `DraftChangesPanel.groupHeading-13221`: an `object_extension` group
reads 「对象扩展 1」 (zh) and "2 object extensions" (en), against the real
packs.
- `error-message.test`, `answeredLoadFailure`:
- a 404 `OBJECT_NOT_FOUND` in the adapter's raw-read shape;
- a body under `details`;
- a wrapped `{error:{code,message}}` body that was not lifted;
- an `HTTP 500` JSON tail;
- controls: no answer, junk input, and the kind of an answered 404 is
still `network`.
- `ListView.loadErrorKind`:
- a 404 `OBJECT_NOT_FOUND` shows its sentence, its code and Retry, with
no network sentence;
- an answered 500 JSON tail is quoted, with no code;
- controls: `Failed to fetch` keeps the network sentence; a 403 shows no
server text.
- `RecordDetailView.recordReadFailure-11902`, over the real
`ObjectStackAdapter`:
- the 5xx answer is now the dispatcher's wrapped envelope;
- in en and zh, the page shows its sentence and `INTERNAL_ERROR`, never
请检查网络连接;
- a transport failure keeps the network sentence in en and zh (new zh
pin).
- `PageView.appPageRecord-12931`: an answered 500 shows its sentence and
code; a control for no answer.
**Moved pins**
These pins asserted the old new-item key list or the 平台生成 group on a new
item. Seat 5 approved adding the last two files to the surface.
- `DraftChangesPanel.generatedGroup-25890`: the repro's new object now
shows its one field and nothing of the platform's. The group's collapsed
line and its opened rows are pinned on an update of the same object.
- `DraftChangesPanel.protectionEnvelope-12594`: the two "still lists an
authored key" controls run on updates (`~ Label`), because a new item
lists no keys.
- `DraftChangesPanel.fieldRows-13125`: a new object draws no generated
group. The hidden-column guard (`__search`, `owning_business_unit_id`)
and the Owner / Created At controls moved to the Ticket update, whose
draft now carries the stamped columns.
- `DraftChangesPanel.bundleMember-12271`: a new `zh-CN` member reads
`draft-entry-new` with no key rows. Its member-selector URL and
expansion assertions are unchanged.
**Ablations** (each red, each restored, `git diff HEAD` empty
afterwards)
| Ablation | Result |
|---|---|
| drop the locale from `KeyRow` | 1 red |
| keep `overrides` | 3 red |
| key rows on a new item | 1 red |
| rename the `object_extension` count row | 2 red |
| `answeredLoadFailure` never answers | 9 red |
| it always answers | 6 red |
| the ListView branch | 2 red |
| the RecordDetailView sentence | 2 red |
| the PageView sentence | 1 red |
## Acceptance notes
- Only `object_extension` gained a count family. Other registered types
without one (for example `hook`, `position`) keep their raw name in a
group heading, as the summary line does.
- A new item whose draft is empty still reads the existing "No
differences detected" sentence (pinned by `noChangeAndKeySplit-11807`,
unchanged).
- On the list page only kind `network` quotes the server. Every other
kind keeps its fixed sentence, as before.
## Verification
Head `eae9d624` (main merged twice; the second merge touched none of
these files).
- Dispatch gates: all 35 derived commands were run, and each exited 0.
This includes `node scripts/check-sdui-manifest.mjs`,
`check-changeset-no-major`, `check-adr-0087-registration`,
`check-empty-changeset`, `pnpm --dir ui exec vitest run scripts/`,
`check:type-check-coverage` and `check:type-check-debt`. `dispatch-gates
--ran` reconciles: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN.
- Type-check: `type-check` is green for `@object-ui/react`,
`@object-ui/plugin-list`, `@object-ui/plugin-detail` and
`@object-ui/app-shell`, after merging main.
- Tests (locked runs):
- preview suite: 35 files, 251 tests;
- the four load-error files: 84 tests;
- `plugin-detail` plus react `utils`: 3330 passed;
- all of `packages/i18n`: 1443 passed, including `count-families-11445`,
`untranslated-identity-4376`, the key-parity tests and
`studio-namespace`;
- post-merge re-run of the preview, i18n and load-error files: 1781
passed.
- Lint: eslint on the touched files reports 0 errors.
- `plugin-form/src/affordanceGrantMap-12082.test.tsx` was not run,
because this diff does not touch its files.
Live screenshots, zh-CN, `examples/app-showcase` dev server plus the
Vite console. The "before" leg served `origin/main`'s copies of the
changed source files.
- **Sheet setup:** `ensure-customization`, then three drafts in
`com.example.showcase.custom`:
- the base dashboard `showcase_ops_dashboard`, customized with a new
label and column count, carrying `overrides`;
- a new dashboard;
- an `object_extension` on `showcase_task`.
- **What the sheet shows:**
- Update. Before: `其他变更: + overrides ~ Columns ~ Label`. After: `其他变更: ~
列数 ~ 显示名称`.
- New item. Before: `包含: + Columns + Date Range + Description + Global
Filters + 任务状态 task_status + Label + Name + Widgets`. After: `发布后将新增此项。`
- Group heading. Before: `OBJECT_EXTENSION 1`. After: `对象扩展 1`.
- **List load error:** a Playwright route answers the task list's expand
read with 404
`{"success":false,"error":{"code":"OBJECT_NOT_FOUND","message":"Object
'showcase_task' is not registered"}}`.
- Before: `无法加载记录 / 加载数据时出错。请检查网络连接后重试。`
- After: `无法加载记录 / Object 'showcase_task' is not registered /
OBJECT_NOT_FOUND / 重试`.
- With a 500 `INTERNAL_ERROR` answer, the panel shows that sentence and
code the same way.
- **The PNGs:** ten files, `before-` and `after-`, each of
`sheet-groups`, `sheet-update`, `sheet-new`, `list-load-error-404` and
`list-load-error-500`. They are in the project folder
`issue-29704/screens/`, and the driver script is in
`issue-29704/measure/`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QsR2jVQc3uTU5ZhjP31Sh8
---------
Co-authored-by: Claude <noreply@anthropic.com>
feat(app-shell): the publish sheet speaks in the console's language, and a load error the server answered shows its code and sentence
10
+
11
+
Clause-②: yes (widening)
12
+
Metadata-protocol: none
13
+
14
+
The Pending changes sheet now names an updated item's changed keys by the label the inspector gives them, in the console's language (a customized dashboard reads 「~ 显示名称」, not "~ Label"). It no longer lists the ADR-0146 override declaration (`overrides`) as a change. A new item is added whole, so it lists no key list and no 平台生成 group: it shows only the fields and flow nodes it brings, or "Publishing adds this item." An `object_extension` group reads as its translated name ("2 object extensions", 「对象扩展 2」). This widens the ten shipped packs by `preview.changes.detailNewItem` and the `preview.changes.typeCount.object_extension` count family.
15
+
16
+
When a read fails and the server answered, the list page, the record page, the app page and the related list now show the server's sentence and code, for example 404 `OBJECT_NOT_FOUND` with "Object '…' is not registered". "Check your connection and try again" is only shown when no answer came back. All four share one rule, `answeredLoadFailure`, newly exported from `@object-ui/react`.
0 commit comments