diff --git a/common/app/common/pages.cljc b/common/app/common/pages.cljc index 1332a7c08..aa54c710a 100644 --- a/common/app/common/pages.cljc +++ b/common/app/common/pages.cljc @@ -61,6 +61,7 @@ (d/export helpers/set-touched-group) (d/export helpers/touched-group?) (d/export helpers/get-base-shape) +(d/export helpers/is-parent?) ;; Process changes (d/export changes/process-changes) diff --git a/common/app/common/pages/helpers.cljc b/common/app/common/pages/helpers.cljc index 8957dbe0f..778968bf6 100644 --- a/common/app/common/pages/helpers.cljc +++ b/common/app/common/pages/helpers.cljc @@ -376,3 +376,25 @@ ;; The first id will be the top-most (get objects (first sorted-ids)))) + +(defn is-parent? + "Check if `parent-candidate` is parent of `shape-id`" + [objects shape-id parent-candidate] + + (loop [current (get objects parent-candidate) + done #{} + pending (:shapes current)] + + (cond + (contains? done (:id current)) + (recur (get objects (first pending)) + done + (rest pending)) + + (empty? pending) false + (and current (contains? (set (:shapes current)) shape-id)) true + + :else + (recur (get objects (first pending)) + (conj done (:id current)) + (concat (rest pending) (:shapes current)))))) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index ae552a469..e3fd438ce 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -822,6 +822,9 @@ ;; Ignore any shape whose parent is also intented to be moved ids (cp/clean-loops objects ids) + ;; If we try to move a parent into a child we remove it + ids (filter #(not (cp/is-parent? objects parent-id %)) ids) + parents (loop [res #{parent-id} ids (seq ids)] (if (nil? ids)