Repository navigation
Commit bc8945f
feat(app-shell): Studio opens an off-nav list view on its object's page, lists only views no dropdown reaches, and reads form views as forms (#30401)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgXkTWXsjBzzss3KguAuRzTF)_
domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2
## 维护者速读
- 改了什么:Studio 界面里,从「不在导航中 → 视图」打开列表视图,现在落到对象页(标题 对象 / 视图
▾),条件格式化和视图表单分节一并搬到右侧面板;有导航入口的对象,其列表视图不再重复列在该分组;表单视图显示为「线索表单」这类可读名字,分组标题按内容写「表单视图
/ 视图 / 表单视图与列表视图」,表单视图的「视图类型」读出 简单 / 标签页 / 向导,不再是「simple(未找到)」。
- 为什么改:#30046 Scope 6–8(裁定
A,6651738887)。同一个列表视图以前有两个页面、两套面板,导航里已能到达的视图又在「不在导航中」重复出现,表单视图名字是
`crm_lead.form` 这类内部名。
- 风险与回滚:只动 Studio 前端(app-shell 与 studio 语言包三个新键),不动元数据、spec
或服务端。共用的视图检查器只在表单视图上换类型清单,列表视图那一侧不变并有测试钉住。回滚即 revert 本 PR。
- 先看:`StudioDesignSurface.tsx` 的 `pickOffNav` / `listViewDoorOf`
与离线分组过滤,`ListViewMoreSection.tsx`(新),`ViewVariantInspector.tsx` 的
`useTypeOptions`。
- 两分钟验证:打开示例 CRM 的 Studio → 界面:「不在导航中」只剩「表单视图」4 项;点「线索表单」,视图类型显示「简单」;访问
`?surface=view:crm_lead.pipeline` 落到「线索 / 线索看板」。
- 需要你做的:本 PR 新增三个 i18n 键(Clause-② widening),席位需安排 TIER_DEFAULT 评审;其余无。
Fixes #30046
Clause-②: yes (widening) — three new published `@object-ui/i18n` Studio
keys: `engine.studio.if.offNav.viewForms`,
`engine.studio.if.offNav.viewMixed`, `engine.studio.if.offNav.formName`
(en + zh). No accept set narrowed.
Metadata-protocol: none — Studio UI only: no metadata key, spec schema,
server route or stored shape is added or read differently; the view
items are read through the existing `/meta/view` list (drafts overlaid)
and written through the existing list-view draft path.
## What changes
Scope 6–8 of #30046, ruled as option A (6651738887). Scope 1–5 landed in
#30175 and are untouched.
- **Scope 6 — a list view opens on its object's page from every door.**
Picking a list view under 不在导航中 → 视图, or following a link to the view
itself (`?surface=view:OBJECT.KEY`), now lands on the object page with
its header dropdown (object / view ▾) on that view: the object's nav
entry when it has one, else the object itself with no entry
(`?surface=object:OBJECT&view=…`, which a reload or a shared link opens
again). The panel there gains `ListViewMoreSection` (new): the view's
条件格式化 (`ConditionalFormattingEditor`, whose CEL verdicts now hold the
list-view autosave the way they held the view page's Save) and the spec
authoring form's sections for a view, pruned of every key the panel
already edits, so no setting has two controls. A form view, and a view a
read-only base's pair adds (`addedIn`), still open as themselves. #30039
owns translating those sections.
- **Scope 7 — the 视图 group lists what the dropdowns do not reach.** A
list view whose object has a nav entry is no longer listed, a view only
drafted in the package included (`withDraftViewBindings` reads the
drafted rows' `object`/`viewKind` from the draft-overlaid list,
fail-soft). The list views of an object with no entry stay listed. The
only-customized filter is unchanged.
- **Scope 8 — form views read as forms.** A form view is listed by its
label, else as the object's name plus 表单 ("Lead form", 「线索表单」, with ` ·
key` for a non-default form); the group's heading says what it holds
(表单视图, 视图, or 表单视图与列表视图). In `ViewVariantInspector`, a form view's 视图类型
reads the form-variant schema's `type` enum (simple / tabbed / wizard,
labelled with the existing
`engine.inspector.pageBlock.option.formType.*` keys) and defaults to
`simple`; a list view's picker is byte-for-byte the same roster as
before.
- `ObjectListViewInspector.tsx`: the hook gains `openView(surface,
viewId)`; the panel appends `ListViewMoreSection` as an independent
block after the sort block, with no existing section reordered (seat 4's
#30089 adds a section in the same render region). #30315's
`listViewTargetOf` hunks are not touched. `StudioDesignSurface.tsx`'s
`restoreOriginal` / `publishNonce` region (#30238) is not touched.
## Tests
- New `InterfacesPillar.offNavListViews-30046.test.tsx` (13 cases):
Scope 7 filtering with controls (an object with no entry stays listed, a
drafted view included), Scope 8 names and the three headings, Scope 6
object page landing, the panel's 条件格式化 and spec sections, a second pick
on the same page, `?surface=object:…&view=` and `?surface=view:…` links
with and without an entry, CONTROL that a form view still opens as
itself, and the CEL hold (autosave blocked on a bad rule, saved once
fixed).
- New `ViewVariantInspector.formViewType-30046.test.tsx` (8 cases, en +
zh): a form view reads its layout and offers only the form roster; a
form view with no type reads Simple; CONTROL a list view still offers
the list types; CONTROL an off-enum list type is still flagged.
- `packageSurfaces.test.ts`: 3 cases for `viewBindingOf` /
`withDraftViewBindings`.
- `InterfacesPillar.offNavItems-26889.test.tsx` and
`InterfacesPillar.offNavDeepLink-28561.test.tsx`: their off-nav view
fixture is now a form view (`web_form`), since a list view of an object
with an entry is no longer listed there; what they assert is unchanged.
- Red first: with `origin/main`'s five source files checked out, 17 of
the new/changed cases fail (5 files); all pass on this branch.
- Ablations (`scripts/ablation-replace.mjs`, each restored with blob ==
HEAD and an empty `git diff HEAD`): Scope 7 filter → 3 red; the
list-view door → 5 red; the form-type roster pick → 2 red (both
locales); the CEL hold term → 1 red.
## Acceptance notes
- Card Acceptance 5, browser checks on both package kinds (branch head
before the main merge, which brought no ui change), screenshots in the
project files under `ui-seat2/card-30046/screenshots/`:
- Read-only example CRM (`examples/app-crm`): 不在导航中 lists only 表单视图 (4):
活动表单, 线索表单 · web_to_lead, 线索表单, 商机表单; the default landing panel carries
条件格式化 and 基础信息 below the sort block; `?surface=view:crm_lead.pipeline`
lands on 线索 / 线索看板 at
`surface=object:crm_lead&nav=nav_leads&view=crm_lead.pipeline`; 线索表单
opens as a form view whose 视图类型 reads 简单.
- Writable throwaway package (one object with a nav entry, one without,
all views drafted): the heading reads 表单视图与列表视图 with Case表单 and Open
cases only; the entry object's drafted All tasks / My tasks are absent
from the group and present in its header dropdown; Open cases lands on
Case / Open cases at `surface=object:ws_case&view=ws_case.open`,
survives a reload, and its panel shows the view's CEL rule (CEL 有效).
- Observed, not in this card's scope: the form view inspector's header
still reads the item name (`crm_lead.form`), and its spec sections
(Layout, Columns, Title) are English in zh, which is #30039's.
- Line budget: 1153 insertions, 41 deletions (1194 changed lines, about
half of them tests), under the ~1200 stop.
## Verification
On the final tree (head `9eff7192`, `origin/main` `870ebce3` merged in),
every exit code recorded to a file before any pipe:
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack <14 changed paths>`: 35 commands, all exit 0
(`pnpm --dir ui exec vitest run scripts/`: Test Files 170 passed | 2
skipped, Tests 4985 passed | 2 skipped). `--ran` reconciliation: 35
derived, 35 run, 0 NOT-MEASURED, 0 UNRUN.
- `node scripts/check-sdui-manifest.mjs`: exit 0 (and `--self-test` exit
0).
- `pnpm --filter @object-ui/app-shell --filter @object-ui/i18n lint`:
exit 0, 0 errors (warnings only, existing patterns).
- `pnpm --dir ui run check:new-line-citations`: exit 0. `pnpm
check:nul-bytes`: exit 0.
- `pnpm exec turbo run type-check --filter=@object-ui/app-shell
--filter=@object-ui/i18n --concurrency=2` (under `os-verify-lock`):
69/69 tasks, exit 0.
- Targeted re-run after the merge: the five changed/new test files, Test
Files 5 passed, Tests 50 passed.
- Before the merge, every test file importing a changed module plus
every `InterfacesPillar.*` and `StudioDesignSurface.*` test (167 files):
1220/1221, the one red being the zh lazy-catalogue race in the new
inspector test, since fixed (top-level `await
loadStudioCatalogue('zh')`) and green three runs in a row.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CXDf4Yt5PtKZFbtLVD)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent f6caa12 commit bc8945f
14 files changed
Lines changed: 1153 additions & 41 deletions
File tree
- .changeset
- ui/packages
- app-shell/src/views
- metadata-admin/inspectors
- studio-design
- i18n/src/namespaces/studio
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
| |||
140 | 142 | | |
141 | 143 | | |
142 | 144 | | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
143 | 166 | | |
144 | 167 | | |
145 | 168 | | |
| |||
169 | 192 | | |
170 | 193 | | |
171 | 194 | | |
172 | | - | |
173 | | - | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
174 | 203 | | |
175 | | - | |
| 204 | + | |
176 | 205 | | |
177 | 206 | | |
178 | 207 | | |
179 | 208 | | |
180 | | - | |
181 | | - | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
182 | 214 | | |
183 | 215 | | |
184 | 216 | | |
185 | 217 | | |
186 | 218 | | |
187 | 219 | | |
188 | | - | |
| 220 | + | |
189 | 221 | | |
190 | 222 | | |
191 | 223 | | |
| |||
205 | 237 | | |
206 | 238 | | |
207 | 239 | | |
| 240 | + | |
| 241 | + | |
208 | 242 | | |
209 | | - | |
210 | | - | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
211 | 246 | | |
212 | 247 | | |
213 | 248 | | |
| |||
411 | 446 | | |
412 | 447 | | |
413 | 448 | | |
414 | | - | |
| 449 | + | |
415 | 450 | | |
416 | 451 | | |
417 | 452 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
435 | 435 | | |
436 | 436 | | |
437 | 437 | | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
438 | 480 | | |
439 | 481 | | |
440 | 482 | | |
| |||
446 | 488 | | |
447 | 489 | | |
448 | 490 | | |
| 491 | + | |
449 | 492 | | |
450 | 493 | | |
451 | 494 | | |
452 | | - | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
453 | 500 | | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
454 | 507 | | |
455 | 508 | | |
456 | 509 | | |
| |||
464 | 517 | | |
465 | 518 | | |
466 | 519 | | |
467 | | - | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
468 | 529 | | |
469 | 530 | | |
470 | 531 | | |
| |||
473 | 534 | | |
474 | 535 | | |
475 | 536 | | |
| 537 | + | |
476 | 538 | | |
477 | 539 | | |
| 540 | + | |
478 | 541 | | |
479 | 542 | | |
480 | 543 | | |
| 544 | + | |
481 | 545 | | |
482 | 546 | | |
| 547 | + | |
483 | 548 | | |
484 | 549 | | |
485 | 550 | | |
| |||
489 | 554 | | |
490 | 555 | | |
491 | 556 | | |
492 | | - | |
| 557 | + | |
493 | 558 | | |
494 | 559 | | |
495 | 560 | | |
| |||
506 | 571 | | |
507 | 572 | | |
508 | 573 | | |
509 | | - | |
| 574 | + | |
510 | 575 | | |
511 | 576 | | |
512 | 577 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
96 | 96 | | |
97 | 97 | | |
98 | 98 | | |
| 99 | + | |
99 | 100 | | |
100 | 101 | | |
101 | 102 | | |
| |||
134 | 135 | | |
135 | 136 | | |
136 | 137 | | |
| 138 | + | |
| 139 | + | |
137 | 140 | | |
138 | 141 | | |
139 | | - | |
140 | | - | |
141 | | - | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
142 | 145 | | |
143 | 146 | | |
144 | 147 | | |
| |||
0 commit comments