0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-09 00:10:11 -05:00

🐛 Advance shape-refs of subinstances when detaching a copy

This commit is contained in:
Andrés Moya 2024-01-12 15:52:31 +01:00 committed by Andrey Antukh
parent a3241d1442
commit 2664a846e9
3 changed files with 32 additions and 15 deletions

View file

@ -182,7 +182,7 @@
[file page libraries shape & {:keys [include-deleted?] :or {include-deleted? false}}]
(let [root-shape (ctn/get-copy-root (:objects page) shape)
component-file (when root-shape
(if (= (:component-file root-shape) (:id file))
(if (and (some? file) (= (:component-file root-shape) (:id file)))
file
(get libraries (:component-file root-shape))))
component (when component-file
@ -193,7 +193,7 @@
(if (some? ref-shape) ; There is a case when we have a nested orphan copy. In this case there is no near
ref-shape ; component for this copy, so shape-ref points to the remote main.
(let [head-shape (ctn/get-head-shape (:objects page) shape)
head-file (if (= (:component-file head-shape) (:id file))
head-file (if (and (some? file) (= (:component-file head-shape) (:id file)))
file
(get libraries (:component-file head-shape)))
head-component (when (some? head-file)

View file

@ -566,11 +566,12 @@
(let [file (wsh/get-local-file state)
page-id (get state :current-page-id)
container (cfh/get-container file :page page-id)
libraries (wsh/get-libraries state)
changes (-> (pcb/empty-changes it)
(pcb/with-container container)
(pcb/with-objects (:objects container))
(dwlh/generate-detach-instance container id))]
(dwlh/generate-detach-instance container libraries id))]
(rx/of (dch/commit-changes changes))))))
@ -595,13 +596,14 @@
objects (wsh/lookup-page-objects state page-id)
file (wsh/get-local-file state)
container (cfh/get-container file :page page-id)
libraries (wsh/get-libraries state)
selected (->> state
(wsh/lookup-selected)
(cfh/clean-loops objects))
changes (reduce
(fn [changes id]
(dwlh/generate-detach-instance changes container id))
(dwlh/generate-detach-instance changes libraries container id))
(-> (pcb/empty-changes it)
(pcb/with-container container)
(pcb/with-objects objects))

View file

@ -200,31 +200,46 @@
[new-shape changes])))
(declare generate-detach-recursive)
(declare generate-advance-nesting-level)
(defn generate-detach-instance
"Generate changes to remove the links between a shape and all its children
with a component."
[changes container shape-id]
[changes container libraries shape-id]
(let [shape (ctn/get-shape container shape-id)]
(log/debug :msg "Detach instance" :shape-id shape-id :container (:id container))
(generate-detach-recursive changes container shape-id true (true? (:component-root shape)))))
(generate-detach-recursive changes container libraries shape-id true (true? (:component-root shape)))))
(defn- generate-detach-recursive
[changes container shape-id first component-root?]
[changes container libraries shape-id first component-root?]
(let [shape (ctn/get-shape container shape-id)]
(if (and (ctk/instance-head? shape) (not first))
;; Subinstances are not detached
(if component-root?
;; if the original shape was component-root, the subinstances are converted in top instances
(pcb/update-shapes changes [(:id shape)] #(assoc % :component-root true))
changes)
; Subinstances are not detached
(cond-> changes
component-root?
; If the initial shape was component-root, first level subinstances are converted in top instances
(pcb/update-shapes [shape-id] #(assoc % :component-root true))
:always
; Near shape-refs need to be advanced one level
(generate-advance-nesting-level nil container libraries (:id shape)))
;; Otherwise, detach the shape and all children
(let [children-ids (:shapes shape)]
(reduce #(generate-detach-recursive %1 container %2 false component-root?)
(reduce #(generate-detach-recursive %1 container libraries %2 false component-root?)
(pcb/update-shapes changes [(:id shape)] ctk/detach-shape)
children-ids)))))
(defn- generate-advance-nesting-level
[changes file container libraries shape-id]
(let [children (cfh/get-children-with-self (:objects container) shape-id)
skip-near (fn [changes shape]
(let [ref-shape (ctf/find-ref-shape file container libraries shape {:include-deleted? true})]
(if (some? (:shape-ref ref-shape))
(pcb/update-shapes changes [(:id shape)] #(assoc % :shape-ref (:shape-ref ref-shape)))
changes)))]
(reduce skip-near changes children)))
(defn prepare-restore-component
([library-data component-id current-page it]
(let [component (ctkl/get-deleted-component library-data component-id)
@ -604,7 +619,7 @@
;; deleted or the library unlinked, do nothing in v2 or detach in v1.
(if components-v2
changes
(generate-detach-instance changes container shape-id))))
(generate-detach-instance changes libraries container shape-id))))
changes)))
(defn- find-main-container
@ -634,7 +649,7 @@
;; This should not occur, but protect against it in any case
(if components-v2
changes
(generate-detach-instance changes container (:id shape-inst)))
(generate-detach-instance changes container {(:id library) library} (:id shape-inst)))
(let [omit-touched? (not reset?)
clear-remote-synced? (and initial-root? reset?)
set-remote-synced? (and (not initial-root?) reset?)