mirror of
https://github.com/penpot/penpot.git
synced 2025-06-04 04:01:41 +02:00
✨ Add duplicate sets feature (#6240)
* ✨ Add duplicate sets feature * ✨ Add test to each module * 🎉 Fix comments * 🎉 Remove duplicate from groups * 🎉 Remove create theme from test * 🎉 Remove ' from names
This commit is contained in:
parent
f5c699ab7a
commit
eee5cf5fb4
10 changed files with 190 additions and 23 deletions
|
@ -427,11 +427,6 @@
|
||||||
(map #(str/concat base-name (suffix-fn %))
|
(map #(str/concat base-name (suffix-fn %))
|
||||||
(iterate inc 1))))
|
(iterate inc 1))))
|
||||||
|
|
||||||
(defn ^:private get-suffix
|
|
||||||
"Default suffix impelemtation"
|
|
||||||
[copy-count]
|
|
||||||
(str/concat " " copy-count))
|
|
||||||
|
|
||||||
(defn generate-unique-name
|
(defn generate-unique-name
|
||||||
"Generates a unique name by selecting the first available name from a generated sequence.
|
"Generates a unique name by selecting the first available name from a generated sequence.
|
||||||
The sequence consists of `base-name` and its variants, avoiding conflicts with `existing-names`.
|
The sequence consists of `base-name` and its variants, avoiding conflicts with `existing-names`.
|
||||||
|
@ -445,8 +440,7 @@
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
- A unique name not present in `existing-names`."
|
- A unique name not present in `existing-names`."
|
||||||
[base-name existing-names & {:keys [suffix-fn immediate-suffix?]
|
[base-name existing-names & {:keys [suffix-fn immediate-suffix? suffix]}]
|
||||||
:or {suffix-fn get-suffix}}]
|
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected a set of strings"
|
"expected a set of strings"
|
||||||
(coll? existing-names))
|
(coll? existing-names))
|
||||||
|
@ -454,9 +448,21 @@
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected a string for `basename`."
|
"expected a string for `basename`."
|
||||||
(string? base-name))
|
(string? base-name))
|
||||||
(let [existing-name-set (cond-> (set existing-names)
|
(let [suffix-fn (if suffix-fn
|
||||||
|
suffix-fn
|
||||||
|
(if suffix
|
||||||
|
(fn [copy-count]
|
||||||
|
(str/concat "-"
|
||||||
|
suffix
|
||||||
|
(when (> copy-count 1)
|
||||||
|
(str "-" copy-count))))
|
||||||
|
(fn [copy-count]
|
||||||
|
(str/concat " " copy-count))))
|
||||||
|
|
||||||
|
existing-name-set (cond-> (set existing-names)
|
||||||
immediate-suffix? (conj base-name))
|
immediate-suffix? (conj base-name))
|
||||||
names (name-seq base-name suffix-fn)]
|
names (name-seq base-name suffix-fn)]
|
||||||
|
|
||||||
(->> names
|
(->> names
|
||||||
(remove #(contains? existing-name-set %))
|
(remove #(contains? existing-name-set %))
|
||||||
first)))
|
first)))
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#?(:clj [app.common.fressian :as fres])
|
#?(:clj [app.common.fressian :as fres])
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.time :as dt]
|
[app.common.time :as dt]
|
||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
|
@ -321,6 +322,7 @@
|
||||||
(assoc-in [:ids temp-id] token))))
|
(assoc-in [:ids temp-id] token))))
|
||||||
{:tokens-tree {} :ids {}} tokens))
|
{:tokens-tree {} :ids {}} tokens))
|
||||||
|
|
||||||
|
|
||||||
(defprotocol ITokenSet
|
(defprotocol ITokenSet
|
||||||
(update-name [_ set-name] "change a token set name while keeping the path")
|
(update-name [_ set-name] "change a token set name while keeping the path")
|
||||||
(add-token [_ token] "add a token at the end of the list")
|
(add-token [_ token] "add a token at the end of the list")
|
||||||
|
@ -920,6 +922,7 @@ Will return a value that matches this schema:
|
||||||
this)))
|
this)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(delete-set [_ set-name]
|
(delete-set [_ set-name]
|
||||||
(let [prefixed-path (set-name->prefixed-full-path set-name)]
|
(let [prefixed-path (set-name->prefixed-full-path set-name)]
|
||||||
(TokensLib. (d/dissoc-in sets prefixed-path)
|
(TokensLib. (d/dissoc-in sets prefixed-path)
|
||||||
|
@ -1468,6 +1471,14 @@ Will return a value that matches this schema:
|
||||||
{:encode/json encode-dtcg
|
{:encode/json encode-dtcg
|
||||||
:decode/json decode-dtcg}})
|
:decode/json decode-dtcg}})
|
||||||
|
|
||||||
|
(defn duplicate-set [set-name lib & {:keys [suffix]}]
|
||||||
|
(let [sets (get-sets lib)
|
||||||
|
unames (map :name sets)
|
||||||
|
copy-name (cfh/generate-unique-name set-name unames :suffix suffix)]
|
||||||
|
(some-> (get-set lib set-name)
|
||||||
|
(assoc :name copy-name)
|
||||||
|
(assoc :modified-at (dt/now)))))
|
||||||
|
|
||||||
(sm/register! type:tokens-lib)
|
(sm/register! type:tokens-lib)
|
||||||
|
|
||||||
;; === Serialization handlers for RPC API (transit) and database (fressian)
|
;; === Serialization handlers for RPC API (transit) and database (fressian)
|
||||||
|
|
|
@ -120,7 +120,6 @@
|
||||||
(t/is (= ["Foo/Foo" "Foo/Baz" "Foo/Bar"] (move ["Foo"] ["Foo" "Foo"] ["Foo" "Baz"] false)))
|
(t/is (= ["Foo/Foo" "Foo/Baz" "Foo/Bar"] (move ["Foo"] ["Foo" "Foo"] ["Foo" "Baz"] false)))
|
||||||
(t/is (= ["Foo/Baz" "Foo/Bar" "Foo/Foo"] (move ["Foo"] ["Foo" "Foo"] nil false))))))
|
(t/is (= ["Foo/Baz" "Foo/Bar" "Foo/Foo"] (move ["Foo"] ["Foo" "Foo"] nil false))))))
|
||||||
|
|
||||||
|
|
||||||
(t/deftest move-token-set-nested-2
|
(t/deftest move-token-set-nested-2
|
||||||
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
(ctob/add-set (ctob/make-token-set :name "a/b"))
|
(ctob/add-set (ctob/make-token-set :name "a/b"))
|
||||||
|
@ -220,7 +219,6 @@
|
||||||
(t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-theme"
|
(t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-theme"
|
||||||
(ctob/make-token-theme params)))))
|
(ctob/make-token-theme params)))))
|
||||||
|
|
||||||
|
|
||||||
(t/deftest make-tokens-lib
|
(t/deftest make-tokens-lib
|
||||||
(let [tokens-lib (ctob/make-tokens-lib)]
|
(let [tokens-lib (ctob/make-tokens-lib)]
|
||||||
(t/is (= (ctob/set-count tokens-lib) 0))))
|
(t/is (= (ctob/set-count tokens-lib) 0))))
|
||||||
|
@ -315,6 +313,58 @@
|
||||||
(t/is (= (:sets token-theme') #{}))
|
(t/is (= (:sets token-theme') #{}))
|
||||||
(t/is (nil? token-set'))))
|
(t/is (nil? token-set'))))
|
||||||
|
|
||||||
|
(t/deftest duplicate-token-set
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"
|
||||||
|
:tokens {"test-token"
|
||||||
|
(ctob/make-token :name "test-token"
|
||||||
|
:type :boolean
|
||||||
|
:value true)})))
|
||||||
|
token-set-copy (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"})
|
||||||
|
token (get-in token-set-copy [:tokens "test-token"])]
|
||||||
|
|
||||||
|
(t/is (some? token-set-copy))
|
||||||
|
(t/is (= (:name token-set-copy) "test-token-set-copy"))
|
||||||
|
(t/is (= (count (:tokens token-set-copy)) 1))
|
||||||
|
(t/is (= (:name token) "test-token"))))
|
||||||
|
|
||||||
|
(t/deftest duplicate-token-set-twice
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"
|
||||||
|
:tokens {"test-token"
|
||||||
|
(ctob/make-token :name "test-token"
|
||||||
|
:type :boolean
|
||||||
|
:value true)})))
|
||||||
|
|
||||||
|
tokens-lib (ctob/add-set tokens-lib (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"}))
|
||||||
|
|
||||||
|
token-set-copy (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"})
|
||||||
|
token (get-in token-set-copy [:tokens "test-token"])]
|
||||||
|
|
||||||
|
(t/is (some? token-set-copy))
|
||||||
|
(t/is (= (:name token-set-copy) "test-token-set-copy-2"))
|
||||||
|
(t/is (= (count (:tokens token-set-copy)) 1))
|
||||||
|
(t/is (= (:name token) "test-token"))))
|
||||||
|
|
||||||
|
(t/deftest duplicate-empty-token-set
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
|
||||||
|
|
||||||
|
token-set-copy (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"})
|
||||||
|
tokens (get token-set-copy :tokens)]
|
||||||
|
|
||||||
|
(t/is (some? token-set-copy))
|
||||||
|
(t/is (= (:name token-set-copy) "test-token-set-copy"))
|
||||||
|
(t/is (= (count (:tokens token-set-copy)) 0))
|
||||||
|
(t/is (= (count tokens) 0))))
|
||||||
|
|
||||||
|
(t/deftest duplicate-not-existing-token-set
|
||||||
|
(let [tokens-lib (ctob/make-tokens-lib)
|
||||||
|
|
||||||
|
token-set-copy (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"})]
|
||||||
|
|
||||||
|
(t/is (nil? token-set-copy))))
|
||||||
|
|
||||||
(t/deftest active-themes-set-names
|
(t/deftest active-themes-set-names
|
||||||
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
|
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
|
||||||
|
@ -918,7 +968,6 @@
|
||||||
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
|
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
|
||||||
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
|
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
|
||||||
|
|
||||||
|
|
||||||
(t/deftest update-token-in-sets-rename
|
(t/deftest update-token-in-sets-rename
|
||||||
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
[app.main.ui.workspace.tokens.update :as wtu]
|
[app.main.ui.workspace.tokens.update :as wtu]
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[cuerdas.core :as str]
|
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(declare set-selected-token-set-name)
|
(declare set-selected-token-set-name)
|
||||||
|
@ -192,6 +191,23 @@
|
||||||
(rx/of (set-selected-token-set-name name)
|
(rx/of (set-selected-token-set-name name)
|
||||||
(dch/commit-changes changes))))))))
|
(dch/commit-changes changes))))))))
|
||||||
|
|
||||||
|
(defn duplicate-token-set
|
||||||
|
[id is-group]
|
||||||
|
(ptk/reify ::duplicate-token-set
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [it state _]
|
||||||
|
(let [data (dsh/lookup-file-data state)
|
||||||
|
name (ctob/normalize-set-name id)
|
||||||
|
tokens-lib (get data :tokens-lib)
|
||||||
|
suffix (tr "workspace.token.duplicate-suffix")]
|
||||||
|
|
||||||
|
(when-let [set (ctob/duplicate-set name tokens-lib {:suffix suffix})]
|
||||||
|
(let [changes (-> (pcb/empty-changes it)
|
||||||
|
(pcb/with-library-data data)
|
||||||
|
(pcb/set-token-set (:name set) is-group set))]
|
||||||
|
(rx/of (set-selected-token-set-name name)
|
||||||
|
(dch/commit-changes changes))))))))
|
||||||
|
|
||||||
(defn toggle-token-set
|
(defn toggle-token-set
|
||||||
[name]
|
[name]
|
||||||
(assert (string? name) "expected a string for `name`")
|
(assert (string? name) "expected a string for `name`")
|
||||||
|
@ -385,17 +401,8 @@
|
||||||
(when-let [token (ctob/get-token token-set token-name)]
|
(when-let [token (ctob/get-token token-set token-name)]
|
||||||
(let [tokens (ctob/get-tokens token-set)
|
(let [tokens (ctob/get-tokens token-set)
|
||||||
unames (map :name tokens)
|
unames (map :name tokens)
|
||||||
|
suffix (tr "workspace.token.duplicate-suffix")
|
||||||
suffix-fn
|
copy-name (cfh/generate-unique-name token-name unames :suffix suffix)]
|
||||||
(fn [copy-count]
|
|
||||||
(let [suffix (tr "workspace.token.duplicate-suffix")]
|
|
||||||
(str/concat "-"
|
|
||||||
suffix
|
|
||||||
(when (> copy-count 1)
|
|
||||||
(str "-" copy-count)))))
|
|
||||||
|
|
||||||
copy-name
|
|
||||||
(cfh/generate-unique-name token-name unames :suffix-fn suffix-fn)]
|
|
||||||
|
|
||||||
(rx/of (create-token (assoc token :name copy-name)))))))))
|
(rx/of (create-token (assoc token :name copy-name)))))))))
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,12 @@
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dt/start-token-set-edition edition-id))))
|
(st/emit! (dt/start-token-set-edition edition-id))))
|
||||||
|
|
||||||
|
on-duplicate
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps is-group id)
|
||||||
|
(fn []
|
||||||
|
(st/emit! (dt/duplicate-token-set id is-group))))
|
||||||
|
|
||||||
on-delete
|
on-delete
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps is-group path)
|
(mf/deps is-group path)
|
||||||
|
@ -53,6 +59,8 @@
|
||||||
(when is-group
|
(when is-group
|
||||||
[:> menu-entry* {:title (tr "workspace.token.add-set-to-group") :on-click create-set-at-path}])
|
[:> menu-entry* {:title (tr "workspace.token.add-set-to-group") :on-click create-set-at-path}])
|
||||||
[:> menu-entry* {:title (tr "labels.rename") :on-click on-edit}]
|
[:> menu-entry* {:title (tr "labels.rename") :on-click on-edit}]
|
||||||
|
(when-not is-group
|
||||||
|
[:> menu-entry* {:title (tr "labels.duplicate") :on-click on-duplicate}])
|
||||||
[:> menu-entry* {:title (tr "labels.delete") :on-click on-delete}]]))
|
[:> menu-entry* {:title (tr "labels.delete") :on-click on-delete}]]))
|
||||||
|
|
||||||
(mf/defc token-set-context-menu*
|
(mf/defc token-set-context-menu*
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[frontend-tests.logic.groups-test]
|
[frontend-tests.logic.groups-test]
|
||||||
[frontend-tests.plugins.context-shapes-test]
|
[frontend-tests.plugins.context-shapes-test]
|
||||||
[frontend-tests.tokens.logic.token-actions-test]
|
[frontend-tests.tokens.logic.token-actions-test]
|
||||||
|
[frontend-tests.tokens.logic.token-data-test]
|
||||||
[frontend-tests.tokens.style-dictionary-test]
|
[frontend-tests.tokens.style-dictionary-test]
|
||||||
[frontend-tests.tokens.token-form-test]
|
[frontend-tests.tokens.token-form-test]
|
||||||
[frontend-tests.tokens.token-test]
|
[frontend-tests.tokens.token-test]
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
'frontend-tests.util-simple-math-test
|
'frontend-tests.util-simple-math-test
|
||||||
'frontend-tests.basic-shapes-test
|
'frontend-tests.basic-shapes-test
|
||||||
'frontend-tests.tokens.logic.token-actions-test
|
'frontend-tests.tokens.logic.token-actions-test
|
||||||
|
'frontend-tests.tokens.logic.token-data-test
|
||||||
'frontend-tests.tokens.style-dictionary-test
|
'frontend-tests.tokens.style-dictionary-test
|
||||||
'frontend-tests.tokens.token-test
|
'frontend-tests.tokens.token-test
|
||||||
'frontend-tests.tokens.token-form-test))
|
'frontend-tests.tokens.token-form-test))
|
||||||
|
|
|
@ -20,3 +20,6 @@
|
||||||
:objects shape-id
|
:objects shape-id
|
||||||
:applied-tokens]
|
:applied-tokens]
|
||||||
merge applied-attributes)))
|
merge applied-attributes)))
|
||||||
|
|
||||||
|
(defn get-tokens-lib [file]
|
||||||
|
(get-in file [:data :tokens-lib]))
|
|
@ -0,0 +1,61 @@
|
||||||
|
(ns frontend-tests.tokens.logic.token-data-test
|
||||||
|
(:require
|
||||||
|
[app.common.test-helpers.files :as cthf]
|
||||||
|
[app.common.types.tokens-lib :as ctob]
|
||||||
|
[app.main.data.tokens :as dt]
|
||||||
|
[cljs.test :as t :include-macros true]
|
||||||
|
[frontend-tests.helpers.pages :as thp]
|
||||||
|
[frontend-tests.helpers.state :as ths]
|
||||||
|
[frontend-tests.tokens.helpers.state :as tohs]
|
||||||
|
[frontend-tests.tokens.helpers.tokens :as toht]))
|
||||||
|
|
||||||
|
(t/use-fixtures :each
|
||||||
|
{:before thp/reset-idmap!})
|
||||||
|
|
||||||
|
(defn setup-file []
|
||||||
|
(cthf/sample-file :file-1 :page-label :page-1))
|
||||||
|
|
||||||
|
(defn setup-file-with-token-lib
|
||||||
|
[]
|
||||||
|
(-> (setup-file)
|
||||||
|
(assoc-in [:data :tokens-lib]
|
||||||
|
(-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "Set A"))))))
|
||||||
|
|
||||||
|
(t/deftest duplicate-set
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [file (setup-file-with-token-lib)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
events [(dt/duplicate-token-set "Set A" false)]]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store done events
|
||||||
|
(fn [new-state]
|
||||||
|
(let [file' (ths/get-file-from-state new-state)
|
||||||
|
token-lib (toht/get-tokens-lib file')
|
||||||
|
sets (ctob/get-sets token-lib)
|
||||||
|
set (ctob/get-set token-lib "Set A")]
|
||||||
|
|
||||||
|
(t/testing "Token lib contains two sets"
|
||||||
|
(t/is (= (count sets) 2))
|
||||||
|
(t/is (some? set)))))))))
|
||||||
|
|
||||||
|
(t/deftest duplicate-non-exist-set
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [file (setup-file-with-token-lib)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
events [(dt/duplicate-token-set "Set B" false)]]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store done events
|
||||||
|
(fn [new-state]
|
||||||
|
(let [file' (ths/get-file-from-state new-state)
|
||||||
|
token-lib (toht/get-tokens-lib file')
|
||||||
|
sets (ctob/get-sets token-lib)
|
||||||
|
set (ctob/get-set token-lib "Set B")]
|
||||||
|
|
||||||
|
(t/testing "Token lib contains one set"
|
||||||
|
(t/is (= (count sets) 1))
|
||||||
|
(t/is (nil? set)))))))))
|
|
@ -1367,6 +1367,10 @@ msgstr "Owner can't leave team, you must reassign the owner role."
|
||||||
msgid "errors.token-set-already-exists"
|
msgid "errors.token-set-already-exists"
|
||||||
msgstr "A set with the same name already exists"
|
msgstr "A set with the same name already exists"
|
||||||
|
|
||||||
|
#: src/app/main/data/tokens.cljs:
|
||||||
|
msgid "errors.token-set-doesnt-exists"
|
||||||
|
msgstr "Can't duplicate an unkown set"
|
||||||
|
|
||||||
#: src/app/main/data/tokens.cljs:245
|
#: src/app/main/data/tokens.cljs:245
|
||||||
msgid "errors.token-set-exists-on-drop"
|
msgid "errors.token-set-exists-on-drop"
|
||||||
msgstr "Cannot complete drop, a set with same name already exists at path."
|
msgstr "Cannot complete drop, a set with same name already exists at path."
|
||||||
|
@ -1896,6 +1900,10 @@ msgstr "Dashboard"
|
||||||
msgid "labels.delete"
|
msgid "labels.delete"
|
||||||
msgstr "Delete"
|
msgstr "Delete"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/sets_context_menu.cljs
|
||||||
|
msgid "labels.duplicate"
|
||||||
|
msgstr "Duplicate"
|
||||||
|
|
||||||
#: src/app/main/ui/comments.cljs:976
|
#: src/app/main/ui/comments.cljs:976
|
||||||
msgid "labels.delete-comment"
|
msgid "labels.delete-comment"
|
||||||
msgstr "Delete comment"
|
msgstr "Delete comment"
|
||||||
|
|
|
@ -1385,6 +1385,10 @@ msgstr ""
|
||||||
msgid "errors.token-set-already-exists"
|
msgid "errors.token-set-already-exists"
|
||||||
msgstr "Ya existe un set con el mismo nombre"
|
msgstr "Ya existe un set con el mismo nombre"
|
||||||
|
|
||||||
|
#: src/app/main/data/tokens.cljs:
|
||||||
|
msgid "errors.token-set-doesnt-exists"
|
||||||
|
msgstr "No se puede duplicar un set que no existe."
|
||||||
|
|
||||||
#: src/app/main/data/tokens.cljs:245
|
#: src/app/main/data/tokens.cljs:245
|
||||||
msgid "errors.token-set-exists-on-drop"
|
msgid "errors.token-set-exists-on-drop"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -1919,6 +1923,10 @@ msgstr "Panel"
|
||||||
msgid "labels.delete"
|
msgid "labels.delete"
|
||||||
msgstr "Borrar"
|
msgstr "Borrar"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/sets_context_menu.cljs
|
||||||
|
msgid "labels.duplicate"
|
||||||
|
msgstr "Duplicar"
|
||||||
|
|
||||||
#: src/app/main/ui/comments.cljs:976
|
#: src/app/main/ui/comments.cljs:976
|
||||||
msgid "labels.delete-comment"
|
msgid "labels.delete-comment"
|
||||||
msgstr "Eliminar comentario"
|
msgstr "Eliminar comentario"
|
||||||
|
@ -6713,6 +6721,10 @@ msgstr "Borrar theme"
|
||||||
msgid "workspace.token.duplicate"
|
msgid "workspace.token.duplicate"
|
||||||
msgstr "Duplicar token"
|
msgstr "Duplicar token"
|
||||||
|
|
||||||
|
#: src/app/main/data/tokens.cljs:386
|
||||||
|
msgid "workspace.token.duplicate-suffix"
|
||||||
|
msgstr "copiar"
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/tokens/context_menu.cljs:262
|
#: src/app/main/ui/workspace/tokens/context_menu.cljs:262
|
||||||
msgid "workspace.token.edit"
|
msgid "workspace.token.edit"
|
||||||
msgstr "Editar token"
|
msgstr "Editar token"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue