From 4e7cca7ff4050501f70e315ce7df46b3ff8fbae4 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]