mirror of
https://github.com/penpot/penpot.git
synced 2025-06-07 12:31:38 +02:00
♻️ Simplifies RPC pattern for tokens (#5765)
* ♻️ Refactor to RPC pattern Co-authored-by: andrei <andrei@hyma.io> * ♻️ Remove unused alias * ♻️ Change function signature --------- Co-authored-by: andrei <andrei@hyma.io> Co-authored-by: Andrey Fedorov <oran9e.red@gmail.com>
This commit is contained in:
parent
5c32ec8cfa
commit
8b380a01e6
7 changed files with 143 additions and 88 deletions
|
@ -458,24 +458,12 @@
|
||||||
[:type [:= :set-tokens-lib]]
|
[:type [:= :set-tokens-lib]]
|
||||||
[:tokens-lib :any]]]
|
[:tokens-lib :any]]]
|
||||||
|
|
||||||
[:add-token
|
[:set-token
|
||||||
[:map {:title "AddTokenChange"}
|
[:map {:title "SetTokenChange"}
|
||||||
[:type [:= :add-token]]
|
[:type [:= :set-token]]
|
||||||
[:set-name :string]
|
[:set-name :string]
|
||||||
[:token ::cto/token]]]
|
[:token-name :string]
|
||||||
|
[:token [:maybe ::cto/token]]]]]])
|
||||||
[:mod-token
|
|
||||||
[:map {:title "ModTokenChange"}
|
|
||||||
[:type [:= :mod-token]]
|
|
||||||
[:set-name :string]
|
|
||||||
[:name :string]
|
|
||||||
[:token ::cto/token]]]
|
|
||||||
|
|
||||||
[:del-token
|
|
||||||
[:map {:title "DelTokenChange"}
|
|
||||||
[:type [:= :del-token]]
|
|
||||||
[:set-name :string]
|
|
||||||
[:name :string]]]]])
|
|
||||||
|
|
||||||
(def schema:changes
|
(def schema:changes
|
||||||
[:sequential {:gen/max 5 :gen/min 1} schema:change])
|
[:sequential {:gen/max 5 :gen/min 1} schema:change])
|
||||||
|
@ -1036,29 +1024,21 @@
|
||||||
[data {:keys [tokens-lib]}]
|
[data {:keys [tokens-lib]}]
|
||||||
(assoc data :tokens-lib tokens-lib))
|
(assoc data :tokens-lib tokens-lib))
|
||||||
|
|
||||||
(defmethod process-change :add-token
|
(defmethod process-change :set-token
|
||||||
[data {:keys [set-name token]}]
|
[data {:keys [set-name token-name token]}]
|
||||||
(update data :tokens-lib #(-> %
|
(update data :tokens-lib
|
||||||
(ctob/ensure-tokens-lib)
|
(fn [lib]
|
||||||
(ctob/add-token-in-set set-name (ctob/make-token token)))))
|
(let [lib' (ctob/ensure-tokens-lib lib)]
|
||||||
|
(cond
|
||||||
|
(not token)
|
||||||
|
(ctob/delete-token-from-set lib' set-name token-name)
|
||||||
|
|
||||||
(defmethod process-change :mod-token
|
(not (ctob/get-token-in-set lib' set-name token-name))
|
||||||
[data {:keys [set-name name token]}]
|
(ctob/add-token-in-set lib' set-name (ctob/make-token token))
|
||||||
(update data :tokens-lib #(-> %
|
|
||||||
(ctob/ensure-tokens-lib)
|
|
||||||
(ctob/update-token-in-set
|
|
||||||
set-name
|
|
||||||
name
|
|
||||||
(fn [old-token]
|
|
||||||
(ctob/make-token (merge old-token token)))))))
|
|
||||||
|
|
||||||
(defmethod process-change :del-token
|
:else
|
||||||
[data {:keys [set-name name]}]
|
(ctob/update-token-in-set lib' set-name token-name (fn [prev-token]
|
||||||
(update data :tokens-lib #(-> %
|
(ctob/make-token (merge prev-token token)))))))))
|
||||||
(ctob/ensure-tokens-lib)
|
|
||||||
(ctob/delete-token-from-set
|
|
||||||
set-name
|
|
||||||
name))))
|
|
||||||
|
|
||||||
(defmethod process-change :add-temporary-token-theme
|
(defmethod process-change :add-temporary-token-theme
|
||||||
[data {:keys [token-theme]}]
|
[data {:keys [token-theme]}]
|
||||||
|
|
|
@ -884,30 +884,31 @@
|
||||||
(update :undo-changes conj {:type :set-tokens-lib :tokens-lib prev-tokens-lib})
|
(update :undo-changes conj {:type :set-tokens-lib :tokens-lib prev-tokens-lib})
|
||||||
(apply-changes-local))))
|
(apply-changes-local))))
|
||||||
|
|
||||||
(defn add-token
|
(defn set-token [changes set-name token-name token]
|
||||||
[changes set-name token]
|
|
||||||
(-> changes
|
|
||||||
(update :redo-changes conj {:type :add-token :set-name set-name :token token})
|
|
||||||
(update :undo-changes conj {:type :del-token :set-name set-name :name (:name token)})
|
|
||||||
(apply-changes-local)))
|
|
||||||
|
|
||||||
(defn update-token
|
|
||||||
[changes set-name token prev-token]
|
|
||||||
(-> changes
|
|
||||||
(update :redo-changes conj {:type :mod-token :set-name set-name :name (:name prev-token) :token token})
|
|
||||||
(update :undo-changes conj {:type :mod-token :set-name set-name :name (:name token) :token (or prev-token token)})
|
|
||||||
(apply-changes-local)))
|
|
||||||
|
|
||||||
(defn delete-token
|
|
||||||
[changes set-name token-name]
|
|
||||||
(assert-library! changes)
|
(assert-library! changes)
|
||||||
(let [library-data (::library-data (meta changes))
|
(let [library-data (::library-data (meta changes))
|
||||||
prev-token (some-> (get library-data :tokens-lib)
|
prev-token (some-> (get library-data :tokens-lib)
|
||||||
(ctob/get-set set-name)
|
(ctob/get-set set-name)
|
||||||
(ctob/get-token token-name))]
|
(ctob/get-token token-name))]
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes conj {:type :del-token :set-name set-name :name token-name})
|
(update :redo-changes conj {:type :set-token
|
||||||
(update :undo-changes conj {:type :add-token :set-name set-name :token prev-token})
|
:set-name set-name
|
||||||
|
:token-name token-name
|
||||||
|
:token token})
|
||||||
|
(update :undo-changes conj (if prev-token
|
||||||
|
{:type :set-token
|
||||||
|
:set-name set-name
|
||||||
|
:token-name (or
|
||||||
|
;; Undo of edit
|
||||||
|
(:name token)
|
||||||
|
;; Undo of delete
|
||||||
|
token-name)
|
||||||
|
:token prev-token}
|
||||||
|
;; Undo of create token
|
||||||
|
{:type :set-token
|
||||||
|
:set-name set-name
|
||||||
|
:token-name token-name
|
||||||
|
:token nil}))
|
||||||
(apply-changes-local))))
|
(apply-changes-local))))
|
||||||
|
|
||||||
(defn add-component
|
(defn add-component
|
||||||
|
|
|
@ -35,6 +35,11 @@
|
||||||
(ctob/get-set set-name)
|
(ctob/get-set set-name)
|
||||||
(ctob/get-token token-name)))))
|
(ctob/get-token token-name)))))
|
||||||
|
|
||||||
|
(defn token-data-eq?
|
||||||
|
"Compare token data without comparing modified timestamp"
|
||||||
|
[t1 t2]
|
||||||
|
(= (dissoc t1 :modified-at) (dissoc t2 :modified-at)))
|
||||||
|
|
||||||
(defn- set-stroke-width
|
(defn- set-stroke-width
|
||||||
[shape stroke-width]
|
[shape stroke-width]
|
||||||
(let [strokes (if (seq (:strokes shape))
|
(let [strokes (if (seq (:strokes shape))
|
||||||
|
|
|
@ -801,6 +801,7 @@ used for managing active sets without a user created theme.")
|
||||||
(set-path-exists? [_ path] "if a set at `path` exists")
|
(set-path-exists? [_ path] "if a set at `path` exists")
|
||||||
(set-group-path-exists? [_ path] "if a set group at `path` exists")
|
(set-group-path-exists? [_ path] "if a set group at `path` exists")
|
||||||
(add-token-in-set [_ set-name token] "add token to a set")
|
(add-token-in-set [_ set-name token] "add token to a set")
|
||||||
|
(get-token-in-set [_ set-name token-name] "get token in a set")
|
||||||
(update-token-in-set [_ set-name token-name f] "update a token in 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")
|
(toggle-set-in-theme [_ group-name theme-name set-name] "toggle a set used / not used in a theme")
|
||||||
|
@ -1134,6 +1135,11 @@ Will return a value that matches this schema:
|
||||||
(dm/assert! "expected valid token instance" (check-token! token))
|
(dm/assert! "expected valid token instance" (check-token! token))
|
||||||
(update-set this set-name #(add-token % token)))
|
(update-set this set-name #(add-token % token)))
|
||||||
|
|
||||||
|
(get-token-in-set [this set-name token-name]
|
||||||
|
(some-> this
|
||||||
|
(get-set set-name)
|
||||||
|
(get-token token-name)))
|
||||||
|
|
||||||
(update-token-in-set [this set-name token-name f]
|
(update-token-in-set [this set-name token-name f]
|
||||||
(update-set this set-name #(update-token % token-name f)))
|
(update-set this set-name #(update-token % token-name f)))
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,70 @@
|
||||||
;; Undo
|
;; Undo
|
||||||
(t/is (some? (ctob/get-hidden-theme undo-lib))))))
|
(t/is (some? (ctob/get-hidden-theme undo-lib))))))
|
||||||
|
|
||||||
|
(t/deftest set-token-test
|
||||||
|
(t/testing "delete token"
|
||||||
|
(let [set-name "foo"
|
||||||
|
token-name "to.delete.color.red"
|
||||||
|
file (setup-file #(-> %
|
||||||
|
(ctob/add-set (ctob/make-token-set :name set-name))
|
||||||
|
(ctob/add-token-in-set set-name (ctob/make-token {:name token-name
|
||||||
|
:value "red"
|
||||||
|
:type :color}))))
|
||||||
|
changes (-> (pcb/empty-changes)
|
||||||
|
(pcb/with-library-data (:data file))
|
||||||
|
(pcb/set-token set-name token-name nil))
|
||||||
|
|
||||||
|
redo (thf/apply-changes file changes)
|
||||||
|
redo-lib (tht/get-tokens-lib redo)
|
||||||
|
undo (thf/apply-undo-changes redo changes)
|
||||||
|
undo-lib (tht/get-tokens-lib undo)]
|
||||||
|
(t/is (nil? (ctob/get-token-in-set redo-lib set-name token-name)))
|
||||||
|
;; Undo
|
||||||
|
(t/is (some? (ctob/get-token-in-set undo-lib set-name token-name)))))
|
||||||
|
|
||||||
|
(t/testing "add token"
|
||||||
|
(let [set-name "foo"
|
||||||
|
token (ctob/make-token {:name "to.add.color.red"
|
||||||
|
:value "red"
|
||||||
|
:type :color})
|
||||||
|
file (setup-file #(-> % (ctob/add-set (ctob/make-token-set :name set-name))))
|
||||||
|
changes (-> (pcb/empty-changes)
|
||||||
|
(pcb/with-library-data (:data file))
|
||||||
|
(pcb/set-token set-name (:name token) token))
|
||||||
|
|
||||||
|
redo (thf/apply-changes file changes)
|
||||||
|
redo-lib (tht/get-tokens-lib redo)
|
||||||
|
undo (thf/apply-undo-changes redo changes)
|
||||||
|
undo-lib (tht/get-tokens-lib undo)]
|
||||||
|
(t/is (= token (ctob/get-token-in-set redo-lib set-name (:name token))))
|
||||||
|
;; Undo
|
||||||
|
(t/is (nil? (ctob/get-token-in-set undo-lib set-name (:name token))))))
|
||||||
|
|
||||||
|
(t/testing "update token"
|
||||||
|
(let [set-name "foo"
|
||||||
|
prev-token (ctob/make-token {:name "to.update.color.red"
|
||||||
|
:value "red"
|
||||||
|
:type :color})
|
||||||
|
token (-> prev-token
|
||||||
|
(assoc :name "color.red.changed")
|
||||||
|
(assoc :value "blue"))
|
||||||
|
file (setup-file #(-> %
|
||||||
|
(ctob/add-set (ctob/make-token-set :name set-name))
|
||||||
|
(ctob/add-token-in-set set-name prev-token)))
|
||||||
|
changes (-> (pcb/empty-changes)
|
||||||
|
(pcb/with-library-data (:data file))
|
||||||
|
(pcb/set-token set-name (:name prev-token) token))
|
||||||
|
|
||||||
|
redo (thf/apply-changes file changes)
|
||||||
|
redo-lib (tht/get-tokens-lib redo)
|
||||||
|
undo (thf/apply-undo-changes redo changes)
|
||||||
|
undo-lib (tht/get-tokens-lib undo)]
|
||||||
|
(t/is (tht/token-data-eq? token (ctob/get-token-in-set redo-lib set-name (:name token))))
|
||||||
|
(t/is (nil? (ctob/get-token-in-set redo-lib set-name (:name prev-token))))
|
||||||
|
;; Undo
|
||||||
|
(t/is (tht/token-data-eq? prev-token (ctob/get-token-in-set undo-lib set-name (:name prev-token))))
|
||||||
|
(t/is (nil? (ctob/get-token-in-set undo-lib set-name (:name token)))))))
|
||||||
|
|
||||||
(t/deftest generate-toggle-token-set-group-test
|
(t/deftest generate-toggle-token-set-group-test
|
||||||
(t/testing "toggling set group with no active sets inside will activate all child sets"
|
(t/testing "toggling set group with no active sets inside will activate all child sets"
|
||||||
(let [file (setup-file #(-> %
|
(let [file (setup-file #(-> %
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
(ns common-tests.types.tokens-lib-test
|
(ns common-tests.types.tokens-lib-test
|
||||||
(:require
|
(:require
|
||||||
#?(:clj [app.common.fressian :as fres])
|
#?(:clj [app.common.fressian :as fres])
|
||||||
#?(:clj [clojure.data.json :as json])
|
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.test-helpers.tokens :as tht]
|
||||||
[app.common.time :as dt]
|
[app.common.time :as dt]
|
||||||
[app.common.transit :as tr]
|
[app.common.transit :as tr]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
|
@ -1188,8 +1188,7 @@
|
||||||
lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json)
|
lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json)
|
||||||
get-set-token (fn [set-name token-name]
|
get-set-token (fn [set-name token-name]
|
||||||
(some-> (ctob/get-set lib set-name)
|
(some-> (ctob/get-set lib set-name)
|
||||||
(ctob/get-token token-name)
|
(ctob/get-token token-name)))
|
||||||
(dissoc :modified-at)))
|
|
||||||
token-theme (ctob/get-theme lib "group-1" "theme-1")]
|
token-theme (ctob/get-theme lib "group-1" "theme-1")]
|
||||||
(t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib)))
|
(t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib)))
|
||||||
(t/testing "set exists in theme"
|
(t/testing "set exists in theme"
|
||||||
|
@ -1197,21 +1196,21 @@
|
||||||
(t/is (= (:name token-theme) "theme-1"))
|
(t/is (= (:name token-theme) "theme-1"))
|
||||||
(t/is (= (:sets token-theme) #{"light"})))
|
(t/is (= (:sets token-theme) #{"light"})))
|
||||||
(t/testing "tokens exist in core set"
|
(t/testing "tokens exist in core set"
|
||||||
(t/is (= (get-set-token "core" "colors.red.600")
|
(t/is (tht/token-data-eq? (get-set-token "core" "colors.red.600")
|
||||||
{:name "colors.red.600"
|
{:name "colors.red.600"
|
||||||
:type :color
|
:type :color
|
||||||
:value "#e53e3e"
|
:value "#e53e3e"
|
||||||
:description nil}))
|
:description nil}))
|
||||||
(t/is (= (get-set-token "core" "spacing.multi-value")
|
(t/is (tht/token-data-eq? (get-set-token "core" "spacing.multi-value")
|
||||||
{:name "spacing.multi-value"
|
{:name "spacing.multi-value"
|
||||||
:type :spacing
|
:type :spacing
|
||||||
:value "{dimension.sm} {dimension.xl}"
|
:value "{dimension.sm} {dimension.xl}"
|
||||||
:description "You can have multiple values in a single spacing token"}))
|
:description "You can have multiple values in a single spacing token"}))
|
||||||
(t/is (= (get-set-token "theme" "button.primary.background")
|
(t/is (tht/token-data-eq? (get-set-token "theme" "button.primary.background")
|
||||||
{:name "button.primary.background"
|
{:name "button.primary.background"
|
||||||
:type :color
|
:type :color
|
||||||
:value "{accent.default}"
|
:value "{accent.default}"
|
||||||
:description nil})))
|
:description nil})))
|
||||||
(t/testing "invalid tokens got discarded"
|
(t/testing "invalid tokens got discarded"
|
||||||
(t/is (nil? (get-set-token "typography" "H1.Bold"))))))
|
(t/is (nil? (get-set-token "typography" "H1.Bold"))))))
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.tokens.selected-set :as dwts]
|
[app.main.data.workspace.tokens.selected-set :as dwts]
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.store :as st]
|
|
||||||
[app.main.ui.workspace.tokens.update :as wtu]
|
[app.main.ui.workspace.tokens.update :as wtu]
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
|
@ -241,14 +240,15 @@
|
||||||
[{:keys [token prev-token-name]}]
|
[{:keys [token prev-token-name]}]
|
||||||
(ptk/reify ::update-create-token
|
(ptk/reify ::update-create-token
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [it state _]
|
||||||
(let [token-set (dwts/get-selected-token-set state)
|
(let [data (dsh/lookup-file-data state)
|
||||||
token-set-name (or (:name token-set) "Global")
|
token-set (dwts/get-selected-token-set state)
|
||||||
|
set-name (or (:name token-set) "Global")
|
||||||
changes (if (not token-set)
|
changes (if (not token-set)
|
||||||
;; No set created add a global set
|
;; No set created add a global set
|
||||||
(let [tokens-lib (get-tokens-lib state)
|
(let [tokens-lib (get-tokens-lib state)
|
||||||
token-set (ctob/make-token-set :name token-set-name :tokens {(:name token) token})
|
token-set (ctob/make-token-set :name set-name :tokens {(:name token) token})
|
||||||
hidden-theme (ctob/make-hidden-token-theme :sets [token-set-name])
|
hidden-theme (ctob/make-hidden-token-theme :sets [set-name])
|
||||||
active-theme-paths (some-> tokens-lib ctob/get-active-theme-paths)
|
active-theme-paths (some-> tokens-lib ctob/get-active-theme-paths)
|
||||||
add-to-hidden-theme? (= active-theme-paths #{ctob/hidden-token-theme-path})
|
add-to-hidden-theme? (= active-theme-paths #{ctob/hidden-token-theme-path})
|
||||||
base-changes (pcb/add-token-set (pcb/empty-changes) token-set)]
|
base-changes (pcb/add-token-set (pcb/empty-changes) token-set)]
|
||||||
|
@ -262,14 +262,14 @@
|
||||||
(pcb/update-token-theme (ctob/toggle-set prev-hidden-theme ctob/hidden-token-theme-path) prev-hidden-theme)))
|
(pcb/update-token-theme (ctob/toggle-set prev-hidden-theme ctob/hidden-token-theme-path) prev-hidden-theme)))
|
||||||
|
|
||||||
:else base-changes))
|
:else base-changes))
|
||||||
;; Either update or add token to existing set
|
(-> (pcb/empty-changes it)
|
||||||
(if-let [prev-token (ctob/get-token token-set (or prev-token-name (:name token)))]
|
(pcb/with-library-data data)
|
||||||
(pcb/update-token (pcb/empty-changes) (:name token-set) token prev-token)
|
(pcb/set-token set-name (or prev-token-name (:name token)) token)))]
|
||||||
(do
|
|
||||||
(st/emit! (ptk/event ::ev/event {::ev/name "create-tokens"}))
|
|
||||||
(pcb/add-token (pcb/empty-changes) (:name token-set) token))))]
|
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwts/set-selected-token-set-name token-set-name)
|
(dwts/set-selected-token-set-name set-name)
|
||||||
|
(when-not prev-token-name
|
||||||
|
(ptk/event ::ev/event {::ev/name "create-tokens"}))
|
||||||
(dch/commit-changes changes))))))
|
(dch/commit-changes changes))))))
|
||||||
|
|
||||||
(defn delete-token
|
(defn delete-token
|
||||||
|
@ -282,7 +282,7 @@
|
||||||
(let [data (dsh/lookup-file-data state)
|
(let [data (dsh/lookup-file-data state)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-token set-name token-name))]
|
(pcb/set-token set-name token-name nil))]
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
||||||
(defn duplicate-token
|
(defn duplicate-token
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue