diff --git a/common/src/app/common/files/helpers.cljc b/common/src/app/common/files/helpers.cljc index 5ac14ac501..360d8428d3 100644 --- a/common/src/app/common/files/helpers.cljc +++ b/common/src/app/common/files/helpers.cljc @@ -117,6 +117,12 @@ ([shape] (d/not-empty? (:shapes shape)))) +(defn has-layout? + "Returns true if the provided shape has a layout assigned" + [objects id] + (let [shape (get objects id)] + (boolean (and shape (:layout shape))))) + (defn group-like-shape? ([objects id] (group-like-shape? (get objects id))) @@ -127,6 +133,24 @@ ;; ---- ACCESSORS +(defn get-selected-type + "Returns the type of the shape if only one, or :multiple if more + than one" + [objects selected] + (if (= 1 (count selected)) + (let [shape (get objects (first selected))] + (:type shape)) + :multiple)) + +(defn get-shape-type + "Returns the type of the shape, or 'root' if it's Root Frame, always + as string" + [objects id] + (let [shape (get objects id)] + (if (root? shape) + :root + (dm/get-prop shape :type)))) + (defn get-children-ids [objects id] (letfn [(get-children-ids-rec [id processed] diff --git a/frontend/src/app/main/data/event.cljs b/frontend/src/app/main/data/event.cljs index 045312b2ac..51d59b6f97 100644 --- a/frontend/src/app/main/data/event.cljs +++ b/frontend/src/app/main/data/event.cljs @@ -8,7 +8,6 @@ (:require ["ua-parser-js" :as ua] [app.common.data :as d] - [app.common.files.helpers :as cfh] [app.common.json :as json] [app.common.logging :as l] [app.config :as cf] @@ -243,39 +242,3 @@ (l/error :hint "error on event batching stream" :cause cause)) (fn [] (l/debug :hitn "events batching stream terminated"))))))))) - -;; ---- HELPERS - -(defn get-shape-type - "Returns the type of the shape, or Empty if it's Root Frame" - [objects id] - (let [shape (get objects id)] - (if (cfh/root? shape) - "Empty" - (:type shape)))) - -(defn frame-has-layout - "Returns true if the provided frame has a layout." - [objects id] - (let [frame (get objects id)] - (boolean (and frame (:layout frame))))) - -(defn get-shape-event-name - "Returns the event name corresponding to a shape type, or nil if no match." - [shape] - (cond - (cfh/frame-shape? shape) "create-board" - (cfh/image-shape? shape) "create-image" - (cfh/path-shape? shape) "create-path" - (cfh/circle-shape? shape) "create-circle" - (cfh/rect-shape? shape) "create-rectangle" - (cfh/text-shape? shape) "create-text" - :else nil)) - -(defn get-selected-type - "Returns the type of the shape if only one, or multiple if more than one" - [objects selected] - (if (= 1 (count selected)) - (let [shape (get objects (first selected))] - (:type shape)) - "multiple")) diff --git a/frontend/src/app/main/data/workspace/clipboard.cljs b/frontend/src/app/main/data/workspace/clipboard.cljs index 84b602a515..a66bca8188 100644 --- a/frontend/src/app/main/data/workspace/clipboard.cljs +++ b/frontend/src/app/main/data/workspace/clipboard.cljs @@ -902,26 +902,32 @@ undo-id (js/Symbol)] (rx/concat - (->> orig-shapes - (keep (fn [shape] + (->> (rx/from orig-shapes) + (rx/map (fn [shape] + (let [parent-type (cfh/get-shape-type all-objects (:parent-id shape)) + external-lib? (not= file-id (:component-file shape)) + origin "workspace:paste"] - (if (ctc/instance-head? shape) - (ptk/event ::ev/event - {::ev/name "use-library-component" - ::ev/origin "paste" - :external-library (not= file-id (:component-file shape)) - :parent-type (ev/get-shape-type all-objects (:parent-id shape))}) - (when (ev/get-shape-event-name shape) - (if (ev/frame-has-layout all-objects (:parent-id shape)) - (ptk/event ::ev/event - {::ev/name "layout-add-element" - :element-type (:type shape) - :source "paste" - :parent-type (ev/get-shape-type all-objects (:parent-id shape))}) - (ptk/event ::ev/event - {::ev/name (ev/get-shape-event-name shape) - :parent-type (ev/get-shape-type all-objects (:parent-id shape)) - :source "paste"}))))))) + ;; NOTE: we don't emit the create-shape event all the time for + ;; avoid send a lot of events (that are not necessary); this + ;; decision is made explicitly by the responsible team. + (if (ctc/instance-head? shape) + (ptk/data-event ::ev/event + {::ev/name "use-library-component" + ::ev/origin origin + :is-external-library external-lib? + :parent-shape-type parent-type}) + (if (cfh/has-layout? objects (:parent-id shape)) + (ptk/data-event ::ev/event + {::ev/name "layout-add-element" + ::ev/origin origin + :element-type (get shape :type) + :parent-type parent-type}) + (ptk/data-event ::ev/event + {::ev/name "create-shape" + ::ev/origin origin + :shape-type (get shape :type) + :parent-shape-type parent-type}))))))) (rx/of (dwu/start-undo-transaction undo-id) (dch/commit-changes changes) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 8b006311e1..17c29a9d44 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -479,26 +479,35 @@ ids) undo-id (js/Symbol)] (rx/concat - (->> (map (d/getf objects) ids) - (keep (fn [shape] - (if (ctk/instance-head? shape) - (ptk/event ::ev/event - {::ev/name "use-library-component" - ::ev/origin "duplicate" - :parent-type (ev/get-shape-type objects (:parent-id shape)) - :external-library (not= file-id (:component-file shape))}) - (when-let [event-name (ev/get-shape-event-name shape)] - (if (ev/frame-has-layout objects (:parent-id shape)) - (ptk/event ::ev/event - {::ev/name "layout-add-element" - :element-type (:type shape) - :source "duplicate"}) - (ptk/event ::ev/event - {::ev/name event-name - :parent-type (ev/get-shape-type objects (:parent-id shape)) - :source "duplicate"})))))) - (rx/from)) - ;; Warning: This order is important for the focus mode. + (->> (rx/from ids) + (rx/map (fn [shape-id] + (let [shape (get objects shape-id) + parent-type (cfh/get-shape-type objects (:parent-id shape)) + external-lib? (not= file-id (:component-file shape)) + origin "workspace:duplicate-shapes"] + + ;; NOTE: we don't emit the create-shape event all the time for + ;; avoid send a lot of events (that are not necessary); this + ;; decision is made explicitly by the responsible team. + (if (ctk/instance-head? shape) + (ptk/data-event ::ev/event + {::ev/name "use-library-component" + ::ev/origin origin + :is-external-library external-lib? + :parent-shape-type parent-type}) + (if (cfh/has-layout? objects (:parent-id shape)) + (ptk/data-event ::ev/event + {::ev/name "layout-add-element" + ::ev/origin origin + :element-type (get shape :type) + :parent-type parent-type}) + (ptk/data-event ::ev/event + {::ev/name "create-shape" + ::ev/origin origin + :shape-type (get shape :type) + :parent-shape-type parent-type}))))))) + + ;; Warning: This order is important for the focus mode. (->> (rx/of (dwu/start-undo-transaction undo-id) (dch/commit-changes changes) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 19a049e066..87e4aba23c 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -143,19 +143,18 @@ (->> (rx/of (dwe/start-edition-mode (:id shape))) (rx/observe-on :async))) - (when-let [event-name (ev/get-shape-event-name shape)] - (if (ev/frame-has-layout objects (:parent-id shape)) - (rx/of - (ptk/event ::ev/event - {::ev/name "layout-add-element" - :element-type (:type shape) - :source "new"})) + (rx/of (ptk/data-event ::ev/event + {::ev/name "create-shape" + ::ev/origin "workspace:add-shape" + :type (get shape :type) + :parent-type (cfh/get-shape-type objects (:parent-id shape))})) + + (when (cfh/has-layout? objects (:parent-id shape)) + (rx/of (ptk/data-event ::ev/event + {::ev/name "layout-add-element" + ::ev/origin "workspace:add-shape" + :element-type (get shape :type)}))))))))) - (rx/of - (ptk/event ::ev/event - {::ev/name event-name - :parent-type (ev/get-shape-type objects (:parent-id shape)) - :source "new"})))))))))) (defn move-shapes-into-frame [frame-id shapes] @@ -298,8 +297,8 @@ (ptk/data-event :layout/update {:ids [(:id frame-shape)]}) (ptk/event ::ev/event {::ev/name "create-board" - :converted-from (ev/get-selected-type objects selected) - :parent-type (ev/get-shape-type objects (:parent-id frame-shape))}) + :converted-from (cfh/get-selected-type objects selected) + :parent-type (cfh/get-shape-type objects (:parent-id frame-shape))}) (dwu/commit-undo-transaction undo-id)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 69b0bce285..f924f62758 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -1087,14 +1087,14 @@ (rx/concat (let [shapes (mapv #(get objects %) ids) moved-count (count (filter #(not= (:parent-id %) frame-id) shapes)) - emit-layout-event? (and (ev/frame-has-layout objects frame-id) + emit-layout-event? (and (cfh/has-layout? objects frame-id) (pos? moved-count))] (when emit-layout-event? - (rx/of (ptk/event ::ev/event - {::ev/name "layout-add-element" - :source "move-shapes-to-frame" - :element-type (ev/get-selected-type objects ids) - :moved moved-count})))) + (rx/of (ptk/data-event ::ev/event + {::ev/name "layout-add-element" + :source "move-shapes-to-frame" + :element-type (cfh/get-selected-type objects ids) + :moved moved-count})))) (when (and (some? frame-id) (d/not-empty? changes)) (rx/of (dch/commit-changes changes)