diff --git a/.serena/memories/common/changes-architecture.md b/.serena/memories/common/changes-architecture.md index b7ba2e1974..d08395a620 100644 --- a/.serena/memories/common/changes-architecture.md +++ b/.serena/memories/common/changes-architecture.md @@ -64,3 +64,9 @@ combines copy-structure and nesting guards for normal frontend/pure nodes. The duplicate builder checks the actual destination after ALT placement; a duplicate at the page root remains allowed. Undo still restores existing nesting through its explicit inverse flag, not through a forward bypass. + +Component restoration reports its component id from components-changed +(F183). Its main does not exist in the old page objects, so add/mod-object +detection cannot find it. Restore can rename a variant when its container +has gone; the restored component and its dependents must sync in that same +undo group. diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index f39f3bbb48..c067ab3354 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -1233,6 +1233,10 @@ (into #{} xform shape-and-parents)) (when component-id #{component-id}))) +(defmethod components-changed :restore-component + [_ {:keys [id]}] + #{id}) + (defmethod components-changed :default [_ _] nil) diff --git a/common/test/common_tests/logic/comp_sync_test.cljc b/common/test/common_tests/logic/comp_sync_test.cljc index bb6b2c703e..20956310f7 100644 --- a/common/test/common_tests/logic/comp_sync_test.cljc +++ b/common/test/common_tests/logic/comp_sync_test.cljc @@ -993,6 +993,25 @@ (ch/components-changed (:data file) (change {:type :assign :value {:opacity 0.5}})))) (t/is (nil? (ch/components-changed (:data file) (change {:type :assign :value {:interactions []}})))))) +(t/deftest restoring-a-variant-without-its-container-syncs-the-new-main-name + (let [initial (tm/apply-to (n/make-variant-container "restore" [["b" "#ffffff"]]) + (setup/empty-situation)) + initial (tm/with-file initial + (thc/instantiate-component (tm/file initial) :sync-restore-v0-component :copy)) + deletion (n/delete-component :sync-restore-v0-root) + deleted (-> initial (r/step deletion) r/settle) + restored (-> deleted (r/step (n/restore-component deletion)) r/settle) + main (tm/resolve-shape restored :sync-restore-v0-root) + copy (tm/resolve-shape restored :copy)] + (t/is (nil? (ths/get-shape (tm/file deleted) :sync-restore-vcontainer))) + (t/is (= "Board / b" (:name main))) + (t/is (= (:name main) (:name copy))) + (t/is (empty? (:touched copy))) + (t/is (= (thn/normalize-file (tm/file deleted)) + (thn/normalize-file (tm/file (r/step restored (n/undo)))))) + (t/is (= (thn/normalize-file (tm/file restored)) + (thn/normalize-file (tm/file (-> restored (r/step (n/undo)) (r/step (n/redo))))))))) + (t/deftest test-sync-of-a-flip ;; the main flips its child as the editor does: a transform that scales ;; it by -1, which toggles :flip-x