0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-03 04:49:03 -05:00

Merge pull request #4237 from penpot/palba-fix-swap-loop

🐛 Fix possible loop in the list of swappable components
This commit is contained in:
Alejandro 2024-03-12 11:45:28 +01:00 committed by GitHub
commit 9328974511
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -7,12 +7,10 @@
(ns app.main.ui.workspace.sidebar.options.menus.component (ns app.main.ui.workspace.sidebar.options.menus.component
(:require-macros [app.main.style :as stl]) (:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.files.helpers :as cfh] [app.common.files.helpers :as cfh]
[app.common.types.component :as ctk] [app.common.types.component :as ctk]
[app.common.types.file :as ctf] [app.common.types.file :as ctf]
[app.common.uuid :as uuid]
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.libraries :as dwl]
@ -296,16 +294,6 @@
(= (:component-id shape-a) (= (:component-id shape-a)
(:component-id shape-b))) (:component-id shape-b)))
;; Get the ids of the components and its root-shapes that are parents of the current shape, to avoid loops
(defn get-parent-component-ids
[objects shape ids]
(let [shape-id (:id shape)]
(if (uuid/zero? shape-id)
ids
(let [ids (if (ctk/instance-head? shape)
(conj ids shape-id (:component-id shape))
ids)]
(get-parent-component-ids objects (get objects (:parent-id shape)) ids)))))
(mf/defc component-swap (mf/defc component-swap
{::mf/props :obj} {::mf/props :obj}
@ -386,13 +374,17 @@
(->> (concat groups components) (->> (concat groups components)
(sort-by :name))) (sort-by :name)))
parent-components (mf/with-memo [shapes objects] find-parent-components
(into #{} (mf/use-fn
(comp (mf/deps objects)
(map :parent-id) (fn [shape]
(map (d/getf objects)) (->> (cfh/get-parents objects (:id shape))
(mapcat #(get-parent-component-ids objects % []))) (map :component-id)
shapes)) (remove nil?))))
;; Get the ids of the components that are parents of the shapes, to avoid loops
parent-components (mapcat find-parent-components shapes)
libraries-options (map (fn [library] {:value (:id library) :label (:name library)}) libraries-options (map (fn [library] {:value (:id library) :label (:name library)})
(vals libraries)) (vals libraries))
@ -490,8 +482,10 @@
(let [data (dm/get-in libraries [current-library-id :data]) (let [data (dm/get-in libraries [current-library-id :data])
container (ctf/get-component-page data item) container (ctf/get-component-page data item)
root-shape (ctf/get-component-root data item) root-shape (ctf/get-component-root data item)
loop? (or (contains? parent-components (:main-instance-id item)) components (->> (cfh/get-children-with-self (:objects container) (:id root-shape))
(contains? parent-components (:id item)))] (keep :component-id)
set)
loop? (some #(contains? components %) parent-components)]
[:& component-swap-item {:key (dm/str (:id item)) [:& component-swap-item {:key (dm/str (:id item))
:item item :item item
:loop loop? :loop loop?