Repository: penpot/penpot
File: frontend/src/app/main/data/workspace/variants.cljs (ClojureScript)

Code before:
   [app.common.files.helpers :as cfh]
   [app.common.files.variant :as cfv]
   [app.common.geom.point :as gpt]
   [app.common.logic.variant-properties :as clvp]
   [app.common.logic.variants :as clv]
   [app.common.types.component :as ctc]
   [app.common.types.components-list :as ctkl]
   [app.common.types.shape.layout :as ctsl]
   [app.common.uuid :as uuid]
   [app.main.data.changes :as dch]
   [app.main.data.helpers :as dsh]
   [app.main.data.workspace.colors :as cl]
   [app.main.data.workspace.libraries :as dwl]
   [app.main.data.workspace.selection :as dws]
   [app.main.data.workspace.shape-layout :as dwsl]
   [app.main.data.workspace.shapes :as dwsh]
   [app.main.data.workspace.transforms :as dwt]
   [app.main.data.workspace.undo :as dwu]
   [app.main.features :as features]
   [app.util.dom :as dom]
   [beicon.v2.core :as rx]
   [potok.v2.core :as ptk]))

(defn- find-properties-to-remove
  [prev-props upd-props]
  (filterv #(not (some (fn [prop] (= (:name %) (:name prop))) upd-props)) prev-props))

(defn- find-properties-to-update
  [prev-props upd-props]
  (filterv #(some (fn [prop] (and (= (:name %) (:name prop))
                                  (not= (:value %) (:value prop)))) prev-props) upd-props))

(defn- find-properties-to-add
  [prev-props upd-props]
  (filterv #(not (some (fn [prop] (= (:name %) (:name prop))) prev-props)) upd-props))

(defn- find-property-index [props name]
  (some (fn [[idx prop]]
          (when (= (:name prop) name)
            idx))
        (keep-indexed vector props)))

(defn update-properties-names-and-values
  "Compares the previous properties with the updated ones and executes the correspondent action
   for each one depending on if it needs to be removed, updated or added"
  [component-id variant-id previous-properties updated-properties]
  (ptk/reify ::update-properties-names-and-values
    ptk/UpdateEvent
    (update [_ state]
      (update state :workspace-local dissoc :shape-for-rename))


Review comment (performance):
This isn't very efficient, because it needs to go trough all the upd-props for each prev-prop.
I would do it with a set, something like:

```
(let [upd-names (set (map :name upd-props))]
    (filterv #(not (contains? upd-names (:name %))) prev-props)))
```
    

Code after:
   [app.common.files.helpers :as cfh]
   [app.common.files.variant :as cfv]
   [app.common.geom.point :as gpt]
   [app.common.logic.variant-properties :as clvp]
   [app.common.logic.variants :as clv]
   [app.common.types.component :as ctc]
   [app.common.types.components-list :as ctkl]
   [app.common.types.shape.layout :as ctsl]
   [app.common.types.variant :as ctv]
   [app.common.uuid :as uuid]
   [app.main.data.changes :as dch]
   [app.main.data.helpers :as dsh]
   [app.main.data.workspace.colors :as cl]
   [app.main.data.workspace.libraries :as dwl]
   [app.main.data.workspace.selection :as dws]
   [app.main.data.workspace.shape-layout :as dwsl]
   [app.main.data.workspace.shapes :as dwsh]
   [app.main.data.workspace.transforms :as dwt]
   [app.main.data.workspace.undo :as dwu]
   [app.main.features :as features]
   [app.util.dom :as dom]
   [beicon.v2.core :as rx]
   [potok.v2.core :as ptk]))

(defn update-properties-names-and-values
  "Compares the previous properties with the updated ones and executes the correspondent action
   for each one depending on if it needs to be removed, updated or added"
  [component-id variant-id previous-properties updated-properties]
  (ptk/reify ::update-properties-names-and-values
    ptk/UpdateEvent
    (update [_ state]
      (update state :workspace-local dissoc :shape-for-rename))

    ptk/WatchEvent
    (watch [it state _]
      (let [page-id (:current-page-id state)
            data    (dsh/lookup-file-data state)
            objects (-> (dsh/get-page data page-id)
                        (get :objects))

            properties-to-remove (ctv/find-properties-to-remove previous-properties updated-properties)
            properties-to-add    (ctv/find-properties-to-add previous-properties updated-properties)
            properties-to-update (ctv/find-properties-to-update previous-properties updated-properties)

            changes (-> (pcb/empty-changes it page-id)
                        (pcb/with-objects objects)
                        (pcb/with-library-data data))

            changes (reduce
                     (fn [changes {:keys [name]}]
                       (-> changes