mirror of
https://github.com/penpot/penpot.git
synced 2025-02-21 06:16:28 -05:00
🎉 Add drag components in or out a variant container
This commit is contained in:
parent
6277db8d45
commit
014c297458
18 changed files with 613 additions and 206 deletions
|
@ -174,6 +174,26 @@
|
|||
::applied-changes-count (count redo-changes)))
|
||||
changes))
|
||||
|
||||
(defn apply-changes-local-library
|
||||
[changes]
|
||||
(dm/assert!
|
||||
"expected valid changes"
|
||||
(check-changes! changes))
|
||||
|
||||
(if-let [library-data (::library-data (meta changes))]
|
||||
(let [index (::applied-changes-count (meta changes))
|
||||
redo-changes (:redo-changes changes)
|
||||
new-changes (if (< index (count redo-changes))
|
||||
(->> (subvec (:redo-changes changes) index)
|
||||
(map #(-> %
|
||||
(assoc :page-id uuid/zero)
|
||||
(dissoc :component-id))))
|
||||
[])
|
||||
new-library-data (cfc/process-changes library-data new-changes)]
|
||||
(vary-meta changes assoc ::library-data new-library-data
|
||||
::applied-changes-count (count redo-changes)))
|
||||
changes))
|
||||
|
||||
;; Page changes
|
||||
|
||||
(defn add-empty-page
|
||||
|
@ -970,37 +990,37 @@
|
|||
(apply-changes-local)))))
|
||||
|
||||
(defn update-component
|
||||
([changes id update-fn]
|
||||
(let [library-data (::library-data (meta changes))
|
||||
prev-component (get-in library-data [:components id])]
|
||||
(update-component changes id prev-component update-fn)))
|
||||
([changes id prev-component update-fn]
|
||||
(assert-library! changes)
|
||||
(let [new-component (update-fn prev-component)]
|
||||
(if prev-component
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :mod-component
|
||||
:id id
|
||||
:name (:name new-component)
|
||||
:path (:path new-component)
|
||||
:main-instance-id (:main-instance-id new-component)
|
||||
:main-instance-page (:main-instance-page new-component)
|
||||
:annotation (:annotation new-component)
|
||||
:variant-id (:variant-id new-component)
|
||||
:variant-properties (:variant-properties new-component)
|
||||
:objects (:objects new-component) ;; this won't exist in components-v2 (except for deleted components)
|
||||
:modified-at (:modified-at new-component)})
|
||||
(update :undo-changes conj {:type :mod-component
|
||||
:id id
|
||||
:name (:name prev-component)
|
||||
:path (:path prev-component)
|
||||
:main-instance-id (:main-instance-id prev-component)
|
||||
:main-instance-page (:main-instance-page prev-component)
|
||||
:annotation (:annotation prev-component)
|
||||
:variant-id (:variant-id prev-component)
|
||||
:variant-properties (:variant-properties prev-component)
|
||||
:objects (:objects prev-component)}))
|
||||
changes))))
|
||||
[changes id update-fn & {:keys [apply-changes-local-library?]}]
|
||||
(assert-library! changes)
|
||||
(let [library-data (::library-data (meta changes))
|
||||
prev-component (get-in library-data [:components id])
|
||||
new-component (update-fn prev-component)]
|
||||
(if prev-component
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :mod-component
|
||||
:id id
|
||||
:name (:name new-component)
|
||||
:path (:path new-component)
|
||||
:main-instance-id (:main-instance-id new-component)
|
||||
:main-instance-page (:main-instance-page new-component)
|
||||
:annotation (:annotation new-component)
|
||||
:variant-id (:variant-id new-component)
|
||||
:variant-properties (:variant-properties new-component)
|
||||
:objects (:objects new-component) ;; this won't exist in components-v2 (except for deleted components)
|
||||
:modified-at (:modified-at new-component)})
|
||||
(update :undo-changes conj {:type :mod-component
|
||||
:id id
|
||||
:name (:name prev-component)
|
||||
:path (:path prev-component)
|
||||
:main-instance-id (:main-instance-id prev-component)
|
||||
:main-instance-page (:main-instance-page prev-component)
|
||||
:annotation (:annotation prev-component)
|
||||
:variant-id (:variant-id prev-component)
|
||||
:variant-properties (:variant-properties prev-component)
|
||||
:objects (:objects prev-component)})
|
||||
(cond-> apply-changes-local-library?
|
||||
(apply-changes-local-library)))
|
||||
changes)))
|
||||
|
||||
(defn delete-component
|
||||
[changes id page-id]
|
||||
|
@ -1061,3 +1081,11 @@
|
|||
(reduce reorder-grid changes))]
|
||||
|
||||
changes))
|
||||
|
||||
(defn get-library-data
|
||||
[changes]
|
||||
(::library-data (meta changes)))
|
||||
|
||||
(defn get-objects
|
||||
[changes]
|
||||
(dm/get-in (::file-data (meta changes)) [:pages-index uuid/zero :objects]))
|
||||
|
|
|
@ -10,12 +10,14 @@
|
|||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.logic.variants :as clv]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.token :as cto]
|
||||
[app.common.uuid :as uuid]))
|
||||
[app.common.uuid :as uuid]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn- generate-unapply-tokens
|
||||
"When updating attributes that have a token applied, we must unapply it, because the value
|
||||
|
@ -239,21 +241,21 @@
|
|||
|
||||
|
||||
(defn generate-relocate
|
||||
[changes objects parent-id page-id to-index ids & {:keys [cell ignore-parents?]}]
|
||||
(let [ids (cfh/order-by-indexed-shapes objects ids)
|
||||
shapes (map (d/getf objects) ids)
|
||||
parent (get objects parent-id)
|
||||
[changes parent-id to-index ids & {:keys [cell ignore-parents?]}]
|
||||
(let [objects (pcb/get-objects changes)
|
||||
ids (cfh/order-by-indexed-shapes objects ids)
|
||||
shapes (map (d/getf objects) ids)
|
||||
parent (get objects parent-id)
|
||||
all-parents (into #{parent-id} (map #(cfh/get-parent-id objects %)) ids)
|
||||
parents (if ignore-parents? #{parent-id} all-parents)
|
||||
parents (if ignore-parents? #{parent-id} all-parents)
|
||||
|
||||
children-ids
|
||||
(->> ids
|
||||
(mapcat #(cfh/get-children-ids-with-self objects %)))
|
||||
children-ids (mapcat #(cfh/get-children-ids-with-self objects %) ids)
|
||||
|
||||
child-heads
|
||||
(->> ids
|
||||
(mapcat #(ctn/get-child-heads objects %))
|
||||
(map :id))
|
||||
child-heads (mapcat #(ctn/get-child-heads objects %) ids)
|
||||
|
||||
child-heads-ids (map :id child-heads)
|
||||
|
||||
variant-heads (filter ctk/is-variant? child-heads)
|
||||
|
||||
component-main-parent
|
||||
(ctn/find-component-main objects parent false)
|
||||
|
@ -340,9 +342,6 @@
|
|||
cell (or cell (and index-cell-data [(:row index-cell-data) (:column index-cell-data)]))]
|
||||
|
||||
(-> changes
|
||||
(pcb/with-page-id page-id)
|
||||
(pcb/with-objects objects)
|
||||
|
||||
;; Remove layout-item properties when moving a shape outside a layout
|
||||
(cond-> (not (ctl/any-layout? parent))
|
||||
(pcb/update-shapes ids ctl/remove-layout-item-data))
|
||||
|
@ -353,7 +352,7 @@
|
|||
|
||||
;; Remove the swap slots if it is moving to a different component
|
||||
(pcb/update-shapes
|
||||
child-heads
|
||||
child-heads-ids
|
||||
(fn [shape]
|
||||
(cond-> shape
|
||||
(not= component-main-parent (ctn/find-component-main objects shape false))
|
||||
|
@ -365,7 +364,86 @@
|
|||
|
||||
;; Add component-root property when moving a component outside a component
|
||||
(cond-> (not (ctn/get-instance-root objects parent))
|
||||
(pcb/update-shapes child-heads #(assoc % :component-root true)))
|
||||
(pcb/update-shapes child-heads-ids #(assoc % :component-root true)))
|
||||
|
||||
;; Remove variant info and rename when moving outside a variant-container
|
||||
(cond-> (not (ctk/is-variant-container? parent))
|
||||
((fn [changes]
|
||||
(reduce
|
||||
(fn [changes shape]
|
||||
(let [new-name (str/replace (:variant-name shape) #", " " / ")
|
||||
[cpath cname] (cfh/parse-path-name new-name)]
|
||||
(-> changes
|
||||
(pcb/update-component (:component-id shape)
|
||||
#(-> (dissoc % :variant-id :variant-properties)
|
||||
(assoc :name cname
|
||||
:path cpath))
|
||||
{:apply-changes-local-library? true})
|
||||
(pcb/update-shapes [(:id shape)]
|
||||
#(-> (dissoc % :variant-id :variant-name)
|
||||
(assoc :name new-name))))))
|
||||
changes
|
||||
variant-heads))))
|
||||
|
||||
;; Add variant info and rename when moving into a different variant-container
|
||||
(cond-> (ctk/is-variant-container? parent)
|
||||
((fn [changes]
|
||||
(let [get-base-name #(if (some? (:variant-name %))
|
||||
(str/replace (:variant-name %) #", " " / ")
|
||||
(:name %))
|
||||
|
||||
calc-num-props #(-> %
|
||||
get-base-name
|
||||
cfh/split-path
|
||||
count)
|
||||
|
||||
max-path-items (apply max (map calc-num-props child-heads))
|
||||
|
||||
first-comp-id (->> parent
|
||||
:shapes
|
||||
first
|
||||
(get objects)
|
||||
:component-id)
|
||||
|
||||
data (pcb/get-library-data changes)
|
||||
variant-properties (get-in data [:components first-comp-id :variant-properties])
|
||||
num-props (count variant-properties)
|
||||
num-new-props (if (< max-path-items num-props)
|
||||
0
|
||||
(- max-path-items num-props))
|
||||
|
||||
changes (nth
|
||||
(iterate #(clv/generate-add-new-property % (:id parent)) changes)
|
||||
num-new-props)]
|
||||
(reduce
|
||||
(fn [changes shape]
|
||||
(if (= (:id parent) (:variant-id shape))
|
||||
changes ;; do nothing if we aren't changing the parent
|
||||
(let [base-name (get-base-name shape)
|
||||
|
||||
;; we need to get the updated library data to have access to the current properties
|
||||
data (pcb/get-library-data changes)
|
||||
|
||||
props (clv/path-to-properties
|
||||
base-name
|
||||
(get-in data [:components first-comp-id :variant-properties]))
|
||||
|
||||
variant-name (clv/properties-to-name props)
|
||||
[cpath cname] (cfh/parse-path-name (:name parent))]
|
||||
|
||||
(-> (pcb/update-component changes
|
||||
(:component-id shape)
|
||||
#(assoc % :variant-id (:id parent)
|
||||
:variant-properties props
|
||||
:name cname
|
||||
:path cpath)
|
||||
{:apply-changes-local-library? true})
|
||||
(pcb/update-shapes [(:id shape)]
|
||||
#(assoc % :variant-id (:id parent)
|
||||
:variant-name variant-name
|
||||
:name (:name parent)))))))
|
||||
changes
|
||||
child-heads)))))
|
||||
|
||||
;; Move the shapes
|
||||
(pcb/change-parent parent-id
|
||||
|
|
|
@ -5,58 +5,138 @@
|
|||
;; Copyright (c) KALEIDOS INC
|
||||
(ns app.common.logic.variants
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.types.components-list :as ctcl]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
|
||||
|
||||
(def property-prefix "Property")
|
||||
(def property-regex (re-pattern (str property-prefix "(\\d+)")))
|
||||
(def value-prefix "Value")
|
||||
|
||||
(defn find-related-components
|
||||
"Find a list of the components thet belongs to this variant-id"
|
||||
[data objects variant-id]
|
||||
(->> (dm/get-in objects [variant-id :shapes])
|
||||
(map #(dm/get-in objects [% :component-id]))
|
||||
(map #(ctcl/get-component data % true))
|
||||
reverse))
|
||||
|
||||
|
||||
(defn properties-to-name
|
||||
"Transform the properties into a name, with the values separated by comma"
|
||||
[properties]
|
||||
(->> properties
|
||||
(map :value)
|
||||
(remove str/empty?)
|
||||
(str/join ", ")))
|
||||
|
||||
|
||||
(defn next-property-number
|
||||
"Returns the next property number, to avoid duplicates on the property names"
|
||||
[properties]
|
||||
(let [numbers (keep
|
||||
#(some->> (:name %) (re-find property-regex) second d/parse-integer)
|
||||
properties)
|
||||
max-num (if (seq numbers)
|
||||
(apply max numbers)
|
||||
0)]
|
||||
(inc (max max-num (count properties)))))
|
||||
|
||||
|
||||
(defn path-to-properties
|
||||
"From a list of properties and a name with path, assign each token of the
|
||||
path as value of a different property"
|
||||
[path properties]
|
||||
(let [next-prop-num (next-property-number properties)
|
||||
cpath (cfh/split-path path)
|
||||
assigned (mapv #(assoc % :value (nth cpath %2 "")) properties (range))
|
||||
remaining (drop (count properties) cpath)
|
||||
new-properties (map-indexed (fn [i v] {:name (str property-prefix (+ next-prop-num i))
|
||||
:value v}) remaining)]
|
||||
(into assigned new-properties)))
|
||||
|
||||
|
||||
(defn generate-update-property-name
|
||||
[changes related-components pos new-name]
|
||||
(reduce (fn [changes component]
|
||||
(pcb/update-component
|
||||
changes (:id component)
|
||||
#(assoc-in % [:variant-properties pos :name] new-name)))
|
||||
changes
|
||||
related-components))
|
||||
[changes variant-id pos new-name]
|
||||
(let [data (pcb/get-library-data changes)
|
||||
objects (pcb/get-objects changes)
|
||||
related-components (find-related-components data objects variant-id)]
|
||||
(reduce (fn [changes component]
|
||||
(pcb/update-component
|
||||
changes (:id component)
|
||||
#(assoc-in % [:variant-properties pos :name] new-name)
|
||||
{:apply-changes-local-library? true}))
|
||||
changes
|
||||
related-components)))
|
||||
|
||||
|
||||
(defn generate-remove-property
|
||||
[changes related-components pos]
|
||||
(reduce (fn [changes component]
|
||||
(let [props (:variant-properties component)
|
||||
props (vec (concat (subvec props 0 pos) (subvec props (inc pos))))
|
||||
main-id (:main-instance-id component)
|
||||
name (properties-to-name props)]
|
||||
(-> changes
|
||||
(pcb/update-component (:id component) #(assoc % :variant-properties props))
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
||||
changes
|
||||
related-components))
|
||||
[changes variant-id pos]
|
||||
(let [data (pcb/get-library-data changes)
|
||||
objects (pcb/get-objects changes)
|
||||
related-components (find-related-components data objects variant-id)]
|
||||
(reduce (fn [changes component]
|
||||
(let [props (:variant-properties component)
|
||||
props (d/remove-at-index props pos)
|
||||
main-id (:main-instance-id component)
|
||||
name (properties-to-name props)]
|
||||
(-> changes
|
||||
(pcb/update-component (:id component) #(assoc % :variant-properties props)
|
||||
{:apply-changes-local-library? true})
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
||||
changes
|
||||
related-components)))
|
||||
|
||||
|
||||
(defn generate-update-property-value
|
||||
[changes component-id main-id pos value name]
|
||||
(-> changes
|
||||
(pcb/update-component component-id #(assoc-in % [:variant-properties pos :value] value))
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name))))
|
||||
[changes component-id pos value]
|
||||
(let [data (pcb/get-library-data changes)
|
||||
component (ctcl/get-component data component-id true)
|
||||
main-id (:main-instance-id component)
|
||||
name (-> (:variant-properties component)
|
||||
(update pos assoc :value value)
|
||||
properties-to-name)]
|
||||
(-> changes
|
||||
(pcb/update-component component-id #(assoc-in % [:variant-properties pos :value] value)
|
||||
{:apply-changes-local-library? true})
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
||||
|
||||
|
||||
(defn generate-add-new-property
|
||||
[changes related-components property-name]
|
||||
(let [[_ changes]
|
||||
[changes variant-id & {:keys [fill-values?]}]
|
||||
(let [data (pcb/get-library-data changes)
|
||||
objects (pcb/get-objects changes)
|
||||
related-components (find-related-components data objects variant-id)
|
||||
|
||||
props (-> related-components first :variant-properties)
|
||||
next-prop-num (next-property-number props)
|
||||
property-name (str property-prefix next-prop-num)
|
||||
|
||||
[_ changes]
|
||||
(reduce (fn [[num changes] component]
|
||||
(let [props (-> (or (:variant-properties component) [])
|
||||
(conj {:name property-name :value (str "Value" num)}))
|
||||
main-id (:main-instance-id component)
|
||||
variant-name (properties-to-name props)]
|
||||
(let [main-id (:main-instance-id component)
|
||||
|
||||
update-props #(-> (d/nilv % [])
|
||||
(conj {:name property-name
|
||||
:value (if fill-values? (str value-prefix num) "")}))
|
||||
|
||||
update-name #(if fill-values?
|
||||
(if (str/empty? %)
|
||||
(str value-prefix num)
|
||||
(str % ", " value-prefix num))
|
||||
%)]
|
||||
[(inc num)
|
||||
(-> changes
|
||||
(pcb/update-component (:id component) #(assoc % :variant-properties props))
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name variant-name)))]))
|
||||
(pcb/update-component (:id component)
|
||||
#(update % :variant-properties update-props)
|
||||
{:apply-changes-local-library? true})
|
||||
(pcb/update-shapes [main-id] #(update % :variant-name update-name)))]))
|
||||
[1 changes]
|
||||
related-components)]
|
||||
changes))
|
||||
|
||||
|
|
|
@ -57,6 +57,14 @@
|
|||
:main-instance-page (:id page)
|
||||
:shapes updated-shapes))))))))
|
||||
|
||||
(defn update-component
|
||||
[file component-label & {:keys [] :as params}]
|
||||
(let [component-id (thi/id component-label)]
|
||||
(ctf/update-file-data
|
||||
file
|
||||
(fn [file-data]
|
||||
(ctkl/update-component file-data component-id #(merge % params))))))
|
||||
|
||||
(defn get-component
|
||||
[file label & {:keys [include-deleted?] :or {include-deleted? false}}]
|
||||
(ctkl/get-component (:data file) (thi/id label) include-deleted?))
|
||||
|
|
25
common/src/app/common/test_helpers/variants.cljc
Normal file
25
common/src/app/common/test_helpers/variants.cljc
Normal file
|
@ -0,0 +1,25 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.common.test-helpers.variants
|
||||
(:require
|
||||
[app.common.test-helpers.components :as thc]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]))
|
||||
|
||||
(defn add-variant
|
||||
[file variant-label component1-label root1-label component2-label root2-label
|
||||
& {:keys []}]
|
||||
(let [file (ths/add-sample-shape file variant-label :type :frame :is-variant-container true)
|
||||
variant-id (thi/id variant-label)]
|
||||
|
||||
(-> file
|
||||
(ths/add-sample-shape root2-label :type :frame :parent-label variant-label :variant-id variant-id :variant-name "Value2")
|
||||
(ths/add-sample-shape root1-label :type :frame :parent-label variant-label :variant-id variant-id :variant-name "Value1")
|
||||
(thc/make-component component1-label root1-label)
|
||||
(thc/update-component component1-label {:variant-id variant-id :variant-properties [{:name "Property1" :value "Value1"}]})
|
||||
(thc/make-component component2-label root2-label)
|
||||
(thc/update-component component2-label {:variant-id variant-id :variant-properties [{:name "Property1" :value "Value1"}]}))))
|
|
@ -535,11 +535,17 @@
|
|||
(letfn [(get-frame [parent-id]
|
||||
(if (cfh/frame-shape? objects parent-id) parent-id (get-in objects [parent-id :frame-id])))]
|
||||
(let [parent (get objects parent-id)
|
||||
;; We can always move the children to the parent they already have.
|
||||
;; We can always move the children to the parent they already have.
|
||||
;; But if we are pasting, those are new items, so it is considered a change
|
||||
no-changes?
|
||||
(->> children (every? #(= parent-id (:parent-id %))))]
|
||||
;; In case no-changes is true we must ensure we are copy pasting the children in the same position
|
||||
(if (or (and no-changes? (not pasting?)) (not (invalid-structure-for-component? objects parent children pasting? libraries)))
|
||||
(and (->> children (every? #(= parent-id (:parent-id %))))
|
||||
(not pasting?))
|
||||
all-main?
|
||||
(->> children (every? #(ctk/main-instance? %)))]
|
||||
(if (or no-changes?
|
||||
(and (not (invalid-structure-for-component? objects parent children pasting? libraries))
|
||||
;; If we are moving into a variant-container, all the items should be main
|
||||
(or all-main? (not (ctk/is-variant-container? parent)))))
|
||||
[parent-id (get-frame parent-id)]
|
||||
(recur (:parent-id parent) objects children pasting? libraries))))))
|
||||
|
||||
|
|
|
@ -61,10 +61,10 @@
|
|||
blue1 (ths/get-shape file :blue1)
|
||||
|
||||
;; ==== Action
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
uuid/zero ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -91,10 +91,10 @@
|
|||
|
||||
|
||||
;; ==== Action
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id b2) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -121,10 +121,10 @@
|
|||
|
||||
;; ==== Action
|
||||
;; Move blue1 into yellow
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id yellow) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -134,10 +134,10 @@
|
|||
yellow' (ths/get-shape file' :frame-yellow)
|
||||
|
||||
;; Move yellow into root
|
||||
changes' (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page')
|
||||
changes' (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page'))
|
||||
(pcb/with-objects (:objects page')))
|
||||
uuid/zero ;; parent-id
|
||||
(:id page') ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id yellow')}) ;; ids
|
||||
|
||||
|
@ -164,10 +164,10 @@
|
|||
|
||||
;; ==== Action
|
||||
;; Move blue1 into yellow
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id yellow) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -178,10 +178,10 @@
|
|||
b2' (ths/get-shape file' :frame-b2)
|
||||
|
||||
;; Move yellow into b2
|
||||
changes' (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page')
|
||||
changes' (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page'))
|
||||
(pcb/with-objects (:objects page')))
|
||||
(:id b2') ;; parent-id
|
||||
(:id page') ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id yellow')}) ;; ids
|
||||
|
||||
|
@ -254,10 +254,10 @@
|
|||
|
||||
;; ==== Action
|
||||
;; Move blue1 into yellow
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id yellow) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -308,10 +308,10 @@
|
|||
blue1 (ths/get-shape file :blue1)
|
||||
|
||||
;; ==== Action
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:parent-id blue1) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
2 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -338,10 +338,10 @@
|
|||
|
||||
;; ==== Action
|
||||
;; Move blue1 into yellow
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id yellow) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -351,10 +351,10 @@
|
|||
page' (thf/current-page file')
|
||||
blue1' (ths/get-shape file' :blue1)
|
||||
b1' (ths/get-shape file' :frame-b1)
|
||||
changes' (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page')
|
||||
changes' (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page'))
|
||||
(pcb/with-objects (:objects page')))
|
||||
(:id b1') ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1')}) ;; ids
|
||||
|
||||
|
@ -382,10 +382,10 @@
|
|||
|
||||
;; ==== Action
|
||||
;; Relocate blue1 into yellow
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id yellow) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1)}) ;; ids
|
||||
|
||||
|
@ -396,10 +396,10 @@
|
|||
page' (thf/current-page file')
|
||||
blue1' (ths/get-shape file' :blue1)
|
||||
b1' (ths/get-shape file' :frame-b1)
|
||||
changes' (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page')
|
||||
changes' (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page'))
|
||||
(pcb/with-objects (:objects page')))
|
||||
(:id b1') ;; parent-id
|
||||
(:id page') ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id blue1')}) ;; ids
|
||||
|
||||
|
@ -428,10 +428,10 @@
|
|||
green-copy (ths/get-shape file :green-copy)
|
||||
|
||||
;; ==== Action
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
uuid/zero ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id green-copy)}) ;; ids
|
||||
|
||||
|
@ -459,10 +459,10 @@
|
|||
b2 (ths/get-shape file :frame-b2)
|
||||
|
||||
;; ==== Action
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id b2) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id green-copy)}) ;; ids
|
||||
|
||||
|
|
|
@ -136,10 +136,10 @@
|
|||
|
||||
;; IMPORTANT: as modifying copies structure is now forbidden, this action
|
||||
;; will not have any effect, and so the parent shape won't also be touched.
|
||||
changes (cls/generate-relocate (pcb/empty-changes)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(thi/id :copy-root) ; parent-id
|
||||
(:id page) ; page-id
|
||||
0 ; to-index
|
||||
#{(thi/id :free-shape)}) ; ids
|
||||
|
||||
|
@ -231,10 +231,10 @@
|
|||
|
||||
;; IMPORTANT: as modifying copies structure is now forbidden, this action
|
||||
;; will not have any effect, and so the parent shape won't also be touched.
|
||||
changes (cls/generate-relocate (pcb/empty-changes)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(thi/id :copy-root) ; parent-id
|
||||
(:id page) ; page-id
|
||||
2 ; to-index
|
||||
#{(:id copy-child1)}) ; ids
|
||||
|
||||
|
|
|
@ -195,10 +195,10 @@
|
|||
page (thf/current-page file)
|
||||
|
||||
;; ==== Action
|
||||
changes1 (cls/generate-relocate (pcb/empty-changes)
|
||||
(:objects page)
|
||||
changes1 (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(thi/id :main-root) ; parent-id
|
||||
(:id page) ; page-id
|
||||
0 ; to-index
|
||||
#{(thi/id :free-shape)}) ; ids
|
||||
|
||||
|
@ -292,10 +292,10 @@
|
|||
main-child1 (ths/get-shape file :main-child1)
|
||||
|
||||
;; ==== Action
|
||||
changes1 (cls/generate-relocate (pcb/empty-changes)
|
||||
(:objects page)
|
||||
changes1 (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(thi/id :main-root) ; parent-id
|
||||
(:id page) ; page-id
|
||||
2 ; to-index
|
||||
#{(:id main-child1)}) ; ids
|
||||
|
||||
|
|
|
@ -112,10 +112,10 @@
|
|||
|
||||
;; IMPORTANT: as modifying copies structure is now forbidden, this action
|
||||
;; will not have any effect, and so the parent shape won't also be touched.
|
||||
changes (cls/generate-relocate (pcb/empty-changes)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(thi/id :copy-root) ; parent-id
|
||||
(:id page) ; page-id
|
||||
0 ; to-index
|
||||
#{(thi/id :free-shape)}) ; ids
|
||||
|
||||
|
@ -187,10 +187,10 @@
|
|||
|
||||
;; IMPORTANT: as modifying copies structure is now forbidden, this action
|
||||
;; will not have any effect, and so the parent shape won't also be touched.
|
||||
changes (cls/generate-relocate (pcb/empty-changes)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(thi/id :copy-root) ; parent-id
|
||||
(:id page) ; page-id
|
||||
2 ; to-index
|
||||
#{(:id copy-child1)}) ; ids
|
||||
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
|
||||
;; ==== Action
|
||||
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(:id frame-parent) ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id frame-to-move)}) ;; ids
|
||||
|
||||
|
@ -61,10 +61,10 @@
|
|||
|
||||
;; ==== Action
|
||||
|
||||
changes (cls/generate-relocate (pcb/empty-changes nil)
|
||||
(:objects page)
|
||||
changes (cls/generate-relocate (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
uuid/zero ;; parent-id
|
||||
(:id page) ;; page-id
|
||||
0 ;; to-index
|
||||
#{(:id circle)}) ;; ids
|
||||
|
||||
|
|
194
common/test/common_tests/logic/variants_test.cljc
Normal file
194
common/test/common_tests/logic/variants_test.cljc
Normal file
|
@ -0,0 +1,194 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns common-tests.logic.variants-test
|
||||
(:require
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.logic.variants :as clv]
|
||||
[app.common.test-helpers.components :as thc]
|
||||
[app.common.test-helpers.files :as thf]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]
|
||||
[app.common.test-helpers.variants :as thv]
|
||||
[clojure.test :as t]))
|
||||
|
||||
(t/use-fixtures :each thi/test-fixture)
|
||||
|
||||
(t/deftest test-update-property-name
|
||||
(let [;; ==== Setup
|
||||
file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
|
||||
v-id (-> (ths/get-shape file :v01) :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))
|
||||
(clv/generate-update-property-name v-id 0 "NewName1")
|
||||
(clv/generate-update-property-name v-id 1 "NewName2"))
|
||||
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
||||
|
||||
;; ==== Get
|
||||
comp01' (thc/get-component file' :c01)
|
||||
comp02' (thc/get-component file' :c02)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (= (-> comp01' :variant-properties first :name) "NewName1"))
|
||||
(t/is (= (-> comp01' :variant-properties last :name) "NewName2"))
|
||||
(t/is (= (-> comp02' :variant-properties first :name) "NewName1"))
|
||||
(t/is (= (-> comp02' :variant-properties last :name) "NewName2"))))
|
||||
|
||||
|
||||
|
||||
(t/deftest test-add-new-property-without-values
|
||||
(let [;; ==== Setup
|
||||
file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
|
||||
v-id (-> (ths/get-shape file :v01) :id)
|
||||
page (thf/current-page file)
|
||||
|
||||
comp01 (thc/get-component file :c01)
|
||||
comp02 (thc/get-component file :c02)
|
||||
|
||||
|
||||
;; ==== Action
|
||||
changes (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-library-data (:data file))
|
||||
(pcb/with-objects (:objects page))
|
||||
(clv/generate-add-new-property v-id))
|
||||
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
||||
|
||||
;; ==== Get
|
||||
comp01' (thc/get-component file' :c01)
|
||||
comp02' (thc/get-component file' :c02)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (= (count (:variant-properties comp01)) 1))
|
||||
(t/is (= (count (:variant-properties comp01')) 2))
|
||||
(t/is (= (count (:variant-properties comp02)) 1))
|
||||
(t/is (= (count (:variant-properties comp02')) 2))
|
||||
(t/is (= (-> comp01' :variant-properties last :value) ""))))
|
||||
|
||||
|
||||
|
||||
(t/deftest test-add-new-property-with-values
|
||||
(let [;; ==== Setup
|
||||
file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
|
||||
v-id (-> (ths/get-shape file :v01) :id)
|
||||
page (thf/current-page file)
|
||||
|
||||
comp01 (thc/get-component file :c01)
|
||||
comp02 (thc/get-component file :c02)
|
||||
|
||||
|
||||
;; ==== Action
|
||||
changes (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-library-data (:data file))
|
||||
(pcb/with-objects (:objects page))
|
||||
(clv/generate-add-new-property v-id {:fill-values? true}))
|
||||
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
||||
|
||||
;; ==== Get
|
||||
comp01' (thc/get-component file' :c01)
|
||||
comp02' (thc/get-component file' :c02)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (= (count (:variant-properties comp01)) 1))
|
||||
(t/is (= (count (:variant-properties comp01')) 2))
|
||||
(t/is (= (count (:variant-properties comp02)) 1))
|
||||
(t/is (= (count (:variant-properties comp02')) 2))
|
||||
(t/is (= (-> comp01' :variant-properties last :value) "Value1"))))
|
||||
|
||||
|
||||
|
||||
(t/deftest test-remove-property
|
||||
(let [;; ==== Setup
|
||||
file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
|
||||
v-id (-> (ths/get-shape file :v01) :id)
|
||||
page (thf/current-page file)
|
||||
|
||||
changes (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-library-data (:data file))
|
||||
(pcb/with-objects (:objects page))
|
||||
(clv/generate-add-new-property v-id))
|
||||
|
||||
|
||||
file (thf/apply-changes file changes)
|
||||
page (thf/current-page file)
|
||||
|
||||
comp01 (thc/get-component file :c01)
|
||||
comp02 (thc/get-component file :c02)
|
||||
|
||||
|
||||
;; ==== Action
|
||||
changes (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-library-data (:data file))
|
||||
(pcb/with-objects (:objects page))
|
||||
(clv/generate-remove-property v-id 0))
|
||||
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
||||
|
||||
;; ==== Get
|
||||
comp01' (thc/get-component file' :c01)
|
||||
comp02' (thc/get-component file' :c02)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (= (count (:variant-properties comp01)) 2))
|
||||
(t/is (= (count (:variant-properties comp01')) 1))
|
||||
(t/is (= (count (:variant-properties comp02)) 2))
|
||||
(t/is (= (count (:variant-properties comp02')) 1))
|
||||
(t/is (= (-> comp01' :variant-properties first :name) "Property2"))))
|
||||
|
||||
(t/deftest test-update-property-value
|
||||
(let [;; ==== Setup
|
||||
file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
|
||||
|
||||
page (thf/current-page file)
|
||||
|
||||
comp01 (thc/get-component file :c01)
|
||||
comp02 (thc/get-component file :c02)
|
||||
|
||||
;; ==== Action
|
||||
changes (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-library-data (:data file))
|
||||
(pcb/with-objects (:objects page))
|
||||
(clv/generate-update-property-value (:id comp01) 0 "NewValue1")
|
||||
(clv/generate-update-property-value (:id comp02) 0 "NewValue2"))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
;; ==== Get
|
||||
comp01' (thc/get-component file' :c01)
|
||||
comp02' (thc/get-component file' :c02)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (= (-> comp01' :variant-properties first :value) "NewValue1"))
|
||||
(t/is (= (-> comp02' :variant-properties first :value) "NewValue2"))))
|
|
@ -890,6 +890,7 @@
|
|||
(watch [it state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dsh/lookup-page-objects state page-id)
|
||||
data (dsh/lookup-file-data state)
|
||||
|
||||
;; Ignore any shape whose parent is also intended to be moved
|
||||
ids (cfh/clean-loops objects ids)
|
||||
|
@ -899,13 +900,15 @@
|
|||
|
||||
all-parents (into #{parent-id} (map #(cfh/get-parent-id objects %)) ids)
|
||||
|
||||
changes (cls/generate-relocate (pcb/empty-changes it)
|
||||
objects
|
||||
parent-id
|
||||
page-id
|
||||
to-index
|
||||
ids
|
||||
:ignore-parents? ignore-parents?)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-page-id page-id)
|
||||
(pcb/with-objects objects)
|
||||
(pcb/with-library-data data)
|
||||
(cls/generate-relocate
|
||||
parent-id
|
||||
to-index
|
||||
ids
|
||||
:ignore-parents? ignore-parents?))
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
|
|
|
@ -232,7 +232,8 @@
|
|||
ids (->> ids
|
||||
(remove #(ctn/has-any-copy-parent? objects (get objects %)))
|
||||
;; components can't be ungrouped
|
||||
(remove #(ctk/instance-head? (get objects %))))
|
||||
(remove #(ctk/instance-head? (get objects %)))
|
||||
(remove #(ctk/is-variant-container? (get objects %))))
|
||||
|
||||
changes-list (sequence (keep prepare) ids)
|
||||
|
||||
|
|
|
@ -930,14 +930,17 @@
|
|||
(watch [it state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dsh/lookup-page-objects state page-id)
|
||||
data (dsh/lookup-file-data state)
|
||||
ids (cleanup-invalid-moving-shapes ids objects frame-id)
|
||||
changes (cls/generate-relocate (pcb/empty-changes it)
|
||||
objects
|
||||
frame-id
|
||||
page-id
|
||||
drop-index
|
||||
ids
|
||||
:cell cell)]
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-page-id page-id)
|
||||
(pcb/with-objects objects)
|
||||
(pcb/with-library-data data)
|
||||
(cls/generate-relocate
|
||||
frame-id
|
||||
drop-index
|
||||
ids
|
||||
:cell cell))]
|
||||
|
||||
(when (and (some? frame-id) (d/not-empty? changes))
|
||||
(rx/of (dch/commit-changes changes)
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.logic.variants :as clv]
|
||||
[app.common.types.components-list :as ctcl]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.changes :as dch]
|
||||
[app.main.data.helpers :as dsh]
|
||||
|
@ -22,11 +21,7 @@
|
|||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn find-related-components
|
||||
[data objects variant-id]
|
||||
(->> (dm/get-in objects [variant-id :shapes])
|
||||
(map #(dm/get-in objects [% :component-id]))
|
||||
(map #(ctcl/get-component data % true))))
|
||||
(dm/export clv/find-related-components)
|
||||
|
||||
(defn update-property-name
|
||||
"Update the variant property name on the position pos
|
||||
|
@ -39,10 +34,11 @@
|
|||
data (dsh/lookup-file-data state)
|
||||
objects (-> (dsh/get-page data page-id)
|
||||
(get :objects))
|
||||
related-components (find-related-components data objects variant-id)
|
||||
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects)
|
||||
(pcb/with-library-data data)
|
||||
(clv/generate-update-property-name related-components pos new-name))
|
||||
(clv/generate-update-property-name variant-id pos new-name))
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
|
@ -59,17 +55,11 @@
|
|||
data (dsh/lookup-file-data state)
|
||||
objects (-> (dsh/get-page data page-id)
|
||||
(get :objects))
|
||||
component (ctcl/get-component data component-id true)
|
||||
main-id (:main-instance-id component)
|
||||
properties (-> (:variant-properties component)
|
||||
(update pos assoc :value value))
|
||||
|
||||
name (clv/properties-to-name properties)
|
||||
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/with-objects objects)
|
||||
(clv/generate-update-property-value component-id main-id pos value name))
|
||||
(clv/generate-update-property-value component-id pos value))
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
|
@ -88,12 +78,11 @@
|
|||
data (dsh/lookup-file-data state)
|
||||
objects (-> (dsh/get-page data page-id)
|
||||
(get :objects))
|
||||
related-components (find-related-components data objects variant-id)
|
||||
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/with-objects objects)
|
||||
(clv/generate-remove-property related-components pos))
|
||||
(clv/generate-remove-property variant-id pos))
|
||||
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
|
@ -105,7 +94,7 @@
|
|||
|
||||
(defn add-new-property
|
||||
"Add a new variant property to all the components with this variant-id"
|
||||
[variant-id]
|
||||
[variant-id & [options]]
|
||||
(ptk/reify ::add-new-property
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
|
@ -114,20 +103,10 @@
|
|||
objects (-> (dsh/get-page data page-id)
|
||||
(get :objects))
|
||||
|
||||
related-components (find-related-components data objects variant-id)
|
||||
|
||||
|
||||
property-name (str "Property" (-> related-components
|
||||
first
|
||||
:variant-properties
|
||||
count
|
||||
inc))
|
||||
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/with-objects objects)
|
||||
(clv/generate-add-new-property related-components property-name))
|
||||
|
||||
(clv/generate-add-new-property variant-id options))
|
||||
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
|
@ -155,7 +134,7 @@
|
|||
(defn transform-in-variant
|
||||
"Given the id of a main shape of a component, creates a variant structure for
|
||||
that component"
|
||||
[id]
|
||||
[main-instance-id]
|
||||
(ptk/reify ::transform-in-variant
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
|
@ -165,7 +144,7 @@
|
|||
file-id (:current-file-id state)
|
||||
page-id (:current-page-id state)
|
||||
objects (dsh/lookup-page-objects state file-id page-id)
|
||||
main (get objects id)
|
||||
main (get objects main-instance-id)
|
||||
main-id (:id main)
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
|
@ -193,5 +172,5 @@
|
|||
(dwl/duplicate-component file-id (:component-id main) new-component-id)
|
||||
(set-variant-id (:component-id main) variant-id)
|
||||
(set-variant-id new-component-id variant-id)
|
||||
(add-new-property variant-id)
|
||||
(add-new-property variant-id {:fill-values? true})
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
|
|
@ -324,8 +324,8 @@
|
|||
any-in-copy? (some true? (map #(ctn/has-any-copy-parent? objects %) shapes))
|
||||
|
||||
;; components can't be ungrouped
|
||||
has-frame? (->> shapes (d/seek #(and (cfh/frame-shape? %) (not (ctk/instance-head? %)))))
|
||||
has-group? (->> shapes (d/seek #(and (cfh/group-shape? %) (not (ctk/instance-head? %)))))
|
||||
has-frame? (->> shapes (d/seek #(and (cfh/frame-shape? %) (not (ctk/instance-head? %)) (not (ctk/is-variant-container? %)))))
|
||||
has-group? (->> shapes (d/seek #(and (cfh/group-shape? %) (not (ctk/instance-head? %)) (not (ctk/is-variant-container? %)))))
|
||||
has-bool? (->> shapes (d/seek cfh/bool-shape?))
|
||||
has-mask? (->> shapes (d/seek :masked-group))
|
||||
|
||||
|
|
|
@ -254,11 +254,11 @@
|
|||
(mf/deps related-components)
|
||||
(fn [prop-name]
|
||||
(->> related-components
|
||||
(mapcat (fn [item]
|
||||
(map :value (filter (fn [prop] (= (:name prop) prop-name))
|
||||
(:variant-properties item)))))
|
||||
(filter some?)
|
||||
(mapcat (fn [component]
|
||||
(map :value (filter #(= (:name %) prop-name)
|
||||
(:variant-properties component)))))
|
||||
distinct
|
||||
(map #(if (str/empty? %) "--" %))
|
||||
(map (fn [val] {:label val :id val})))))
|
||||
|
||||
filter-matching
|
||||
|
@ -278,8 +278,7 @@
|
|||
(mf/use-fn
|
||||
(mf/deps id-component)
|
||||
(fn [pos value]
|
||||
(when-not (str/empty? value)
|
||||
(st/emit! (dwv/update-property-value id-component pos value)))))
|
||||
(st/emit! (dwv/update-property-value id-component pos value))))
|
||||
|
||||
switch-component
|
||||
(mf/use-fn
|
||||
|
@ -293,7 +292,7 @@
|
|||
(if (ctk/main-instance? shape)
|
||||
[:*
|
||||
[:span {:class (stl/css :variant-property-name :variant-property-name-bg)} (:name prop)]
|
||||
[:> combobox* {:default-selected (str (or (:value prop) ""))
|
||||
[:> combobox* {:default-selected (if (str/empty? (:value prop)) "--" (:value prop))
|
||||
:options (clj->js (get-options (:name prop)))
|
||||
:on-change (partial change-property-value pos)}]]
|
||||
|
||||
|
@ -761,7 +760,10 @@
|
|||
properties (->> (dwv/find-related-components data objects variant-id)
|
||||
(mapcat :variant-properties)
|
||||
(group-by :name)
|
||||
(map (fn [[k v]] {:name k :values (map :value v)})))
|
||||
(map (fn [[k v]]
|
||||
{:name k
|
||||
:values (distinct
|
||||
(map #(if (str/empty? (:value %)) "--" (:value %)) v))})))
|
||||
|
||||
menu-open* (mf/use-state false)
|
||||
menu-open? (deref menu-open*)
|
||||
|
|
Loading…
Add table
Reference in a new issue