From 29c49b0fe098b26db791dc2287236bb1681d1b88 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 14 Oct 2026 16:38:12 +0200 Subject: [PATCH] :bug: Remove the right empty variant properties when there are many remove-empty-properties, run after a rename in the layers panel, found the position of each property by grouping all the properties of the variant's components by name and numbering the groups. A map of more than eight keys does not keep their order, so with nine or more properties the numbers did not match the positions and the wrong property was removed: with ten properties and the sixth empty in every component, it removed the first (F86). The positions now come from the properties themselves: a property is removed when its value is empty in every component. The work moves to common as clvp/generate-remove-empty-properties, and the event only commits what it builds. workspace-variants-test checks the case with ten properties. AI-assisted-by: claude-opus-5-5 --- .../app/common/logic/variant_properties.cljc | 13 +++++++++ .../src/app/main/data/workspace/variants.cljs | 27 ++----------------- .../data/workspace_variants_test.cljs | 20 ++++++++++++++ 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/common/src/app/common/logic/variant_properties.cljc b/common/src/app/common/logic/variant_properties.cljc index a880dd6eaf..13c89439fa 100644 --- a/common/src/app/common/logic/variant_properties.cljc +++ b/common/src/app/common/logic/variant_properties.cljc @@ -59,6 +59,19 @@ changes))) +(defn generate-remove-empty-properties + "Remove each property of the variant `variant-id` whose value is empty in + all its components." + [changes variant-id] + (let [data (pcb/get-library-data changes) + objects (pcb/get-objects changes) + components (cfv/find-variant-components data objects variant-id) + empty-pos (filter (fn [pos] + (every? #(empty? (get-in % [:variant-properties pos :value])) components)) + (range (count (-> components first :variant-properties))))] + ;; from the last one, so the positions of the others stay + (reduce #(generate-remove-property %1 variant-id %2) changes (reverse empty-pos)))) + (defn generate-update-property-value [changes component-id pos value] (let [component (ctcl/get-component (pcb/get-library-data changes) component-id true)] diff --git a/frontend/src/app/main/data/workspace/variants.cljs b/frontend/src/app/main/data/workspace/variants.cljs index f8f320f5d4..ff6a79fb9e 100644 --- a/frontend/src/app/main/data/workspace/variants.cljs +++ b/frontend/src/app/main/data/workspace/variants.cljs @@ -164,31 +164,8 @@ (ptk/reify ::remove-empty-properties ptk/WatchEvent (watch [it state _] - (let [data (dsh/lookup-file-data state) - objects (dsh/lookup-page-objects state) - - variant-components (cfv/find-variant-components data objects variant-id) - - properties-empty-pos (->> variant-components - (mapcat :variant-properties) - (group-by :name) - (map-indexed - (fn [i [_ v]] - [i (->> v - (map :value) - (remove empty?) - empty?)])) - (reverse)) - - changes (reduce - (fn [changes [pos property-empty?]] - (if property-empty? - (-> changes - (clvp/generate-remove-property variant-id pos)) - changes)) - (variant-changes it state) - properties-empty-pos)] - + (let [changes (-> (variant-changes it state) + (clvp/generate-remove-empty-properties variant-id))] (when (seq (:redo-changes changes)) (rx/of (ev/event {::ev/name "variant-remove-property" ::ev/origin "workspace:rename-in-layers"}) diff --git a/frontend/test/frontend_tests/data/workspace_variants_test.cljs b/frontend/test/frontend_tests/data/workspace_variants_test.cljs index f1f607bc21..a133422fd4 100644 --- a/frontend/test/frontend_tests/data/workspace_variants_test.cljs +++ b/frontend/test/frontend_tests/data/workspace_variants_test.cljs @@ -205,3 +205,23 @@ (let [file' (ths/get-file-from-state state)] (t/is (= "Renamed" (:name (ctkl/get-component (:data file') (cthi/id :plain1))))) (t/is (= "Renamed" (:name (cths/get-shape file' :plain1-root)))))))))) + +(t/deftest remove-empty-properties-of-a-set-with-many-properties + (t/async + done + (let [props (fn [value] + (mapv (fn [i] + {:name (str "Property " (inc i)) + :value (if (= i 5) "" value)}) + (range 10))) + file (-> (cthf/sample-file :file1) + (cthv/add-variant :v01 :c01 :m01 :c02 :m02) + (cthc/update-component :c01 {:variant-properties (props "a")}) + (cthc/update-component :c02 {:variant-properties (props "b")}))] + (ths/run-store + (ths/setup-store file) done + [(dwv/remove-empty-properties (cthi/id :v01))] + (fn [state] + (let [data (:data (ths/get-file-from-state state))] + (t/is (= (remove #{"Property 6"} (map :name (props "a"))) + (map :name (:variant-properties (ctkl/get-component data (cthi/id :c01))))))))))))