mirror of
https://github.com/penpot/penpot.git
synced 2025-01-22 14:39:45 -05:00
Merge pull request #3758 from penpot/hiru-bugfix-validation
🐛 Fix component-root when createing new component
This commit is contained in:
commit
69435e32d9
6 changed files with 106 additions and 67 deletions
|
@ -211,22 +211,22 @@
|
|||
|
||||
transform-to-frames
|
||||
(fn [file-data]
|
||||
; Transform components and copies to frames, and set the
|
||||
; frame-id of its childrens
|
||||
; Transform component and copy heads to frames, and set the
|
||||
; frame-id of its childrens
|
||||
(letfn [(fix-container
|
||||
[container]
|
||||
(update container :objects update-vals fix-shape))
|
||||
[container]
|
||||
(update container :objects update-vals fix-shape))
|
||||
|
||||
(fix-shape
|
||||
[shape]
|
||||
(if (ctk/instance-head? shape)
|
||||
(assoc shape
|
||||
:type :frame ; Old groups must be converted
|
||||
:fills [] ; to frames and conform to spec
|
||||
:hide-in-viewer true
|
||||
:rx 0
|
||||
:ry 0)
|
||||
shape))]
|
||||
[shape]
|
||||
(if (ctk/instance-head? shape)
|
||||
(assoc shape
|
||||
:type :frame ; Old groups must be converted
|
||||
:fills [] ; to frames and conform to spec
|
||||
:hide-in-viewer true
|
||||
:rx 0
|
||||
:ry 0)
|
||||
shape))]
|
||||
(-> file-data
|
||||
(update :pages-index update-vals fix-container)
|
||||
(update :components update-vals fix-container))))
|
||||
|
@ -236,15 +236,39 @@
|
|||
; Remap the frame-ids of the primary childs of the head instances
|
||||
; to point to the head instance.
|
||||
(letfn [(fix-container
|
||||
[container]
|
||||
(update container :objects update-vals (partial fix-shape container)))
|
||||
[container]
|
||||
(update container :objects update-vals (partial fix-shape container)))
|
||||
|
||||
(fix-shape
|
||||
[container shape]
|
||||
(let [parent (ctst/get-shape container (:parent-id shape))]
|
||||
(if (ctk/instance-head? parent)
|
||||
(assoc shape :frame-id (:id parent))
|
||||
shape)))]
|
||||
[container shape]
|
||||
(let [parent (ctst/get-shape container (:parent-id shape))]
|
||||
(if (ctk/instance-head? parent)
|
||||
(assoc shape :frame-id (:id parent))
|
||||
shape)))]
|
||||
(-> file-data
|
||||
(update :pages-index update-vals fix-container)
|
||||
(update :components update-vals fix-container))))
|
||||
|
||||
fix-frame-ids
|
||||
(fn [file-data]
|
||||
;; Ensure that frame-id of all shapes point to the parent or to the frame-id
|
||||
;; of the parent, and that the destination is indeed a frame.
|
||||
(letfn [(fix-container [container]
|
||||
(update container :objects #(cph/reduce-objects % fix-shape %)))
|
||||
|
||||
(fix-shape [objects shape]
|
||||
(let [parent (when (:parent-id shape)
|
||||
(get objects (:parent-id shape)))
|
||||
error? (when (some? parent)
|
||||
(if (= (:type parent) :frame)
|
||||
(not= (:frame-id shape) (:id parent))
|
||||
(not= (:frame-id shape) (:frame-id parent))))]
|
||||
(if error?
|
||||
(let [nearest-frame (cph/get-frame objects (:parent-id shape))
|
||||
frame-id (or (:id nearest-frame) uuid/zero)]
|
||||
(update objects (:id shape) assoc :frame-id frame-id))
|
||||
objects)))]
|
||||
|
||||
(-> file-data
|
||||
(update :pages-index update-vals fix-container)
|
||||
(update :components update-vals fix-container))))]
|
||||
|
@ -257,7 +281,8 @@
|
|||
(remap-refs)
|
||||
(fix-copies-of-detached)
|
||||
(transform-to-frames)
|
||||
(remap-frame-ids))))
|
||||
(remap-frame-ids)
|
||||
(fix-frame-ids))))
|
||||
|
||||
(defn- migrate-components
|
||||
"If there is any component in the file library, add a new 'Library
|
||||
|
@ -312,8 +337,8 @@
|
|||
(fn [page shape]
|
||||
(let [parent (ctst/get-shape page (:parent-id shape))]
|
||||
(if (= :frame (:type parent))
|
||||
(:parent-id shape)
|
||||
(:frame-id shape))))
|
||||
(:id parent)
|
||||
(:frame-id parent))))
|
||||
|
||||
add-shapes
|
||||
(fn [page]
|
||||
|
@ -369,7 +394,7 @@
|
|||
"Convert a media object that contains a bitmap image into shapes,
|
||||
one shape of type :image and one group that contains it."
|
||||
[{:keys [name width height id mtype]} position]
|
||||
(let [group-shape (cts/setup-shape
|
||||
(let [frame-shape (cts/setup-shape
|
||||
{:type :frame
|
||||
:x (:x position)
|
||||
:y (:y position)
|
||||
|
@ -390,9 +415,9 @@
|
|||
:height height
|
||||
:mtype mtype}
|
||||
:name name
|
||||
:frame-id uuid/zero
|
||||
:parent-id (:id group-shape)})]
|
||||
[group-shape [img-shape]]))
|
||||
:frame-id (:id frame-shape)
|
||||
:parent-id (:id frame-shape)})]
|
||||
[frame-shape [img-shape]]))
|
||||
|
||||
(defn- parse-datauri
|
||||
[data]
|
||||
|
@ -549,7 +574,8 @@
|
|||
cfsh/prepare-create-artboard-from-selection)
|
||||
changes (pcb/concat-changes changes changes2)]
|
||||
|
||||
(cp/process-changes fdata (:redo-changes changes) false)))
|
||||
(cp/process-changes (assoc-in fdata [:options :components-v2] true) ; Process component creation in v2 way
|
||||
(:redo-changes changes) false)))
|
||||
|
||||
(defn- migrate-graphics
|
||||
[fdata]
|
||||
|
|
|
@ -20,14 +20,7 @@
|
|||
[root-shape new-shapes updated-shapes]
|
||||
(if-not components-v2
|
||||
(ctn/make-component-shape root objects file-id components-v2)
|
||||
(let [new-id (uuid/next)]
|
||||
[(assoc root :id new-id)
|
||||
nil
|
||||
[(assoc root
|
||||
:component-id new-id
|
||||
:component-file file-id
|
||||
:component-root true
|
||||
:main-instance true)]]))
|
||||
(ctn/convert-shape-in-component root objects file-id))
|
||||
|
||||
changes (-> changes
|
||||
(pcb/add-component (:id root-shape)
|
||||
|
@ -39,12 +32,10 @@
|
|||
page-id))]
|
||||
[root-shape changes]))
|
||||
|
||||
|
||||
(defn generate-add-component
|
||||
"If there is exactly one id, and it's a frame (or a group in v1), and not already a
|
||||
component, use it as root. Otherwise, create a frame (v2) or group (v1) that contains
|
||||
all ids. Then, make a component with it, and link all shapes to their corresponding one
|
||||
in the component."
|
||||
"If there is exactly one id, and it's a frame (or a group in v1), and not already a component,
|
||||
use it as root. Otherwise, create a frame (v2) or group (v1) that contains all ids. Then, make a
|
||||
component with it, and link all shapes to their corresponding one in the component."
|
||||
[it shapes objects page-id file-id components-v2 prepare-create-group prepare-create-board]
|
||||
(let [changes (pcb/empty-changes it page-id)
|
||||
|
||||
|
@ -81,7 +72,9 @@
|
|||
|
||||
[root changes (map :id shapes)]))
|
||||
|
||||
[root-shape changes] (generate-add-component-changes changes root objects file-id page-id components-v2)
|
||||
objects' (assoc objects (:id root) root)
|
||||
|
||||
[root-shape changes] (generate-add-component-changes changes root objects' file-id page-id components-v2)
|
||||
|
||||
changes (pcb/update-shapes changes
|
||||
old-root-ids
|
||||
|
|
|
@ -86,7 +86,8 @@
|
|||
|
||||
:always
|
||||
(assoc :frame-id frame-id
|
||||
:parent-id parent-id)
|
||||
:parent-id parent-id
|
||||
:shapes (into [] selected))
|
||||
|
||||
:always
|
||||
(with-meta {:index new-index})
|
||||
|
|
|
@ -1604,6 +1604,7 @@
|
|||
(watch [_ _ _]
|
||||
(try
|
||||
(let [clipboard-str (wapi/read-from-clipboard)
|
||||
|
||||
paste-transit-str
|
||||
(->> clipboard-str
|
||||
(rx/filter t/transit?)
|
||||
|
|
|
@ -405,28 +405,29 @@
|
|||
(ptk/reify ::duplicate-component
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [libraries (wsh/get-libraries state)
|
||||
library (get libraries library-id)
|
||||
component (ctkl/get-component (:data library) component-id)
|
||||
new-name (:name component)
|
||||
(let [libraries (wsh/get-libraries state)
|
||||
library (get libraries library-id)
|
||||
component (ctkl/get-component (:data library) component-id)
|
||||
new-name (:name component)
|
||||
|
||||
components-v2 (features/active-feature? state "components/v2")
|
||||
components-v2 (features/active-feature? state "components/v2")
|
||||
|
||||
main-instance-page (when components-v2
|
||||
(ctf/get-component-page (:data library) component))
|
||||
main-instance-page (when components-v2
|
||||
(ctf/get-component-page (:data library) component))
|
||||
|
||||
new-component (assoc component :id (uuid/next))
|
||||
new-component-id (when components-v2
|
||||
(uuid/next))
|
||||
|
||||
[new-component-shape new-component-shapes ; <- null in components-v2
|
||||
new-main-instance-shape new-main-instance-shapes]
|
||||
(dwlh/duplicate-component new-component (:data library))
|
||||
(dwlh/duplicate-component component new-component-id (:data library))
|
||||
|
||||
changes (-> (pcb/empty-changes it nil)
|
||||
(pcb/with-page main-instance-page)
|
||||
(pcb/with-objects (:objects main-instance-page))
|
||||
(pcb/add-objects new-main-instance-shapes {:ignore-touched true})
|
||||
(pcb/add-component (if components-v2
|
||||
(:id new-component)
|
||||
new-component-id
|
||||
(:id new-component-shape))
|
||||
(:path component)
|
||||
new-name
|
||||
|
|
|
@ -65,26 +65,43 @@
|
|||
(defn duplicate-component
|
||||
"Clone the root shape of the component and all children. Generate new
|
||||
ids from all of them."
|
||||
[component library-data]
|
||||
[component new-component-id library-data]
|
||||
(let [components-v2 (dm/get-in library-data [:options :components-v2])]
|
||||
(if components-v2
|
||||
|
||||
(let [main-instance-page (ctf/get-component-page library-data component)
|
||||
main-instance-shape (ctf/get-component-root library-data component)
|
||||
position (gpt/point (+ (:x main-instance-shape)
|
||||
(:width main-instance-shape)
|
||||
50)
|
||||
(:y main-instance-shape))
|
||||
options (if components-v2 {:main-instance? true} {})
|
||||
delta (gpt/point (+ (:width main-instance-shape) 50) 0)
|
||||
|
||||
[new-instance-shape new-instance-shapes]
|
||||
(when (and (some? main-instance-page) (some? main-instance-shape))
|
||||
(ctn/make-component-instance main-instance-page
|
||||
component
|
||||
library-data
|
||||
position
|
||||
true
|
||||
options))]
|
||||
ids-map (volatile! {})
|
||||
|
||||
update-original-shape
|
||||
(fn [original-shape new-shape]
|
||||
(vswap! ids-map assoc (:id original-shape) (:id new-shape))
|
||||
original-shape)
|
||||
|
||||
update-new-shape
|
||||
(fn [shape]
|
||||
(cond-> shape
|
||||
(= (:component-id shape) (:id component))
|
||||
(assoc :component-id new-component-id)
|
||||
|
||||
:always
|
||||
(gsh/move delta)))
|
||||
|
||||
[new-instance-shape new-instance-shapes _]
|
||||
(ctst/clone-object main-instance-shape
|
||||
(:parent-id main-instance-shape)
|
||||
(:objects main-instance-page)
|
||||
update-new-shape
|
||||
update-original-shape)
|
||||
|
||||
remap-frame
|
||||
(fn [shape]
|
||||
(update shape :frame-id
|
||||
#(get @ids-map % (:frame-id shape))))
|
||||
|
||||
new-instance-shapes (map remap-frame new-instance-shapes)]
|
||||
|
||||
[nil nil new-instance-shape new-instance-shapes])
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue