From 7aeb5498a1f37e13da66710a60befe49bd58b375 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 26 Jan 2024 14:21:41 +0100 Subject: [PATCH] :bug: Fix problem with grid component synchronization --- common/src/app/common/types/file.cljc | 8 +++ .../data/workspace/libraries_helpers.cljs | 67 ++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/common/src/app/common/types/file.cljc b/common/src/app/common/types/file.cljc index 2d42ba1b1..8241640e4 100644 --- a/common/src/app/common/types/file.cljc +++ b/common/src/app/common/types/file.cljc @@ -13,6 +13,7 @@ [app.common.files.helpers :as cfh] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] + [app.common.geom.shapes.tree-seq :as gsts] [app.common.logging :as l] [app.common.schema :as sm] [app.common.text :as ct] @@ -176,6 +177,13 @@ (when (:shape-ref shape) (get-component-shape file-data component (:shape-ref shape)))) +(defn get-shape-in-copy + "Given a shape in the main component and the root of the copy component returns the equivalent + shape inside the root copy that matches the main-shape" + [file-data main-shape root-copy] + (->> (gsts/get-children-seq (:id root-copy) (:objects file-data)) + (d/seek #(= (:shape-ref %) (:id main-shape))))) + (defn find-ref-shape "Locate the near component in the local file or libraries, and retrieve the shape referenced by the instance shape." diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index c9057dc1a..2ce22441e 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -51,6 +51,8 @@ (declare change-touched) (declare change-remote-synced) (declare update-attrs) +(declare update-grid-main-attrs) +(declare update-grid-copy-attrs) (declare reposition-shape) (declare make-change) @@ -665,6 +667,13 @@ container omit-touched?) + (ctl/grid-layout? shape-main) + (update-grid-copy-attrs shape-main + shape-inst + library + component + container) + reset? (change-touched shape-inst shape-main @@ -836,6 +845,12 @@ component-container {:copy-touched? true})) + (ctl/grid-layout? shape-main) + (update-grid-main-attrs shape-main + shape-inst + component-container + container) + clear-remote-synced? (change-remote-synced shape-inst container nil) @@ -957,12 +972,12 @@ (recur (next children-inst) (remove #(= (:id %) (:id child-main')) children-main) (-> changes - (both-cb child-inst' child-main) + (both-cb child-inst child-main') (moved-cb child-inst child-main'))) (recur (remove #(= (:id %) (:id child-inst')) children-inst) (next children-main) (-> changes - (both-cb child-inst child-main') + (both-cb child-inst' child-main) (moved-cb child-inst' child-main))))))))))) (defn- add-shape-to-instance @@ -1286,7 +1301,9 @@ origin-shape (reposition-shape origin-shape origin-root dest-root) touched (get dest-shape :touched #{})] - (loop [attrs (seq (keys ctk/sync-attrs)) + (loop [attrs (->> (seq (keys ctk/sync-attrs)) + ;; We don't do automatic update of the `layout-grid-cells` property. + (remove #(= :layout-grid-cells %))) roperations [] uoperations '()] @@ -1335,6 +1352,50 @@ (conj roperations roperation) (conj uoperations uoperation))))))))) +(defn- update-grid-copy-attrs + "Synchronizes the `layout-grid-cells` property from the main shape to the copies" + [changes shape-main shape-copy main-container main-component copy-container] + (let [ids-map + (into {} + (comp + (map #(dm/get-in copy-container [:objects %])) + (keep + (fn [copy-shape] + (let [main-shape (ctf/get-ref-shape main-container main-component copy-shape)] + [(:id main-shape) (:id copy-shape)])))) + (:shapes shape-copy))] + + (-> changes + (pcb/with-container copy-container) + (pcb/update-shapes + [(:id shape-copy)] + (fn [shape-copy] + ;; Take cells from main and remap the shapes to assign it to the copy + (let [new-cells (-> (ctl/remap-grid-cells shape-main ids-map) :layout-grid-cells)] + (assoc shape-copy :layout-grid-cells new-cells))))))) + +(defn- update-grid-main-attrs + "Synchronizes the `layout-grid-cells` property from the copy to the main shape" + [changes shape-main shape-copy main-container copy-container] + (let [ids-map + (into {} + (comp + (map #(dm/get-in main-container [:objects %])) + (keep + (fn [main-shape] + (let [copy-shape (ctf/get-shape-in-copy copy-container main-shape shape-copy)] + [(:id copy-shape) (:id main-shape)])))) + (:shapes shape-main))] + (-> changes + (pcb/with-page main-container) + (pcb/with-objects (:objects main-container)) + (pcb/update-shapes + [(:id shape-main)] + (fn [shape-main] + ;; Take cells from copy and remap the shapes to assign it to the copy + (let [new-cells (-> (ctl/remap-grid-cells shape-copy ids-map) :layout-grid-cells)] + (assoc shape-main :layout-grid-cells new-cells))))))) + (defn- reposition-shape [shape origin-root dest-root] (let [shape-pos (fn [shape]