This commit is contained in:
Andrés Moya 2026-06-15 20:51:00 +02:00
parent 217219f492
commit 726afaea25
12 changed files with 149 additions and 79 deletions

View File

@ -402,7 +402,8 @@
[:map {:title "SetTokenThemeStatus"}
[:type [:= :set-token-theme-status]]
[:id ::sm/uuid]
[:status :boolean]]]
[:theme-ids [:set ::sm/uuid]]
[:set-ids [:set ::sm/uuid]]]]
;; TODO deprecate this once everyone uses set-token-theme-status
[:set-active-token-themes
@ -1050,10 +1051,10 @@
(ctob/make-token-theme (merge prev-token-theme attrs)))))))))
(defmethod process-change :set-token-theme-status
[data {:keys [id status]}]
[data {:keys [id theme-ids set-ids]}]
(let [data' (ctf/ensure-tokens-lib data)]
(-> data'
(ctf/update-token-status ctos/set-theme-status (ctf/get-tokens-lib data') id status))))
(ctf/update-token-status ctos/set-theme-status id theme-ids set-ids))))
(defmethod process-change :set-active-token-themes
[data {:keys [theme-paths]}]

View File

@ -1022,14 +1022,15 @@
(apply-changes-local))))
(defn set-token-theme-status
[changes id status]
[changes id theme-ids set-ids]
(assert-library! changes)
(let [library-data (::library-data (meta changes))
token-status (ctf/get-token-status library-data)
prev-status (ctos/theme-active? token-status id)]
token-status (ctf/get-token-status library-data nil)
prev-theme-ids (ctos/get-active-theme-ids token-status)
prev-set-ids (ctos/get-active-set-ids token-status)]
(-> changes
(update :redo-changes conj {:type :set-token-theme-status :id id :status status})
(update :undo-changes conj {:type :set-token-theme-status :id id :status prev-status})
(update :redo-changes conj {:type :set-token-theme-status :id id :theme-ids theme-ids :set-ids set-ids})
(update :undo-changes conj {:type :set-token-theme-status :id id :theme-ids prev-theme-ids :set-ids prev-set-ids})
(apply-changes-local))))
(defn set-active-token-themes

View File

@ -8,7 +8,8 @@
(:require
[app.common.files.changes-builder :as pcb]
[app.common.types.token-status :as ctos]
[app.common.types.tokens-lib :as ctob]))
[app.common.types.tokens-lib :as ctob]
[clojure.set :as set]))
(defn- generate-update-active-sets
"Copy the active sets from the currently active themes and move them
@ -52,16 +53,45 @@
;; (disj active-token-themes ctob/hidden-theme-path))]
;; (pcb/set-active-token-themes changes active-token-themes')))
(defn generate-activate-token-theme
[changes token-status tokens-lib id]
(assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
(assert (uuid? id) "expected valid theme id")
(if-not (ctos/theme-active? token-status id)
(if-let [theme (ctob/get-theme tokens-lib id)]
(let [group-themes (into #{} (ctob/get-themes-in-group tokens-lib (:group theme)))
active-theme-ids (ctos/get-active-theme-ids token-status)
active-theme-ids' (-> (set/difference active-theme-ids group-themes)
(conj id))
active-set-ids' (ctos/calculate-active-sets active-theme-ids' tokens-lib)]
(pcb/set-token-theme-status changes id active-theme-ids' active-set-ids'))
changes)
changes))
(defn generate-deactivate-token-theme
[changes token-status tokens-lib id]
(assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
(assert (uuid? id) "expected valid theme id")
(if (ctos/theme-active? token-status id)
(let [active-theme-ids' (disj (ctos/get-active-theme-ids token-status) id)
active-set-ids' (ctos/calculate-active-sets active-theme-ids' tokens-lib)]
(pcb/set-token-theme-status changes id active-theme-ids' active-set-ids'))
changes))
(defn generate-set-token-theme-status
"Activate or deactivate a token theme in `token-status`."
[changes _ id active?]
(pcb/set-token-theme-status changes id (not active?)))
[changes token-status tokens-lib id active?]
(if active?
(generate-activate-token-theme changes token-status tokens-lib id)
(generate-deactivate-token-theme changes token-status tokens-lib id)))
(defn generate-toggle-token-theme
"Toggle the active status of a token theme in `token-status`."
[changes token-status id]
[changes token-status tokens-lib id]
(let [active? (ctos/theme-active? token-status id)]
(pcb/set-token-theme-status changes id (not active?))))
(if active?
(generate-deactivate-token-theme changes token-status tokens-lib id)
(generate-activate-token-theme changes token-status tokens-lib id))))
(defn toggle-token-set-group
"Toggle a token set group at `group-path` in `tokens-lib` for a `tokens-lib-theme`."

View File

@ -21,7 +21,7 @@
(defn get-token-status
[file]
(-> file (ctf/file-data) (ctf/get-token-status)))
(-> file (ctf/file-data) (ctf/get-token-status nil)))
(defn add-tokens-lib
"Ensure the file has a tokens-lib and a token-statusin its data, creating empty ones if not"
@ -35,7 +35,8 @@
(defn update-token-status
[file f]
(ctf/update-file-data file #(ctf/update-token-status % f)))
(let [tokens-lib (get-tokens-lib file)]
(ctf/update-file-data file #(ctf/update-token-status % f tokens-lib))))
(defn sample-file-with-tokens [tokens-lib-fn token-status-fn]
(-> (thf/sample-file :file1)

View File

@ -323,11 +323,12 @@
(:tokens-lib file-data))
(defn get-token-status
[file-data]
(if (and (some? (:tokens-lib file-data)) (nil? (:token-status file-data)))
;; TODO: remove this when we deprecate old-style files without token-status
(ctos/make-token-status-from-lib (:tokens-lib file-data))
(:token-status file-data)))
[file-data tokens-file-data]
(let [tokens-file-data (or tokens-file-data file-data)]
(if (and (some? (:tokens-lib tokens-file-data)) (nil? (:token-status file-data)))
;; TODO: remove this when we deprecate old-style files without token-status
(ctos/make-token-status-from-lib (:tokens-lib tokens-file-data))
(:token-status file-data))))
(defn update-tokens-lib
"Update the tokens-lib inside file-data through a callback function.

View File

@ -8,6 +8,7 @@
(:require
#?(:clj [app.common.fressian :as fres])
#?(:clj [clojure.data.json :as c.json])
[app.common.data :as d]
[app.common.schema :as sm]
[app.common.schema.generators :as sg]
[app.common.transit :as t]
@ -25,6 +26,9 @@
(deactivate-theme [_ tokens-lib theme-id] "Deactivate a theme and update active sets")
(set-theme-status [_ tokens-lib theme-id status] "Set the activation status of a theme")
(theme-active? [_ theme-id] "Check if a theme is active")
(get-active-theme-ids [_] "Return a clojure set of active theme ids")
(get-active-set-ids [_] "Return a clojure set of active set ids")
(active-themes [_ tokens-lib] "Return an ordered sequence of active themes")
(active-themes-count [_] "Return the number of active themes")
(activate-set [_ set-id] "Add a set to active sets")
(deactivate-set [_ set-id] "Remove a set from active sets")
@ -45,21 +49,27 @@
(c.json/-write (datafy this) writter options))])
ITokenStatus
(get-active-theme-ids [_]
active-theme-ids)
(get-active-set-ids [_]
active-set-ids)
(activate-theme [this tokens-lib theme-id]
(assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
;; (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
(assert (uuid? theme-id) "expected valid theme-id")
(if-not (theme-active? this theme-id)
(if-let [theme (ctob/get-theme tokens-lib theme-id)]
(let [group-themes (ctob/get-themes-in-group tokens-lib (:group theme))
(let [group-themes (into #{} (ctob/get-themes-in-group tokens-lib (:group theme)))
active-theme-ids' (-> (set/difference active-theme-ids group-themes)
(conj theme-id))]
(conj theme-id))]
(TokenStatus. active-theme-ids'
(calculate-active-sets active-theme-ids' tokens-lib)))
this)
this))
(deactivate-theme [this tokens-lib theme-id]
(assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
;; (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
(assert (uuid? theme-id) "expected valid theme-id")
(if (theme-active? this theme-id)
(let [active-theme-ids' (disj active-theme-ids theme-id)]
@ -67,18 +77,25 @@
(calculate-active-sets active-theme-ids' tokens-lib)))
this))
(set-theme-status [this tokens-lib theme-id status]
(assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
(assert (uuid? theme-id) "expected valid theme-id")
(assert (boolean? status) "expected boolean status")
(if status
(activate-theme this tokens-lib theme-id)
(deactivate-theme this tokens-lib theme-id)))
;; (set-theme-status [this tokens-lib theme-id status]
;; (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
;; (assert (uuid? theme-id) "expected valid theme-id")
;; (assert (boolean? status) "expected boolean status")
;; (if status
;; (activate-theme this tokens-lib theme-id)
;; (deactivate-theme this tokens-lib theme-id)))
(set-theme-status [_ _id theme-ids set-ids]
(TokenStatus. theme-ids set-ids))
(theme-active? [_ theme-id]
(assert (uuid? theme-id) "expected valid theme-id")
(contains? active-theme-ids theme-id))
(active-themes [this tokens-lib]
(->> (ctob/get-themes tokens-lib)
(filter #(theme-active? this (ctob/get-id %)))))
(active-themes-count [_]
(count active-theme-ids))
@ -103,7 +120,7 @@
(active-set-count [_]
(count active-set-ids)))
(defn- calculate-active-sets
(defn calculate-active-sets
[active-theme-ids tokens-lib]
(let [active-themes (map #(ctob/get-theme tokens-lib %) active-theme-ids) ;; OJOOOOOOOOOOOOOOOOOOOOO
active-set-names (reduce set/union #{} (map :sets active-themes))
@ -162,6 +179,7 @@
(ctob/get-active-themes tokens-lib))
active-set-ids (into #{}
(comp (map #(ctob/get-set-by-name tokens-lib %))
(remove nil?)
(map ctob/get-id))
(ctob/get-active-themes-set-names tokens-lib))]
(make-token-status :active-theme-ids active-theme-ids

View File

@ -755,11 +755,15 @@
(def ^:private theme-separator "/")
(defn- join-theme-path [group name]
(cpn/join-path [group name] :separator theme-separator :with-spaces? false))
(defn- join-theme-path [group name with-spaces?]
(let [path (if (and (str/empty? group) with-spaces?) [name] [group name])]
(cpn/join-path path :separator theme-separator :with-spaces? with-spaces?)))
(defn get-theme-path [theme]
(join-theme-path (:group theme) (:name theme)))
(defn get-theme-path
([theme]
(get-theme-path theme false))
([theme with-spaces?]
(join-theme-path (:group theme) (:name theme) with-spaces?)))
(defn split-theme-path [path]
(cpn/split-group-name path
@ -767,7 +771,7 @@
:with-spaces? false))
(def hidden-theme-path
(join-theme-path hidden-theme-group hidden-theme-name))
(join-theme-path hidden-theme-group hidden-theme-name false))
;; === TokenThemes (collection)
@ -1179,7 +1183,7 @@ Will return a value that matches this schema:
(d/dissoc-in [group name])))
(if same-path?
active-themes
(disj active-themes (join-theme-path group name)))))))
(disj active-themes (join-theme-path group name false)))))))
this))
(delete-theme [this id]
@ -1188,14 +1192,14 @@ Will return a value that matches this schema:
(if theme
(TokensLib. sets
(d/dissoc-in themes [group name])
(disj active-themes (join-theme-path group name)))
(disj active-themes (join-theme-path group name false)))
this)))
(get-theme-tree [_]
themes)
(get-theme-tree-no-hidden [_]
(dissoc themes hidden-theme-group))
(d/dissoc-in themes [hidden-theme-group hidden-theme-name]))
(get-theme-groups [_]
(into [] (comp

View File

@ -247,6 +247,16 @@
theme' (ctob/toggle-set theme nil)]
(t/is (= (:sets theme') #{})))))
(t/deftest get-theme-path
(let [theme1 (ctob/make-token-theme :name "theme1")
theme2 (ctob/make-token-theme :group "group1" :name "theme2")]
(t/is (= "/theme1" (ctob/get-theme-path theme1))) ;; TODO perhaps we should remove the leading /
(t/is (= "/theme1" (ctob/get-theme-path theme1 false))) ;; but this may be a breaking change
(t/is (= " / theme1" (ctob/get-theme-path theme1 true)))
(t/is (= "group1/theme2" (ctob/get-theme-path theme2)))
(t/is (= "group1/theme2" (ctob/get-theme-path theme2 false)))
(t/is (= "group1 / theme2" (ctob/get-theme-path theme2 true)))))
(t/deftest make-tokens-lib
(let [tokens-lib (ctob/make-tokens-lib)]
(t/is (= (ctob/set-count tokens-lib) 0))))

View File

@ -38,17 +38,23 @@
([state file-id]
(dm/get-in state [:files file-id :data])))
(defn lookup-tokens-lib
(defn lookup-tokens-file-data
[state]
(let [current-file-data (lookup-file-data state)
tokens-file-id (or (:tokens-file current-file-data) (:id current-file-data))
tokens-file-data (lookup-file-data state tokens-file-id)]
tokens-file-id (or (:tokens-file current-file-data) (:id current-file-data))]
(lookup-file-data state tokens-file-id)))
(defn lookup-tokens-lib
[state]
(let [tokens-file-data (lookup-tokens-file-data state)]
(ctf/get-tokens-lib tokens-file-data)))
(defn lookup-token-status
[state]
(let [current-file-data (lookup-file-data state)]
(ctf/get-token-status current-file-data)))
(let [current-file-data (lookup-file-data state)
tokens-file-id (or (:tokens-file current-file-data) (:id current-file-data))
tokens-file-data (lookup-file-data state tokens-file-id)]
(ctf/get-token-status current-file-data tokens-file-data)))
(defn get-page
[fdata page-id]

View File

@ -269,9 +269,10 @@
(watch [_ state _]
(let [data (dsh/lookup-file-data state)
token-status (dsh/lookup-token-status state)
tokens-lib (dsh/lookup-tokens-lib state)
changes (-> (pcb/empty-changes)
(pcb/with-library-data data)
(clt/generate-set-token-theme-status token-status id active?))]
(clt/generate-set-token-theme-status token-status tokens-lib id active?))]
(rx/of (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens))))))
@ -281,11 +282,12 @@
(ptk/reify ::toggle-token-theme-active
ptk/WatchEvent
(watch [it state _]
(let [data (dsh/lookup-file-data state)
(let [data (dsh/lookup-tokens-file-data state)
token-status (dsh/lookup-token-status state)
tokens-lib (dsh/lookup-tokens-lib state)
changes (-> (pcb/empty-changes it)
(pcb/with-library-data data)
(clt/generate-toggle-token-theme token-status id))]
(clt/generate-toggle-token-theme token-status tokens-lib id))]
(rx/of
(dch/commit-changes changes)
(dwtp/propagate-workspace-tokens))))))

View File

@ -66,7 +66,6 @@
[:> text* {:as "span" :typography "headline-small" :class (stl/css :group) :id (dm/str (str/kebab group) "-label") :title group} group])
[:> themes-list* {:themes themes
:token-status token-status
;; :active-theme-paths active-theme-paths
:on-close on-close
:is-grouped true}]])
[:li {:class (stl/css :separator)
@ -81,22 +80,19 @@
(mf/defc theme-selector*
[{:keys []}]
(let [;; Store
tokens-lib (mf/use-ctx ctx/tokens-lib)
token-status (mf/use-ctx ctx/token-status)
tokens-lib (mf/use-ctx ctx/tokens-lib)
token-status (mf/use-ctx ctx/token-status)
active-themes-count (ctos/active-themes-count token-status)
active-theme-paths (-> (ctob/get-active-theme-paths tokens-lib) ;; TODO replace by a call to ctos
(disj ctob/hidden-theme-path))
active-themes (ctos/active-themes token-status tokens-lib)
active-themes-count (count active-themes)
can-edit? (:can-edit (deref refs/permissions))
;; Data
current-label (cond
(> active-themes-count 1) (tr "workspace.tokens.active-themes" active-themes-count)
(= active-themes-count 1) (some->> (first active-theme-paths)
(ctob/split-theme-path)
(remove empty?)
(str/join " / "))
(= active-themes-count 1) (-> (first active-themes)
(ctob/get-theme-path true))
:else (tr "workspace.tokens.no-active-theme"))
;; State
@ -148,9 +144,7 @@
[:& dropdown {:show is-open?
:on-close on-close-dropdown}
[:> theme-options* {;;:active-theme-paths active-theme-paths
;;:themes themes
:tokens-lib tokens-lib
[:> theme-options* {:tokens-lib tokens-lib
:token-status token-status
:on-close on-close-dropdown}]]])
container))]))

View File

@ -16,25 +16,27 @@
(-> (thf/sample-file :file1)
(tht/add-tokens-lib)
(tht/update-tokens-lib
#(-> %
;; Add token sets
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-active)
:name "set-active"))
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-inactive)
:name "set-inactive"))
;; Add themes
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-active)
:name "theme-active"
:group "group-1"
:sets #{"set-active"}))
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-inactive)
:name "theme-inactive"
:group "group-1"
:sets #{"set-inactive"}))))
(fn [tokens-lib]
(-> tokens-lib
;; Add token sets
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-active)
:name "set-active"))
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-inactive)
:name "set-inactive"))
;; Add themes
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-active)
:name "theme-active"
:group "group-1"
:sets #{"set-active"}))
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-inactive)
:name "theme-inactive"
:group "group-1"
:sets #{"set-inactive"})))))
(tht/update-token-status
#(-> %
(ctos/activate-theme (thi/id :theme-active))
(ctos/activate-set (thi/id :set-active))))))
(fn [token-status tokens-lib]
(-> token-status
(ctos/activate-theme tokens-lib (thi/id :theme-active))
(ctos/activate-set (thi/id :set-active)))))))
(t/deftest test-token-status-active-inactive
(t/testing "lookup helpers and active checks"