From e610caddc69684da081fe1a8442c17803f4cf4df Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 23 Oct 2026 14:51:12 +0200 Subject: [PATCH] :bug: Preserve untouched parent grid cells during component swaps Restore the original cell metadata after replacing a child in place, and ignore touched while assigning the new instance. Later main cell moves can then reach the swapped copy. Fix F128. The regression failed before the fix. Swap suite: 37 tests, 137 assertions. Benchmark ratios against Phase 1e: main 10/100/1000 0.46/0.52/0.53; three levels 0.47; chain 0.51; library 0.51; many shapes 0.49; variant switch 0.61. No regression flag. AI-assisted-by: GPT-6 --- common/src/app/common/logic/instances.cljc | 2 +- common/src/app/common/logic/variants.cljc | 10 +++++++++- .../test/common_tests/logic/swap_group_test.cljc | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/common/src/app/common/logic/instances.cljc b/common/src/app/common/logic/instances.cljc index e62fce510a..a4496d89d9 100644 --- a/common/src/app/common/logic/instances.cljc +++ b/common/src/app/common/logic/instances.cljc @@ -99,7 +99,7 @@ (cond-> (and (some? row) (some? column)) (-> (ctsl/push-into-cell [(:id first-shape)] row column) (ctsl/assign-cells objects))))) - {:with-objects? true}) + {:with-objects? true :ignore-touched true}) (pcb/reorder-grid-children [(:parent-id first-shape)]))) changes) diff --git a/common/src/app/common/logic/variants.cljc b/common/src/app/common/logic/variants.cljc index e022f29e74..fa8ae37a1f 100644 --- a/common/src/app/common/logic/variants.cljc +++ b/common/src/app/common/logic/variants.cljc @@ -428,7 +428,15 @@ [changes parents-of-swapped] (if keep-touched? (generate-keep-touched changes new-shape shape orig-shapes page libraries ldata) - [changes []])] + [changes []]) + + ;; Replacement keeps the head id and its cell. Cleanup during the + ;; temporary deletion must not change the parent's placement data. + changes (cond-> changes + (ctsl/grid-layout? parent) + (pcb/update-shapes [(:id parent)] + #(assoc % :layout-grid-cells (:layout-grid-cells parent)) + {:ignore-touched true}))] [new-shape changes (concat all-parents parents-of-swapped)])) (defn find-switch-target diff --git a/common/test/common_tests/logic/swap_group_test.cljc b/common/test/common_tests/logic/swap_group_test.cljc index 9a01570661..d6df6d007d 100644 --- a/common/test/common_tests/logic/swap_group_test.cljc +++ b/common/test/common_tests/logic/swap_group_test.cljc @@ -22,6 +22,10 @@ [app.common.logic.variants :as clv] [app.common.math :as mth] [app.common.test-helpers.components :as thc] + [app.common.test-helpers.composable.comp.nodes :as n] + [app.common.test-helpers.composable.comp.runner :as r] + [app.common.test-helpers.composable.comp.setups :as setups] + [app.common.test-helpers.composable.core :as tm] [app.common.test-helpers.compositions :as tho] [app.common.test-helpers.files :as thf] [app.common.test-helpers.ids-map :as thi] @@ -34,6 +38,18 @@ (t/use-fixtures :each thi/test-fixture) +(t/deftest swapping-a-grid-child-keeps-the-parent-cells-untouched + (let [initial (setups/grid-component-with-copy) + swapped (-> initial (r/step (n/swap-shape :copy-child1 :other)) r/settle) + parent (tm/resolve-shape swapped :grid-copy) + moved (-> swapped (r/step (n/move-to-cell :grid-root :child1 1 3)) r/settle) + final-parent (tm/resolve-shape moved :grid-copy) + child-id (:id (tm/resolve-shape moved :copy-child1)) + cell (first (filter #(some #{child-id} (:shapes %)) (vals (:layout-grid-cells final-parent))))] + (t/is (nil? (:touched parent))) + (t/is (= (:layout-grid-cells (tm/resolve-shape initial :grid-copy)) (:layout-grid-cells parent))) + (t/is (= 3 (:column cell))))) + (defn- setup [] ;; {:star-main} [:name Frame1] # [Component :star]