Repository navigation
Commit 31a608e
fix(app-shell): nav page picker offers a draft page only when its draft body can be a nav target (#26968)
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8PBqR3JqcpQdxvP362pdfwm)_
Fixes #26743
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:Studio Interfaces 导航项的「页面」选择器不再列出草稿态的记录页;草稿页按其草稿正文的 `type`
判定,与已发布页同一规则(绑定对象的草稿动作同理)。
- 为什么改:`_drafts` 行只带元数据类型 `page`,不带页面自身的
`type`,原代码对草稿行一律放行,选中草稿记录页、随应用发布后导航项打不开。
- 风险与回滚:只改 Studio 选择器的候选列表;每个仅草稿的页面/动作多一次草稿读取;读不到正文时仍列出(与无 `type`
的已发布行一致)。回滚即 revert 本 PR。
- 先看:`StudioDesignSurface.tsx` 的 `isDraftNavTarget` 与
`usePackageNavTargets` 中草稿循环;再看新测试
`StudioDesignSurface.navPageDrafts-26743.test.tsx`。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/app-shell/src/views/studio-design/StudioDesignSurface.navPageDrafts-26743.test.tsx`,预期
6 个测试全过。
- 需要你做的:无,席位落地。
## What changes
- `usePackageNavTargets` (Interfaces nav item inspector's target
picker): a draft-only row of a type whose `isNavTargetRow` verdict reads
a body key (`page`: the body's `type`; `action`: `objectName`) is now
judged on its draft body, read with `client.getDraft` and unwrapped by
`extractDraftBody`, the one draft-envelope reader. A draft record page
is no longer offered; a draft static page still is.
- A body that cannot be read (no draft served, a failed read) keeps the
row, as a published row with no `type` is kept: only a confirmed
non-target is dropped. Other target types (`dashboard`, `report`, `doc`)
read no body.
- In-place fix named here: the same draft loop also offered a draft
action bound to an object, which the nav cannot run (it runs global
actions only). Same defect class, same line, same gate families; covered
by one test.
## Why
The `_drafts` header (`ListDraftsResponseSchema`) carries the metadata
type name and the draft's `label`, never the body's own `type`, so the
old loop could not filter and added every draft-only row. Fixed
client-side with the existing draft read; no spec or server change.
## Tests
New `StudioDesignSurface.navPageDrafts-26743.test.tsx` (6 tests): a
draft record page is not offered; a draft static page is offered; a
published record page is still not offered; CONTROL an unreadable draft
body is still offered; a draft object-bound action is not offered, a
draft global action is; only body-keyed types read drafts, published
rows are never re-read.
<details><summary>Ablation (commit ca23ec4)</summary>
`node scripts/ablation-replace.mjs` replaced the anchor `if
(verdicts[i]) byName.set(row.name, row);` with an always-true condition:
anchor 1 -> 0, blob 8a30d22 -> e63569e6a119. Result: `a draft
record page is not offered` and `a draft action bound to an object is
not offered, a draft global action is` failed (2 failed, 4 passed).
Restored: blob == HEAD (8a30d22), `git diff HEAD` empty. No dist
leg: the test imports the component by relative path.
</details>
## Verification
All local readings at head `ca23ec41` (base `aa00362f`).
<details><summary>Local gates</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: 24 derived families, all run, every one
exit 0; `--ran` reconciliation: 24 derived, 24 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 run type-check` exit 0.
- `pnpm --dir ui exec vitest run
packages/app-shell/src/views/studio-design/
packages/app-shell/src/views/metadata-admin/inspectors/`: Test Files 429
passed, Tests 4289 passed, 1 skipped.
- `pnpm --dir ui run check:new-line-citations`: 0 new citations, exit 0.
- `node scripts/check-nul-bytes.mjs` exit 0.
</details>
Changeset: none. `@object-ui/app-shell` is `private: true`, so nothing
publishes; `skip-changeset` is declared with this PR.
## Acceptance notes
- Each draft-only page or action costs one `?state=draft` read when the
picker opens; `getDraft` asks the shared `_drafts` ledger read first, so
no extra ledger request is sent.
## 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 (CI).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset (nothing publishes
here), and both declaration lines are filled in.
- [x] 6. `packages/spec` 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)
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbYChiSg5184uQo2r5x)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent fd246c2 commit 31a608e
2 files changed
Lines changed: 241 additions & 4 deletions
| 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 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2980 | 2980 | | |
2981 | 2981 | | |
2982 | 2982 | | |
2983 | | - | |
2984 | | - | |
2985 | | - | |
| 2983 | + | |
| 2984 | + | |
| 2985 | + | |
| 2986 | + | |
| 2987 | + | |
| 2988 | + | |
| 2989 | + | |
2986 | 2990 | | |
2987 | 2991 | | |
2988 | 2992 | | |
2989 | 2993 | | |
2990 | 2994 | | |
2991 | 2995 | | |
2992 | 2996 | | |
| 2997 | + | |
| 2998 | + | |
| 2999 | + | |
| 3000 | + | |
| 3001 | + | |
| 3002 | + | |
| 3003 | + | |
| 3004 | + | |
| 3005 | + | |
| 3006 | + | |
| 3007 | + | |
| 3008 | + | |
| 3009 | + | |
| 3010 | + | |
| 3011 | + | |
| 3012 | + | |
| 3013 | + | |
| 3014 | + | |
| 3015 | + | |
| 3016 | + | |
| 3017 | + | |
| 3018 | + | |
| 3019 | + | |
| 3020 | + | |
| 3021 | + | |
2993 | 3022 | | |
2994 | 3023 | | |
2995 | 3024 | | |
| |||
3021 | 3050 | | |
3022 | 3051 | | |
3023 | 3052 | | |
| 3053 | + | |
3024 | 3054 | | |
3025 | 3055 | | |
3026 | | - | |
| 3056 | + | |
| 3057 | + | |
| 3058 | + | |
3027 | 3059 | | |
| 3060 | + | |
| 3061 | + | |
| 3062 | + | |
| 3063 | + | |
| 3064 | + | |
| 3065 | + | |
3028 | 3066 | | |
3029 | 3067 | | |
3030 | 3068 | | |
| |||
0 commit comments