diff --git a/common/src/app/common/data.cljc b/common/src/app/common/data.cljc index 77e9af51b..2d0011be7 100644 --- a/common/src/app/common/data.cljc +++ b/common/src/app/common/data.cljc @@ -57,6 +57,54 @@ #?(:cljs (instance? lkm/LinkedMap o) :clj (instance? LinkedMap o))) +(defn oassoc + [o & kvs] + (apply assoc (or o (ordered-map)) kvs)) + +(defn oassoc-in + [o [k & ks] v] + (if ks + (oassoc o k (oassoc-in (get o k) ks v)) + (oassoc o k v))) + +(defn oupdate-in + [m ks f & args] + (let [up (fn up [m ks f args] + (let [[k & ks] ks] + (if ks + (oassoc m k (up (get m k) ks f args)) + (oassoc m k (apply f (get m k) args)))))] + (up m ks f args))) + +(declare index-of) + +(defn oassoc-before + "Assoc a k v pair, in the order position just before the other key" + [o before-k k v] + (if-let [index (index-of (keys o) before-k)] + (-> (ordered-map) + (into (take index o)) + (assoc k v) + (into (drop index o))) + (oassoc o k v))) + +(defn oassoc-in-before + [o [before-k & before-ks] [k & ks] v] + (if-let [index (index-of (keys o) before-k)] + (let [new-v (if ks + (oassoc-in-before (get o k) before-ks ks v) + v)] + (if (= k before-k) + (-> (ordered-map) + (into (take index o)) + (assoc k new-v) + (into (drop (inc index) o))) + (-> (ordered-map) + (into (take index o)) + (assoc k new-v) + (into (drop index o))))) + (oassoc-in o (cons k ks) v))) + (defn vec2 "Creates a optimized vector compatible type of length 2 backed internally with MapEntry impl because it has faster access method @@ -564,6 +612,7 @@ new-elems (remove p? after)))) +;; TODO: remove this (defn addm-at-index "Insert an element in an ordered map at an arbitrary index" [coll index key element] diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index ae9b6362f..67353769a 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -263,7 +263,8 @@ [:delete-temporary-token-theme [:map {:title "DeleteTemporaryTokenThemeChange"} [:type [:= :delete-temporary-token-theme]] - [:id ::sm/uuid]]] + [:id ::sm/uuid] + [:name :string]]] [:add-token-theme [:map {:title "AddTokenThemeChange"} @@ -274,12 +275,14 @@ [:map {:title "ModTokenThemeChange"} [:type [:= :mod-token-theme]] [:id ::sm/uuid] + [:name :string] [:token-theme ::ctot/token-theme]]] [:del-token-theme [:map {:title "DelTokenThemeChange"} [:type [:= :del-token-theme]] - [:id ::sm/uuid]]] + [:id ::sm/uuid] + [:name :string]]] [:add-token-set [:map {:title "AddTokenSetChange"} @@ -822,29 +825,70 @@ set-name name))))) +(defn- set-ids->names + [data sets] + (let [lib-sets (:token-sets-index data) + set-id->name + (fn [set-id] + (dm/get-in lib-sets [set-id :name]))] + (map set-id->name sets))) + (defmethod process-change :add-temporary-token-theme [data {:keys [token-theme]}] - (ctotl/add-temporary-token-theme data token-theme)) + (-> data + (ctotl/add-temporary-token-theme token-theme) + (update :tokens-lib + #(-> % + (ctob/ensure-tokens-lib) + (ctob/add-theme (-> token-theme + (update :sets (partial set-ids->names data)) + (ctob/make-token-theme))))))) (defmethod process-change :update-active-token-themes [data {:keys [theme-ids]}] (ctotl/assoc-active-token-themes data theme-ids)) (defmethod process-change :delete-temporary-token-theme - [data {:keys [id]}] - (ctotl/delete-temporary-token-theme data id)) + [data {:keys [id group name]}] + (-> data + (ctotl/delete-temporary-token-theme id) + (update :tokens-lib + #(-> % + (ctob/ensure-tokens-lib) + (ctob/delete-theme group name))))) (defmethod process-change :add-token-theme [data {:keys [token-theme]}] - (ctotl/add-token-theme data token-theme)) + (-> data + (ctotl/add-token-theme token-theme) + (update :tokens-lib + #(-> % + (ctob/ensure-tokens-lib) + (ctob/add-theme (-> token-theme + (update :sets (partial set-ids->names data)) + (ctob/make-token-theme))))))) (defmethod process-change :mod-token-theme - [data {:keys [id token-theme]}] - (ctotl/update-token-theme data id merge token-theme)) + [data {:keys [id name group token-theme]}] + (-> data + (ctotl/update-token-theme id merge token-theme) + (update :tokens-lib + #(-> % + (ctob/ensure-tokens-lib) + (ctob/update-theme name group + (fn [prev-theme] + (merge prev-theme + (-> token-theme + (update :sets (partial set-ids->names data)))))))))) (defmethod process-change :del-token-theme - [data {:keys [id]}] - (ctotl/delete-token-theme data id)) + [data {:keys [id group name]}] + (-> data + (ctotl/delete-token-theme id) + (update :tokens-lib + #(-> % + (ctob/ensure-tokens-lib) + (ctob/delete-theme group name))))) (defmethod process-change :add-token-set [data {:keys [token-set]}] diff --git a/common/src/app/common/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index 09148d542..44f57464c 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -699,7 +699,7 @@ [changes token-theme] (-> changes (update :redo-changes conj {:type :add-temporary-token-theme :token-theme token-theme}) - (update :undo-changes conj {:type :delete-temporary-token-theme :id (:id token-theme)}) + (update :undo-changes conj {:type :delete-temporary-token-theme :id (:id token-theme) :name (:name token-theme)}) (apply-changes-local))) (defn update-active-token-themes @@ -713,14 +713,14 @@ [changes token-theme] (-> changes (update :redo-changes conj {:type :add-token-theme :token-theme token-theme}) - (update :undo-changes conj {:type :del-token-theme :id (:id token-theme)}) + (update :undo-changes conj {:type :del-token-theme :id (:id token-theme) :name (:name token-theme)}) (apply-changes-local))) (defn update-token-theme [changes token-theme prev-token-theme] (-> changes - (update :redo-changes conj {:type :mod-token-theme :id (:id token-theme) :token-theme token-theme}) - (update :undo-changes conj {:type :mod-token-theme :id (:id token-theme) :token-theme (or prev-token-theme token-theme)}) + (update :redo-changes conj {:type :mod-token-theme :id (:id token-theme) :name (:name prev-token-theme) :token-theme token-theme}) + (update :undo-changes conj {:type :mod-token-theme :id (:id token-theme) :name (:name token-theme) :token-theme (or prev-token-theme token-theme)}) (apply-changes-local))) (defn delete-token-theme @@ -729,7 +729,7 @@ (let [library-data (::library-data (meta changes)) prev-token-theme (get-in library-data [:token-themes-index token-theme-id])] (-> changes - (update :redo-changes conj {:type :del-token-theme :id token-theme-id}) + (update :redo-changes conj {:type :del-token-theme :id token-theme-id :name (:name prev-token-theme)}) (update :undo-changes conj {:type :add-token-theme :token-theme prev-token-theme}) (apply-changes-local)))) diff --git a/common/src/app/common/fressian.clj b/common/src/app/common/fressian.clj index 4a640cd8c..f75ece0bf 100644 --- a/common/src/app/common/fressian.clj +++ b/common/src/app/common/fressian.clj @@ -16,6 +16,7 @@ java.time.OffsetDateTime java.util.List linked.map.LinkedMap + linked.set.LinkedSet org.fressian.Reader org.fressian.StreamingWriter org.fressian.Writer @@ -275,7 +276,12 @@ {:name "clj/seq" :class clojure.lang.ISeq :wfn write-list-like - :rfn (comp sequence read-object!)}) + :rfn (comp sequence read-object!)} + + {:name "linked/set" + :class LinkedSet + :wfn write-list-like + :rfn (comp #(into (d/ordered-set) %) read-object!)}) ;; --- PUBLIC API diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 7e34404c4..0a8b8d7d9 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -12,9 +12,88 @@ [app.common.time :as dt] [app.common.transit :as t] [app.common.types.token :as cto] + [cuerdas.core :as str] #?(:clj [app.common.fressian :as fres]))) -;; #?(:clj (set! *warn-on-reflection* true)) +;; === Groups handling + +(def schema:groupable-item + [:map {:title "Groupable item"} + [:name :string]]) + +(def valid-groupable-item? + (sm/validator schema:groupable-item)) + +(defn split-path + "Decompose a string in the form 'one.two.three' into a vector of strings, removing spaces." + [path separator] + (let [xf (comp (map str/trim) + (remove str/empty?))] + (->> (str/split path separator) + (into [] xf)))) + +(defn join-path + "Regenerate a path as a string, from a vector." + [path separator] + (str/join separator path)) + +(defn group-item + "Add a group to the item name, in the form group.name." + [item group-name separator] + (dm/assert! + "expected groupable item" + (valid-groupable-item? item)) + (update item :name #(str group-name separator %))) + +(defn ungroup-item + "Remove the first group from the item name." + [item separator] + (dm/assert! + "expected groupable item" + (valid-groupable-item? item)) + (update item :name #(-> % + (split-path separator) + (rest) + (join-path separator)))) + +(defn get-path + "Get the groups part of the name as a vector. E.g. group.subgroup.name -> ['group' 'subrgoup']" + [item separator] + (dm/assert! + "expected groupable item" + (valid-groupable-item? item)) + (split-path (:name item) separator)) + +(defn get-groups-str + "Get the groups part of the name. E.g. group.subgroup.name -> group.subrgoup" + [item separator] + (-> (get-path item separator) + (butlast) + (join-path separator))) + +(defn get-final-name + "Get the final part of the name. E.g. group.subgroup.name -> name" + [item separator] + (dm/assert! + "expected groupable item" + (valid-groupable-item? item)) + (-> (:name item) + (split-path separator) + (last))) + +(defn group? + "Check if a node of the grouping tree is a group or a final item." + [item] + (d/ordered-map? item)) + +(defn get-children + "Get all children of a group of a grouping tree. Each child is + a tuple [name item], where item " + [group] + (dm/assert! + "expected group node" + (group? group)) + (seq group)) ;; === Token @@ -23,10 +102,10 @@ (def schema:token [:and [:map {:title "Token"} - [:name cto/token-name-ref] ;; not necessary to have uuid + [:name cto/token-name-ref] ;; not necessary to have uuid [:type [::sm/one-of cto/token-types]] [:value :any] - [:description [:maybe :string]] ;; defrecord always have the attributes, even with nil value + [:description [:maybe :string]] ;; defrecord always have the attributes, even with nil value [:modified-at ::sm/inst]] [:fn (partial instance? Token)]]) @@ -56,7 +135,8 @@ (defprotocol ITokenSet (add-token [_ token] "add a token at the end of the list") (update-token [_ token-name f] "update a token in the list") - (delete-token [_ token-name] "delete a token from the list")) + (delete-token [_ token-name] "delete a token from the list") + (get-tokens [_] "return an ordered sequence of all tokens in the set")) (defrecord TokenSet [name description modified-at tokens] ITokenSet @@ -77,24 +157,27 @@ (dt/now) (if (= (:name token) (:name token')) (assoc tokens (:name token') token') - (let [index (d/index-of (keys tokens) (:name token))] - (-> tokens - (dissoc (:name token)) - (d/addm-at-index index (:name token') token')))))) + (-> tokens + (d/oassoc-before (:name token) (:name token') token') + (dissoc (:name token)))))) this)) (delete-token [_ token-name] (TokenSet. name description (dt/now) - (dissoc tokens token-name)))) + (dissoc tokens token-name))) + + (get-tokens [_] + (vals tokens))) (def schema:token-set [:and [:map {:title "TokenSet"} [:name :string] [:description [:maybe :string]] [:modified-at ::sm/inst] - [:tokens [:map-of {:gen/max 5} :string ::token]]] + [:tokens [:and [:map-of {:gen/max 5} :string ::token] + [:fn d/ordered-map?]]]] [:fn (partial instance? TokenSet)]]) (sm/register! ::token-set schema:token-set) @@ -119,6 +202,16 @@ token-set)) +;; === TokenSetGroup + +(defrecord TokenSetGroup [attr1 attr2]) + +;; TODO schema, validators, etc. + +(defn make-token-set-group + [] + (TokenSetGroup. "one" "two")) + ;; === TokenSets (collection) (defprotocol ITokenSets @@ -126,14 +219,24 @@ (update-set [_ set-name f] "modify a set in the ilbrary") (delete-set [_ set-name] "delete a set in the library") (set-count [_] "get the total number if sets in the library") + (get-set-tree [_] "get a nested tree of all sets in the library") (get-sets [_] "get an ordered sequence of all sets in the library") (get-set [_ set-name] "get one set looking for name") - (validate [_])) + (get-set-group [_ set-group-path] "get the attributes of a set group")) + +(def schema:token-set-node + [:schema {:registry {::node [:or ::token-set + [:and + [:map-of {:gen/max 5} :string [:ref ::node]] + [:fn d/ordered-map?]]]}} + [:ref ::node]]) + +(sm/register! ::token-set-node schema:token-set-node) (def schema:token-sets [:and [:map-of {:title "TokenSets"} - :string ::token-set] + :string ::token-set-node] [:fn d/ordered-map?]]) (sm/register! ::token-sets schema:token-sets) @@ -144,10 +247,83 @@ (def check-token-sets! (sm/check-fn ::token-sets)) +;; === TokenTheme + +(defprotocol ITokenTheme + (toggle-set [_ set-name] "togle a set used / not used in the theme")) + +(defrecord TokenTheme [name group description is-source modified-at sets] + ITokenTheme + (toggle-set [_ set-name] + (TokenTheme. name + group + description + is-source + (dt/now) + (if (sets set-name) + (disj sets set-name) + (conj sets set-name))))) + +(def schema:token-theme + [:and [:map {:title "TokenTheme"} + [:name :string] + [:group :string] + [:description [:maybe :string]] + [:is-source :boolean] + [:modified-at ::sm/inst] + [:sets [:and [:set {:gen/max 5} :string] + [:fn d/ordered-set?]]]] + [:fn (partial instance? TokenTheme)]]) + +(sm/register! ::token-theme schema:token-theme) + +(def valid-token-theme? + (sm/validator schema:token-theme)) + +(def check-token-theme! + (sm/check-fn ::token-theme)) + +(defn make-token-theme + [& {:keys [] :as params}] + (let [params (-> params + (dissoc :id) + (update :group #(or % "")) + (update :is-source #(or % false)) + (update :modified-at #(or % (dt/now))) + (update :sets #(into (d/ordered-set) %))) + token-theme (map->TokenTheme params)] + + (dm/assert! + "expected valid token theme" + (check-token-theme! token-theme)) + + token-theme)) + ;; === TokenThemes (collection) +(defprotocol ITokenThemes + (add-theme [_ token-theme] "add a theme to the library, at the end") + (update-theme [_ group name f] "modify a theme in the ilbrary") + (delete-theme [_ group name] "delete a theme in the library") + (theme-count [_] "get the total number if themes in the library") + (get-theme-tree [_] "get a nested tree of all themes in the library") + (get-themes [_] "get an ordered sequence of all themes in the library") + (get-theme [_ group name] "get one theme looking for name")) + +(def schema:token-themes + [:and + [:map-of {:title "TokenThemes"} + :string [:and [:map-of :string ::token-theme] + [:fn d/ordered-map?]]] + [:fn d/ordered-map?]]) + +(sm/register! ::token-themes schema:token-themes) + (def valid-token-themes? - (constantly true)) + (sm/validator schema:token-themes)) + +(def check-token-themes! + (sm/check-fn ::token-themes)) ;; === Tokens Lib @@ -155,62 +331,122 @@ "A library of tokens, sets and themes." (add-token-in-set [_ set-name token] "add token to a set") (update-token-in-set [_ set-name token-name f] "update a token in a set") - (delete-token-from-set [_ set-name token-name] "delete a token from a set")) + (delete-token-from-set [_ set-name token-name] "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") + (validate [_])) -(deftype TokensLib [sets themes] +(deftype TokensLib [sets set-groups themes] ;; NOTE: This is only for debug purposes, pending to properly ;; implement the toString and alternative printing. #?@(:clj [clojure.lang.IDeref - (deref [_] {:sets sets :themes themes})] + (deref [_] {:sets sets :set-groups set-groups :themes themes})] :cljs [cljs.core/IDeref - (-deref [_] {:sets sets :themes themes})]) + (-deref [_] {:sets sets :set-groups set-groups :themes themes})]) #?@(:cljs [cljs.core/IEncodeJS (-clj->js [_] (js-obj "sets" (clj->js sets) + "set-groups" (clj->js set-groups) "themes" (clj->js themes)))]) ITokenSets (add-set [_ token-set] (dm/assert! "expected valid token set" (check-token-set! token-set)) - (TokensLib. (assoc sets (:name token-set) token-set) - themes)) + (let [path (get-path token-set "/") + groups-str (get-groups-str token-set "/")] + (TokensLib. (d/oassoc-in sets path token-set) + (cond-> set-groups + (not (str/empty? groups-str)) + (assoc groups-str (make-token-set-group))) + themes))) (update-set [this set-name f] - (if-let [set (get sets set-name)] - (let [set' (-> (make-token-set (f set)) - (assoc :modified-at (dt/now)))] - (check-token-set! set') - (TokensLib. (if (= (:name set) (:name set')) - (assoc sets (:name set') set') - (let [index (d/index-of (keys sets) (:name set))] + (let [path (split-path set-name "/") + set (get-in sets path)] + (if set + (let [set' (-> (make-token-set (f set)) + (assoc :modified-at (dt/now))) + path' (get-path set' "/")] + (check-token-set! set') + (TokensLib. (if (= (:name set) (:name set')) + (d/oassoc-in sets path set') (-> sets - (dissoc (:name set)) - (d/addm-at-index index (:name set') set')))) - themes)) - this)) + (d/oassoc-in-before path path' set') + (d/dissoc-in path))) + set-groups ;; TODO update set-groups as needed + themes)) + this))) (delete-set [_ set-name] - (TokensLib. (dissoc sets set-name) - themes)) + (let [path (split-path set-name "/")] + (TokensLib. (d/dissoc-in sets path) + set-groups ;; TODO remove set-group if needed + themes))) - (validate [_] - (and (valid-token-sets? sets) - (valid-token-themes? themes))) - - (set-count [_] - (count sets)) + (get-set-tree [_] + sets) (get-sets [_] - (vals sets)) + (->> (tree-seq d/ordered-map? vals sets) + (filter (partial instance? TokenSet)))) + + (set-count [this] + (count (get-sets this))) (get-set [_ set-name] - (get sets set-name)) + (let [path (split-path set-name "/")] + (get-in sets path))) + + (get-set-group [_ set-group-path] + (get set-groups set-group-path)) + + ITokenThemes + (add-theme [_ token-theme] + (dm/assert! "expected valid token theme" (check-token-theme! token-theme)) + (TokensLib. sets + set-groups + (update themes (:group token-theme) d/oassoc (:name token-theme) token-theme))) + + (update-theme [this group name f] + (let [theme (dm/get-in themes [group name])] + (if theme + (let [theme' (-> (make-token-theme (f theme)) + (assoc :modified-at (dt/now))) + group' (:group theme') + name' (:name theme')] + (check-token-theme! theme') + (TokensLib. sets + set-groups + (if (and (= group group') (= name name')) + (update themes group' assoc name' theme') + (-> themes + (d/oassoc-in-before [group name] [group' name'] theme') + (d/dissoc-in [group name]))))) + this))) + + (delete-theme [_ group name] + (TokensLib. sets + set-groups + (d/dissoc-in themes [group name]))) + + (get-theme-tree [_] + themes) + + (get-themes [_] + (->> (tree-seq d/ordered-map? vals themes) + (filter (partial instance? TokenTheme)))) + + (theme-count [this] + (count (get-themes this))) + + (get-theme [_ group name] + (dm/get-in themes [group name])) ITokensLib (add-token-in-set [this set-name token] (dm/assert! "expected valid token instance" (check-token! token)) (if (contains? sets set-name) (TokensLib. (update sets set-name add-token token) + set-groups themes) this)) @@ -218,6 +454,7 @@ (if (contains? sets set-name) (TokensLib. (update sets set-name #(update-token % token-name f)) + set-groups themes) this)) @@ -225,8 +462,21 @@ (if (contains? sets set-name) (TokensLib. (update sets set-name #(delete-token % token-name)) + set-groups themes) - this))) + this)) + + (toggle-set-in-theme [this theme-group theme-name set-name] + (if-let [_theme (get-in themes theme-group theme-name)] + (TokensLib. sets + set-groups + (d/oupdate-in themes [theme-group theme-name] + #(toggle-set % set-name))) + this)) + + (validate [_] + (and (valid-token-sets? sets) ;; TODO: validate set-groups + (valid-token-themes? themes)))) (defn valid-tokens-lib? [o] @@ -248,10 +498,11 @@ ;; structure the data and the order separately as we already do ;; with pages and pages-index. (make-tokens-lib :sets (d/ordered-map) + :set-groups {} :themes (d/ordered-map))) - ([& {:keys [sets themes]}] - (let [tokens-lib (TokensLib. sets themes)] + ([& {:keys [sets set-groups themes]}] + (let [tokens-lib (TokensLib. sets set-groups themes)] (dm/assert! "expected valid tokens lib" @@ -269,7 +520,7 @@ (sm/register! ::tokens-lib type:tokens-lib) -;; === Serialization handlers for RPC API and database +;; === Serialization handlers for RPC API (transit) and database (fressian) (t/add-handlers! {:id "penpot/tokens-lib" @@ -281,6 +532,11 @@ :class TokenSet :wfn #(into {} %) :rfn #(make-token-set %)} + + {:id "penpot/token-theme" + :class TokenTheme + :wfn #(into {} %) + :rfn #(make-token-theme %)} {:id "penpot/token" :class Token @@ -307,13 +563,24 @@ (let [obj (fres/read-object! r)] (map->TokenSet obj)))} + {:name "penpot/token-theme/v1" + :class TokenTheme + :wfn (fn [n w o] + (fres/write-tag! w n 1) + (fres/write-object! w (into {} o))) + :rfn (fn [r] + (let [obj (fres/read-object! r)] + (map->TokenTheme obj)))} + {:name "penpot/tokens-lib/v1" :class TokensLib :wfn (fn [n w o] - (fres/write-tag! w n 2) + (fres/write-tag! w n 3) (fres/write-object! w (.-sets o)) + (fres/write-object! w (.-set-groups o)) (fres/write-object! w (.-themes o))) :rfn (fn [r] - (let [sets (fres/read-object! r) - themes (fres/read-object! r)] - (->TokensLib sets themes)))})) + (let [sets (fres/read-object! r) + set-groups (fres/read-object! r) + themes (fres/read-object! r)] + (->TokensLib sets set-groups themes)))})) diff --git a/common/src/app/common/types/tokens_theme_list.cljc b/common/src/app/common/types/tokens_theme_list.cljc index f9c3857ff..971c96946 100644 --- a/common/src/app/common/types/tokens_theme_list.cljc +++ b/common/src/app/common/types/tokens_theme_list.cljc @@ -19,16 +19,17 @@ (assoc file-data :token-active-themes theme-ids)) (defn add-temporary-token-theme - [file-data {:keys [id] :as token-theme}] + [file-data {:keys [id name] :as token-theme}] (-> file-data (d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)]) (assoc :token-theme-temporary-id id) + (assoc :token-theme-temporary-name name) (update :token-themes-index assoc id token-theme))) (defn delete-temporary-token-theme [file-data token-theme-id] (cond-> file-data - (= (:token-theme-temporary-id file-data) token-theme-id) (dissoc :token-theme-temporary-id) + (= (:token-theme-temporary-id file-data) token-theme-id) (dissoc :token-theme-temporary-id :token-theme-temporary-name) :always (d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)]))) (defn add-token-theme diff --git a/common/test/common_tests/types/tokens_lib_test.cljc b/common/test/common_tests/types/tokens_lib_test.cljc index 09ad19b17..fd342c95c 100644 --- a/common/test/common_tests/types/tokens_lib_test.cljc +++ b/common/test/common_tests/types/tokens_lib_test.cljc @@ -13,247 +13,933 @@ [app.common.types.tokens-lib :as ctob] [clojure.test :as t])) -(t/deftest make-token - (let [now (dt/now) - token1 (ctob/make-token :name "test-token-1" - :type :boolean - :value true) - token2 (ctob/make-token :name "test-token-2" - :type :numeric - :value 66 - :description "test description" - :modified-at now)] +(t/testing "token" + (t/deftest make-token + (let [now (dt/now) + token1 (ctob/make-token :name "test-token-1" + :type :boolean + :value true) + token2 (ctob/make-token :name "test-token-2" + :type :numeric + :value 66 + :description "test description" + :modified-at now)] - (t/is (= (:name token1) "test-token-1")) - (t/is (= (:type token1) :boolean)) - (t/is (= (:value token1) true)) - (t/is (nil? (:description token1))) - (t/is (some? (:modified-at token1))) - (t/is (ctob/valid-token? token1)) + (t/is (= (:name token1) "test-token-1")) + (t/is (= (:type token1) :boolean)) + (t/is (= (:value token1) true)) + (t/is (nil? (:description token1))) + (t/is (some? (:modified-at token1))) + (t/is (ctob/valid-token? token1)) - (t/is (= (:name token2) "test-token-2")) - (t/is (= (:type token2) :numeric)) - (t/is (= (:value token2) 66)) - (t/is (= (:description token2) "test description")) - (t/is (= (:modified-at token2) now)) - (t/is (ctob/valid-token? token2)))) + (t/is (= (:name token2) "test-token-2")) + (t/is (= (:type token2) :numeric)) + (t/is (= (:value token2) 66)) + (t/is (= (:description token2) "test description")) + (t/is (= (:modified-at token2) now)) + (t/is (ctob/valid-token? token2)))) -(t/deftest invalid-tokens - (let [args {:name 777 - :type :invalid}] - (t/is (thrown-with-msg? Exception #"expected valid token" - (apply ctob/make-token args))) - (t/is (false? (ctob/valid-token? {}))))) + (t/deftest invalid-tokens + (let [args {:name 777 + :type :invalid}] + (t/is (thrown-with-msg? Exception #"expected valid token" + (apply ctob/make-token args))) + (t/is (false? (ctob/valid-token? {})))))) -(t/deftest make-token-set - (let [now (dt/now) - token-set1 (ctob/make-token-set :name "test-token-set-1") - token-set2 (ctob/make-token-set :name "test-token-set-2" - :description "test description" - :modified-at now - :tokens [])] - (t/is (= (:name token-set1) "test-token-set-1")) - (t/is (nil? (:description token-set1))) - (t/is (some? (:modified-at token-set1))) - (t/is (empty? (:tokens token-set1))) +(t/testing "token-set" + (t/deftest make-token-set + (let [now (dt/now) + token-set1 (ctob/make-token-set :name "test-token-set-1") + token-set2 (ctob/make-token-set :name "test-token-set-2" + :description "test description" + :modified-at now + :tokens [])] - (t/is (= (:name token-set2) "test-token-set-2")) - (t/is (= (:description token-set2) "test description")) - (t/is (= (:modified-at token-set2) now)) - (t/is (empty? (:tokens token-set2))))) + (t/is (= (:name token-set1) "test-token-set-1")) + (t/is (nil? (:description token-set1))) + (t/is (some? (:modified-at token-set1))) + (t/is (empty? (:tokens token-set1))) -(t/deftest invalid-token-set - (let [args {:name 777 - :description 999}] - (t/is (thrown-with-msg? Exception #"expected valid token set" - (apply ctob/make-token-set args))))) + (t/is (= (:name token-set2) "test-token-set-2")) + (t/is (= (:description token-set2) "test description")) + (t/is (= (:modified-at token-set2) now)) + (t/is (empty? (:tokens token-set2))))) -(t/deftest make-tokens-lib - (let [tokens-lib (ctob/make-tokens-lib)] - (t/is (= (ctob/set-count tokens-lib) 0)))) + (t/deftest invalid-token-set + (let [args {:name 777 + :description 999}] + (t/is (thrown-with-msg? Exception #"expected valid token set" + (apply ctob/make-token-set args)))))) -(t/deftest add-token-set - (let [tokens-lib (ctob/make-tokens-lib) - token-set (ctob/make-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")] +(t/testing "token-theme" + (t/deftest make-token-theme + (let [now (dt/now) + token-theme1 (ctob/make-token-theme :name "test-token-theme-1") + token-theme2 (ctob/make-token-theme :name "test-token-theme-2" + :group "group-1" + :description "test description" + :is-source true + :modified-at now + :sets #{})] - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (first token-sets') token-set)) - (t/is (= token-set' token-set)))) + (t/is (= (:name token-theme1) "test-token-theme-1")) + (t/is (= (:group token-theme1) "")) + (t/is (nil? (:description token-theme1))) + (t/is (false? (:is-source token-theme1))) + (t/is (some? (:modified-at token-theme1))) + (t/is (empty? (:sets token-theme1))) -(t/deftest update-token-set - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set"))) + (t/is (= (:name token-theme2) "test-token-theme-2")) + (t/is (= (:group token-theme2) "group-1")) + (t/is (= (:description token-theme2) "test description")) + (t/is (true? (:is-source token-theme2))) + (t/is (= (:modified-at token-theme2) now)) + (t/is (empty? (:sets token-theme2))))) - tokens-lib' (-> tokens-lib - (ctob/update-set "test-token-set" - (fn [token-set] - (assoc token-set - :name "updated-name" - :description "some description"))) - (ctob/update-set "not-existing-set" - (fn [token-set] - (assoc token-set - :name "no-effect")))) + (t/deftest invalid-token-theme + (let [args {:name 777 + :group nil + :description 999 + :is-source 42}] + (t/is (thrown-with-msg? Exception #"expected valid token theme" + (apply ctob/make-token-theme args)))))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "updated-name")] - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (:name token-set') "updated-name")) - (t/is (= (:description token-set') "some description")) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) +(t/testing "tokens-lib" + (t/deftest make-tokens-lib + (let [tokens-lib (ctob/make-tokens-lib)] + (t/is (= (ctob/set-count tokens-lib) 0)))) -(t/deftest delete-token-set - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set"))) + (t/deftest invalid-tokens-lib + (let [args {:sets nil + :themes nil}] + (t/is (thrown-with-msg? Exception #"expected valid tokens lib" + (apply ctob/make-tokens-lib args)))))) - tokens-lib' (-> tokens-lib - (ctob/delete-set "test-token-set") - (ctob/delete-set "not-existing-set")) - token-set' (ctob/get-set tokens-lib' "updated-name")] +(t/testing "token-set in a lib" + (t/deftest add-token-set + (let [tokens-lib (ctob/make-tokens-lib) + token-set (ctob/make-token-set :name "test-token-set") + tokens-lib' (ctob/add-set tokens-lib token-set) - (t/is (= (ctob/set-count tokens-lib') 0)) - (t/is (nil? token-set')))) + token-sets' (ctob/get-sets tokens-lib') + token-set' (ctob/get-set tokens-lib' "test-token-set")] -(t/deftest add-token - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set"))) - token (ctob/make-token :name "test-token" - :type :boolean - :value true) - tokens-lib' (-> tokens-lib - (ctob/add-token-in-set "test-token-set" token) - (ctob/add-token-in-set "not-existing-set" token)) + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (first token-sets') token-set)) + (t/is (= token-set' token-set)))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") - token' (get-in token-set' [:tokens "test-token"])] + (t/deftest add-token-set-with-group + (let [tokens-lib (ctob/make-tokens-lib) + token-set (ctob/make-token-set :name "test-group/test-token-set") + tokens-lib' (ctob/add-set tokens-lib token-set) - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (count (:tokens token-set')) 1)) - (t/is (= (:name token') "test-token")) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + set-group (ctob/get-set-group tokens-lib' "test-group")] -(t/deftest update-token - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set")) - (ctob/add-token-in-set "test-token-set" - (ctob/make-token :name "test-token-1" - :type :boolean - :value true)) - (ctob/add-token-in-set "test-token-set" - (ctob/make-token :name "test-token-2" - :type :boolean - :value true))) + (t/is (= (:attr1 set-group) "one")) + (t/is (= (:attr2 set-group) "two")))) - tokens-lib' (-> tokens-lib - (ctob/update-token-in-set "test-token-set" "test-token-1" - (fn [token] - (assoc token - :description "some description" - :value false))) - (ctob/update-token-in-set "not-existing-set" "test-token-1" - (fn [token] - (assoc token - :name "no-effect"))) - (ctob/update-token-in-set "test-token-set" "not-existing-token" - (fn [token] - (assoc token - :name "no-effect")))) + (t/deftest update-token-set + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set"))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") - token (get-in token-set [:tokens "test-token-1"]) - token' (get-in token-set' [:tokens "test-token-1"])] + tokens-lib' (-> tokens-lib + (ctob/update-set "test-token-set" + (fn [token-set] + (assoc token-set + :description "some description"))) + (ctob/update-set "not-existing-set" + (fn [token-set] + (assoc token-set + :description "no-effect")))) - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (count (:tokens token-set')) 2)) - (t/is (= (d/index-of (keys (:tokens token-set')) "test-token-1") 0)) - (t/is (= (:name token') "test-token-1")) - (t/is (= (:description token') "some description")) - (t/is (= (:value token') false)) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))) - (t/is (dt/is-after? (:modified-at token') (:modified-at token))))) + token-set (ctob/get-set tokens-lib "test-token-set") + token-set' (ctob/get-set tokens-lib' "test-token-set")] -(t/deftest rename-token - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set")) - (ctob/add-token-in-set "test-token-set" - (ctob/make-token :name "test-token-1" - :type :boolean - :value true)) - (ctob/add-token-in-set "test-token-set" - (ctob/make-token :name "test-token-2" - :type :boolean - :value true))) + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (:name token-set') "test-token-set")) + (t/is (= (:description token-set') "some description")) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) - tokens-lib' (-> tokens-lib - (ctob/update-token-in-set "test-token-set" "test-token-1" - (fn [token] - (assoc token - :name "updated-name")))) + (t/deftest rename-token-set + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set"))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") - token (get-in token-set [:tokens "test-token-1"]) - token' (get-in token-set' [:tokens "updated-name"])] + tokens-lib' (-> tokens-lib + (ctob/update-set "test-token-set" + (fn [token-set] + (assoc token-set + :name "updated-name")))) - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (count (:tokens token-set')) 2)) - (t/is (= (d/index-of (keys (:tokens token-set')) "updated-name") 0)) - (t/is (= (:name token') "updated-name")) - (t/is (= (:description token') nil)) - (t/is (= (:value token') true)) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))) - (t/is (dt/is-after? (:modified-at token') (:modified-at token))))) + token-set (ctob/get-set tokens-lib "test-token-set") + token-set' (ctob/get-set tokens-lib' "updated-name")] -(t/deftest delete-token - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set")) - (ctob/add-token-in-set "test-token-set" - (ctob/make-token :name "test-token" - :type :boolean - :value true))) - tokens-lib' (-> tokens-lib - (ctob/delete-token-from-set "test-token-set" "test-token") - (ctob/delete-token-from-set "not-existing-set" "test-token") - (ctob/delete-token-from-set "test-set" "not-existing-token")) + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (:name token-set') "updated-name")) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set") - token' (get-in token-set' [:tokens "test-token"])] + (t/deftest delete-token-set + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set"))) - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (count (:tokens token-set')) 0)) - (t/is (nil? token')) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + tokens-lib' (-> tokens-lib + (ctob/delete-set "test-token-set") + (ctob/delete-set "not-existing-set")) -(t/deftest transit-serialization - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set")) - (ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token" - :type :boolean - :value true))) - encoded-str (tr/encode-str tokens-lib) - tokens-lib' (tr/decode-str encoded-str)] + token-set' (ctob/get-set tokens-lib' "updated-name")] - (t/is (ctob/valid-tokens-lib? tokens-lib')) - (t/is (= (ctob/set-count tokens-lib') 1)))) + (t/is (= (ctob/set-count tokens-lib') 0)) + (t/is (nil? token-set'))))) -(t/deftest fressian-serialization - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set")) - (ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token" - :type :boolean - :value true))) - encoded-blob (fres/encode tokens-lib) - tokens-lib' (fres/decode encoded-blob)] - (t/is (ctob/valid-tokens-lib? tokens-lib')) - (t/is (= (ctob/set-count tokens-lib') 1)))) +(t/testing "token in a lib" + (t/deftest add-token + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set"))) + token (ctob/make-token :name "test-token" + :type :boolean + :value true) + tokens-lib' (-> tokens-lib + (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") + token' (get-in token-set' [:tokens "test-token"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 1)) + (t/is (= (:name token') "test-token")) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + + (t/deftest update-token + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token-1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token-2" + :type :boolean + :value true))) + + tokens-lib' (-> tokens-lib + (ctob/update-token-in-set "test-token-set" "test-token-1" + (fn [token] + (assoc token + :description "some description" + :value false))) + (ctob/update-token-in-set "not-existing-set" "test-token-1" + (fn [token] + (assoc token + :name "no-effect"))) + (ctob/update-token-in-set "test-token-set" "not-existing-token" + (fn [token] + (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 (get-in token-set [:tokens "test-token-1"]) + token' (get-in token-set' [:tokens "test-token-1"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 2)) + (t/is (= (d/index-of (keys (:tokens token-set')) "test-token-1") 0)) + (t/is (= (:name token') "test-token-1")) + (t/is (= (:description token') "some description")) + (t/is (= (:value token') false)) + (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/deftest rename-token + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token-1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token-2" + :type :boolean + :value true))) + + tokens-lib' (-> tokens-lib + (ctob/update-token-in-set "test-token-set" "test-token-1" + (fn [token] + (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 (get-in token-set [:tokens "test-token-1"]) + token' (get-in token-set' [:tokens "updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 2)) + (t/is (= (d/index-of (keys (:tokens token-set')) "updated-name") 0)) + (t/is (= (:name token') "updated-name")) + (t/is (= (:description token') nil)) + (t/is (= (:value token') true)) + (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/deftest delete-token + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token" + :type :boolean + :value true))) + tokens-lib' (-> tokens-lib + (ctob/delete-token-from-set "test-token-set" "test-token") + (ctob/delete-token-from-set "not-existing-set" "test-token") + (ctob/delete-token-from-set "test-set" "not-existing-token")) + + token-set (ctob/get-set tokens-lib "test-token-set") + token-set' (ctob/get-set tokens-lib' "test-token-set") + token' (get-in token-set' [:tokens "test-token"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 0)) + (t/is (nil? token')) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))) + + +(t/testing "token-theme in a lib" + (t/deftest add-token-theme + (let [tokens-lib (ctob/make-tokens-lib) + token-theme (ctob/make-token-theme :name "test-token-theme") + tokens-lib' (ctob/add-theme tokens-lib token-theme) + + token-themes' (ctob/get-themes tokens-lib') + token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] + + (t/is (= (ctob/theme-count tokens-lib') 1)) + (t/is (= (first token-themes') token-theme)) + (t/is (= token-theme' token-theme)))) + + (t/deftest update-token-theme + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) + + tokens-lib' (-> tokens-lib + (ctob/update-theme "" "test-token-theme" + (fn [token-theme] + (assoc token-theme + :description "some description"))) + (ctob/update-theme "" "not-existing-theme" + (fn [token-theme] + (assoc token-theme + :description "no-effect")))) + + token-theme (ctob/get-theme tokens-lib "" "test-token-theme") + token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] + + (t/is (= (ctob/theme-count tokens-lib') 1)) + (t/is (= (:name token-theme') "test-token-theme")) + (t/is (= (:description token-theme') "some description")) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) + + (t/deftest rename-token-theme + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) + + tokens-lib' (-> tokens-lib + (ctob/update-theme "" "test-token-theme" + (fn [token-theme] + (assoc token-theme + :name "updated-name")))) + + token-theme (ctob/get-theme tokens-lib "" "test-token-theme") + token-theme' (ctob/get-theme tokens-lib' "" "updated-name")] + + (t/is (= (ctob/theme-count tokens-lib') 1)) + (t/is (= (:name token-theme') "updated-name")) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) + + (t/deftest delete-token-theme + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) + + tokens-lib' (-> tokens-lib + (ctob/delete-theme "" "test-token-theme") + (ctob/delete-theme "" "not-existing-theme")) + + token-theme' (ctob/get-theme tokens-lib' "" "updated-name")] + + (t/is (= (ctob/theme-count tokens-lib') 0)) + (t/is (nil? token-theme')))) + + (t/deftest toggle-set-in-theme + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "token-set-1")) + (ctob/add-set (ctob/make-token-set :name "token-set-2")) + (ctob/add-set (ctob/make-token-set :name "token-set-3")) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) + tokens-lib' (-> tokens-lib + (ctob/toggle-set-in-theme "" "test-token-theme" "token-set-1") + (ctob/toggle-set-in-theme "" "test-token-theme" "token-set-2") + (ctob/toggle-set-in-theme "" "test-token-theme" "token-set-2")) + + token-theme (ctob/get-theme tokens-lib "" "test-token-theme") + token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] + + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))) + + +(t/testing "serialization" + (t/deftest transit-serialization + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token" + :type :boolean + :value true)) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme")) + (ctob/toggle-set-in-theme "" "test-token-theme" "test-token-set")) + encoded-str (tr/encode-str tokens-lib) + tokens-lib' (tr/decode-str encoded-str)] + + (t/is (ctob/valid-tokens-lib? tokens-lib')) + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (ctob/theme-count tokens-lib') 1)))) + + (t/deftest fressian-serialization + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token" + :type :boolean + :value true)) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme")) + (ctob/toggle-set-in-theme "" "test-token-theme" "test-token-set")) + encoded-blob (fres/encode tokens-lib) + tokens-lib' (fres/decode encoded-blob)] + + (t/is (ctob/valid-tokens-lib? tokens-lib')) + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (ctob/theme-count tokens-lib') 1))))) + +(t/testing "grouping" + (t/deftest split-and-join + (let [name "group/subgroup/name" + path (ctob/split-path name "/") + name' (ctob/join-path path "/")] + (t/is (= (first path) "group")) + (t/is (= (second path) "subgroup")) + (t/is (= (nth path 2) "name")) + (t/is (= name' name)))) + + (t/deftest remove-spaces + (let [name "group / subgroup / name" + path (ctob/split-path name "/")] + (t/is (= (first path) "group")) + (t/is (= (second path) "subgroup")) + (t/is (= (nth path 2) "name")))) + + (t/deftest group-and-ungroup + (let [token-set1 (ctob/make-token-set :name "token-set1") + token-set2 (ctob/make-token-set :name "some group/token-set2") + + token-set1' (ctob/group-item token-set1 "big group" "/") + token-set2' (ctob/group-item token-set2 "big group" "/") + token-set1'' (ctob/ungroup-item token-set1' "/") + token-set2'' (ctob/ungroup-item token-set2' "/")] + (t/is (= (:name token-set1') "big group/token-set1")) + (t/is (= (:name token-set2') "big group/some group/token-set2")) + (t/is (= (:name token-set1'') "token-set1")) + (t/is (= (:name token-set2'') "some group/token-set2")))) + + (t/deftest get-groups-str + (let [token-set1 (ctob/make-token-set :name "token-set1") + token-set2 (ctob/make-token-set :name "some-group/token-set2") + token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")] + (t/is (= (ctob/get-groups-str token-set1 "/") "")) + (t/is (= (ctob/get-groups-str token-set2 "/") "some-group")) + (t/is (= (ctob/get-groups-str token-set3 "/") "some-group/some-subgroup")))) + + (t/deftest get-final-name + (let [token-set1 (ctob/make-token-set :name "token-set1") + token-set2 (ctob/make-token-set :name "some-group/token-set2") + token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")] + (t/is (= (ctob/get-final-name token-set1 "/") "token-set1")) + (t/is (= (ctob/get-final-name token-set2 "/") "token-set2")) + (t/is (= (ctob/get-final-name token-set3 "/") "token-set3")))) + + (t/testing "grouped tokens" + (t/deftest grouped-tokens + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "token1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.token2" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.token3" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.subgroup11.token4" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group2.token5" + :type :boolean + :value true))) + + set (ctob/get-set tokens-lib "test-token-set") + tokens-list (vals (:tokens set))] + + (t/is (= (count tokens-list) 5)) + (t/is (= (:name (nth tokens-list 0)) "token1")) + (t/is (= (:name (nth tokens-list 1)) "group1.token2")) + (t/is (= (:name (nth tokens-list 2)) "group1.token3")) + (t/is (= (:name (nth tokens-list 3)) "group1.subgroup11.token4")) + (t/is (= (:name (nth tokens-list 4)) "group2.token5")))) + + (t/deftest update-token-in-groups + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token-1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.test-token-2" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.test-token-3" + :type :boolean + :value true))) + + tokens-lib' (-> tokens-lib + (ctob/update-token-in-set "test-token-set" "group1.test-token-2" + (fn [token] + (assoc token + :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 (get-in token-set [:tokens "group1.test-token-2"]) + token' (get-in token-set' [:tokens "group1.test-token-2"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (:name token') "group1.test-token-2")) + (t/is (= (:description token') "some description")) + (t/is (= (:value token') false)) + (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/deftest rename-token-in-groups + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token-1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.test-token-2" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.test-token-3" + :type :boolean + :value true))) + + tokens-lib' (-> tokens-lib + (ctob/update-token-in-set "test-token-set" "group1.test-token-2" + (fn [token] + (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 (get-in token-set [:tokens "group1.test-token-2"]) + token' (get-in token-set' [:tokens "group1.updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (:name token') "group1.updated-name")) + (t/is (= (:description token') nil)) + (t/is (= (:value token') true)) + (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/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-token-in-set "test-token-set" + (ctob/make-token :name "test-token-1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.test-token-2" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.test-token-3" + :type :boolean + :value true))) + + tokens-lib' (-> tokens-lib + (ctob/update-token-in-set "test-token-set" "group1.test-token-2" + (fn [token] + (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 (get-in token-set [:tokens "group1.test-token-2"]) + token' (get-in token-set' [:tokens "group2.updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (d/index-of (keys (:tokens token-set')) "group2.updated-name") 1)) + (t/is (= (:name token') "group2.updated-name")) + (t/is (= (:description token') nil)) + (t/is (= (:value token') true)) + (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/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-token-in-set "test-token-set" + (ctob/make-token :name "test-token-1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "group1.test-token-2" + :type :boolean + :value true))) + tokens-lib' (-> tokens-lib + (ctob/delete-token-from-set "test-token-set" "group1.test-token-2")) + + token-set (ctob/get-set tokens-lib "test-token-set") + token-set' (ctob/get-set tokens-lib' "test-token-set") + token' (get-in token-set' [:tokens "group1.test-token-2"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 1)) + (t/is (nil? token')) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))) + + (t/testing "grouped sets" + (t/deftest grouped-sets + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "token-set-1")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-3")) + (ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4")) + (ctob/add-set (ctob/make-token-set :name "group2/token-set-5"))) + + sets-list (ctob/get-sets tokens-lib) + + sets-tree (ctob/get-set-tree tokens-lib) + + [node-set1 node-group1 node-group2] + (ctob/get-children sets-tree) + + [node-set2 node-set3 node-subgroup11] + (ctob/get-children (second node-group1)) + + [node-set4] + (ctob/get-children (second node-subgroup11)) + + [node-set5] + (ctob/get-children (second node-group2))] + + (t/is (= (count sets-list) 5)) + (t/is (= (:name (nth sets-list 0)) "token-set-1")) + (t/is (= (:name (nth sets-list 1)) "group1/token-set-2")) + (t/is (= (:name (nth sets-list 2)) "group1/token-set-3")) + (t/is (= (:name (nth sets-list 3)) "group1/subgroup11/token-set-4")) + (t/is (= (:name (nth sets-list 4)) "group2/token-set-5")) + + (t/is (= (first node-set1) "token-set-1")) + (t/is (= (ctob/group? (second node-set1)) false)) + (t/is (= (:name (second node-set1)) "token-set-1")) + + (t/is (= (first node-group1) "group1")) + (t/is (= (ctob/group? (second node-group1)) true)) + (t/is (= (count (second node-group1)) 3)) + + (t/is (= (first node-set2) "token-set-2")) + (t/is (= (ctob/group? (second node-set2)) false)) + (t/is (= (:name (second node-set2)) "group1/token-set-2")) + + (t/is (= (first node-set3) "token-set-3")) + (t/is (= (ctob/group? (second node-set3)) false)) + (t/is (= (:name (second node-set3)) "group1/token-set-3")) + + (t/is (= (first node-subgroup11) "subgroup11")) + (t/is (= (ctob/group? (second node-subgroup11)) true)) + (t/is (= (count (second node-subgroup11)) 1)) + + (t/is (= (first node-set4) "token-set-4")) + (t/is (= (ctob/group? (second node-set4)) false)) + (t/is (= (:name (second node-set4)) "group1/subgroup11/token-set-4")) + + (t/is (= (first node-set5) "token-set-5")) + (t/is (= (ctob/group? (second node-set5)) false)) + (t/is (= (:name (second node-set5)) "group2/token-set-5")))) + + (t/deftest update-set-in-groups + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "token-set-1")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-3")) + (ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4")) + (ctob/add-set (ctob/make-token-set :name "group2/token-set-5"))) + + tokens-lib' (-> tokens-lib + (ctob/update-set "group1/token-set-2" + (fn [token-set] + (assoc token-set :description "some description")))) + + sets-tree (ctob/get-set-tree tokens-lib) + sets-tree' (ctob/get-set-tree tokens-lib') + group1' (get sets-tree' "group1") + token-set (get-in sets-tree ["group1" "token-set-2"]) + token-set' (get-in sets-tree' ["group1" "token-set-2"])] + + (t/is (= (ctob/set-count tokens-lib') 5)) + (t/is (= (count group1') 3)) + (t/is (= (d/index-of (keys group1') "token-set-2") 0)) + (t/is (= (:name token-set') "group1/token-set-2")) + (t/is (= (:description token-set') "some description")) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + + (t/deftest rename-set-in-groups + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "token-set-1")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-3")) + (ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4")) + (ctob/add-set (ctob/make-token-set :name "group2/token-set-5"))) + + tokens-lib' (-> tokens-lib + (ctob/update-set "group1/token-set-2" + (fn [token-set] + (assoc token-set + :name "group1/updated-name")))) + + sets-tree (ctob/get-set-tree tokens-lib) + sets-tree' (ctob/get-set-tree tokens-lib') + group1' (get sets-tree' "group1") + token-set (get-in sets-tree ["group1" "token-set-2"]) + token-set' (get-in sets-tree' ["group1" "updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 5)) + (t/is (= (count group1') 3)) + (t/is (= (d/index-of (keys group1') "updated-name") 0)) + (t/is (= (:name token-set') "group1/updated-name")) + (t/is (= (:description token-set') nil)) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + + (t/deftest move-set-of-group + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "token-set-1")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-3")) + (ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4")) + #_(ctob/add-set (ctob/make-token-set :name "group2/token-set-5"))) + + tokens-lib' (-> tokens-lib + (ctob/update-set "group1/token-set-2" + (fn [token-set] + (assoc token-set + :name "group2/updated-name")))) + + sets-tree (ctob/get-set-tree tokens-lib) + sets-tree' (ctob/get-set-tree tokens-lib') + group1' (get sets-tree' "group1") + group2' (get sets-tree' "group2") + token-set (get-in sets-tree ["group1" "token-set-2"]) + token-set' (get-in sets-tree' ["group2" "updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 4)) + (t/is (= (count group1') 2)) + (t/is (= (count group2') 1)) + (t/is (= (d/index-of (keys group2') "updated-name") 0)) + (t/is (= (:name token-set') "group2/updated-name")) + (t/is (= (:description token-set') nil)) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + + (t/deftest delete-set-in-group + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "token-set-1")) + (ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))) + + tokens-lib' (-> tokens-lib + (ctob/delete-set "group1/token-set-2")) + + sets-tree' (ctob/get-set-tree tokens-lib') + token-set' (get-in sets-tree' ["group1" "token-set-2"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count sets-tree') 1)) + (t/is (nil? token-set'))))) + + (t/testing "grouped themes" + (t/deftest grouped-themes + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3")) + (ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4"))) + + themes-list (ctob/get-themes tokens-lib) + + themes-tree (ctob/get-theme-tree tokens-lib) + + [node-group0 node-group1 node-group2] + (ctob/get-children themes-tree) + + [node-theme1] + (ctob/get-children (second node-group0)) + + [node-theme2 node-theme3] + (ctob/get-children (second node-group1)) + + [node-theme4] + (ctob/get-children (second node-group2))] + + (t/is (= (count themes-list) 4)) + (t/is (= (:name (nth themes-list 0)) "token-theme-1")) + (t/is (= (:name (nth themes-list 1)) "token-theme-2")) + (t/is (= (:name (nth themes-list 2)) "token-theme-3")) + (t/is (= (:name (nth themes-list 3)) "token-theme-4")) + (t/is (= (:group (nth themes-list 0)) "")) + (t/is (= (:group (nth themes-list 1)) "group1")) + (t/is (= (:group (nth themes-list 2)) "group1")) + (t/is (= (:group (nth themes-list 3)) "group2")) + + (t/is (= (first node-group0) "")) + (t/is (= (ctob/group? (second node-group0)) true)) + (t/is (= (count (second node-group0)) 1)) + + (t/is (= (first node-theme1) "token-theme-1")) + (t/is (= (ctob/group? (second node-theme1)) false)) + (t/is (= (:name (second node-theme1)) "token-theme-1")) + + (t/is (= (first node-group1) "group1")) + (t/is (= (ctob/group? (second node-group1)) true)) + (t/is (= (count (second node-group1)) 2)) + + (t/is (= (first node-theme2) "token-theme-2")) + (t/is (= (ctob/group? (second node-theme2)) false)) + (t/is (= (:name (second node-theme2)) "token-theme-2")) + + (t/is (= (first node-theme3) "token-theme-3")) + (t/is (= (ctob/group? (second node-theme3)) false)) + (t/is (= (:name (second node-theme3)) "token-theme-3")) + + (t/is (= (first node-theme4) "token-theme-4")) + (t/is (= (ctob/group? (second node-theme4)) false)) + (t/is (= (:name (second node-theme4)) "token-theme-4")))) + + (t/deftest update-theme-in-groups + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3")) + (ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4"))) + + tokens-lib' (-> tokens-lib + (ctob/update-theme "group1" "token-theme-2" + (fn [token-theme] + (assoc token-theme :description "some description")))) + + themes-tree (ctob/get-theme-tree tokens-lib) + themes-tree' (ctob/get-theme-tree tokens-lib') + group1' (get themes-tree' "group1") + token-theme (get-in themes-tree ["group1" "token-theme-2"]) + token-theme' (get-in themes-tree' ["group1" "token-theme-2"])] + + (t/is (= (ctob/theme-count tokens-lib') 4)) + (t/is (= (count group1') 2)) + (t/is (= (d/index-of (keys group1') "token-theme-2") 0)) + (t/is (= (:name token-theme') "token-theme-2")) + (t/is (= (:group token-theme') "group1")) + (t/is (= (:description token-theme') "some description")) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) + + (t/deftest rename-theme-in-groups + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3")) + (ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4"))) + + tokens-lib' (-> tokens-lib + (ctob/update-theme "group1" "token-theme-2" + (fn [token-theme] + (assoc token-theme + :name "updated-name")))) + + themes-tree (ctob/get-theme-tree tokens-lib) + themes-tree' (ctob/get-theme-tree tokens-lib') + group1' (get themes-tree' "group1") + token-theme (get-in themes-tree ["group1" "token-theme-2"]) + token-theme' (get-in themes-tree' ["group1" "updated-name"])] + + (t/is (= (ctob/theme-count tokens-lib') 4)) + (t/is (= (count group1') 2)) + (t/is (= (d/index-of (keys group1') "updated-name") 0)) + (t/is (= (:name token-theme') "updated-name")) + (t/is (= (:group token-theme') "group1")) + (t/is (= (:description token-theme') nil)) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) + + (t/deftest move-theme-of-group + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3")) + #_(ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4"))) + + tokens-lib' (-> tokens-lib + (ctob/update-theme "group1" "token-theme-2" + (fn [token-theme] + (assoc token-theme + :name "updated-name" + :group "group2")))) + + themes-tree (ctob/get-theme-tree tokens-lib) + themes-tree' (ctob/get-theme-tree tokens-lib') + group1' (get themes-tree' "group1") + group2' (get themes-tree' "group2") + token-theme (get-in themes-tree ["group1" "token-theme-2"]) + token-theme' (get-in themes-tree' ["group2" "updated-name"])] + + (t/is (= (ctob/theme-count tokens-lib') 3)) + (t/is (= (count group1') 1)) + (t/is (= (count group2') 1)) + (t/is (= (d/index-of (keys group2') "updated-name") 0)) + (t/is (= (:name token-theme') "updated-name")) + (t/is (= (:group token-theme') "group2")) + (t/is (= (:description token-theme') nil)) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) + + (t/deftest delete-theme-in-group + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1")) + (ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2"))) + + tokens-lib' (-> tokens-lib + (ctob/delete-theme "group1" "token-theme-2")) + + themes-tree' (ctob/get-theme-tree tokens-lib') + token-theme' (get-in themes-tree' ["group1" "token-theme-2"])] + + (t/is (= (ctob/theme-count tokens-lib') 1)) + (t/is (= (count themes-tree') 1)) + (t/is (nil? token-theme')))))) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index 904811b80..820911b82 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -115,10 +115,9 @@ (ptk/reify ::update-token-theme ptk/WatchEvent (watch [it state _] - (let [prev-token-theme (wtts/get-workspace-token-theme state (:id token-theme)) + (let [prev-token-theme (wtts/get-workspace-token-theme (:id token-theme) state) changes (-> (pcb/empty-changes it) (pcb/update-token-theme token-theme prev-token-theme))] - (js/console.log "changes" changes) (rx/of (dch/commit-changes changes)))))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs index 82d97180d..b8fa39058 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs @@ -69,11 +69,11 @@ (defn group-assets "Convert a list of assets in a nested structure like this: - {'': [{assetA} {assetB}] - 'group1': {'': [{asset1A} {asset1B}] - 'subgroup11': {'': [{asset11A} {asset11B} {asset11C}]} - 'subgroup12': {'': [{asset12A}]}} - 'group2': {'subgroup21': {'': [{asset21A}}}} + {'': [assetA assetB] + 'group1': {'': [asset1A asset1B] + 'subgroup11': {'': [asset11A asset11B asset11C]} + 'subgroup12': {'': [asset12A]}} + 'group2': {'subgroup21': {'': [asset21A]}}} " [assets reverse-sort?] (when-not (empty? assets)