fix(ui): Paste Chunk fills the destination's blanks instead of dropping structure (#589) [DO NOT MERGE — needs review] - #725
Conversation
…ng structure (#589) Per maintainer decision, Paste Chunk should "paste everything that isn't already set in the destination." Today it applies only the form-managed subset with a source-wins merge, so a copied component's structure/identifiers are dropped and the target's stale structure survives (the #589 bug), and other set fields get clobbered. New behavior — a deep fill-empty merge (fillEmptyDeepMerge): - Keep every value the destination already has set; only fill its blanks from the chunk. - Non-empty arrays are kept wholesale (don't splice source items into a populated list). - Never paste separately-managed metadata — recordModified, automationCode, measurements (PASTE_PRESERVED_FIELDS) — preserving the #704 fix even into a blank destination. - The form still renders its managed subset, but we now persist the full merged entity so pasted structure/identifiers the form doesn't itself show are saved. Covered by fillEmptyDeepMerge unit tests (fill-empty, preserve-set, nested, 0/false, never-paste metadata) and the updated paste integration test. NOTE: behavioral change to a shared, delicate code path — holding for review by others before merge, per maintainer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #725 +/- ##
==========================================
+ Coverage 55.57% 55.64% +0.07%
==========================================
Files 457 457
Lines 18355 18387 +32
Branches 742 753 +11
==========================================
+ Hits 10200 10231 +31
- Misses 8142 8143 +1
Partials 13 13
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Runtime verification note. I drove the no-auth stack to exercise this end-to-end in the reaction editor, but reliably automating the full path (add component A → set fields → Save → Copy Chunk → add component B → set one field → Paste Chunk → read back) kept fighting the editor's Drawer + "Reaction updated" toast + form-remount-on-save behavior. Rather than keep grinding browser automation, I'm relying on the deterministic coverage:
The editor flow is best exercised by a reviewer directly (the Key review questions in the description are the things to poke at). Happy to pair on a Playwright E2E for this once the semantics are agreed. 🤖 Generated with Claude Code |



Summary
Per the maintainer decision on #589, Paste Chunk should "paste everything that isn't already set in the destination."
Today, paste applies only each entity's form-managed subset with a source-wins merge (
deepMergeWithArrayMerge). Two consequences:New behavior —
fillEmptyDeepMergeA deep fill-empty merge:
recordModified,automationCode,measurements(PASTE_PRESERVED_FIELDS) — preserving the fix(ui): submit filtered values on Paste Chunk (#601, #592) #704 fix even into a blank destination."Not set" = nullish, empty string, or empty array/object.
0andfalsecount as set.🔎 Key review questions
PASTE_PRESERVED_FIELDSset (recordModified,automationCode,measurements) is the crux — it's what keeps fix(ui): submit filtered values on Paste Chunk (#601, #592) #704 from regressing. Is this the right/complete set of "never paste" fields across all entities (provenance, setup, product, conditions measurements, …)?Test plan
npx tsc -bcleannpx vitest run— 561 passing; 10 newfillEmptyDeepMergeunit tests (fill-empty, preserve-set, nested,0/falsetreated as set, never-paste metadata) + updated paste integration test (blankdoifilled,recordModifiednot leaked).prettier/eslintcleanCloses #589.
🤖 Generated with Claude Code