Repository navigation
Commit 968925c
fix(studio): the publish review names the flow steps that changed instead of "~ nodes" (#27432)
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ836VkJMbRirYcP4FDCFmjrE)_
Part of #27356
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:发布前的变更审阅里,流程草稿不再只写「其他变更:~ nodes」,而是逐个列出新增/修改/删除的步骤(先写步骤名,旁边是
id),修改的步骤写出改了哪个属性(如 `config.fields`)。
- 为什么改:HotCRM 18.2.0 走查(hotcrm#2320 Studio S6)发现发布对话框只说「Also changed: ~
nodes」,看不出改了哪一步。
- 风险与回滚:只在类型为 flow 且两侧步骤都有 id 时逐步对比;仅调整顺序或步骤无 id 时仍显示 `nodes`
行,不会把有变化的草稿说成「无变化」;回滚即 revert 本 PR。
-
先看:`ui/packages/app-shell/src/preview/DraftChangesPanel.tsx`(`diffFlowNodes`、`computeChangeDetail`
的 `type` 参数、`EntryDetail` 的节点行)。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/app-shell/src/preview/__tests__/DraftChangesPanel.flowNodeRows-27356.test.tsx`,预期
7 个用例全绿。
- 需要你做的:无,席位落地。
## What changes
Row 17 of #27356 (hotcrm#2320, Studio report finding S6): "The publish
dialog says "Also changed: ~ nodes"."
Premise measured first, as the order asked: the drill-in (`EntryDetail`)
already reads BOTH full bodies, the published item and the draft, and
every flow node carries its `id` and `label`. So the names are on the
client; no server door is needed. `computeChangeDetail` compared every
top-level key other than `fields` whole, and a flow keeps all its steps
in `nodes`, so any step edit read `~ nodes`.
In `ui/packages/app-shell/src/preview/DraftChangesPanel.tsx`:
- `computeChangeDetail(published, draft, type?)` takes the entry's type
(the drill-in passes `entry.type`). For a `flow`, `diffFlowNodes`
matches the two `nodes` lists by `id` and returns `nodes: { added,
changed, removed }` on `EntryChangeDetail`. Each row is `{ id, label?
}`; a changed node lists the properties that differ, `config` one level
down (`config.fields`), since nearly every inspector edit lands there.
Rows sort by id, as field rows sort by name.
- When that yields at least one node row, `nodes` leaves the "Also
changed:" key list. `edges` and every other key stay there.
- The drill-in renders the node rows after the field rows in
`FieldRow`'s own shape: mark, label, the id in monospace beside it, and
`· config.fields` for a changed node. `FieldRow` takes a `testId`
(default `draft-field-row`, unchanged); node rows are `draft-node-row`.
- `isEmptyChangeDetail` counts node rows.
Guards, each pinned:
- A reorder alone changes no node, so `nodes` stays a key row and the
draft never reads "No differences detected".
- A `nodes` list that is not keyed by a unique string `id` keeps the old
whole-key comparison (`nodes: null`).
- Any type other than `flow` is compared exactly as before.
## Why
"~ nodes" tells the author that something in the flow changed, which
they knew. The summary is the last look before publishing, and it should
say which step and what about it, the way the same panel already names
an object's fields.
## Tests
`ui/packages/app-shell/src/preview/__tests__/DraftChangesPanel.flowNodeRows-27356.test.tsx`
(7 tests):
- `computeChangeDetail` on a flow: the added node (no label, id only),
the changed node with `config.fields`, the removed node by label;
`nodes` is not a key row and `edges` is.
- A changed top-level node property (`label`) is named as itself.
- A NEW flow adds every node.
- CONTROL: a reorder alone keeps `nodes` as a key row.
- CONTROL: a list not keyed by `id` gives `nodes: null` and keeps the
key row.
- CONTROL: the same bodies typed `page` compare `nodes` whole.
- The panel: expanding a flow draft shows `+ wait_a_day`, `~ Create
follow-up task create_task · config.fields`, `− Notify owner
notify_owner`, the id in monospace, no "~ nodes", and "Also changed:"
with `~ edges`.
<details><summary>Ablation (one: the flow branch never taken)</summary>
`node scripts/ablation-replace.mjs --anchor " if (type === 'flow') {"
--replacement " if (type === 'not-a-flow') {"` on
`DraftChangesPanel.tsx` (anchor 1 → 0, blob `0583bc280d81` →
`9f20adc71adb`): 5 failed / 2 passed. The two that stay green are the
not-keyed and not-a-flow controls, which assert the old behaviour.
Restored: blob after restore = blob at HEAD = `0583bc280d81`, `git diff
HEAD` empty.
</details>
## Acceptance notes
- A changed node lists property paths (`config.fields`), not the field
names inside the map (`subject`, `due_date`). One level down covers the
inspector's edits without restating each node type's config shape here.
- Node rows sort by id, not by canvas position: the drill-in has no
layout order to read, and field rows sort by name the same way.
- `edges` still reads `~ edges`. Edge ids are machine ids with no label,
so per-edge rows would not read better; the node rows already say which
steps were added or removed.
- `computeChangeDetail` stays one function for every type; the flow
branch is opt-in by `type`, so no caller that passes two arguments
changes.
## Verification
All on head `751c7d1b` (merge base `b10fd655`), after `pnpm install
--frozen-lockfile` and a fresh `@object-ui/app-shell^...` closure build,
under the shared verification lock.
- New file: 7 / 7 passed. Every test file under `ui/` that names
`DraftChangesPanel` (72 files, the new one included): 436 / 436 passed.
- `pnpm --filter @object-ui/app-shell run type-check` (both `tsc`
programs): exit 0.
- `pnpm --dir ui run check:new-line-citations`: 0 new citations, exit 0.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: the same 34 families as rows 21 and 16, all
34 exit 0 (the `ui scripts/` family: 169 files passed, 2 skipped);
`--ran`: 34 run, 0 NOT-MEASURED, 0 UNRUN. Tier: no path-derived mandate;
290 changed lines.
Repo-wide lint, the full ui test battery and the e2e jobs are CI's.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbWuU6sVfBYiy4dY4PA)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent b74793c commit 968925c
3 files changed
Lines changed: 283 additions & 7 deletions
File tree
- .changeset
- ui/packages/app-shell/src/preview
- __tests__
| 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 | |
|---|---|---|---|
| |||
314 | 314 | | |
315 | 315 | | |
316 | 316 | | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
317 | 329 | | |
318 | 330 | | |
319 | 331 | | |
| |||
347 | 359 | | |
348 | 360 | | |
349 | 361 | | |
350 | | - | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
351 | 369 | | |
352 | | - | |
| 370 | + | |
353 | 371 | | |
354 | | - | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
355 | 445 | | |
356 | 446 | | |
357 | 447 | | |
| |||
460 | 550 | | |
461 | 551 | | |
462 | 552 | | |
| 553 | + | |
463 | 554 | | |
464 | 555 | | |
465 | 556 | | |
| |||
506 | 597 | | |
507 | 598 | | |
508 | 599 | | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
509 | 607 | | |
510 | 608 | | |
511 | 609 | | |
| |||
521 | 619 | | |
522 | 620 | | |
523 | 621 | | |
524 | | - | |
| 622 | + | |
525 | 623 | | |
526 | 624 | | |
527 | 625 | | |
| |||
649 | 747 | | |
650 | 748 | | |
651 | 749 | | |
| 750 | + | |
652 | 751 | | |
653 | 752 | | |
654 | 753 | | |
655 | 754 | | |
656 | 755 | | |
| 756 | + | |
657 | 757 | | |
658 | 758 | | |
659 | 759 | | |
660 | 760 | | |
661 | | - | |
| 761 | + | |
662 | 762 | | |
663 | 763 | | |
664 | 764 | | |
| |||
758 | 858 | | |
759 | 859 | | |
760 | 860 | | |
761 | | - | |
| 861 | + | |
762 | 862 | | |
763 | 863 | | |
764 | 864 | | |
| |||
812 | 912 | | |
813 | 913 | | |
814 | 914 | | |
815 | | - | |
| 915 | + | |
816 | 916 | | |
817 | 917 | | |
818 | 918 | | |
| |||
887 | 987 | | |
888 | 988 | | |
889 | 989 | | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
890 | 1002 | | |
891 | 1003 | | |
892 | 1004 | | |
| |||
| 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 | + | |
0 commit comments