Add removal of variant container when it becomes empty (#6311)

This commit is contained in:
Pablo Alba 2025-04-22 09:22:18 +02:00 committed by GitHub
parent fae1df7f4b
commit fe003d7496
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 185 additions and 123 deletions

View file

@ -1095,3 +1095,11 @@
(defn get-objects
[changes]
(dm/get-in (::file-data (meta changes)) [:pages-index uuid/zero :objects]))
(defn get-page
[changes]
(::page (meta changes)))
(defn get-page-id
[changes]
(::page-id (meta changes)))

View file

@ -13,6 +13,7 @@
[app.common.logic.variant-properties :as clvp]
[app.common.types.component :as ctk]
[app.common.types.container :as ctn]
[app.common.types.pages-list :as ctpl]
[app.common.types.shape.interactions :as ctsi]
[app.common.types.shape.layout :as ctl]
[app.common.types.token :as cto]
@ -80,9 +81,21 @@
(pcb/update-shapes ids update-fn {:attrs #{:blocked :hidden}}))))
(defn generate-delete-shapes
[changes file page objects ids {:keys [ignore-touched component-swap]}]
(let [ids (cfh/clean-loops objects ids)
([changes file page objects ids options]
(generate-delete-shapes (-> changes
(pcb/with-page page)
(pcb/with-objects objects)
(pcb/with-library-data file))
ids
options))
([changes ids {:keys [ignore-touched component-swap]}]
(let [objects (pcb/get-objects changes)
data (pcb/get-library-data changes)
page-id (pcb/get-page-id changes)
page (or (pcb/get-page changes)
(ctpl/get-page data page-id))
ids (cfh/clean-loops objects ids)
in-component-copy?
(fn [shape-id]
;; Look for shapes that are inside a component copy, but are
@ -109,12 +122,6 @@
(conj ids-to-delete id)
ids-to-hide)))))
changes (-> changes
(pcb/with-page page)
(pcb/with-objects objects)
(pcb/with-library-data file))
lookup (d/getf objects)
groups-to-unmask
@ -170,7 +177,7 @@
(let [all-ids (into empty-parents ids-to-delete)
contains? (partial contains? all-ids)
xform (comp (map lookup)
(filter #(or (cfh/group-shape? %) (cfh/bool-shape? %)))
(filter #(or (cfh/group-shape? %) (cfh/bool-shape? %) (ctk/is-variant-container? %)))
(remove #(->> (:shapes %) (remove contains?) seq))
(map :id))
parents (into #{} xform all-parents)]
@ -189,7 +196,7 @@
components-to-delete
(reduce (fn [components id]
(let [shape (get objects id)]
(if (and (= (:component-file shape) (:id file)) ;; Main instances should exist only in local file
(if (and (= (:component-file shape) (:id data)) ;; Main instances should exist only in local file
(:main-instance shape)) ;; but check anyway
(conj components (:component-id shape))
components)))
@ -234,7 +241,7 @@
(remove #(and (ctsi/has-destination %)
(contains? ids-to-delete (:destination %))))
interactions))))))]
[all-parents changes]))
[all-parents changes])))
(defn generate-relocate
@ -336,7 +343,19 @@
(map :id)))
index-cell-data (when to-index (ctl/get-cell-by-index parent to-index))
cell (or cell (and index-cell-data [(:row index-cell-data) (:column index-cell-data)]))]
cell (or cell (and index-cell-data [(:row index-cell-data) (:column index-cell-data)]))
;; Parents that are a variant-container that becomes empty
empty-variant-cont (reduce
(fn [to-delete parent-id]
(let [parent (get objects parent-id)]
(if (and (ctk/is-variant-container? parent)
(empty? (remove (set ids) (:shapes parent))))
(conj to-delete (:id parent))
to-delete)))
#{}
(remove #(= % parent-id) all-parents))]
(-> changes
;; Remove layout-item properties when moving a shape outside a layout
@ -444,7 +463,11 @@
(pcb/update-shapes ids #(assoc % :blocked true)))
;; Resize parent containers that need to
(pcb/resize-parents parents))))
(pcb/resize-parents parents)
;; Remove parents when are a variant-container that becomes empty
(cond-> (seq empty-variant-cont)
(#(second (generate-delete-shapes % empty-variant-cont {})))))))
(defn change-show-in-viewer
[shape hide?]

View file

@ -9,6 +9,7 @@
[app.common.files.changes-builder :as pcb]
[app.common.geom.point :as gpt]
[app.common.logic.libraries :as cll]
[app.common.logic.shapes :as cls]
[app.common.logic.variant-properties :as clvp]
[app.common.test-helpers.components :as thc]
[app.common.test-helpers.files :as thf]
@ -234,3 +235,33 @@
(t/is (= (count (:components data')) 4))
(t/is (= (count objects) 4))
(t/is (= (count objects') 7))))
(t/deftest test-delete-variant
;; When a variant container becomes empty, it id automatically deleted
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant-two-properties :v01 :c01 :m01 :c02 :m02))
container (ths/get-shape file :v01)
m01-id (-> (ths/get-shape file :m01) :id)
m02-id (-> (ths/get-shape file :m02) :id)
page (thf/current-page file)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(#(second (cls/generate-delete-shapes % #{m01-id m02-id} {}))))
file' (thf/apply-changes file changes)
;; ==== Get
container' (ths/get-shape file' :v01)]
;; ==== Check
;; The variant containew was not nil before the deletion
(t/is (not (nil? container)))
;; The variant containew is nil after the deletion
(t/is (nil? container'))))