🐛 Fix error when reset overrides (#11604)

* 🐛 Fix error when reset overrides on a swapped copy

* 🐛 Add regression test for reset overrides inside group

Cover the case where a nested copy lives inside a group (not directly
under the instance root). After a swap, reset overrides must undo the
swap without error (#11656).

---------

Co-authored-by: Alejandro Alonso <alejandroalonsofernandez@gmail.com>
This commit is contained in:
Andrés Moya 2026-09-23 14:47:10 +02:00 committed by GitHub
parent 8302a984a2
commit 45b8320ac7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 1 deletions

View File

@ -2783,7 +2783,7 @@
(let [shape-inst (ctn/get-shape container id)
objects (:objects container)
parent (get objects (:parent-id shape-inst))
head (ctn/get-component-shape container parent)
head (ctn/get-component-shape objects parent)
changes
(-> changes
(pcb/with-container container)
@ -2802,6 +2802,10 @@
(pcb/with-objects objects)
(generate-sync-shape-direct file-full libraries container id true))]
;; If the shape has been swapped, the reset also have to undo the swap. As the
;; shape has been reset and it's not touched now, by the sync above, if we
;; do another reset of the parent, the shape will be reset as it is in the
;; near main component.
(cond-> changes
(some? swap-slot)
(generate-sync-head file-full libraries container id true))))

View File

@ -82,3 +82,63 @@
(validate #(t/is (= (copy-type %) :rect)))
(validate #(t/is (= (nested-component-id %) (rectangle-component-id %))))
(validate #(t/is (nil? (nested-swap-slot %)))))))
;; The nested component sits inside a group, not directly under the instance root.
;; Resetting overrides after a swap must undo the swap without error.
(t/deftest test-swap-and-reset-override-inside-group
(letfn [(nested-in-copy [file]
(->> (ths/get-shape file :copy-group)
:shapes
first
(ths/get-shape-by-id file)))]
(let [;; ==== Setup
file
(-> (thf/sample-file :file1)
(tho/add-frame :frame-rectangle)
(ths/add-sample-shape :rectangle-shape :parent-label :frame-rectangle :type :rect)
(thc/make-component :rectangle :frame-rectangle)
(tho/add-frame :frame-circle)
(ths/add-sample-shape :circle :parent-label :frame-circle :type :circle)
(thc/make-component :circle :frame-circle)
(tho/add-frame :frame-main)
(tho/add-group :group-main :parent-label :frame-main)
(thc/instantiate-component :rectangle :nested-rectangle
:parent-label :group-main
:children-labels [:nested-rectangle-shape])
(thc/make-component :main :frame-main)
(thc/instantiate-component :main :copy
:children-labels [:copy-group
:copy-nested-rectangle
:copy-nested-rectangle-shape]))
rectangle-id (:id (thc/get-component file :rectangle))
circle-id (:id (thc/get-component file :circle))
main-nested-id (:id (ths/get-shape file :nested-rectangle))
;; ==== Action swap nested copy inside the group, then reset overrides
file-swapped
(tho/swap-component-in-shape file :copy-nested-rectangle :circle
:new-shape-label :copy-nested-swapped)
swapped (ths/get-shape file-swapped :copy-nested-swapped)
file'
(tho/reset-overrides file-swapped swapped)
restored (nested-in-copy file')]
;; ==== Check after swap
(t/is (= :circle (:type (tho/bottom-shape file-swapped :copy-nested-swapped))))
(t/is (= circle-id (:component-id swapped)))
(t/is (= main-nested-id (ctk/get-swap-slot swapped)))
;; ==== Check after reset: back to rectangle, no swap slot, file still valid
(t/is (some? restored))
(t/is (= :rect (:type (tho/bottom-shape-by-id file' (:id restored)))))
(t/is (= rectangle-id (:component-id restored)))
(t/is (nil? (ctk/get-swap-slot restored))))))