mirror of
https://github.com/penpot/penpot.git
synced 2025-05-02 05:15:54 +02:00
🎉 Create a new variant from an existing one
This commit is contained in:
parent
aa468e2153
commit
8eb2aaa0a8
12 changed files with 207 additions and 56 deletions
|
@ -155,13 +155,14 @@
|
|||
(dm/get-in data [:pages-index uuid/zero :objects])))
|
||||
|
||||
(defn- apply-changes-local
|
||||
[changes]
|
||||
[changes & {:keys [apply-to-library?]}]
|
||||
(dm/assert!
|
||||
"expected valid changes"
|
||||
(check-changes! changes))
|
||||
|
||||
(if-let [file-data (::file-data (meta changes))]
|
||||
(let [index (::applied-changes-count (meta changes))
|
||||
(let [library-data (::library-data (meta changes))
|
||||
index (::applied-changes-count (meta changes))
|
||||
redo-changes (:redo-changes changes)
|
||||
new-changes (if (< index (count redo-changes))
|
||||
(->> (subvec (:redo-changes changes) index)
|
||||
|
@ -169,28 +170,12 @@
|
|||
(assoc :page-id uuid/zero)
|
||||
(dissoc :component-id))))
|
||||
[])
|
||||
new-file-data (cfc/process-changes file-data new-changes)]
|
||||
new-file-data (cfc/process-changes file-data new-changes)
|
||||
new-library-data (if apply-to-library?
|
||||
(cfc/process-changes library-data new-changes)
|
||||
library-data)]
|
||||
(vary-meta changes assoc ::file-data new-file-data
|
||||
::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
|
||||
::library-data new-library-data
|
||||
::applied-changes-count (count redo-changes)))
|
||||
changes))
|
||||
|
||||
|
@ -932,8 +917,10 @@
|
|||
|
||||
(defn add-component
|
||||
([changes id path name new-shapes updated-shapes main-instance-id main-instance-page]
|
||||
(add-component changes id path name new-shapes updated-shapes main-instance-id main-instance-page nil))
|
||||
(add-component changes id path name new-shapes updated-shapes main-instance-id main-instance-page nil nil nil))
|
||||
([changes id path name new-shapes updated-shapes main-instance-id main-instance-page annotation]
|
||||
(add-component changes id path name new-shapes updated-shapes main-instance-id main-instance-page annotation nil nil))
|
||||
([changes id path name new-shapes updated-shapes main-instance-id main-instance-page annotation variant-id variant-properties & {:keys [apply-changes-local-library?]}]
|
||||
(assert-page-id! changes)
|
||||
(assert-objects! changes)
|
||||
(let [page-id (::page-id (meta changes))
|
||||
|
@ -972,7 +959,9 @@
|
|||
:name name
|
||||
:main-instance-id main-instance-id
|
||||
:main-instance-page main-instance-page
|
||||
:annotation annotation}
|
||||
:annotation annotation
|
||||
:variant-id variant-id
|
||||
:variant-properties variant-properties}
|
||||
(some? new-shapes) ;; this will be null in components-v2
|
||||
(assoc :shapes (vec new-shapes))))
|
||||
(into (map mk-change) updated-shapes))))
|
||||
|
@ -987,7 +976,7 @@
|
|||
(map mk-change))
|
||||
updated-shapes))))
|
||||
|
||||
(apply-changes-local)))))
|
||||
(apply-changes-local {:apply-to-library? apply-changes-local-library?})))))
|
||||
|
||||
(defn update-component
|
||||
[changes id update-fn & {:keys [apply-changes-local-library?]}]
|
||||
|
@ -1019,7 +1008,7 @@
|
|||
:variant-properties (:variant-properties prev-component)
|
||||
:objects (:objects prev-component)})
|
||||
(cond-> apply-changes-local-library?
|
||||
(apply-changes-local-library)))
|
||||
(apply-changes-local {:apply-to-library? true})))
|
||||
changes)))
|
||||
|
||||
(defn delete-component
|
||||
|
|
|
@ -100,10 +100,10 @@
|
|||
|
||||
;; ---- Components and instances creation ----
|
||||
|
||||
(defn duplicate-component
|
||||
(defn- duplicate-component
|
||||
"Clone the root shape of the component and all children. Generate new
|
||||
ids from all of them."
|
||||
[component new-component-id library-data]
|
||||
[component new-component-id library-data force-id]
|
||||
(let [components-v2 (dm/get-in library-data [:options :components-v2])]
|
||||
(if components-v2
|
||||
(let [main-instance-page (ctf/get-component-page library-data component)
|
||||
|
@ -139,7 +139,8 @@
|
|||
(:parent-id main-instance-shape)
|
||||
(:objects main-instance-page)
|
||||
:update-new-shape update-new-shape
|
||||
:update-original-shape update-original-shape)
|
||||
:update-original-shape update-original-shape
|
||||
:force-id force-id)
|
||||
|
||||
remap-frame
|
||||
(fn [shape]
|
||||
|
@ -179,7 +180,7 @@
|
|||
|
||||
(defn generate-duplicate-component
|
||||
"Create a new component copied from the one with the given id."
|
||||
[changes library component-id new-component-id components-v2]
|
||||
[changes library component-id new-component-id components-v2 & {:keys [new-shape-id apply-changes-local-library?]}]
|
||||
(let [component (ctkl/get-component (:data library) component-id)
|
||||
new-name (:name component)
|
||||
|
||||
|
@ -191,7 +192,7 @@
|
|||
|
||||
[new-component-shape new-component-shapes ; <- null in components-v2
|
||||
new-main-instance-shape new-main-instance-shapes]
|
||||
(duplicate-component component new-component-id (:data library))]
|
||||
(duplicate-component component new-component-id (:data library) new-shape-id)]
|
||||
|
||||
[new-main-instance-shape
|
||||
(-> changes
|
||||
|
@ -207,7 +208,10 @@
|
|||
[]
|
||||
(:id new-main-instance-shape)
|
||||
(:id main-instance-page)
|
||||
(:annotation component))
|
||||
(:annotation component)
|
||||
(:variant-id component)
|
||||
(:variant-properties component)
|
||||
{:apply-changes-local-library? apply-changes-local-library?})
|
||||
;; Update grid layout if the new main instance is inside
|
||||
(pcb/update-shapes
|
||||
[(:frame-id new-main-instance-shape)]
|
||||
|
|
|
@ -61,6 +61,17 @@
|
|||
(into assigned new-properties)))
|
||||
|
||||
|
||||
(defn extract-properties-values
|
||||
[data objects variant-id]
|
||||
(->> (find-related-components data objects variant-id)
|
||||
(mapcat :variant-properties)
|
||||
(group-by :name)
|
||||
(map (fn [[k v]]
|
||||
{:name k
|
||||
:values (distinct
|
||||
(map #(if (str/empty? (:value %)) "--" (:value %)) v))}))))
|
||||
|
||||
|
||||
(defn generate-update-property-name
|
||||
[changes variant-id pos new-name]
|
||||
(let [data (pcb/get-library-data changes)
|
||||
|
|
|
@ -333,6 +333,8 @@
|
|||
(let [parent (get objects (:parent-id shape))]
|
||||
;; We don't want to change the structure of component copies
|
||||
(and (not (in-component-copy-not-head? shape))
|
||||
;; We don't want to duplicate variants
|
||||
(not (is-variant? shape))
|
||||
;; Non instance, non copy. We allow
|
||||
(or (not (instance-head? shape))
|
||||
(not (in-component-copy? parent))))))
|
||||
|
|
|
@ -34,12 +34,14 @@
|
|||
(assoc component :modified-at (dt/now)))
|
||||
|
||||
(defn add-component
|
||||
[fdata {:keys [id name path main-instance-id main-instance-page shapes annotation]}]
|
||||
[fdata {:keys [id name path main-instance-id main-instance-page shapes annotation variant-id variant-properties]}]
|
||||
(let [components-v2 (dm/get-in fdata [:options :components-v2])
|
||||
fdata (update fdata :components assoc id (touch {:id id :name name :path path}))]
|
||||
(if components-v2
|
||||
(cond-> (update-in fdata [:components id] assoc :main-instance-id main-instance-id :main-instance-page main-instance-page)
|
||||
annotation (update-in [:components id] assoc :annotation annotation))
|
||||
annotation (update-in [:components id] assoc :annotation annotation)
|
||||
variant-id (update-in [:components id] assoc :variant-id variant-id)
|
||||
variant-properties (update-in [:components id] assoc :variant-properties variant-properties))
|
||||
|
||||
(let [wrap-object-fn cfeat/*wrap-with-objects-map-fn*]
|
||||
(assoc-in fdata [:components id :objects]
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
[app.main.data.workspace.texts :as dwtxt]
|
||||
[app.main.data.workspace.transforms :as dwt]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.data.workspace.variants :as dwv]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
|
@ -121,7 +122,7 @@
|
|||
:duplicate {:tooltip (ds/meta "D")
|
||||
:command (ds/c-mod "d")
|
||||
:subsections [:edit]
|
||||
:fn #(emit-when-no-readonly (dw/duplicate-selected true))}
|
||||
:fn #(emit-when-no-readonly (dwv/duplicate-or-add-variant))}
|
||||
|
||||
:start-editing {:tooltip (ds/enter)
|
||||
:command "enter"
|
||||
|
@ -175,7 +176,7 @@
|
|||
:create-component {:tooltip (ds/meta "K")
|
||||
:command (ds/c-mod "k")
|
||||
:subsections [:modify-layers]
|
||||
:fn #(emit-when-no-readonly (dwl/add-component))}
|
||||
:fn #(emit-when-no-readonly (dwv/add-component-or-variant))}
|
||||
|
||||
:detach-component {:tooltip (ds/meta-shift "K")
|
||||
:command (ds/c-mod "shift+k")
|
||||
|
|
|
@ -7,17 +7,24 @@
|
|||
(ns app.main.data.workspace.variants
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.logic.libraries :as cll]
|
||||
[app.common.logic.variants :as clv]
|
||||
[app.common.types.component :as ctc]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[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.undo :as dwu]
|
||||
[app.main.features :as features]
|
||||
[app.util.dom :as dom]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
|
@ -131,6 +138,70 @@
|
|||
(dch/commit-changes changes)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn focus-property
|
||||
[shape-id prop-num]
|
||||
(ptk/reify ::focus-property
|
||||
ptk/EffectEvent
|
||||
(effect [_ _ _]
|
||||
(dom/focus! (dom/get-element (str "variant-prop-" shape-id prop-num))))))
|
||||
|
||||
|
||||
(defn add-new-variant
|
||||
"Create a new variant and add it to the variant-container"
|
||||
[shape-id]
|
||||
(ptk/reify ::add-new-variant
|
||||
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))
|
||||
shape (get objects shape-id)
|
||||
shape (if (ctc/is-variant-container? shape)
|
||||
(get objects (last (:shapes shape)))
|
||||
shape)
|
||||
component-id (:component-id shape)
|
||||
component (ctkl/get-component data component-id)
|
||||
|
||||
new-component-id (uuid/next)
|
||||
new-shape-id (uuid/next)
|
||||
|
||||
value (str clv/value-prefix
|
||||
(-> (clv/extract-properties-values data objects (:variant-id component))
|
||||
last
|
||||
:values
|
||||
count
|
||||
inc))
|
||||
|
||||
prop-num (dec (count (:variant-properties component)))
|
||||
|
||||
|
||||
[new-shape changes] (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/with-objects objects)
|
||||
(pcb/with-page-id page-id)
|
||||
(cll/generate-duplicate-component
|
||||
{:data data}
|
||||
component-id
|
||||
new-component-id
|
||||
true
|
||||
{:new-shape-id new-shape-id :apply-changes-local-library? true}))
|
||||
|
||||
changes (-> changes
|
||||
(clv/generate-update-property-value new-component-id prop-num value)
|
||||
(pcb/change-parent (:parent-id shape) [new-shape] 0))
|
||||
|
||||
undo-id (js/Symbol)]
|
||||
(rx/concat
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(dwu/commit-undo-transaction undo-id)
|
||||
(ptk/data-event :layout/update {:ids [(:parent-id shape)]})
|
||||
(dws/select-shape new-shape-id))
|
||||
(->> (rx/of (focus-property new-shape-id prop-num))
|
||||
(rx/delay 250)))))))
|
||||
|
||||
(defn transform-in-variant
|
||||
"Given the id of a main shape of a component, creates a variant structure for
|
||||
that component"
|
||||
|
@ -174,3 +245,55 @@
|
|||
(set-variant-id new-component-id variant-id)
|
||||
(add-new-property variant-id {:fill-values? true})
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn add-component-or-variant
|
||||
[]
|
||||
(ptk/reify ::add-component-or-variant
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [variants? (features/active-feature? state "variants/v1")
|
||||
objects (dsh/lookup-page-objects state)
|
||||
selected-ids (dsh/lookup-selected state)
|
||||
selected-shapes (map (d/getf objects) selected-ids)
|
||||
single? (= 1 (count selected-ids))
|
||||
first-shape (first selected-shapes)
|
||||
|
||||
transform-in-variant? (and variants?
|
||||
single?
|
||||
(not (ctc/is-variant? first-shape))
|
||||
(ctc/main-instance? first-shape))
|
||||
add-new-variant? (and variants?
|
||||
(every? ctc/is-variant? selected-shapes))
|
||||
undo-id (js/Symbol)]
|
||||
(cond
|
||||
transform-in-variant?
|
||||
(rx/of (transform-in-variant (:id first-shape)))
|
||||
|
||||
add-new-variant?
|
||||
(rx/concat
|
||||
(rx/of (dwu/start-undo-transaction undo-id))
|
||||
(rx/from (map add-new-variant selected-ids))
|
||||
(rx/of (dwu/commit-undo-transaction undo-id)))
|
||||
|
||||
:else
|
||||
(rx/of (dwl/add-component)))))))
|
||||
|
||||
(defn duplicate-or-add-variant
|
||||
[]
|
||||
(ptk/reify ::duplicate-or-add-variant
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [variants? (features/active-feature? state "variants/v1")
|
||||
objects (dsh/lookup-page-objects state)
|
||||
selected-ids (dsh/lookup-selected state)
|
||||
selected-shapes (map (d/getf objects) selected-ids)
|
||||
add-new-variant? (and variants?
|
||||
(every? ctc/is-variant? selected-shapes))
|
||||
undo-id (js/Symbol)]
|
||||
(if add-new-variant?
|
||||
(rx/concat
|
||||
(rx/of (dwu/start-undo-transaction undo-id))
|
||||
(rx/from (map add-new-variant selected-ids))
|
||||
(rx/of (dwu/commit-undo-transaction undo-id)))
|
||||
(rx/of (dws/duplicate-selected true)))))))
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.shortcuts :as sc]
|
||||
[app.main.data.workspace.variants :as dwv]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
|
@ -555,8 +556,10 @@
|
|||
can-make-component (every? true? (map #(ctn/valid-shape-for-component? objects %) shapes))
|
||||
heads (filter ctk/instance-head? shapes)
|
||||
components-menu-entries (cmm/generate-components-menu-entries heads true)
|
||||
variant-container? (and single? (ctk/is-variant-container? (first shapes)))
|
||||
do-add-component #(st/emit! (dwl/add-component))
|
||||
do-add-multiple-components #(st/emit! (dwl/add-multiple-components))]
|
||||
do-add-multiple-components #(st/emit! (dwl/add-multiple-components))
|
||||
do-add-variant #(st/emit! (dwv/add-new-variant (:id (first shapes))))]
|
||||
[:*
|
||||
(when can-make-component ;; We don't want to change the structure of component copies
|
||||
[:*
|
||||
|
@ -577,7 +580,13 @@
|
|||
:title (:title entry)
|
||||
:shortcut (when (contains? entry :shortcut)
|
||||
(sc/get-tooltip (:shortcut entry)))
|
||||
:on-click (:action entry)}])])]))
|
||||
:on-click (:action entry)}])])
|
||||
|
||||
(when variant-container?
|
||||
[:> menu-separator*]
|
||||
[:> menu-entry* {:title (tr "workspace.shape.menu.add-variant")
|
||||
:shortcut (sc/get-tooltip :create-component)
|
||||
:on-click do-add-variant}])]))
|
||||
|
||||
(mf/defc context-menu-delete*
|
||||
{::mf/props :obj
|
||||
|
|
|
@ -471,5 +471,6 @@
|
|||
:action do-update-component})
|
||||
(when (and variants? (not multi) main-instance?)
|
||||
{:title (tr "workspace.shape.menu.add-variant")
|
||||
:shortcut :create-component
|
||||
:action do-add-variant})]]
|
||||
(filter (complement nil?) menu-entries)))
|
||||
|
|
|
@ -288,11 +288,12 @@
|
|||
[:*
|
||||
(for [[pos prop] (map vector (range) properties)]
|
||||
|
||||
[:div {:key (str (:id shape) (:name prop)) :class (stl/css :variant-property-container)}
|
||||
[:div {:key (str (:id shape) pos) :class (stl/css :variant-property-container)}
|
||||
(if (ctk/main-instance? shape)
|
||||
[:*
|
||||
[:span {:class (stl/css :variant-property-name :variant-property-name-bg)} (:name prop)]
|
||||
[:> combobox* {:default-selected (if (str/empty? (:value prop)) "--" (:value prop))
|
||||
[:> combobox* {:id (str "variant-prop-" (:id shape) pos)
|
||||
:default-selected (if (str/empty? (:value prop)) "--" (:value prop))
|
||||
:options (clj->js (get-options (:name prop)))
|
||||
:on-change (partial change-property-value pos)}]]
|
||||
|
||||
|
@ -741,7 +742,7 @@
|
|||
|
||||
(mf/defc variant-menu*
|
||||
[{:keys [shapes]}]
|
||||
(let [multi (> (count shapes) 1)
|
||||
(let [multi? (> (count shapes) 1)
|
||||
|
||||
shape (first shapes)
|
||||
shape-name (:name shape)
|
||||
|
@ -757,6 +758,11 @@
|
|||
first-variant (get objects (first (:shapes shape)))
|
||||
variant-id (:variant-id first-variant)
|
||||
|
||||
dashes-to-end (mf/use-fn
|
||||
(fn [data]
|
||||
(let [dashes (if (some #(= % "--") data) ["--"] [])]
|
||||
(concat (remove #(= % "--") data) dashes))))
|
||||
|
||||
properties (mf/with-memo [data objects variant-id]
|
||||
(->> (dwv/find-related-components data objects variant-id)
|
||||
(mapcat :variant-properties)
|
||||
|
@ -764,17 +770,20 @@
|
|||
(map-indexed (fn [index [k v]]
|
||||
{:name k
|
||||
:pos index
|
||||
:values (distinct
|
||||
(map #(if (str/empty? (:value %)) "--" (:value %)) v))}))))
|
||||
:values (->> v
|
||||
(map #(if (str/empty? (:value %)) "--" (:value %)))
|
||||
distinct
|
||||
dashes-to-end)}))))
|
||||
|
||||
|
||||
menu-open* (mf/use-state false)
|
||||
menu-open? (deref menu-open*)
|
||||
|
||||
|
||||
menu-entries [{:title (tr "workspace.shape.menu.add-variant-property")
|
||||
:action #(st/emit! (dwv/add-new-property variant-id))}]
|
||||
|
||||
show-menu? (seq menu-entries)
|
||||
:action #(st/emit! (dwv/add-new-property variant-id))}
|
||||
{:title (tr "workspace.shape.menu.add-variant")
|
||||
:action #(st/emit! (dwv/add-new-variant (:id shape)))}]
|
||||
|
||||
on-menu-click
|
||||
(mf/use-fn
|
||||
|
@ -821,8 +830,8 @@
|
|||
|
||||
[:div {:class (stl/css :element-content)}
|
||||
[:div {:class (stl/css-case :component-wrapper true
|
||||
:with-actions show-menu?
|
||||
:without-actions (not show-menu?))}
|
||||
:with-actions (not multi?)
|
||||
:without-actions multi?)}
|
||||
[:button {:class (stl/css-case :component-name-wrapper true
|
||||
:with-main true
|
||||
:swappeable false)}
|
||||
|
@ -832,12 +841,12 @@
|
|||
[:div {:class (stl/css :name-wrapper)}
|
||||
[:div {:class (stl/css :component-name)}
|
||||
[:span {:class (stl/css :component-name-inside)}
|
||||
(if multi
|
||||
(if multi?
|
||||
(tr "settings.multiple")
|
||||
(cfh/last-path shape-name))]]]]
|
||||
|
||||
|
||||
(when show-menu?
|
||||
(when-not multi?
|
||||
[:div {:class (stl/css :component-actions)}
|
||||
[:button {:class (stl/css-case :menu-btn true
|
||||
:selected menu-open?)
|
||||
|
@ -848,11 +857,11 @@
|
|||
:on-close on-menu-close
|
||||
:menu-entries menu-entries
|
||||
:main-instance true}]])]
|
||||
(when-not multi
|
||||
(when-not multi?
|
||||
[:*
|
||||
(for [property properties]
|
||||
(for [[pos property] (map vector (range) properties)]
|
||||
(let [val (str/join ", " (:values property))]
|
||||
[:div {:key (str (:id shape) (:name property)) :class (stl/css :variant-property-row)}
|
||||
[:div {:key (str (:id shape) pos) :class (stl/css :variant-property-row)}
|
||||
[:> input-with-values* {:name (:name property)
|
||||
:values val
|
||||
:data-position (:pos property)
|
||||
|
|
|
@ -6218,7 +6218,7 @@ msgid "workspace.shape.menu.create-component"
|
|||
msgstr "Create component"
|
||||
|
||||
msgid "workspace.shape.menu.add-variant"
|
||||
msgstr "Add variant"
|
||||
msgstr "Create variant"
|
||||
|
||||
msgid "workspace.shape.menu.add-variant-property"
|
||||
msgstr "Add new property"
|
||||
|
|
|
@ -6232,7 +6232,7 @@ msgid "workspace.shape.menu.create-component"
|
|||
msgstr "Crear componente"
|
||||
|
||||
msgid "workspace.shape.menu.add-variant"
|
||||
msgstr "Añadir variante"
|
||||
msgstr "Crear variante"
|
||||
|
||||
msgid "workspace.shape.menu.add-variant-property"
|
||||
msgstr "Añadir nueva propiedad"
|
||||
|
|
Loading…
Add table
Reference in a new issue