diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 2f191a50b3..f4ba1b7456 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -96,14 +96,17 @@ (into shapes (mapcat #(get-children-ids-rec % (conj processed id))) shapes))))] (get-children-ids-rec id #{}))) +(defn get-children-ids-with-self + [objects id] + (into [id] (get-children-ids objects id))) + (defn get-children [objects id] (mapv (d/getf objects) (get-children-ids objects id))) (defn get-children-with-self [objects id] - (let [lookup (d/getf objects)] - (into [(lookup id)] (map lookup) (get-children-ids objects id)))) + (mapv (d/getf objects) (get-children-ids-with-self objects id))) (defn get-parent "Retrieve the id of the parent for the shape-id (if exists)" diff --git a/common/src/app/common/types/component.cljc b/common/src/app/common/types/component.cljc index ad37b189c3..59b718415e 100644 --- a/common/src/app/common/types/component.cljc +++ b/common/src/app/common/types/component.cljc @@ -16,6 +16,12 @@ [shape] (some? (:component-id shape))) +(defn subinstance-head? + "Check if this shape is the head of a subinstance." + [shape] + (and (some? (:component-id shape)) + (nil? (:component-root shape)))) + (defn instance-of? [shape file-id component-id] (and (some? (:component-id shape)) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index efed2c61e0..a546e198b4 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -20,6 +20,7 @@ [app.common.pages.helpers :as cph] [app.common.text :as txt] [app.common.transit :as t] + [app.common.types.component :as ctk] [app.common.types.components-list :as ctkl] [app.common.types.container :as ctn] [app.common.types.file :as ctf] @@ -739,14 +740,7 @@ (assoc shape :masked-group? false))) ;; Detach shapes moved out of their component - (pcb/update-shapes shapes-to-detach - (fn [shape] - (assoc shape :component-id nil - :component-file nil - :component-root? nil - :remote-synced? nil - :shape-ref nil - :touched nil))) + (pcb/update-shapes shapes-to-detach ctk/detach-shape) ;; Make non root a component moved inside another one (pcb/update-shapes shapes-to-deroot @@ -862,21 +856,18 @@ ;; `shapes-to-reroot` Adds a root flag when a nested component instance is moved outside [shapes-to-detach shapes-to-deroot shapes-to-reroot] (reduce (fn [[shapes-to-detach shapes-to-deroot shapes-to-reroot] id] - (let [shape (get objects id) - instance-part? (and (:shape-ref shape) - (not (:component-id shape))) - instance-root? (:component-root? shape) - sub-instance? (and (:component-id shape) - (not (:component-root? shape))) - + (let [shape (get objects id) parent (get objects parent-id) component-shape (ctn/get-component-shape objects shape) component-shape-parent (ctn/get-component-shape objects parent) - detach? (and instance-part? (not= (:id component-shape) - (:id component-shape-parent))) - deroot? (and instance-root? component-shape-parent) - reroot? (and sub-instance? (not component-shape-parent)) + detach? (and (ctk/in-component-copy-not-root? shape) + (not= (:id component-shape) + (:id component-shape-parent))) + deroot? (and (ctk/instance-root? shape) + component-shape-parent) + reroot? (and (ctk/subinstance-head? shape) + (not component-shape-parent)) ids-to-detach (when detach? (cons id (cph/get-children-ids objects id)))] diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 1bf7828289..862cb4599c 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -17,6 +17,8 @@ [app.common.math :as mth] [app.common.pages.changes-builder :as pcb] [app.common.pages.helpers :as cph] + [app.common.types.component :as ctk] + [app.common.types.container :as ctn] [app.common.types.modifiers :as ctm] [app.common.types.shape-tree :as ctst] [app.common.types.shape.layout :as ctl] @@ -717,8 +719,9 @@ (watch [it state _] (let [page-id (:current-page-id state) objects (wsh/lookup-page-objects state page-id) - layout? (get-in objects [frame-id :layout]) lookup (d/getf objects) + frame (get objects frame-id) + layout? (:layout frame) shapes (->> ids (cph/clean-loops objects) (keep lookup)) @@ -765,6 +768,21 @@ (remove (fn [shape] (and (ctl/layout-absolute? shape) (= frame-id (:parent-id shape)))))) + + frame-component + (ctn/get-component-shape objects frame) + + shape-ids-to-detach + (reduce (fn [result shape] + (if (and (some? shape) (ctk/in-component-copy-not-root? shape)) + (let [shape-component (ctn/get-component-shape objects shape)] + (if (= (:id frame-component) (:id shape-component)) + result + (into result (cph/get-children-ids-with-self objects (:id shape))))) + result)) + #{} + moving-shapes) + moving-shapes-ids (map :id moving-shapes) @@ -775,12 +793,14 @@ (cond-> (not (ctl/any-layout? objects frame-id)) (pcb/update-shapes moving-shapes-ids ctl/remove-layout-item-data)) (pcb/update-shapes moving-shapes-ids #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true))) + (pcb/update-shapes shape-ids-to-detach ctk/detach-shape) (pcb/change-parent frame-id moving-shapes drop-index) (pcb/remove-objects empty-parents))] (when (and (some? frame-id) (d/not-empty? changes)) (rx/of (dch/commit-changes changes) (dwc/expand-collapse frame-id))))))) + (defn- get-displacement "Retrieve the correct displacement delta point for the provided direction speed and distances thresholds."