0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-09 08:20:45 -05:00

🐛 Add validator and repair for duplicated slots on deleted components

This commit is contained in:
Pablo Alba 2024-06-17 14:46:37 +02:00 committed by Andrés Moya
parent 4546e98dc6
commit 4e6c1857dd
2 changed files with 56 additions and 10 deletions

View file

@ -496,6 +496,36 @@
(pcb/with-file-data file-data)
(pcb/update-shapes (map :id child-with-duplicate) repair-shape))))
(defmethod repair-error :component-duplicate-slot
[_ {:keys [shape] :as error} file-data _]
(let [main-shape (get-in shape [:objects (:main-instance-id shape)])
childs (map #(get (:objects shape) %) (:shapes main-shape))
childs-with-duplicate (let [result (reduce (fn [[seen duplicates] item]
(let [swap-slot (ctk/get-swap-slot item)]
(if (contains? seen swap-slot)
[seen (conj duplicates item)]
[(conj seen swap-slot) duplicates])))
[#{} []]
childs)]
(second result))
duplicated-ids (set (mapv :id childs-with-duplicate))
repair-component
(fn [component]
(let [objects (reduce-kv (fn [acc k v]
(if (contains? duplicated-ids k)
(assoc acc k (ctk/remove-swap-slot v))
(assoc acc k v)))
{}
(:objects component))]
(assoc component :objects objects)))]
(log/dbg :hint "repairing component :component-duplicated-slot" :id (:id shape) :name (:name shape))
(-> (pcb/empty-changes nil)
(pcb/with-library-data file-data)
(pcb/update-component (:id shape) repair-component))))
(defmethod repair-error :missing-slot
[_ {:keys [shape page-id args] :as error} file-data _]
(let [repair-shape

View file

@ -31,6 +31,7 @@
:child-not-found
:frame-not-found
:invalid-frame
:component-duplicate-slot
:component-not-main
:component-main-external
:component-not-found
@ -65,7 +66,7 @@
[:shape {:optional true} :map] ; Cannot validate a shape because here it may be broken
[:shape-id {:optional true} ::sm/uuid]
[:file-id ::sm/uuid]
[:page-id ::sm/uuid]]))
[:page-id {:optional true} [:maybe ::sm/uuid]]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ERROR HANDLING
@ -297,17 +298,21 @@
"This shape should not have swap slot"
shape file page)))
(defn- check-duplicate-swap-slot
"Validate that the children of this shape does not have duplicated slots."
[shape file page]
(let [shapes (map #(get (:objects page) %) (:shapes shape))
(defn- has-duplicate-swap-slot?
[shape container]
(let [shapes (map #(get (:objects container) %) (:shapes shape))
slots (->> (map #(ctk/get-swap-slot %) shapes)
(remove nil?))
counts (frequencies slots)]
(when (some (fn [[_ count]] (> count 1)) counts)
(report-error :duplicate-slot
"This shape has children with the same swap slot"
shape file page))))
(some (fn [[_ count]] (> count 1)) counts)))
(defn- check-duplicate-swap-slot
"Validate that the children of this shape does not have duplicated slots."
[shape file page]
(when (has-duplicate-swap-slot? shape page)
(report-error :duplicate-slot
"This shape has children with the same swap slot"
shape file page)))
(defn- check-shape-main-root-top
"Root shape of a top main instance:
@ -468,13 +473,24 @@
shape file page)
(check-shape-not-component shape file page libraries))))))))
(defn check-component-duplicate-swap-slot
[component file]
(let [shape (get-in component [:objects (:main-instance-id component)])]
(when (has-duplicate-swap-slot? shape component)
(report-error :component-duplicate-slot
"This deleted component has children with the same swap slot"
component file nil))))
(defn- check-component
"Validate semantic coherence of a component. Report all errors found."
[component file]
(when (and (contains? component :objects) (nil? (:objects component)))
(report-error :component-nil-objects-not-allowed
"Objects list cannot be nil"
component file nil)))
component file nil))
(when (:deleted component)
(check-component-duplicate-swap-slot component file)))
(defn- get-orphan-shapes
[{:keys [objects] :as page}]