Repository navigation
Commit 7ba8b11
fix(app-shell): Studio's form view canvas honours layout horizontal and the other form view keys (#29759)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9Ubb1jwz5572SRdM7sFPV66BJ3)_
Fixes #29676
Clause-②: no
Metadata-protocol: none
Claim 6593560214, surface amendment 6593906746.
## 维护者速读
- **改了什么**:Studio「界面」里打开表单视图时,画布(设计和运行两种模式)现在按视图的 `layout`
画字段:`horizontal` 时标签在输入框左侧同一行,`vertical` 或未设置时标签在上方,和以前一样。画布同时会用上视图的
`columns`、`defaultTab`、`tabPosition`(分页表单)、`allowSkip`、`showStepIndicator`(向导表单)。
- **为什么改**:画布拼表单时只拿了 `type`、`sections`、`fields`,其余键全部丢掉。作者在属性面板里选了
horizontal,画布毫无变化,而终端用户的表单页其实已经按 horizontal 画了,两边看到的不一样。
- **风险与回滚**:只改 Studio 画布的显示,不改保存内容,也不改终端用户的表单页。`layout`
走的是控制台表单宿主自己用的同一个映射(`resolveFormViewChrome`),所以两边读法一致。回滚即 revert 本 PR。
- **先看**:`ViewPreview.tsx` 的 `buildFormPreviewSchema`;新测试
`ViewPreview.formLayout-29676.test.tsx`。
- **两分钟验证**:在可写包里存一个 `config.layout: 'horizontal'` 的表单视图并发布,打开
`/studio/包ID/interfaces?surface=view:视图名`:设计和运行两种模式下,"Project Name"
标签都在输入框左边同一行;手机宽度下仍是上下排列(断点设计如此)。
- **需要你做的**:无,席位落地。
## What changes
- **`buildFormPreviewSchema` (the form view canvas, shared by Studio
Design and Run) forwards the form view keys `ObjectForm` reads.** It
built the `object-form` schema from `type`, `sections` and `fields`
only, so a view stored with `config.layout: 'horizontal'` drew every
label above its control in Studio while the console's form page drew it
beside.
- **`layout` is read through `resolveFormViewChrome`**, the mapping the
console's form hosts (`RecordFormPage`, the New/Edit modal) already use,
so the canvas and the runtime read the key one way. Only its `layout` is
taken: the canvas draws no submit or cancel and seeds no create values.
- **`columns`, `defaultTab`, `tabPosition`, `allowSkip` and
`showStepIndicator` are passed as authored**, as `RecordFormPage` passes
them: `columns` to the field grid, `defaultTab` / `tabPosition` to the
tabbed layout, `allowSkip` / `showStepIndicator` to the wizard. A tabbed
view now opens on its authored tab in Studio.
- **`title` and `description` are deliberately not forwarded.** Measured
in `@object-ui/plugin-form`: only `DrawerForm`, `ModalForm` and
`MasterDetailForm` read `schema.title` / `schema.description`. The
canvas folds `drawer` / `modal` to `simple` (`toInlineFormType`), and
`simple`, `tabbed` and `wizard` read neither key, so forwarding them
would be a pin on a value nothing draws. Drawing a form's heading and
description on the canvas would need new canvas markup, so it is listed
under Acceptance notes rather than done here.
- `buildFormPreviewSchema` is now a named export, so the test can pin it
directly. No other module reads it. It adds one
`react-refresh/only-export-components` warning of the same kind the
file's existing `resolveObjectName` export carries.
- The renderer's horizontal branch
(`components/src/renderers/form/form.tsx`, #26843) is unchanged; it was
already correct.
## Why
Studio's form view inspector offers Layout, so an author could pick
`horizontal`, publish it, and see nothing change on the canvas, even
though end users got it (#29672 acceptance[1]). Declared and enforced at
runtime, but misdrawn where it is authored.
## Tests
`ViewPreview.formLayout-29676.test.tsx` (new, real `ViewPreview`,
`@object-ui/plugin-form` registered):
- `horizontal` draws the field item with the renderer's label-column
grid (`sm:grid` plus the two-column template) in Run, in Design
(`editing`), and on a `tabbed` view.
- CONTROL: `vertical` and no layout draw the stacked item, with no
`sm:grid`.
- The built schema carries `layout` through the console hosts' mapping
(`horizontal` kept, `vertical` kept, unset becomes the renderer default
`vertical`), and carries `columns`, `defaultTab`, `tabPosition`,
`allowSkip` and `showStepIndicator` as authored.
- CONTROL: unauthored keys stay unset, and the canvas still draws no
submit or cancel (`mode: 'create'`).
- `defaultTab: 'details'` opens the Details tab on the drawn tabbed form
(`aria-selected`).
## Acceptance notes
- **The canvas draws no form heading or description.** A form view's
`title` / `description` show on the console's `/forms` page (its own
heading and description) but not on the Studio canvas, whose inline
layouts read neither key. Out of scope here (see What changes); noted,
not filed.
- **Phone width:** below the `sm` breakpoint a horizontal form stacks by
design, on the canvas and on the console's form page alike (measured at
390 px below).
- **No end-user host drops `layout`.** The console's `/forms/NAME` page
draws horizontal beside (measured), and `RecordFormPage` and
AppContent's New/Edit modal forward it through `resolveFormViewChrome`
(pinned by the #26843 tests).
## Verification
<details><summary>Live, on the showcase (dev --fresh, Vite source
console, scratch package over REST)</summary>
Three published form views on `showcase_project` (`layout: horizontal`,
`vertical`, unset), each with one two-column section (Project Name,
Status). Label and control positions from `getBoundingClientRect` at
1440 px, x,y in px:
| surface | view | before (c76cdeb) | after (623f76a) |
|:---|:---|:---|:---|
| Studio Design | horizontal | label 274,282 · control 274,300 (stacked,
no grid) | label 274,290 · control 450,276 (beside, grid) |
| Studio Run | horizontal | label 274,282 · control 274,300 (stacked) |
label 274,290 · control 450,276 (beside) |
| Studio Design / Run | vertical, unset | label 274,282 · control
274,300 | unchanged |
| console `/forms/NAME` | horizontal | label 429,191 · control 605,177
(beside) | unchanged |
| console `/forms/NAME` | vertical, unset | label 429,177 · control
429,197 | unchanged |
The label's y sits inside the control's height because the grid aligns
the label on the control's first text line (`items-baseline`). At 390 px
the horizontal view stacks on both surfaces (Studio label 34,351 ·
control 34,369; console label 33,165 · control 33,185).
</details>
<details><summary>Ablations (ablation-replace.mjs on 623f76a,
src-resolved; each restored blob == HEAD, git diff HEAD empty)</summary>
- A: `layout: resolveFormViewChrome(` replaced by `layout: undefined &&
resolveFormViewChrome(` gives 4 failed / 5 passed (the three horizontal
renders and the layout schema pin).
- B: `defaultTab: body.defaultTab,` replaced by `defaultTab: undefined,`
gives 2 failed / 7 passed (the schema pin and the drawn tab).
- C: `columns: body.columns,` replaced by `columns: undefined,` gives 1
failed / 8 passed.
</details>
<details><summary>Local runs</summary>
- New file: 9/9 tests passed (623f76a).
- Neighbour sweep, every ui test file naming `ViewPreview` or
`resolveFormViewChrome` (18 files, locked, 2 workers): 443 tests passed
(1718156).
- `turbo run type-check --filter=@object-ui/app-shell`: 65/65
(623f76a).
- eslint on the touched files: 0 errors.
- `dispatch-gates --commands` derived 35 commands; all 35 exit 0
(1718156), incl. `check-sdui-manifest` and its self-test,
`check:type-check-debt` (locked), and `pnpm --dir ui exec vitest run
scripts/` (170 files passed, 2 skipped, at `--maxWorkers=2`). `--ran`
reconciliation 35/35, 0 NOT-MEASURED.
- After merging `origin/main` again (0d3b9c0, 9 commits, none touching
these files; rebuilt 118/118): the 18-file neighbour sweep, 443 tests
passed, and the app-shell type-check, 65/65.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (eslint on the touched
files, 0 errors; the repo-wide lint is CI's.)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (Not touched.)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QsR2jSTfFyWwerNYfs13mT
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jSTfFyWwerNYfs13mT)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 0712470 commit 7ba8b11
3 files changed
Lines changed: 220 additions & 2 deletions
File tree
- .changeset
- ui/packages/app-shell/src/views/metadata-admin/previews
| 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 | + | |
| 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 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| |||
79 | 80 | | |
80 | 81 | | |
81 | 82 | | |
82 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
83 | 89 | | |
84 | 90 | | |
| 91 | + | |
85 | 92 | | |
86 | 93 | | |
87 | 94 | | |
| |||
100 | 107 | | |
101 | 108 | | |
102 | 109 | | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
103 | 130 | | |
104 | 131 | | |
105 | 132 | | |
| |||
267 | 294 | | |
268 | 295 | | |
269 | 296 | | |
270 | | - | |
| 297 | + | |
271 | 298 | | |
272 | 299 | | |
273 | 300 | | |
| |||
0 commit comments