diff --git a/common/app/common/pages.cljc b/common/app/common/pages.cljc index 619240400..f295c4e76 100644 --- a/common/app/common/pages.cljc +++ b/common/app/common/pages.cljc @@ -29,6 +29,7 @@ (d/export helpers/walk-pages) (d/export helpers/select-objects) (d/export helpers/update-object-list) +(d/export helpers/get-component-shape) (d/export helpers/get-root-shape) (d/export helpers/make-container) (d/export helpers/page?) diff --git a/common/app/common/pages/changes.cljc b/common/app/common/pages/changes.cljc index 61d64015a..37375b218 100644 --- a/common/app/common/pages/changes.cljc +++ b/common/app/common/pages/changes.cljc @@ -222,24 +222,7 @@ (d/dissoc-in [pid :remote-synced?]))))))))) (update-parent-id [objects id] - (update objects id - (fn [object] - (let [prev-component-root (cph/get-root-shape object objects) - detach-component (fn [object] - (let [new-component-root - (cph/get-root-shape object objects)] - (cond-> object - (not= prev-component-root new-component-root) - (dissoc object - :component-id - :component-file - :component-root? - :remote-synced? - :shape-ref - :touched))))] - (-> object - (assoc :parent-id parent-id) - detach-component))))) + (assoc-in objects [id :parent-id] parent-id)) ;; Updates the frame-id references that might be outdated (assign-frame-id [frame-id objects id] @@ -276,7 +259,7 @@ ;; Add the new shapes to the parent object. (update $ parent-id #(add-to-parent % index shapes)) - ;; Update each individual shapre link to the new parent + ;; Update each individual shape link to the new parent (reduce update-parent-id $ shapes) ;; Analyze the old parents and clear the old links diff --git a/common/app/common/pages/helpers.cljc b/common/app/common/pages/helpers.cljc index b96ac8af3..277c9678e 100644 --- a/common/app/common/pages/helpers.cljc +++ b/common/app/common/pages/helpers.cljc @@ -33,12 +33,23 @@ (update page :objects #(into % (d/index-by :id objects-list)))) +(defn get-component-shape + "Get the parent shape linked to a component for this shape, if any" + [shape objects] + (if-not (:shape-ref shape) + nil + (if (:component-id shape) + shape + (if-let [parent-id (:parent-id shape)] + (get-component-shape (get objects parent-id) objects) + nil)))) + (defn get-root-shape "Get the root shape linked to a component for this shape, if any" [shape objects] (if-not (:shape-ref shape) nil - (if (:component-id shape) + (if (:component-root? shape) shape (if-let [parent-id (:parent-id shape)] (get-root-shape (get objects parent-id) objects) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 53fe4d1a8..a6e5ea64d 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -19,6 +19,7 @@ [app.common.geom.align :as gal] [app.common.math :as mth] [app.common.pages :as cp] + [app.common.pages.helpers :as cph] [app.common.spec :as us] [app.common.uuid :as uuid] [app.config :as cfg] @@ -838,6 +839,33 @@ #{} ids) + [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))) + + parent (get objects parent-id) + component-shape (cph/get-component-shape shape objects) + component-shape-parent (cph/get-component-shape parent objects) + + 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)) + + ids-to-detach (when detach? + (cons id (cph/get-children id objects)))] + + [(cond-> shapes-to-detach detach? (into ids-to-detach)) + (cond-> shapes-to-deroot deroot? (conj id)) + (cond-> shapes-to-reroot reroot? (conj id))])) + [[] [] []] + ids) + rchanges (d/concat [{:type :mov-objects :parent-id parent-id @@ -854,7 +882,46 @@ :operations [{:type :set :attr :masked-group? :val false}]}) - groups-to-unmask)) + groups-to-unmask) + (map (fn [id] + {:type :mod-obj + :page-id page-id + :id id + :operations [{:type :set + :attr :component-id + :val nil} + {:type :set + :attr :component-file + :val nil} + {:type :set + :attr :component-root? + :val nil} + {:type :set + :attr :remote-synced? + :val nil} + {:type :set + :attr :shape-ref + :val nil} + {:type :set + :attr :touched + :val nil}]}) + shapes-to-detach) + (map (fn [id] + {:type :mod-obj + :page-id page-id + :id id + :operations [{:type :set + :attr :component-root? + :val nil}]}) + shapes-to-deroot) + (map (fn [id] + {:type :mod-obj + :page-id page-id + :id id + :operations [{:type :set + :attr :component-root? + :val true}]}) + shapes-to-reroot)) uchanges (d/concat (reduce (fn [res id] @@ -876,7 +943,47 @@ :operations [{:type :set :attr :masked-group? :val true}]}) - groups-to-unmask))] + groups-to-unmask) + (map (fn [id] + (let [obj (get objects id)] + {:type :mod-obj + :page-id page-id + :id id + :operations [{:type :set + :attr :component-id + :val (:component-id obj)} + {:type :set + :attr :component-file + :val (:component-file obj)} + {:type :set + :attr :component-root? + :val (:component-root? obj)} + {:type :set + :attr :remote-synced? + :val (:remote-synced? obj)} + {:type :set + :attr :shape-ref + :val (:shape-ref obj)} + {:type :set + :attr :touched + :val (:touched obj)}]})) + shapes-to-detach) + (map (fn [id] + {:type :mod-obj + :page-id page-id + :id id + :operations [{:type :set + :attr :component-root? + :val true}]}) + shapes-to-deroot) + (map (fn [id] + {:type :mod-obj + :page-id page-id + :id id + :operations [{:type :set + :attr :component-root? + :val nil}]}) + shapes-to-reroot))] ;; (println "================ rchanges") ;; (cljs.pprint/pprint rchanges) diff --git a/frontend/src/app/main/store.cljs b/frontend/src/app/main/store.cljs index 3f711e785..14788dfc8 100644 --- a/frontend/src/app/main/store.cljs +++ b/frontend/src/app/main/store.cljs @@ -110,7 +110,7 @@ (show-component [shape objects] (if (nil? (:shape-ref shape)) "" - (let [root-shape (cp/get-root-shape shape objects) + (let [root-shape (cp/get-component-shape shape objects) component-id (when root-shape (:component-id root-shape)) component-file-id (when root-shape (:component-file root-shape)) component-file (when component-file-id (get libraries component-file-id nil)) @@ -125,7 +125,7 @@ (:component-id shape) "@" :else "-") (when component-file (str/format "<%s> " (:name component-file))) - (:name component-shape) + (or (:name component-shape) "?") (if (or (:component-root? shape) (nil? (:component-id shape)) true)