🔧 Add internal id to all token entities

This commit is contained in:
Andrés Moya 2025-05-27 09:05:34 +02:00 committed by Andrés Moya
parent a2abaea637
commit 5c8f6dd498
7 changed files with 253 additions and 47 deletions

View file

@ -377,7 +377,7 @@
[:update-active-token-themes
[:map {:title "UpdateActiveTokenThemes"}
[:type [:= :update-active-token-themes]]
[:theme-ids [:set :string]]]]
[:theme-paths [:set :string]]]]
[:rename-token-set-group
[:map {:title "RenameTokenSetGroup"}
@ -1050,9 +1050,9 @@
(ctob/make-token-theme (merge prev-token-theme theme)))))))))
(defmethod process-change :update-active-token-themes
[data {:keys [theme-ids]}]
[data {:keys [theme-paths]}]
(update data :tokens-lib #(-> % (ctob/ensure-tokens-lib)
(ctob/set-active-themes theme-ids))))
(ctob/set-active-themes theme-paths))))
(defmethod process-change :rename-token-set-group
[data {:keys [set-group-path set-group-fname]}]

View file

@ -799,10 +799,10 @@
(apply-changes-local))))
(defn update-active-token-themes
[changes token-active-theme-ids prev-token-active-theme-ids]
[changes active-theme-paths prev-active-theme-paths]
(-> changes
(update :redo-changes conj {:type :update-active-token-themes :theme-ids token-active-theme-ids})
(update :undo-changes conj {:type :update-active-token-themes :theme-ids prev-token-active-theme-ids})
(update :redo-changes conj {:type :update-active-token-themes :theme-paths active-theme-paths})
(update :undo-changes conj {:type :update-active-token-themes :theme-paths prev-active-theme-paths})
(apply-changes-local)))
(defn set-token-theme [changes group theme-name theme]

View file

@ -36,9 +36,9 @@
(ctob/get-token token-name)))))
(defn token-data-eq?
"Compare token data without comparing modified timestamp"
"Compare token data without comparing unstable fields."
[t1 t2]
(= (dissoc t1 :modified-at) (dissoc t2 :modified-at)))
(= (dissoc t1 :id :modified-at) (dissoc t2 :id :modified-at)))
(defn- set-stroke-width
[shape stroke-width]

View file

@ -109,7 +109,7 @@
[token]
(get-path token token-separator))
(defrecord Token [name type value description modified-at])
(defrecord Token [id name type value description modified-at])
(defn token?
[o]
@ -117,6 +117,7 @@
(def schema:token-attrs
[:map {:title "Token"}
[:id ::sm/uuid]
[:name cto/token-name-ref]
[:type [::sm/one-of cto/token-types]]
[:value ::sm/any]
@ -140,7 +141,7 @@
(defn make-token
[& {:as attrs}]
(-> attrs
(dissoc :id) ;; we will remove this when old data structures are removed
(update :id #(or % (uuid/next)))
(update :modified-at #(or % (dt/now)))
(update :description d/nilv "")
(check-token-attrs)
@ -336,10 +337,11 @@
(get-token [_ token-name] "return token by token-name")
(get-tokens [_] "return an ordered sequence of all tokens in the set"))
(defrecord TokenSet [name description modified-at tokens]
(defrecord TokenSet [id name description modified-at tokens]
ITokenSet
(update-name [_ set-name]
(TokenSet. (-> (split-token-set-name name)
(TokenSet. id
(-> (split-token-set-name name)
(drop-last)
(concat [set-name])
(join-set-path))
@ -349,7 +351,8 @@
(add-token [_ token]
(let [token (check-token token)]
(TokenSet. name
(TokenSet. id
name
description
(dt/now)
(assoc tokens (:name token) token))))
@ -358,7 +361,8 @@
(if-let [token (get tokens token-name)]
(let [token' (-> (make-token (f token))
(assoc :modified-at (dt/now)))]
(TokenSet. name
(TokenSet. id
name
description
(dt/now)
(if (= (:name token) (:name token'))
@ -369,7 +373,8 @@
this))
(delete-token [_ token-name]
(TokenSet. name
(TokenSet. id
name
description
(dt/now)
(dissoc tokens token-name)))
@ -386,6 +391,7 @@
(def schema:token-set-attrs
[:map {:title "TokenSet"}
[:id ::sm/uuid]
[:name :string]
[:description {:optional true} :string]
[:modified-at {:optional true} ::sm/inst]
@ -430,7 +436,7 @@
(defn make-token-set
[& {:as attrs}]
(-> attrs
(dissoc :id)
(update :id #(or % (uuid/next)))
(update :modified-at #(or % (dt/now)))
(update :tokens #(into (d/ordered-map) %))
(update :description d/nilv "")
@ -521,14 +527,15 @@
(theme-matches-group-name [_ group name] "if a theme matches the given group & name")
(hidden-temporary-theme? [_] "if a theme is the (from the user ui) hidden temporary theme"))
(defrecord TokenTheme [name group description is-source id modified-at sets]
(defrecord TokenTheme [id name group description is-source external-id modified-at sets]
ITokenTheme
(set-sets [_ set-names]
(TokenTheme. name
(TokenTheme. id
name
group
description
is-source
id
external-id
(dt/now)
set-names))
@ -551,11 +558,12 @@
(update-set-name [this prev-set-name set-name]
(if (get sets prev-set-name)
(TokenTheme. name
(TokenTheme. id
name
group
description
is-source
id
external-id
(dt/now)
(conj (disj sets prev-set-name) set-name))
this))
@ -576,11 +584,12 @@
(def schema:token-theme-attrs
[:map {:title "TokenTheme"}
[:id ::sm/uuid]
[:name :string]
[:group {:optional true} :string]
[:description {:optional true} :string]
[:is-source {:optional true} :boolean]
[:id {:optional true} :string]
[:external-id {:optional true} :string]
[:modified-at {:optional true} ::sm/inst]
[:sets {:optional true} [:set {:gen/max 5} :string]]])
@ -609,22 +618,25 @@
(defn make-token-theme
[& {:as attrs}]
(let [id (uuid/next)]
(-> attrs
(update :id d/nilv id)
(update :group d/nilv top-level-theme-group-name)
(update :description d/nilv "")
(update :is-source d/nilv false)
(update :id #(or % (str (uuid/next))))
(update :external-id #(or % (str id)))
(update :modified-at #(or % (dt/now)))
(update :sets set)
(check-token-theme-attrs)
(map->TokenTheme)))
(map->TokenTheme))))
(defn make-hidden-token-theme
[& {:as attrs}]
(-> attrs
(assoc :id uuid/zero)
(assoc :external-id "")
(assoc :group hidden-token-theme-group)
(assoc :name hidden-token-theme-name)
(assoc :id (str uuid/zero))
(make-token-theme)))
;; === TokenThemes (collection)
@ -730,8 +742,8 @@
(join-set-path parent)))]
[{:is-new true
:is-group false
:id ""
:parent-path parent
:id "" ; FIXME: This is a calculated id, used for the sets tree in the sidear
:parent-path parent ; It may be refactored now to use the actual :id
:token-set tset
:depth depth}])
@ -1441,10 +1453,12 @@ Will return a value that matches this schema:
(->> (get decoded-json "$themes")
(map (fn [theme]
(make-token-theme
:id (or (uuid/parse* (get theme "id"))
(uuid/next))
:name (get theme "name")
:group (get theme "group")
:is-source (get theme "is-source")
:id (get theme "id")
:external-id (get theme "id")
:modified-at (some-> (get theme "modified-at")
(dt/parse-instant))
:sets (into #{}
@ -1534,7 +1548,8 @@ Will return a value that matches this schema:
(into {})
walk/stringify-keys)]
(-> theme-map
(set/rename-keys {"sets" "selectedTokenSets"})
(set/rename-keys {"sets" "selectedTokenSets"
"external-id" "id"})
(update "selectedTokenSets" (fn [sets]
(->> (for [s sets] [s "enabled"])
(into {})))))))))
@ -1656,8 +1671,8 @@ Will return a value that matches this schema:
;; Ensure we add an :id field for each existing theme
themes
(reduce (fn [result group-id]
(update result group-id
(reduce (fn [acc group-id]
(update acc group-id
(fn [themes]
(reduce (fn [themes theme-id]
(update themes theme-id
@ -1672,6 +1687,51 @@ Will return a value that matches this schema:
(->TokensLib sets themes active-themes))))
#?(:clj
(defn- read-tokens-lib-v1-2
"Reads the tokens lib data structure and add ids to tokens, sets and themes."
[r]
(let [sets (fres/read-object! r)
themes (fres/read-object! r)
active-themes (fres/read-object! r)
migrate-token
(fn [token]
(assoc token :id (uuid/next)))
migrate-sets-node
(fn recurse [node]
(if (token-set? node)
(assoc node
:id (uuid/next)
:tokens (d/update-vals (:tokens node) migrate-token))
(d/update-vals node recurse)))
sets
(d/update-vals sets migrate-sets-node)
migrate-theme
(fn [theme]
(if (get theme :external-id)
theme
(if (hidden-temporary-theme? theme)
(assoc theme
:id uuid/zero
:external-id "")
(assoc theme ;; Rename the :id field to :external-id, and add
:id (or (uuid/parse* (:id theme)) ;; a new :id that is the same as the old if if
(uuid/next)) ;; this is an uuid, else a new uuid is generated.
:external-id (:id theme)))))
migrate-theme-group
(fn [group]
(d/update-vals group migrate-theme))
themes
(d/update-vals themes migrate-theme-group)]
(->TokensLib sets themes active-themes))))
#?(:clj
(defn- write-tokens-lib
[n w ^TokensLib o]
@ -1724,8 +1784,11 @@ Will return a value that matches this schema:
{:name "penpot/tokens-lib/v1.1"
:rfn read-tokens-lib-v1-1}
;; CURRENT TOKENS LIB READER & WRITTER
{:name "penpot/tokens-lib/v1.2"
:rfn read-tokens-lib-v1-2}
;; CURRENT TOKENS LIB READER & WRITTER
{:name "penpot/tokens-lib/v1.3"
:class TokensLib
:wfn write-tokens-lib
:rfn read-tokens-lib}))

View file

@ -265,7 +265,7 @@
: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 :sets first)
prev-token-set (-> file tht/get-tokens-lib (ctob/get-set set-name))
new-set-name "foo1"
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))

View file

@ -9,6 +9,7 @@
#?(:clj [app.common.fressian :as fres])
#?(:clj [app.common.json :as json])
#?(:clj [app.common.test-helpers.tokens :as tht])
#?(:clj [app.common.uuid :as uuid])
[app.common.data :as d]
[app.common.time :as dt]
[app.common.transit :as tr]
@ -1507,7 +1508,7 @@
:value "{accent.default}"})}))
(ctob/add-theme (ctob/make-token-theme :name "theme-1"
:group "group-1"
:id "test-id-00"
:external-id "test-id-00"
:modified-at now
:sets #{"core"})))
result (ctob/export-dtcg-json tokens-lib)
@ -1537,7 +1538,8 @@
#?(:clj
(t/deftest export-parse-dtcg-json
(with-redefs [dt/now (constantly #inst "2024-10-16T12:01:20.257840055-00:00")]
(with-redefs [dt/now (constantly #inst "2024-10-16T12:01:20.257840055-00:00")
uuid/next (constantly uuid/zero)]
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "core"
:tokens {"colors.red.600"
@ -1626,7 +1628,7 @@
:value "{accent.default}"})}))
(ctob/add-theme (ctob/make-token-theme :name "theme-1"
:group "group-1"
:id "test-id-01"
:external-id "test-id-01"
:modified-at now
:sets #{"core"}))
(ctob/toggle-theme-active? "group-1" "theme-1"))

File diff suppressed because it is too large Load diff