diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index 73f48f5661..f055d76ec7 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -405,31 +405,24 @@ [:type [:= :set-tokens-lib]] [:tokens-lib ::sm/any]]] - [:set-token-set - [:map {:title "SetTokenSetChange"} - [:type [:= :set-token-set]] - [:set-name :string] - [:group? :boolean] + [:set-token-set + [:map {:title "SetTokenSetChange"} + [:type [:= :set-token-set]] + [:set-id ::sm/uuid] + [:group? :boolean] + [:token-set [:maybe ctob/schema:token-set-attrs]]]] - ;; FIXME: we should not pass private types as part of changes - ;; protocol, the changes protocol should reflect a - ;; method/protocol for perform surgical operations on file data, - ;; this has nothing todo with internal types of a file data - ;; structure. - [:token-set {:gen/gen (sg/generator ctob/schema:token-set)} - [:maybe [:fn ctob/token-set?]]]]] + [:set-token + [:map {:title "SetTokenChange"} + [:type [:= :set-token]] + [:set-name :string] + [:token-id ::sm/uuid] + [:token [:maybe ctob/schema:token-attrs]]]] - [:set-token - [:map {:title "SetTokenChange"} - [:type [:= :set-token]] - [:set-name :string] - [:token-id ::sm/uuid] - [:token [:maybe ctob/schema:token-attrs]]]] - - [:set-base-font-size - [:map {:title "ModBaseFontSize"} - [:type [:= :set-base-font-size]] - [:base-font-size :string]]]]) + [:set-base-font-size + [:map {:title "ModBaseFontSize"} + [:type [:= :set-base-font-size]] + [:base-font-size :string]]]]) (def schema:changes [:sequential {:gen/max 5 :gen/min 1} schema:change]) @@ -988,12 +981,13 @@ [data {:keys [set-name token-id token]}] (update data :tokens-lib (fn [lib] - (let [lib' (ctob/ensure-tokens-lib lib)] + (let [lib' (ctob/ensure-tokens-lib lib) + set (ctob/set-by-name lib' set-name)] ;; FIXME: remove this when set-token uses set-id (cond (not token) (ctob/delete-token-from-set lib' set-name token-id) - (not (ctob/get-token-in-set lib' set-name token-id)) + (not (ctob/get-token-in-set lib' (ctob/get-id set) token-id)) (ctob/add-token-in-set lib' set-name (ctob/make-token token)) :else @@ -1001,21 +995,22 @@ (ctob/make-token (merge prev-token token))))))))) (defmethod process-change :set-token-set - [data {:keys [set-name group? token-set]}] + [data {:keys [set-id group? token-set]}] (update data :tokens-lib (fn [lib] - (let [lib' (ctob/ensure-tokens-lib lib)] + (let [lib' (ctob/ensure-tokens-lib lib) + set (ctob/set-by-id lib' set-id)] ;; FIXME: remove this when set-token-set uses set-id (cond (not token-set) (if group? - (ctob/delete-set-group lib' set-name) - (ctob/delete-set lib' set-name)) + (ctob/delete-set-group lib' (ctob/get-name set)) ;; FIXME: move to a separate change + (ctob/delete-set lib' (ctob/get-name set))) - (not (ctob/get-set lib' set-name)) - (ctob/add-set lib' token-set) + (not (ctob/set-by-id lib' set-id)) + (ctob/add-set lib' (ctob/make-token-set token-set)) :else - (ctob/update-set lib' set-name (fn [_] token-set))))))) + (ctob/update-set lib' (ctob/get-name set) (fn [_] (ctob/make-token-set token-set)))))))) (defmethod process-change :set-token-theme [data {:keys [group theme-name theme]}] diff --git a/common/src/app/common/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index 473bcf5bef..62f6823ff8 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -21,7 +21,8 @@ [app.common.types.path :as path] [app.common.types.shape.layout :as ctl] [app.common.types.tokens-lib :as ctob] - [app.common.uuid :as uuid])) + [app.common.uuid :as uuid] + [clojure.datafy :refer [datafy]])) ;; Auxiliary functions to help create a set of changes (undo + redo) ;; TODO: this is a duplicate schema @@ -884,7 +885,7 @@ (assert-library! changes) (let [library-data (::library-data (meta changes)) prev-token (some-> (get library-data :tokens-lib) - (ctob/get-set set-name) + (ctob/set-by-name set-name) (ctob/get-token token-id))] (-> changes (update :redo-changes conj {:type :set-token @@ -908,48 +909,37 @@ (apply-changes-local)))) (defn rename-token-set - [changes name new-name] - + [changes id new-name] (assert-library! changes) (let [library-data (::library-data (meta changes)) prev-token-set (some-> (get library-data :tokens-lib) - (ctob/get-set name))] + (ctob/get-set id))] (-> changes (update :redo-changes conj {:type :set-token-set - :set-name name - :token-set (ctob/rename prev-token-set new-name) + :set-id id + :token-set (datafy (ctob/rename prev-token-set new-name)) :group? false}) (update :undo-changes conj {:type :set-token-set - :set-name new-name - :token-set prev-token-set + :set-id id + :token-set (datafy prev-token-set) :group? false}) (apply-changes-local)))) (defn set-token-set - [changes set-name group? token-set] + [changes set-id group? token-set] (assert-library! changes) (let [library-data (::library-data (meta changes)) prev-token-set (some-> (get library-data :tokens-lib) - (ctob/get-set set-name))] + (ctob/get-set set-id))] (-> changes (update :redo-changes conj {:type :set-token-set - :set-name set-name - :token-set token-set + :set-id set-id + :token-set (datafy token-set) + :group? group?}) + (update :undo-changes conj {:type :set-token-set + :set-id set-id + :token-set (datafy prev-token-set) :group? group?}) - (update :undo-changes conj (if prev-token-set - {:type :set-token-set - :set-name (if token-set - ;; Undo of edit - (ctob/get-name token-set) - ;; Undo of delete - set-name) - :token-set prev-token-set - :group? group?} - ;; Undo of create - {:type :set-token-set - :set-name set-name - :token-set nil - :group? group?})) (apply-changes-local)))) (defn add-component diff --git a/common/src/app/common/test_helpers/tokens.cljc b/common/src/app/common/test_helpers/tokens.cljc index e2c6cee4d1..432e56cf58 100644 --- a/common/src/app/common/test_helpers/tokens.cljc +++ b/common/src/app/common/test_helpers/tokens.cljc @@ -28,11 +28,11 @@ (ctf/update-file-data file #(update % :tokens-lib f))) (defn get-token - [file set-name token-id] + [file set-id token-id] (let [tokens-lib (:tokens-lib (:data file))] (when tokens-lib (-> tokens-lib - (ctob/get-set set-name) + (ctob/get-set set-id) (ctob/get-token token-id))))) (defn token-data-eq? diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index ed299e0ce6..e1f6a02e7d 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -63,13 +63,27 @@ ;; === Common (defprotocol INamedItem - "Protocol for items that have a name, a description and a modified date." + "Protocol for items that have an id, a name, a description and a modified date." + (get-id [_] "Get the id of the item.") (get-name [_] "Get the name of the item.") (get-description [_] "Get the description of the item.") (get-modified-at [_] "Get the description of the item.") - (rename [_ new-name] "Set the name of the item.") + (rename [_ new-name] "Change the name of the item.") + (reid [_ new-id] "Change the id of the item.") (set-description [_ new-description] "Set the description of the item.")) +;; Provide an implementation for nil type, so it works when functions are +;; called with nil as argument. +(extend-type nil + INamedItem + (get-id [_] nil) + (get-name [_] nil) + (get-description [_] nil) + (get-modified-at [_] nil) + (rename [_ _] nil) + (reid [_ _] nil) + (set-description [_ _] nil)) + ;; === Token (defrecord Token [id name type value description modified-at] @@ -77,6 +91,9 @@ (datafy [this] (into {} this)) INamedItem + (get-id [_] + id) + (get-name [_] name) @@ -89,6 +106,9 @@ (rename [this new-name] (assoc this :name new-name)) + (reid [this new-id] + (assoc this :id new-id)) + (set-description [this new-description] (assoc this :description new-description))) @@ -233,6 +253,9 @@ (-write [this writter options] (json/-write (datafy this) writter options))]) INamedItem + (get-id [_] + id) + (get-name [_] name) @@ -249,6 +272,13 @@ (ct/now) tokens)) + (reid [_ new-id] + (TokenSet. new-id + name + description + (ct/now) + tokens)) + (set-description [_ new-description] (TokenSet. id name @@ -272,8 +302,8 @@ (ct/now) (assoc tokens (:name token) token)))) - (update-token [this id f] - (if-let [token (token-by-id this id)] + (update-token [this token-id f] + (if-let [token (token-by-id this token-id)] (let [token' (-> (make-token (f token)) (assoc :modified-at (ct/now)))] (TokenSet. id @@ -287,15 +317,15 @@ (dissoc (:name token)))))) this)) - (delete-token [this id] - (let [token (token-by-id this id)] + (delete-token [this token-id] + (let [token (token-by-id this token-id)] (TokenSet. id name description (ct/now) (dissoc tokens (:name token))))) - (get-token [this id] + (get-token [this id] ;; TODO: this is redundant, may be removed (token-by-id this id)) (get-tokens [_] @@ -527,6 +557,8 @@ Prefixed set path or ppath: a path wit added prefixes [\"G-some-group\", \"G-some-subgroup\"]. Prefixed set full path or pfpath: a full path wit prefixes [\"G-some-group\", \"G-some-subgroup\", \"S-some-set\"]. Prefixed set final name or pfname: a final name with prefix \"S-some-set\"." + (set-by-id [_ id] "get a set by its id") + (set-by-name [_ name] "get a set by its name") (add-set [_ token-set] "add a set to the library, at the end") (update-set [_ set-name f] "modify a set in the library") (delete-set-path [_ set-path] "delete a set in the library") @@ -598,6 +630,9 @@ (datafy [this] (into {} this)) INamedItem + (get-id [_] + id) + (get-name [_] name) @@ -610,6 +645,9 @@ (rename [this new-name] (assoc this :name new-name)) + (reid [this new-id] + (assoc this :id new-id)) + (set-description [this new-description] (assoc this :description new-description)) @@ -910,11 +948,11 @@ (empty-lib? [_] "True if the lib does not contain any token, set or theme") (set-path-exists? [_ path] "if a set at `path` exists") (set-group-path-exists? [_ path] "if a set group at `path` exists") - (add-token-in-set [_ set-name token] "add token to a set") - (get-token-in-set [_ set-name token-id] "get token in a set") - (get-token-by-name [_ set-name token-name] "get token in a set searching by token name") - (update-token-in-set [_ set-name token-id f] "update a token in a set") - (delete-token-from-set [_ set-name token-id] "delete a token from a set") + (add-token-in-set [_ set-id token] "add token to a set") + (get-token-in-set [_ set-id token-id] "get token in a set") + (get-token-by-name [_ set-id token-name] "get token in a set searching by token name") + (update-token-in-set [_ set-id token-id f] "update a token in a set") + (delete-token-from-set [_ set-id token-id] "delete a token from a set") (toggle-set-in-theme [_ group-name theme-name set-name] "toggle a set used / not used in a theme") (get-active-themes-set-names [_] "set of set names that are active in the the active themes") (sets-at-path-all-active? [_ group-path] "compute active state for child sets at `group-path`. @@ -942,6 +980,14 @@ Will return a value that matches this schema: (-write [this writter options] (json/-write (export-dtcg-json this) writter options))]) ITokenSets + (set-by-id [this id] + (some #(when (= (get-id %) id) %) ;; TODO: this will be made in an efficient way when + (get-sets this))) ;; we refactor the tokens lib internal structure + + (set-by-name [_ name] + (let [path (set-name->prefixed-full-path name)] + (get-in sets path))) + (add-set [_ token-set] (assert (token-set? token-set) "expected valid token-set") (let [path (get-set-prefixed-path token-set)] @@ -1140,9 +1186,8 @@ Will return a value that matches this schema: (set-count [this] (count (get-sets this))) - (get-set [_ set-name] - (let [path (set-name->prefixed-full-path set-name)] - (get-in sets path))) + (get-set [this set-id] ;; TODO: this is redundant and should be removed + (set-by-id this set-id)) ITokenThemes (add-theme [_ token-theme] @@ -1256,14 +1301,14 @@ Will return a value that matches this schema: (add-token-in-set [this set-name token] (update-set this set-name #(add-token % token))) - (get-token-in-set [this set-name token-id] + (get-token-in-set [this set-id token-id] (some-> this - (get-set set-name) + (get-set set-id) (get-token token-id))) - (get-token-by-name [this set-name token-name] + (get-token-by-name [this set-id token-name] (some-> this - (get-set set-name) + (get-set set-id) (token-by-name token-name))) (update-token-in-set [this set-name token-id f] @@ -1304,7 +1349,7 @@ Will return a value that matches this schema: all-set-names (get-ordered-set-names this) active-set-names (filter theme-set-names all-set-names) tokens (reduce (fn [tokens set-name] - (let [set (get-set this set-name)] + (let [set (set-by-name this set-name)] (merge tokens (get-tokens-map set)))) (d/ordered-map) active-set-names)] @@ -1391,12 +1436,18 @@ Will return a value that matches this schema: {:encode/json #(export-dtcg-json %) :decode/json #(parse-multi-set-dtcg-json %)}})) -(defn duplicate-set [set-name lib & {:keys [suffix]}] - (let [sets (get-sets lib) - unames (map get-name sets) - copy-name (cfh/generate-unique-name set-name unames :suffix suffix)] - (some-> (get-set lib set-name) - (rename copy-name)))) +(defn duplicate-set + "Make a new set with a unique name, copying data from the given set in the lib." + [set-id lib & {:keys [suffix]}] + (let [sets (get-sets lib) + unames (map get-name sets) + set (get-set lib set-id) + copy-name (when set + (cfh/generate-unique-name (get-name set) unames :suffix suffix))] + (when set + (-> set + (rename copy-name) + (reid (uuid/next)))))) ;; === Import / Export from JSON format diff --git a/common/test/common_tests/logic/token_apply_test.cljc b/common/test/common_tests/logic/token_apply_test.cljc index fd6f6d7f86..369e5b49f5 100644 --- a/common/test/common_tests/logic/token_apply_test.cljc +++ b/common/test/common_tests/logic/token_apply_test.cljc @@ -27,7 +27,8 @@ (-> (thf/sample-file :file1) (tht/add-tokens-lib) (tht/update-tokens-lib #(-> % - (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-theme (ctob/make-token-theme :name "test-theme" :sets #{"test-token-set"})) (ctob/set-active-themes #{"/test-theme"}) @@ -131,17 +132,17 @@ frame1 (ths/get-shape file :frame1) text1 (ths/get-shape file :text1) circle1 (ths/get-shape file :circle1) - token-radius (tht/get-token file "test-token-set" (thi/id :token-radius)) - token-rotation (tht/get-token file "test-token-set" (thi/id :token-rotation)) - token-opacity (tht/get-token file "test-token-set" (thi/id :token-opacity)) - token-stroke-width (tht/get-token file "test-token-set" (thi/id :token-stroke-width)) - token-color (tht/get-token file "test-token-set" (thi/id :token-color)) - token-dimensions (tht/get-token file "test-token-set" (thi/id :token-dimensions)) - token-font-size (tht/get-token file "test-token-set" (thi/id :token-font-size)) - token-letter-spacing (tht/get-token file "test-token-set" (thi/id :token-letter-spacing)) - token-font-family (tht/get-token file "test-token-set" (thi/id :token-font-family)) - token-sizing (tht/get-token file "test-token-set" (thi/id :token-sizing)) - token-spacing (tht/get-token file "test-token-set" (thi/id :token-spacing)) + token-radius (tht/get-token file (thi/id :test-token-set) (thi/id :token-radius)) + token-rotation (tht/get-token file (thi/id :test-token-set) (thi/id :token-rotation)) + token-opacity (tht/get-token file (thi/id :test-token-set) (thi/id :token-opacity)) + token-stroke-width (tht/get-token file (thi/id :test-token-set) (thi/id :token-stroke-width)) + token-color (tht/get-token file (thi/id :test-token-set) (thi/id :token-color)) + token-dimensions (tht/get-token file (thi/id :test-token-set) (thi/id :token-dimensions)) + token-font-size (tht/get-token file (thi/id :test-token-set) (thi/id :token-font-size)) + token-letter-spacing (tht/get-token file (thi/id :test-token-set) (thi/id :token-letter-spacing)) + token-font-family (tht/get-token file (thi/id :test-token-set) (thi/id :token-font-family)) + token-sizing (tht/get-token file (thi/id :test-token-set) (thi/id :token-sizing)) + token-spacing (tht/get-token file (thi/id :test-token-set) (thi/id :token-spacing)) ;; ==== Action changes (-> (-> (pcb/empty-changes nil) diff --git a/common/test/common_tests/logic/token_test.cljc b/common/test/common_tests/logic/token_test.cljc index b99df0f8da..88244a0266 100644 --- a/common/test/common_tests/logic/token_test.cljc +++ b/common/test/common_tests/logic/token_test.cljc @@ -13,6 +13,7 @@ [app.common.test-helpers.tokens :as tht] [app.common.types.tokens-lib :as ctob] [app.common.uuid :as uuid] + [clojure.datafy :refer [datafy]] [clojure.test :as t])) (t/use-fixtures :each thi/test-fixture) @@ -165,9 +166,11 @@ (t/deftest set-token-test (t/testing "delete token" (let [set-name "foo" + set-id (uuid/next) token-id (uuid/next) file (setup-file #(-> % - (ctob/add-set (ctob/make-token-set :name set-name)) + (ctob/add-set (ctob/make-token-set :id set-id + :name set-name)) (ctob/add-token-in-set set-name (ctob/make-token {:name "to.delete.color.red" :id token-id :value "red" @@ -180,16 +183,18 @@ redo-lib (tht/get-tokens-lib redo) undo (thf/apply-undo-changes redo changes) undo-lib (tht/get-tokens-lib undo)] - (t/is (nil? (ctob/get-token-in-set redo-lib set-name token-id))) + (t/is (nil? (ctob/get-token-in-set redo-lib set-id token-id))) ;; Undo - (t/is (some? (ctob/get-token-in-set undo-lib set-name token-id))))) + (t/is (some? (ctob/get-token-in-set undo-lib set-id token-id))))) (t/testing "add token" (let [set-name "foo" + set-id (uuid/next) token (ctob/make-token {:name "to.add.color.red" :value "red" :type :color}) - file (setup-file #(-> % (ctob/add-set (ctob/make-token-set :name set-name)))) + file (setup-file #(-> % (ctob/add-set (ctob/make-token-set :id set-id + :name set-name)))) changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) (pcb/set-token set-name (:id token) token)) @@ -198,12 +203,13 @@ redo-lib (tht/get-tokens-lib redo) undo (thf/apply-undo-changes redo changes) undo-lib (tht/get-tokens-lib undo)] - (t/is (= token (ctob/get-token-in-set redo-lib set-name (:id token)))) + (t/is (= token (ctob/get-token-in-set redo-lib set-id (:id token)))) ;; Undo - (t/is (nil? (ctob/get-token-in-set undo-lib set-name (:id token)))))) + (t/is (nil? (ctob/get-token-in-set undo-lib set-id (:id token)))))) (t/testing "update token" (let [set-name "foo" + set-id (uuid/next) prev-token (ctob/make-token {:name "to.update.color.red" :value "red" :type :color}) @@ -211,7 +217,8 @@ (assoc :name "color.red.changed") (assoc :value "blue")) file (setup-file #(-> % - (ctob/add-set (ctob/make-token-set :name set-name)) + (ctob/add-set (ctob/make-token-set :id set-id + :name set-name)) (ctob/add-token-in-set set-name prev-token))) changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) @@ -221,17 +228,18 @@ redo-lib (tht/get-tokens-lib redo) undo (thf/apply-undo-changes redo changes) undo-lib (tht/get-tokens-lib undo)] - (t/is (tht/token-data-eq? token (ctob/get-token-in-set redo-lib set-name (:id token)))) + (t/is (tht/token-data-eq? token (ctob/get-token-in-set redo-lib set-id (:id token)))) ;; Undo - (t/is (tht/token-data-eq? prev-token (ctob/get-token-in-set undo-lib set-name (:id prev-token))))))) + (t/is (tht/token-data-eq? prev-token (ctob/get-token-in-set undo-lib set-id (:id prev-token))))))) (t/deftest set-token-set-test (t/testing "delete token set" (let [set-name "foo" - file (setup-file #(ctob/add-set % (ctob/make-token-set :name set-name))) + set-id (uuid/next) + file (setup-file #(ctob/add-set % (ctob/make-token-set :id set-id :name set-name))) changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) - (pcb/set-token-set set-name false nil)) + (pcb/set-token-set set-id false nil)) redo (thf/apply-changes file changes) redo-lib (tht/get-tokens-lib redo) @@ -243,11 +251,12 @@ (t/testing "add token set" (let [set-name "foo" - token-set (ctob/make-token-set :name set-name) + set-id (uuid/next) + token-set (ctob/make-token-set :id set-id :name set-name) file (setup-file identity) changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) - (pcb/set-token-set set-name false token-set)) + (pcb/set-token-set set-id false token-set)) redo (thf/apply-changes file changes) redo-lib (tht/get-tokens-lib redo) @@ -259,28 +268,26 @@ (t/testing "update token set" (let [set-name "foo" - token-name "bar" - token (ctob/make-token {:name token-name - :value "red" - :type :color}) - file (setup-file #(-> (ctob/add-set % (ctob/make-token-set :name set-name)) - (ctob/add-token-in-set set-name token))) - prev-token-set (-> file tht/get-tokens-lib (ctob/get-set set-name)) + set-id (uuid/next) + token-set (ctob/make-token-set :id set-id :name set-name) + file (setup-file #(-> (ctob/add-set % token-set))) new-set-name "foo1" + changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) - (pcb/set-token-set set-name false (ctob/rename prev-token-set new-set-name))) + (pcb/set-token-set set-id false (ctob/rename token-set new-set-name))) + redo (thf/apply-changes file changes) redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] + redo-token-set (ctob/get-set redo-lib set-id) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo) + undo-token-set (ctob/get-set undo-lib set-id)] + + (t/is (= (ctob/get-name redo-token-set) new-set-name)) ;; Undo - (t/is (some? (ctob/get-token-in-set undo-lib set-name (:id token)))) - (t/is (nil? (ctob/get-token-in-set undo-lib new-set-name (:id token)))) - ;; Redo - (t/is (nil? (ctob/get-token-in-set redo-lib set-name (:id token)))) - (t/is (some? (ctob/get-token-in-set redo-lib new-set-name (:id token))))))) + (t/is (= (ctob/get-name undo-token-set) set-name))))) (t/deftest generate-toggle-token-set-group-test (t/testing "toggling set group with no active sets inside will activate all child sets" diff --git a/common/test/common_tests/types/tokens_lib_test.cljc b/common/test/common_tests/types/tokens_lib_test.cljc index 7fc2ac6053..f2dedb9687 100644 --- a/common/test/common_tests/types/tokens_lib_test.cljc +++ b/common/test/common_tests/types/tokens_lib_test.cljc @@ -178,7 +178,8 @@ (t/deftest tokens-tree (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "A" + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set) + :name "A" :tokens {"foo.bar.baz" (ctob/make-token :name "foo.bar.baz" :type :boolean :value true) @@ -188,7 +189,7 @@ "baz.boo" (ctob/make-token :name "baz.boo" :type :boolean :value true)}))) - expected (-> (ctob/get-set tokens-lib "A") + expected (-> (ctob/get-set tokens-lib (thi/id :test-token-set)) (ctob/get-tokens-map) (ctob/tokens-tree))] (t/is (= (get-in expected ["foo" "bar" "baz" :name]) "foo.bar.baz")) @@ -238,11 +239,12 @@ (t/deftest add-token-set-to-token-lib (let [tokens-lib (ctob/make-tokens-lib) - token-set (ctob/make-token-set :name "test-token-set") + token-set (ctob/make-token-set :id (thi/new-id! :test-token-set) + :name "test-token-set") tokens-lib' (ctob/add-set tokens-lib token-set) token-sets' (ctob/get-sets tokens-lib') - token-set' (ctob/get-set tokens-lib' "test-token-set")] + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set))] (t/is (= (ctob/set-count tokens-lib') 1)) (t/is (= (first token-sets') token-set)) @@ -250,7 +252,8 @@ (t/deftest update-token-set (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 :id (thi/new-id! :test-token-set) + :name "test-token-set"))) tokens-lib' (-> tokens-lib (ctob/update-set "test-token-set" @@ -260,8 +263,8 @@ (fn [token-set] (ctob/set-description token-set "no-effect")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set")] + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set))] (t/is (= (ctob/set-count tokens-lib') 1)) (t/is (= (ctob/get-name token-set') "test-token-set")) @@ -270,15 +273,16 @@ (t/deftest rename-token-set (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 :id (thi/new-id! :test-token-set) + :name "test-token-set"))) tokens-lib' (-> tokens-lib (ctob/update-set "test-token-set" (fn [token-set] (ctob/rename token-set "updated-name")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "updated-name")] + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set))] (t/is (= (ctob/set-count tokens-lib') 1)) (t/is (= (ctob/get-name token-set') "updated-name")) @@ -303,15 +307,16 @@ (t/is (= expected-theme-sets #{"foo/bar-renamed/baz-renamed/baz-child-1"})))) (t/deftest delete-token-set - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set")) - (ctob/add-theme (ctob/make-token-theme :name "test-token-theme" :sets #{"test-token-set"}))) + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set) + :name "test-token-set")) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme" :sets #{"test-token-set"}))) - tokens-lib' (-> tokens-lib - (ctob/delete-set-path "S-test-token-set") - (ctob/delete-set-path "S-not-existing-set")) + tokens-lib' (-> tokens-lib + (ctob/delete-set-path "S-test-token-set") + (ctob/delete-set-path "S-not-existing-set")) - token-set' (ctob/get-set tokens-lib' "updated-name") + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] (t/is (= (ctob/set-count tokens-lib') 0)) @@ -320,13 +325,14 @@ (t/deftest duplicate-token-set (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 :id (thi/new-id! :test-token-set) + :name "test-token-set" :tokens {"test-token" (ctob/make-token :id (thi/new-id! :test-token) :name "test-token" :type :boolean :value true)}))) - token-set-copy (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"}) + token-set-copy (ctob/duplicate-set (thi/id :test-token-set) tokens-lib {:suffix "copy"}) token (ctob/get-token token-set-copy (thi/id :test-token))] (t/is (some? token-set-copy)) @@ -336,16 +342,17 @@ (t/deftest duplicate-token-set-twice (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 :id (thi/new-id! :test-token-set) + :name "test-token-set" :tokens {"test-token" (ctob/make-token :id (thi/new-id! :test-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"})) + tokens-lib (ctob/add-set tokens-lib (ctob/duplicate-set (thi/id :test-token-set) tokens-lib {:suffix "copy"})) - token-set-copy (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"}) + token-set-copy (ctob/duplicate-set (thi/id :test-token-set) tokens-lib {:suffix "copy"}) token (ctob/get-token token-set-copy (thi/id :test-token))] (t/is (some? token-set-copy)) @@ -355,9 +362,10 @@ (t/deftest duplicate-empty-token-set (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 :id (thi/new-id! :test-token-set) + :name "test-token-set"))) - token-set-copy (ctob/duplicate-set "test-token-set" tokens-lib {:suffix "copy"}) + token-set-copy (ctob/duplicate-set (thi/id :test-token-set) tokens-lib {:suffix "copy"}) tokens (ctob/get-tokens-map token-set-copy)] (t/is (some? token-set-copy)) @@ -368,26 +376,28 @@ (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"})] + token-set-copy (ctob/duplicate-set (uuid/next) tokens-lib {:suffix "copy"})] (t/is (nil? token-set-copy)))) (t/deftest active-themes-set-names (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 :id (thi/new-id! :test-token-set) + :name "test-token-set"))) tokens-lib' (-> tokens-lib (ctob/delete-set-path "S-test-token-set") (ctob/delete-set-path "S-not-existing-set")) - token-set' (ctob/get-set tokens-lib' "updated-name")] + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set))] (t/is (= (ctob/set-count tokens-lib') 0)) (t/is (nil? token-set')))) (t/deftest add-token (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 :id (thi/new-id! :test-token-set) + :name "test-token-set"))) token (ctob/make-token :id (thi/new-id! :token) :name "test-token" :type :boolean @@ -396,8 +406,9 @@ (ctob/add-token-in-set "test-token-set" token) (ctob/add-token-in-set "not-existing-set" token)) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + _ (prn "tokens-lib'" (datafy tokens-lib')) + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token' (ctob/get-token token-set' (thi/id :token))] (t/is (= (ctob/set-count tokens-lib') 1)) @@ -407,7 +418,8 @@ (t/deftest update-token (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :id (thi/new-id! :test-token-1) :name "test-token-1" @@ -434,8 +446,8 @@ (assoc token :name "no-effect")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token (ctob/get-token token-set (thi/id :test-token-1)) token' (ctob/get-token token-set' (thi/id :test-token-1))] @@ -450,7 +462,8 @@ (t/deftest rename-token (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :id (thi/new-id! :test-token-1) :name "test-token-1" @@ -468,8 +481,8 @@ (assoc token :name "updated-name")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token (ctob/get-token token-set (thi/id :test-token-1)) token' (ctob/get-token token-set' (thi/id :test-token-1))] @@ -484,7 +497,8 @@ (t/deftest delete-token (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :id (thi/new-id! :test-token) :name "test-token" @@ -493,10 +507,10 @@ tokens-lib' (-> tokens-lib (ctob/delete-token-from-set "test-token-set" (thi/id :test-token)) (ctob/delete-token-from-set "not-existing-set" (thi/id :test-token)) - (ctob/delete-token-from-set "test-set" (uuid/next))) + (ctob/delete-token-from-set "test-token-set" (uuid/next))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token' (ctob/get-token token-set' (thi/id :test-token))] (t/is (= (ctob/set-count tokens-lib') 1)) @@ -885,7 +899,8 @@ (t/deftest add-tokens-in-set (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :name "token1" :type :boolean @@ -907,7 +922,7 @@ :type :boolean :value true))) - set (ctob/get-set tokens-lib "test-token-set") + set (ctob/get-set tokens-lib (thi/id :test-token-set)) tokens-list (ctob/get-tokens set)] (t/is (= (count tokens-list) 5)) @@ -919,7 +934,8 @@ (t/deftest update-token-in-sets (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :id (thi/new-id! :test-token-1) :name "test-token-1" @@ -943,8 +959,8 @@ :description "some description" :value false)))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token (ctob/get-token token-set (thi/id :test-token-2)) token' (ctob/get-token token-set' (thi/id :test-token-2))] @@ -957,7 +973,8 @@ (t/deftest update-token-in-sets-rename (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :id (thi/new-id! :test-token-1) :name "test-token-1" @@ -980,8 +997,8 @@ (assoc token :name "group1.updated-name")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token (ctob/get-token token-set (thi/id :test-token-2)) token' (ctob/get-token token-set' (thi/id :test-token-2))] @@ -994,7 +1011,8 @@ (t/deftest move-token-of-group (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :id (thi/new-id! :test-token-1) :name "test-token-1" @@ -1017,8 +1035,8 @@ (assoc token :name "group2.updated-name")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token (ctob/get-token token-set (thi/id :test-token-2)) token' (ctob/get-token token-set' (thi/id :test-token-2))] @@ -1032,7 +1050,8 @@ (t/deftest delete-token-in-group (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 :id (thi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-token-in-set "test-token-set" (ctob/make-token :id (thi/new-id! :test-token-1) :name "test-token-1" @@ -1046,8 +1065,8 @@ tokens-lib' (-> tokens-lib (ctob/delete-token-from-set "test-token-set" (thi/id :test-token-2))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") + token-set (ctob/get-set tokens-lib (thi/id :test-token-set)) + token-set' (ctob/get-set tokens-lib' (thi/id :test-token-set)) token' (ctob/get-token token-set' (thi/id :test-token-2))] (t/is (= (ctob/set-count tokens-lib') 1)) @@ -1262,79 +1281,85 @@ (t/deftest parse-single-set-legacy-json (let [json (-> (slurp "test/common_tests/types/data/tokens-single-set-legacy-example.json") (json/decode {:key-fn identity})) - lib (ctob/parse-decoded-json json "single_set")] + lib (ctob/parse-decoded-json json "single_set") + token-set (ctob/set-by-name lib "single_set")] (t/is (= '("single_set") (ctob/get-ordered-set-names lib))) (t/testing "token added" - (t/is (some? (ctob/get-token-by-name lib "single_set" "color.red.100"))))))) + (t/is (some? (ctob/get-token-by-name lib (ctob/get-id token-set) "color.red.100"))))))) #?(:clj (t/deftest parse-single-set-dtcg-json (let [json (-> (slurp "test/common_tests/types/data/tokens-single-set-dtcg-example.json") (json/decode {:key-fn identity})) - lib (ctob/parse-decoded-json json "single_set")] + lib (ctob/parse-decoded-json json "single_set") + token-set (ctob/set-by-name lib "single_set")] (t/is (= '("single_set") (ctob/get-ordered-set-names lib))) (t/testing "token added" - (t/is (some? (ctob/get-token-by-name lib "single_set" "color.red.100"))))))) + (t/is (some? (ctob/get-token-by-name lib (ctob/get-id token-set) "color.red.100"))))))) #?(:clj (t/deftest parse-multi-set-legacy-json (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-legacy-example.json") (json/decode {:key-fn identity})) lib (ctob/parse-decoded-json json "") - token-theme (ctob/get-theme lib "group-1" "theme-1")] + token-theme (ctob/get-theme lib "group-1" "theme-1") + core-set (ctob/set-by-name lib "core") + theme-set (ctob/set-by-name lib "theme")] (t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib))) (t/testing "set exists in theme" (t/is (= (:group token-theme) "group-1")) (t/is (= (:name token-theme) "theme-1")) (t/is (= (:sets token-theme) #{"light"}))) (t/testing "tokens exist in core set" - (t/is (tht/token-data-eq? (ctob/get-token-by-name lib "core" "colors.red.600") + (t/is (tht/token-data-eq? (ctob/get-token-by-name lib (ctob/get-id core-set) "colors.red.600") {:name "colors.red.600" :type :color :value "#e53e3e" :description ""})) - (t/is (tht/token-data-eq? (ctob/get-token-by-name lib "core" "spacing.multi-value") + (t/is (tht/token-data-eq? (ctob/get-token-by-name lib (ctob/get-id core-set) "spacing.multi-value") {:name "spacing.multi-value" :type :spacing :value "{dimension.sm} {dimension.xl}" :description "You can have multiple values in a single spacing token"})) - (t/is (tht/token-data-eq? (ctob/get-token-by-name lib "theme" "button.primary.background") + (t/is (tht/token-data-eq? (ctob/get-token-by-name lib (ctob/get-id theme-set) "button.primary.background") {:name "button.primary.background" :type :color :value "{accent.default}" :description ""}))) (t/testing "invalid tokens got discarded" - (t/is (nil? (ctob/get-token-by-name lib "typography" "H1.Bold"))))))) + (t/is (nil? (ctob/get-token-by-name lib (ctob/get-id theme-set) "boxShadow.default"))))))) #?(:clj (t/deftest parse-multi-set-dtcg-json (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json") (json/decode {:key-fn identity})) lib (ctob/parse-decoded-json json "") - token-theme (ctob/get-theme lib "group-1" "theme-1")] + token-theme (ctob/get-theme lib "group-1" "theme-1") + core-set (ctob/set-by-name lib "core") + theme-set (ctob/set-by-name lib "theme")] (t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib))) (t/testing "set exists in theme" (t/is (= (:group token-theme) "group-1")) (t/is (= (:name token-theme) "theme-1")) (t/is (= (:sets token-theme) #{"light"}))) (t/testing "tokens exist in core set" - (t/is (tht/token-data-eq? (ctob/get-token-by-name lib "core" "colors.red.600") + (t/is (tht/token-data-eq? (ctob/get-token-by-name lib (ctob/get-id core-set) "colors.red.600") {:name "colors.red.600" :type :color :value "#e53e3e" :description ""})) - (t/is (tht/token-data-eq? (ctob/get-token-by-name lib "core" "spacing.multi-value") + (t/is (tht/token-data-eq? (ctob/get-token-by-name lib (ctob/get-id core-set) "spacing.multi-value") {:name "spacing.multi-value" :type :spacing :value "{dimension.sm} {dimension.xl}" :description "You can have multiple values in a single spacing token"})) - (t/is (tht/token-data-eq? (ctob/get-token-by-name lib "theme" "button.primary.background") + (t/is (tht/token-data-eq? (ctob/get-token-by-name lib (ctob/get-id theme-set) "button.primary.background") {:name "button.primary.background" :type :color :value "{accent.default}" :description ""}))) (t/testing "invalid tokens got discarded" - (t/is (nil? (ctob/get-token-by-name lib "typography" "H1.Bold"))))))) + (t/is (nil? (ctob/get-token-by-name lib (ctob/get-id theme-set) "boxShadow.default"))))))) #?(:clj (t/deftest parse-multi-set-dtcg-json-default-team @@ -1342,14 +1367,15 @@ (json/decode {:key-fn identity})) lib (ctob/parse-decoded-json json "") themes (ctob/get-themes lib) - first-theme (first themes)] + first-theme (first themes) + dark-set (ctob/set-by-name lib "dark")] (t/is (= '("dark") (ctob/get-ordered-set-names lib))) (t/is (= 1 (count themes))) (t/testing "existing theme is default theme" (t/is (= (:group first-theme) "")) (t/is (= (:name first-theme) ctob/hidden-theme-name))) (t/testing "token exist in dark set" - (t/is (tht/token-data-eq? (ctob/get-token-by-name lib "dark" "small") + (t/is (tht/token-data-eq? (ctob/get-token-by-name lib (ctob/get-id dark-set) "small") {:name "small" :value "8" :type :border-radius diff --git a/frontend/src/app/main/data/workspace/tokens/library_edit.cljs b/frontend/src/app/main/data/workspace/tokens/library_edit.cljs index d25c60b99d..ce45b32829 100644 --- a/frontend/src/app/main/data/workspace/tokens/library_edit.cljs +++ b/frontend/src/app/main/data/workspace/tokens/library_edit.cljs @@ -6,6 +6,7 @@ (ns app.main.data.workspace.tokens.library-edit (: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] @@ -22,9 +23,12 @@ [app.main.data.workspace.tokens.propagation :as dwtp] [app.util.i18n :refer [tr]] [beicon.v2.core :as rx] + [clojure.datafy :refer [datafy]] + [clojure.test :as ct] [potok.v2.core :as ptk])) (declare set-selected-token-set-name) +(declare set-selected-token-set-id) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; TOKENS Getters @@ -39,11 +43,11 @@ (defn lookup-token-set ([state] - (when-let [selected (dm/get-in state [:workspace-tokens :selected-token-set-name])] + (when-let [selected (dm/get-in state [:workspace-tokens :selected-token-set-id])] (lookup-token-set state selected))) - ([state name] + ([state id] (some-> (get-tokens-lib state) - (ctob/get-set name)))) + (ctob/get-set id)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Helpers @@ -149,7 +153,7 @@ (let [data (dsh/lookup-file-data state) tokens-lib (get data :tokens-lib) set-name (ctob/normalize-set-name set-name)] - (if (and tokens-lib (ctob/get-set tokens-lib set-name)) + (if (and tokens-lib (ctob/set-by-name tokens-lib set-name)) (rx/of (ntf/show {:content (tr "errors.token-set-already-exists") :type :toast :level :error @@ -157,8 +161,9 @@ (let [token-set (ctob/make-token-set :name set-name) changes (-> (pcb/empty-changes it) (pcb/with-library-data data) - (pcb/set-token-set set-name false token-set))] + (pcb/set-token-set (ctob/get-id token-set) false token-set))] (rx/of (set-selected-token-set-name set-name) + (set-selected-token-set-id (ctob/get-id token-set)) (dch/commit-changes changes)))))))) (defn rename-token-set-group [set-group-path set-group-fname] @@ -179,15 +184,16 @@ name (ctob/normalize-set-name name (ctob/get-name token-set)) tokens-lib (get data :tokens-lib)] - (if (ctob/get-set tokens-lib name) + (if (ctob/set-by-name tokens-lib name) (rx/of (ntf/show {:content (tr "errors.token-set-already-exists") :type :toast :level :error :timeout 9000})) (let [changes (-> (pcb/empty-changes it) (pcb/with-library-data data) - (pcb/rename-token-set (ctob/get-name token-set) name))] + (pcb/rename-token-set (ctob/get-id token-set) name))] (rx/of (set-selected-token-set-name name) + (set-selected-token-set-id (ctob/get-id token-set)) (dch/commit-changes changes)))))))) (defn duplicate-token-set @@ -196,15 +202,15 @@ 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.tokens.duplicate-suffix")] - (when-let [set (ctob/duplicate-set name tokens-lib {:suffix suffix})] + (when-let [token-set (ctob/duplicate-set id tokens-lib {:suffix suffix})] (let [changes (-> (pcb/empty-changes it) (pcb/with-library-data data) - (pcb/set-token-set (ctob/get-name set) is-group set))] - (rx/of (set-selected-token-set-name name) + (pcb/set-token-set (ctob/get-id token-set) is-group token-set))] + (rx/of (set-selected-token-set-name (ctob/get-name token-set)) + (set-selected-token-set-id (ctob/get-id token-set)) (dch/commit-changes changes)))))))) (defn toggle-token-set @@ -250,6 +256,7 @@ (ptk/reify ::delete-token-set-path ptk/WatchEvent (watch [it state _] + (prn "path" path) (let [data (dsh/lookup-file-data state) changes (-> (pcb/empty-changes it) (pcb/with-library-data data) @@ -334,7 +341,8 @@ hidden-theme-with-set) (pcb/update-active-token-themes #{ctob/hidden-theme-path} #{}))] (rx/of (dch/commit-changes changes) - (set-selected-token-set-name set-name)))))) + (set-selected-token-set-name set-name) + (set-selected-token-set-id (ctob/get-id token-set))))))) (defn create-token [params] @@ -375,7 +383,6 @@ (pcb/set-token (ctob/get-name token-set) id token'))] - (rx/of (dch/commit-changes changes) (ptk/data-event ::ev/event {::ev/name "edit-token" :type token-type})))))) @@ -449,13 +456,20 @@ (update state :workspace-tokens assoc :token-set-context-menu params) (update state :workspace-tokens dissoc :token-set-context-menu))))) -(defn set-selected-token-set-name +(defn set-selected-token-set-name ;; TODO: remove this when all functions use set-id [name] (ptk/reify ::set-selected-token-set-name ptk/UpdateEvent (update [_ state] (update state :workspace-tokens assoc :selected-token-set-name name)))) +(defn set-selected-token-set-id + [id] + (ptk/reify ::set-selected-token-set-id + ptk/UpdateEvent + (update [_ state] + (update state :workspace-tokens assoc :selected-token-set-id id)))) + (defn start-token-set-edition [edition-id] (assert (string? edition-id) "expected a string for `edition-id`") diff --git a/frontend/src/app/main/data/workspace/tokens/selected_set.cljs b/frontend/src/app/main/data/workspace/tokens/selected_set.cljs index c072ea3642..2ac141d903 100644 --- a/frontend/src/app/main/data/workspace/tokens/selected_set.cljs +++ b/frontend/src/app/main/data/workspace/tokens/selected_set.cljs @@ -11,19 +11,19 @@ [app.common.types.tokens-lib :as ctob] [app.main.data.helpers :as dsh])) -(defn- get-selected-token-set-name [state] - (or (get-in state [:workspace-tokens :selected-token-set-name]) +(defn- get-selected-token-set-id [state] + (or (get-in state [:workspace-tokens :selected-token-set-id]) (some-> (dsh/lookup-file-data state) (get :tokens-lib) (ctob/get-sets) (first) - (ctob/get-name)))) + (ctob/get-id)))) (defn get-selected-token-set [state] - (when-let [set-name (get-selected-token-set-name state)] + (when-let [set-id (get-selected-token-set-id state)] (some-> (dsh/lookup-file-data state) (get :tokens-lib) - (ctob/get-set set-name)))) + (ctob/get-set set-id)))) (defn get-token-in-selected-set [state token-id] (some-> (get-selected-token-set state) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 74b509ff6b..abe6ff421d 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -459,9 +459,12 @@ (def workspace-token-themes-no-hidden (l/derived #(remove ctob/hidden-theme? %) workspace-token-themes)) -(def selected-token-set-name +(def selected-token-set-name ;; FIXME: remove this when all functions use set-id (l/derived (l/key :selected-token-set-name) workspace-tokens)) +(def selected-token-set-id + (l/derived (l/key :selected-token-set-id) workspace-tokens)) + (def workspace-ordered-token-sets (l/derived #(or (some-> % ctob/get-sets) []) tokens-lib)) diff --git a/frontend/src/app/main/ui/workspace/tokens/management.cljs b/frontend/src/app/main/ui/workspace/tokens/management.cljs index ba4fbea79e..b9d1123950 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management.cljs @@ -69,14 +69,14 @@ (some #(ctsl/any-layout-immediate-child? objects %) selected-shapes)) ;; This only checks for the currently explicitly selected set - ;; name, it is ephimeral and can be nil + ;; id, it is ephimeral and can be nil ;; FIXME: this is a repeated deref for the same `:workspace-tokens` state - selected-token-set-name - (mf/deref refs/selected-token-set-name) + selected-token-set-id + (mf/deref refs/selected-token-set-id) selected-token-set - (when selected-token-set-name - (some-> tokens-lib (ctob/get-set selected-token-set-name))) + (when selected-token-set-id + (some-> tokens-lib (ctob/get-set selected-token-set-id))) ;; If we have not selected any set explicitly we just ;; select the first one from the list of sets @@ -115,26 +115,28 @@ (mf/with-memo [tokens-by-type] (get-sorted-token-groups tokens-by-type))] - (mf/with-effect [tokens-lib selected-token-set-name] + ;; (mf/with-effect [tokens-lib selected-token-set-id] + (mf/with-effect [] (when (and tokens-lib - (or (nil? selected-token-set-name) - (and selected-token-set-name - (not (ctob/get-set tokens-lib selected-token-set-name))))) + (or (nil? selected-token-set-id) + (and selected-token-set-id + (not (ctob/get-set tokens-lib selected-token-set-id))))) (let [match (->> (ctob/get-sets tokens-lib) (first))] (when match - (st/emit! (dwtl/set-selected-token-set-name (ctob/get-name match))))))) + (st/emit! (dwtl/set-selected-token-set-name (ctob/get-name match)) + (dwtl/set-selected-token-set-id (ctob/get-id match))))))) [:* [:& token-context-menu] [:div {:class (stl/css :sets-header-container)} - [:> text* {:as "span" :typography "headline-small" :class (stl/css :sets-header)} (tr "workspace.tokens.tokens-section-title" selected-token-set-name)] + [:> text* {:as "span" :typography "headline-small" :class (stl/css :sets-header)} (tr "workspace.tokens.tokens-section-title" (ctob/get-name selected-token-set))] [:div {:class (stl/css :sets-header-status) :title (tr "workspace.tokens.inactive-set-description")} - ;; NOTE: when no set in tokens-lib, the selected-token-set-name + ;; NOTE: when no set in tokens-lib, the selected-token-set-id ;; will be `nil`, so for properly hide the inactive message we - ;; check that at least `selected-token-set-name` has a value - (when (and (some? selected-token-set-name) - (not (token-set-active? selected-token-set-name))) + ;; check that at least `selected-token-set-id` has a value + (when (and (some? selected-token-set-id) + (not (token-set-active? (ctob/get-name selected-token-set)))) [:* [:> icon* {:class (stl/css :sets-header-status-icon) :icon-id i/eye-off}] [:> text* {:as "span" :typography "body-small" :class (stl/css :sets-header-status-text)} diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index be7ce5fbae..0b6ec763c8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -15,8 +15,9 @@ [app.main.ui.workspace.tokens.sets.lists :refer [controlled-sets-list*]] [rumext.v2 :as mf])) -(defn- on-select-token-set-click [name] - (st/emit! (dwtl/set-selected-token-set-name name))) +(defn- on-select-token-set-click [id name] + (st/emit! (dwtl/set-selected-token-set-id id) + (dwtl/set-selected-token-set-name name))) (defn- on-toggle-token-set-click [name] (st/emit! (dwtl/toggle-token-set name))) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs b/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs index a275e2ab2d..8015932150 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs @@ -214,7 +214,8 @@ [{:keys [id set label tree-depth tree-path tree-index is-selected is-active is-draggable is-editing on-select on-drop on-toggle on-start-edition on-reset-edition on-edit-submit is-new]}] - (let [set-name (ctob/get-name set) + (let [set-id (ctob/get-id set) + set-name (ctob/get-name set) can-edit? (mf/use-ctx ctx/can-edit?) on-click @@ -224,7 +225,7 @@ (dom/stop-propagation event) (when-not is-editing (when (fn? on-select) - (on-select set-name))))) + (on-select set-id set-name))))) on-context-menu (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 3e8efc67d6..a2e8446498 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -43,8 +43,8 @@ token-sets (some-> tokens-lib (ctob/get-sets)) - selected-token-set-name - (mf/deref refs/selected-token-set-name) + selected-token-set-id + (mf/deref refs/selected-token-set-id) {:keys [token-set-edition-id token-set-new-path]} @@ -61,7 +61,7 @@ {:tokens-lib tokens-lib :new-path token-set-new-path :edition-id token-set-edition-id - :selected selected-token-set-name}]]))) + :selected selected-token-set-id}]]))) (mf/defc token-management-section* {::mf/private true} diff --git a/frontend/test/frontend_tests/logic/components_and_tokens.cljs b/frontend/test/frontend_tests/logic/components_and_tokens.cljs index 5afb4c902b..12d2f08811 100644 --- a/frontend/test/frontend_tests/logic/components_and_tokens.cljs +++ b/frontend/test/frontend_tests/logic/components_and_tokens.cljs @@ -34,7 +34,8 @@ (-> (cthf/sample-file :file1) (ctht/add-tokens-lib) (ctht/update-tokens-lib #(-> % - (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-theme (ctob/make-token-theme :name "test-theme" :sets #{"test-token-set"})) (ctob/set-active-themes #{"/test-theme"}) @@ -206,7 +207,8 @@ store (ths/setup-store file) ;; ==== Action - events [(dwtl/set-selected-token-set-name "test-token-set") + events [(dwtl/set-selected-token-set-id (cthi/id :test-token-set)) + (dwtl/set-selected-token-set-name "test-token-set") (dwtl/update-token (cthi/id :test-token-1) {:name "test-token-1" :type :border-radius @@ -321,7 +323,8 @@ file (-> (cthf/sample-file :file1) (ctht/add-tokens-lib) (ctht/update-tokens-lib #(-> % - (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set) + :name "test-token-set")) (ctob/add-theme (ctob/make-token-theme :name "test-theme" :sets #{"test-token-set"})) (ctob/set-active-themes #{"/test-theme"}) @@ -368,7 +371,8 @@ store (ths/setup-store file) ;; ==== Action - events [(dwtl/set-selected-token-set-name "test-token-set") + events [(dwtl/set-selected-token-set-id (cthi/id :test-token-set)) + (dwtl/set-selected-token-set-name "test-token-set") (dwtl/update-token (cthi/id :token-radius) {:name "token-radius" :value 30}) @@ -396,7 +400,6 @@ (fn [new-state] (let [;; ==== Get file' (ths/get-file-from-state new-state) - frame1' (cths/get-shape file' :frame1) c-frame1' (cths/get-shape file' :c-frame1) tokens-frame1' (:applied-tokens c-frame1')] diff --git a/frontend/test/frontend_tests/tokens/import_export_test.cljs b/frontend/test/frontend_tests/tokens/import_export_test.cljs index c0482d43f7..130b7570ca 100644 --- a/frontend/test/frontend_tests/tokens/import_export_test.cljs +++ b/frontend/test/frontend_tests/tokens/import_export_test.cljs @@ -24,7 +24,7 @@ (dwti/import-file-stream "core") (rx/subs! (fn [tokens-lib] (t/is (instance? ctob/TokensLib tokens-lib)) - (t/is (= "red" (-> (ctob/get-set tokens-lib "core") + (t/is (= "red" (-> (ctob/set-by-name tokens-lib "core") (ctob/token-by-name "color") (:value)))) (done)))))))) @@ -96,6 +96,7 @@ color.value tries to reference missing, which is not defined."))) (->> (rx/of json) (dwti/import-file-stream "") (rx/subs! (fn [tokens-lib] - (t/is (instance? ctob/TokensLib tokens-lib)) - (t/is (= "{missing}" (:value (ctob/get-token-by-name tokens-lib "core" "color")))) - (done)))))))) + (let [token-set (ctob/set-by-name tokens-lib "core")] + (t/is (instance? ctob/TokensLib tokens-lib)) + (t/is (= "{missing}" (:value (ctob/get-token-by-name tokens-lib (ctob/get-id token-set) "color")))) + (done))))))))) diff --git a/frontend/test/frontend_tests/tokens/logic/token_data_test.cljs b/frontend/test/frontend_tests/tokens/logic/token_data_test.cljs index 0329d05f1f..e41faab7f1 100644 --- a/frontend/test/frontend_tests/tokens/logic/token_data_test.cljs +++ b/frontend/test/frontend_tests/tokens/logic/token_data_test.cljs @@ -7,6 +7,7 @@ (ns frontend-tests.tokens.logic.token-data-test (:require [app.common.test-helpers.files :as cthf] + [app.common.test-helpers.ids-map :as cthi] [app.common.types.tokens-lib :as ctob] [app.main.data.workspace.tokens.library-edit :as dwtl] [cljs.test :as t :include-macros true] @@ -26,26 +27,66 @@ (-> (setup-file) (assoc-in [:data :tokens-lib] (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "Set A")))))) + (ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set) + :name "Set A")))))) + +(t/deftest add-set + (t/async + done + (let [file (setup-file-with-token-lib) + store (ths/setup-store file) + events [(dwtl/create-token-set "Set B")]] + + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-state new-state) + tokens-lib' (toht/get-tokens-lib file') + sets' (ctob/get-sets tokens-lib') + set-b' (ctob/set-by-name tokens-lib' "Set B")] + + (t/testing "Token lib contains two sets" + (t/is (= (count sets') 2)) + (t/is (some? set-b'))))))))) + +(t/deftest rename-set + (t/async + done + (let [file (setup-file-with-token-lib) + store (ths/setup-store file) + tokens-lib (toht/get-tokens-lib file) + set-a (ctob/set-by-name tokens-lib "Set A") + events [(dwtl/update-token-set (ctob/rename set-a "Set A updated") + "Set A updated")]] + + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-state new-state) + tokens-lib' (toht/get-tokens-lib file') + sets' (ctob/get-sets tokens-lib') + set-a' (ctob/set-by-name tokens-lib' "Set A updated")] + + (t/testing "Set has been renamed" + (t/is (= (count sets') 1)) + (t/is (some? set-a'))))))))) (t/deftest duplicate-set (t/async done (let [file (setup-file-with-token-lib) store (ths/setup-store file) - events [(dwtl/duplicate-token-set "Set A" false)]] + events [(dwtl/duplicate-token-set (cthi/id :test-token-set) 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")] + sets (ctob/get-sets token-lib)] (t/testing "Token lib contains two sets" - (t/is (= (count sets) 2)) - (t/is (some? set))))))))) + (t/is (= (count sets) 2))))))))) (t/deftest duplicate-non-exist-set (t/async @@ -59,9 +100,24 @@ (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")] + sets (ctob/get-sets token-lib)] (t/testing "Token lib contains one set" - (t/is (= (count sets) 1)) - (t/is (nil? set))))))))) \ No newline at end of file + (t/is (= (count sets) 1)))))))) + + (t/deftest delete-set + (t/async + done + (let [file (setup-file-with-token-lib) + store (ths/setup-store file) + events [(dwtl/delete-token-set-path (ctob/split-set-name "Set A") false)]] + + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-state new-state) + tokens-lib' (toht/get-tokens-lib file') + sets' (ctob/get-sets tokens-lib')] + + (t/testing "Set has been deleted" + (t/is (= (count sets') 0)))))))))) \ No newline at end of file