Repository navigation
Commit 7f328cd
feat(app-shell): fold the .custom pair's landing card under its base and name the base on the pending-changes sheet (#29723)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbUbQXNJDPax1UE5upP9BnZj)_
Part of #29691
Clause-②: yes (widening)
Metadata-protocol: none
## 维护者速读
- 改了什么:Studio 首页「我的软件包」不再给 `BASE.custom`
定制包单独一张卡,它折叠在基座卡下(与软件包切换器同一规则);基座卡保留「已定制 n
项」及其链接。待发布变更面板在审阅定制包草稿时,标题下多一句「保存到 基座名 的定制」。
- 为什么改:定制一个只读软件包后,首页冒出一张用户从没建过的「可写」包卡,而面板只说「本软件包」,用户不知道改动存到了哪里(ADR-0146
D3)。
- 风险与回滚:仅 UI 与一条新文案键;定制包的导出与删除仍在 Studio「概览 → 软件包」页(已实测)。回滚即还原本
PR,无数据或协议变化。
- 先看:`BuilderLanding.tsx`
的折叠(`foldCustomizationPairs`);`DraftChangesPanel.tsx` 的
`customizationOf` 一行;`StudioDesignSurface.tsx` 只在 `pairId` 存在时传入基座名。
- 两分钟验证:在 showcase 定制任意一项后打开 `/_console/studio`,「我的软件包」里不再有
`com.example.showcase.custom` 卡,只读区的 Showcase 卡写着「已定制 1 项」;点 Publish
打开面板,标题下是「保存到 ObjectStack Showcase 的定制」。
- 需要你做的:无,席位落地。
## What changes
- **Landing (ADR-0146 D3).** `BuilderLanding` folds each `BASE.custom`
pair under its base with the switcher's own `foldCustomizationPairs`
before it splits writable from read-only. A pair whose base is listed
draws no card in either section. The base's card keeps its "n
customized" line, and that line's link into the pair. A pair whose base
is not listed keeps its card, the switcher's rule too.
- **Pending-changes sheet.** `DraftChangesPanel` takes an optional
`customizationOf` (the base's label) and, when set, says under its title
"Saved to BASE's customizations" (zh 保存到 BASE 的定制). The sentence is one
exported helper, `savedToCustomizationText`, so the item header can say
the same words in the follow-up PR. `StudioDesignSurface` passes the
base label only while it reviews a pair's drafts (`pairId` set), and
nothing for a writable package or a base with no pair.
- **i18n.** One new key, `preview.changes.savedToCustomization`, in all
ten `@object-ui/i18n` locale packs. Nothing is removed or renamed.
- **Not changed:** the publish toast (the card's direction names only
the item header and the sheet), and the item header, which waits for
#29693 and lands in a second PR.
## Contract review
- **What widens:** the published `@object-ui/i18n` locale packs gain one
leaf, `preview.changes.savedToCustomization`, in each of the ten packs,
and `@object-ui/app-shell` gains an optional `DraftChangesPanel` prop
(`customizationOf`) and one exported helper
(`savedToCustomizationText`).
- **What narrows:** nothing. No key, prop, export or accepted value is
removed or tightened. Metadata authors see no change
(`Metadata-protocol: none`).
## Tests
- `BuilderLanding.customizationCounts-28566.test.tsx`: a new describe
over the real landing. A read-only base and its writable pair draw one
card, the base's, with its customized count and the pair link, and the
pair's name and id appear on no card. A read-only pair folds under its
listed base too. CONTROL: a writable package that is no pair keeps its
card, and a pair whose base is not listed keeps its card. The existing
"no line for a pair" case now finds the orphan pair's card and no card
for the folded one.
- `DraftChangesPanel.test.tsx`: a new describe that renders the real
sheet through the real i18next hook and the shipped packs. With
`customizationOf="HotCRM"` it reads 保存到 HotCRM 的定制 in zh and "Saved to
HotCRM’s customizations" in en. CONTROL: without it, no sentence.
- `StudioDesignSurface.customizePublish-28562.test.tsx` (the real
surface): reviewing a listed pair, and after the first edit makes the
pair, the sheet is handed the base label `HotCRM`. CONTROL: a base with
no pair hands it nothing.
## Acceptance notes
- **Where the pair's export and delete live.** They were never on the
landing card, which offered only Open and Duplicate. They are on Studio,
Overview → Packages (`nav_packages` →
`/apps/studio/component/developer/packages`, the `developer:packages`
page). That page lists every served package with no pair fold. The
pair's row opens a detail sheet with Export (every row, `GET
/api/v1/packages/:id/export`) and Delete package (writable rows, `DELETE
/api/v1/packages/:id`). Measured live on a fresh showcase (`pnpm dev --
--fresh`, branch head `d47495aa`): `POST
/api/v1/packages/com.example.showcase/ensure-customization` answered 201
and created `com.example.showcase.custom`. `GET /api/v1/packages` then
served it as its own row (`writable: true`, `source: authored`), the row
the Packages page draws. `GET
/api/v1/packages/com.example.showcase.custom/export` answered 200 with
the pair's manifest, and `DELETE
/api/v1/packages/com.example.showcase.custom` answered 200, after which
the list held only `com.example.showcase`. Those are the doors the
sheet's Export and Delete package buttons call (`PackagesPage`: Export
on every row, Delete package on writable rows); the buttons themselves
were read from code, not clicked.
- **The review's claim that the pair card's link returns to the base
holds.** The pair card opened `/studio/PAIR/data`, and the
`StudioDesignSurface` wrapper sends every pillar URL of a pair to the
base's surface. `StudioDesignSurface.oneSurface-28572` already pins
that. The base card's customized link takes the same path, unchanged.
## Verification
<details><summary>Tests and gates (final head 62ad4a4; sweep on
d47495a, and the merge of main brought no file under ui/)</summary>
- **Red on main, green here.** The three touched test files with
`origin/main` `1c1a5d40`'s `BuilderLanding.tsx`, `DraftChangesPanel.tsx`
and `StudioDesignSurface.tsx` (each blob-identical to main, restored to
`HEAD` after, `git diff HEAD` empty): 7 failed, 24 passed. The 7 are the
new pins; the CONTROL cases stay green on main. On the branch: Test
Files 3 passed, Tests 31 passed, on `d47495aa` and again on `62ad4a49`.
- **Sweep** (`--maxWorkers=2`, locked): every ui test file naming
`BuilderLanding` or `DraftChangesPanel` plus every test reading the
locale packs or `preview.changes`, 254 files in six batches, all green
(346 + 425 + 554 + 289 + 519 + 677 tests), and `packages/i18n/` whole:
95 files, 1443 passed, 13 skipped.
- **Type check:** `turbo run type-check --filter=@object-ui/app-shell
--filter=@object-ui/i18n`: 66 of 66 tasks green.
- **eslint** on the touched source and test files: 0 errors, 8 warnings.
One is react-refresh's only-export-components warning on the new
`savedToCustomizationText` export, the warning the file's three other
exported helpers already carry. The other 7 are on lines this PR does
not touch.
- **Derived gates** (`node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack`): 35 commands, each exit 0, including
`check-sdui-manifest`, `check-changeset-no-major`,
`check-adr-0087-registration`, `check-closing-keyword-parity` (run
against this body) and `pnpm --dir ui exec vitest run scripts/` (170
files passed, 2 skipped).
- **Not run locally:** the full Test UI shards, which CI's Test UI runs.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jTWKHRdA5msPPhwmw4)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent fd43dc2 commit 7f328cd
17 files changed
Lines changed: 186 additions & 13 deletions
File tree
- .changeset
- ui/packages
- app-shell/src
- preview
- __tests__
- views/studio-design
- 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1328 | 1328 | | |
1329 | 1329 | | |
1330 | 1330 | | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
1331 | 1338 | | |
1332 | 1339 | | |
1333 | 1340 | | |
1334 | 1341 | | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
1335 | 1355 | | |
1336 | 1356 | | |
1337 | 1357 | | |
| |||
1341 | 1361 | | |
1342 | 1362 | | |
1343 | 1363 | | |
| 1364 | + | |
1344 | 1365 | | |
1345 | 1366 | | |
1346 | 1367 | | |
| |||
1608 | 1629 | | |
1609 | 1630 | | |
1610 | 1631 | | |
| 1632 | + | |
| 1633 | + | |
| 1634 | + | |
| 1635 | + | |
| 1636 | + | |
1611 | 1637 | | |
1612 | 1638 | | |
1613 | 1639 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
20 | 27 | | |
| 28 | + | |
21 | 29 | | |
22 | 30 | | |
23 | 31 | | |
24 | 32 | | |
| 33 | + | |
25 | 34 | | |
26 | 35 | | |
27 | 36 | | |
| |||
249 | 258 | | |
250 | 259 | | |
251 | 260 | | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
185 | 185 | | |
186 | 186 | | |
187 | 187 | | |
188 | | - | |
| 188 | + | |
189 | 189 | | |
190 | 190 | | |
191 | 191 | | |
192 | 192 | | |
| 193 | + | |
193 | 194 | | |
194 | | - | |
| 195 | + | |
| 196 | + | |
195 | 197 | | |
196 | 198 | | |
197 | 199 | | |
| |||
210 | 212 | | |
211 | 213 | | |
212 | 214 | | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| |||
117 | 118 | | |
118 | 119 | | |
119 | 120 | | |
120 | | - | |
121 | | - | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
122 | 130 | | |
123 | 131 | | |
124 | 132 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
29 | 31 | | |
30 | 32 | | |
31 | 33 | | |
| |||
78 | 80 | | |
79 | 81 | | |
80 | 82 | | |
81 | | - | |
82 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
83 | 93 | | |
84 | 94 | | |
85 | 95 | | |
| |||
233 | 243 | | |
234 | 244 | | |
235 | 245 | | |
| 246 | + | |
| 247 | + | |
236 | 248 | | |
237 | 249 | | |
238 | 250 | | |
| |||
246 | 258 | | |
247 | 259 | | |
248 | 260 | | |
| 261 | + | |
| 262 | + | |
249 | 263 | | |
250 | 264 | | |
251 | 265 | | |
| |||
259 | 273 | | |
260 | 274 | | |
261 | 275 | | |
| 276 | + | |
262 | 277 | | |
263 | 278 | | |
264 | 279 | | |
| |||
278 | 293 | | |
279 | 294 | | |
280 | 295 | | |
| 296 | + | |
281 | 297 | | |
282 | 298 | | |
283 | 299 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2857 | 2857 | | |
2858 | 2858 | | |
2859 | 2859 | | |
| 2860 | + | |
| 2861 | + | |
| 2862 | + | |
2860 | 2863 | | |
2861 | 2864 | | |
2862 | 2865 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4887 | 4887 | | |
4888 | 4888 | | |
4889 | 4889 | | |
| 4890 | + | |
4890 | 4891 | | |
4891 | 4892 | | |
4892 | 4893 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4490 | 4490 | | |
4491 | 4491 | | |
4492 | 4492 | | |
| 4493 | + | |
4493 | 4494 | | |
4494 | 4495 | | |
4495 | 4496 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3953 | 3953 | | |
3954 | 3954 | | |
3955 | 3955 | | |
| 3956 | + | |
| 3957 | + | |
3956 | 3958 | | |
3957 | 3959 | | |
3958 | 3960 | | |
| |||
0 commit comments