Repository navigation
Commit ac56acf
fix(console): a deployment-level settings value set here reads Modified and offers Reset to default (#30428)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgSR1JGX3VuyVmi9T3mtH6Z4)_
domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2
Fixes #30329
Clause-②: yes (widening) — two published language-pack keys in all ten
built-in packs: `console.settingsView.sourceBadgeModified` and
`console.settingsView.defaultValueHint` (with `{{value}}`).
Metadata-protocol: none
## 维护者速读
- 改了什么:部署级设置页(清单 `scope: 'global'`,如 Setup
的认证页)上管理员自己改过的值,徽标从「继承自全局」改为「已修改」,旁边写出默认值(如「默认:8」,选项显示选项名、开关显示是/否、密码从不显示),并提供「恢复默认」;点了以后照常要按保存才生效。
- 为什么改:原来改过的值看上去像是从别处继承来的,也没有恢复默认按钮,想回到默认只能自己记得默认值或清空输入框。
- 风险与回滚:只动 console 设置页两个文件、十个语言包各加两个键、一个测试文件和 changeset;不动
spec、服务端或元数据。组织级和用户级页面的徽标不变,环境变量锁定的值仍不给恢复。回滚即 revert 本 PR。
- 先看:`ui/apps/console/src/pages/settings/SettingsField.tsx` 的
`sourceBadgeOf`(新增 `modified` 分支)和 `FieldHeader`(恢复按钮条件、默认值提示)→
`SettingsView.tsx` 传入的 `writeScope` → 测试文件新增的 describe。
- 两分钟验证:`pnpm --dir ui exec vitest run
apps/console/src/pages/settings/__tests__/SettingsView.unsetAndReset-13145.test.tsx`,预期
9/9 通过(在 main 源码上新加的 3 条失败)。
- 需要你做的:无,席位落地。
## What changes
The card's two Expected bullets, quoted:
> - A value changed here says so, for example 已修改, and names the
default.
> - Reset to default is available on it, with Save confirming it as
other changes do.
- `SettingsView` passes each row `writeScope`, the scope its Save
writes, resolved exactly as the server resolves it in
`registerManifest`: the specifier's `scope`, else the manifest's, else
the spec default `tenant` (`SettingsManifestSchema` declares `scope:
SpecifierScopeSchema.default('tenant')`). The served manifest is the
registered one unparsed, so an absent `scope` is the server's `tenant`
too.
- `sourceBadgeOf` returns a new `modified` badge when the effective
layer is `global` and the row's `writeScope` is `global`; any other
`global` or `env` value still reads `Inherited from …`. The `tenant` and
`user` arms are unchanged, so the organization and user pages keep their
`Overrides …` badges.
- A `modified` row shows `Modified` (`已修改`), the default layer's value
from the server's `cascadeChain` as `Default: VALUE` (`默认:VALUE`), and
Reset to default. The default is spelled as an option's label, Yes or No
for a boolean, and never shown for a password or encrypted key or for an
object value.
- Reset is the existing draft `null` path: Save sends `null` and the
badge follows the server's answer.
- An env-locked row (`resolved.locked`) gets no badge and no Reset, as
before.
- The number control now shows an empty box for an unset value. With
`value={null}` React left the last number on screen, so a Reset on a
number row (the card's 密码最小长度) looked as if nothing happened. This is
the same path the card asks for, in the same file.
PM mechanism assumptions, measured on `origin/main` 6fa842a:
- The badge: held. `sourceBadgeOf` returned `inherited` for every
effective scope other than `default`, `user` and `tenant`.
- The reset button: held. It rendered only for `badge.kind ===
'overrides'`.
- The page's scope: the console already had it. `GET
/api/settings/:namespace` serves the manifest with `scope` on it and on
each specifier, and the server's write scope per key is `spec.scope ??
manifest.scope ?? 'tenant'` (`registerManifest` in `service-settings`).
No server change was needed, and `packages/**` is untouched.
- Locked values: held, unchanged.
- The org and user pages: unchanged. The existing `Overrides` and
`Inherited` pins in the same file pass unmodified, and the new describe
adds a `scope: 'tenant'` specifier on a global manifest as a control.
## Tests
New top-level describe `a value set on a deployment-level page
(objectstack#30329)` in `SettingsView.unsetAndReset-13145.test.tsx`, the
existing reset harness: the whole page over a stubbed `fetch` and the
real `../api`, so the PUT body is read as it leaves the client.
- A global number value: no `Inherited from`, reads `Modified` and
`Default: 8`, Reset empties the box and dirties the page, Save sends
exactly `{"password_min_length":null}`, and after the re-read the row
shows `8` with no badge and no Reset.
- A global toggle names `Default: No`, and a global select names its
option label `Default: Lax`, each with Reset.
- CONTROL: an env-locked value, a value at its default and a `scope:
'tenant'` key on the global manifest offer no Reset; the tenant key
still reads `Inherited from`; the page carries exactly three Resets.
<details><summary>Readings</summary>
- Red first, on test-only commit 753defd (unfixed source): `Tests 3
failed | 6 passed (9)`. The first case failed on `Inherited from` being
present, the second on `Modified` missing, the third on the Reset count
(0 instead of 3); every existing case passed.
- After the badge change alone, the first case failed on the number box
still reading `12` after Reset (`expected '12' to be ''`), which is the
number-control fix above. Then `Tests 9 passed (9)`.
- `pnpm --dir ui exec vitest run apps/console/src/pages/settings/
packages/i18n/` (every settings test, the timezone prompt that also
renders `SettingsField` included, and the i18n pack parity tests), on
b001f22 after merging `origin/main`: `Test Files 128 passed (128)`,
`Tests 1720 passed | 13 skipped (1733)`.
- `pnpm exec turbo run type-check --filter=@object-ui/console
--concurrency=2`: `Tasks: 74 successful, 74 total`.
- eslint on the changed ui files: 0 errors; 4 `no-explicit-any`
warnings, all on lines this PR does not add (one fewer in
`SettingsField.tsx` than on main).
- `pnpm check:new-line-citations`: 0 new citations.
- `node scripts/pm/dispatch-gates.mjs --ran`: 35 derived families, 35
run, 0 NOT-MEASURED, every exit 0 (`check-sdui-manifest.mjs` and its
self-test included).
</details>
## Acceptance notes
- The organization and user pages keep `Overrides Default` for a value
set there, while the deployment page now reads `Modified · Default:
VALUE`. That is what the dispatch asked (keep their badges); bringing
the other pages to the same wording is a separate choice.
- A tenant or user key whose default is `null` and whose own value is
set shows no badge and no Reset (no upper layer carries a value).
Unchanged here, noted only.
## Verification
`pnpm --dir ui exec vitest run
apps/console/src/pages/settings/__tests__/SettingsView.unsetAndReset-13145.test.tsx`
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CaTSNwaf1AMz4qR7Fs)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 0892a94 commit ac56acf
14 files changed
Lines changed: 282 additions & 15 deletions
File tree
- .changeset
- ui
- apps/console/src/pages/settings
- __tests__
- packages/i18n/src/locales
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
37 | 42 | | |
38 | 43 | | |
39 | 44 | | |
| |||
100 | 105 | | |
101 | 106 | | |
102 | 107 | | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
103 | 113 | | |
104 | 114 | | |
105 | 115 | | |
106 | 116 | | |
107 | | - | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
108 | 120 | | |
109 | 121 | | |
110 | 122 | | |
111 | 123 | | |
112 | 124 | | |
113 | | - | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
114 | 129 | | |
115 | 130 | | |
116 | 131 | | |
| |||
125 | 140 | | |
126 | 141 | | |
127 | 142 | | |
128 | | - | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
129 | 149 | | |
130 | 150 | | |
131 | 151 | | |
| |||
143 | 163 | | |
144 | 164 | | |
145 | 165 | | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
146 | 173 | | |
147 | 174 | | |
148 | 175 | | |
| |||
178 | 205 | | |
179 | 206 | | |
180 | 207 | | |
| 208 | + | |
| 209 | + | |
181 | 210 | | |
182 | 211 | | |
183 | 212 | | |
| |||
186 | 215 | | |
187 | 216 | | |
188 | 217 | | |
189 | | - | |
190 | | - | |
191 | | - | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
192 | 221 | | |
193 | 222 | | |
194 | 223 | | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
195 | 227 | | |
196 | 228 | | |
197 | | - | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
198 | 232 | | |
199 | 233 | | |
200 | 234 | | |
| |||
210 | 244 | | |
211 | 245 | | |
212 | 246 | | |
213 | | - | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
214 | 253 | | |
215 | 254 | | |
216 | 255 | | |
| |||
347 | 386 | | |
348 | 387 | | |
349 | 388 | | |
350 | | - | |
| 389 | + | |
| 390 | + | |
351 | 391 | | |
352 | 392 | | |
353 | 393 | | |
| |||
490 | 530 | | |
491 | 531 | | |
492 | 532 | | |
| 533 | + | |
| 534 | + | |
493 | 535 | | |
494 | 536 | | |
495 | 537 | | |
| |||
511 | 553 | | |
512 | 554 | | |
513 | 555 | | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
514 | 570 | | |
515 | 571 | | |
516 | 572 | | |
| |||
556 | 612 | | |
557 | 613 | | |
558 | 614 | | |
559 | | - | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
560 | 618 | | |
561 | 619 | | |
562 | 620 | | |
| |||
577 | 635 | | |
578 | 636 | | |
579 | 637 | | |
| 638 | + | |
| 639 | + | |
580 | 640 | | |
581 | 641 | | |
582 | 642 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
661 | 661 | | |
662 | 662 | | |
663 | 663 | | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
664 | 667 | | |
665 | 668 | | |
666 | 669 | | |
| |||
0 commit comments