mirror of
https://github.com/penpot/penpot.git
synced 2025-04-09 13:31:23 -05: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
common
src/app/common
test/common_tests
frontend/src/app/main/data
|
@ -458,24 +458,12 @@
|
|||
[:type [:= :set-tokens-lib]]
|
||||
[:tokens-lib :any]]]
|
||||
|
||||
[:add-token
|
||||
[:map {:title "AddTokenChange"}
|
||||
[:type [:= :add-token]]
|
||||
[:set-token
|
||||
[:map {:title "SetTokenChange"}
|
||||
[:type [:= :set-token]]
|
||||
[:set-name :string]
|
||||
[:token ::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]]]]])
|
||||
[:token-name :string]
|
||||
[:token [:maybe ::cto/token]]]]]])
|
||||
|
||||
(def schema:changes
|
||||
[:sequential {:gen/max 5 :gen/min 1} schema:change])
|
||||
|
@ -1036,29 +1024,21 @@
|
|||
[data {:keys [tokens-lib]}]
|
||||
(assoc data :tokens-lib tokens-lib))
|
||||
|
||||
(defmethod process-change :add-token
|
||||
[data {:keys [set-name token]}]
|
||||
(update data :tokens-lib #(-> %
|
||||
(ctob/ensure-tokens-lib)
|
||||
(ctob/add-token-in-set set-name (ctob/make-token token)))))
|
||||
(defmethod process-change :set-token
|
||||
[data {:keys [set-name token-name token]}]
|
||||
(update data :tokens-lib
|
||||
(fn [lib]
|
||||
(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
|
||||
[data {:keys [set-name name 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)))))))
|
||||
(not (ctob/get-token-in-set lib' set-name token-name))
|
||||
(ctob/add-token-in-set lib' set-name (ctob/make-token token))
|
||||
|
||||
(defmethod process-change :del-token
|
||||
[data {:keys [set-name name]}]
|
||||
(update data :tokens-lib #(-> %
|
||||
(ctob/ensure-tokens-lib)
|
||||
(ctob/delete-token-from-set
|
||||
set-name
|
||||
name))))
|
||||
:else
|
||||
(ctob/update-token-in-set lib' set-name token-name (fn [prev-token]
|
||||
(ctob/make-token (merge prev-token token)))))))))
|
||||
|
||||
(defmethod process-change :add-temporary-token-theme
|
||||
[data {:keys [token-theme]}]
|
||||
|
|
|
@ -884,30 +884,31 @@
|
|||
(update :undo-changes conj {:type :set-tokens-lib :tokens-lib prev-tokens-lib})
|
||||
(apply-changes-local))))
|
||||
|
||||
(defn add-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]
|
||||
(defn set-token [changes set-name token-name token]
|
||||
(assert-library! changes)
|
||||
(let [library-data (::library-data (meta changes))
|
||||
prev-token (some-> (get library-data :tokens-lib)
|
||||
(ctob/get-set set-name)
|
||||
(ctob/get-token token-name))]
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :del-token :set-name set-name :name token-name})
|
||||
(update :undo-changes conj {:type :add-token :set-name set-name :token prev-token})
|
||||
(update :redo-changes conj {:type :set-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))))
|
||||
|
||||
(defn add-component
|
||||
|
|
|
@ -35,6 +35,11 @@
|
|||
(ctob/get-set set-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
|
||||
[shape stroke-width]
|
||||
(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-group-path-exists? [_ path] "if a set group at `path` exists")
|
||||
(add-token-in-set [_ set-name token] "add token to a set")
|
||||
(get-token-in-set [_ set-name token-name] "get 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")
|
||||
(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))
|
||||
(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-set this set-name #(update-token % token-name f)))
|
||||
|
||||
|
|
|
@ -73,6 +73,70 @@
|
|||
;; Undo
|
||||
(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/testing "toggling set group with no active sets inside will activate all child sets"
|
||||
(let [file (setup-file #(-> %
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
(ns common-tests.types.tokens-lib-test
|
||||
(:require
|
||||
#?(:clj [app.common.fressian :as fres])
|
||||
#?(:clj [clojure.data.json :as json])
|
||||
[app.common.data :as d]
|
||||
[app.common.test-helpers.tokens :as tht]
|
||||
[app.common.time :as dt]
|
||||
[app.common.transit :as tr]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
|
@ -1188,8 +1188,7 @@
|
|||
lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json)
|
||||
get-set-token (fn [set-name token-name]
|
||||
(some-> (ctob/get-set lib set-name)
|
||||
(ctob/get-token token-name)
|
||||
(dissoc :modified-at)))
|
||||
(ctob/get-token token-name)))
|
||||
token-theme (ctob/get-theme lib "group-1" "theme-1")]
|
||||
(t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib)))
|
||||
(t/testing "set exists in theme"
|
||||
|
@ -1197,21 +1196,21 @@
|
|||
(t/is (= (:name token-theme) "theme-1"))
|
||||
(t/is (= (:sets token-theme) #{"light"})))
|
||||
(t/testing "tokens exist in core set"
|
||||
(t/is (= (get-set-token "core" "colors.red.600")
|
||||
{:name "colors.red.600"
|
||||
:type :color
|
||||
:value "#e53e3e"
|
||||
:description nil}))
|
||||
(t/is (= (get-set-token "core" "spacing.multi-value")
|
||||
{:name "spacing.multi-value"
|
||||
:type :spacing
|
||||
:value "{dimension.sm} {dimension.xl}"
|
||||
:description "You can have multiple values in a single spacing token"}))
|
||||
(t/is (= (get-set-token "theme" "button.primary.background")
|
||||
{:name "button.primary.background"
|
||||
:type :color
|
||||
:value "{accent.default}"
|
||||
:description nil})))
|
||||
(t/is (tht/token-data-eq? (get-set-token "core" "colors.red.600")
|
||||
{:name "colors.red.600"
|
||||
:type :color
|
||||
:value "#e53e3e"
|
||||
:description nil}))
|
||||
(t/is (tht/token-data-eq? (get-set-token "core" "spacing.multi-value")
|
||||
{:name "spacing.multi-value"
|
||||
:type :spacing
|
||||
:value "{dimension.sm} {dimension.xl}"
|
||||
:description "You can have multiple values in a single spacing token"}))
|
||||
(t/is (tht/token-data-eq? (get-set-token "theme" "button.primary.background")
|
||||
{:name "button.primary.background"
|
||||
:type :color
|
||||
:value "{accent.default}"
|
||||
:description nil})))
|
||||
(t/testing "invalid tokens got discarded"
|
||||
(t/is (nil? (get-set-token "typography" "H1.Bold"))))))
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.tokens.selected-set :as dwts]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.workspace.tokens.update :as wtu]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[beicon.v2.core :as rx]
|
||||
|
@ -241,14 +240,15 @@
|
|||
[{:keys [token prev-token-name]}]
|
||||
(ptk/reify ::update-create-token
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [token-set (dwts/get-selected-token-set state)
|
||||
token-set-name (or (:name token-set) "Global")
|
||||
(watch [it state _]
|
||||
(let [data (dsh/lookup-file-data state)
|
||||
token-set (dwts/get-selected-token-set state)
|
||||
set-name (or (:name token-set) "Global")
|
||||
changes (if (not token-set)
|
||||
;; No set created add a global set
|
||||
(let [tokens-lib (get-tokens-lib state)
|
||||
token-set (ctob/make-token-set :name token-set-name :tokens {(:name token) token})
|
||||
hidden-theme (ctob/make-hidden-token-theme :sets [token-set-name])
|
||||
token-set (ctob/make-token-set :name set-name :tokens {(:name token) token})
|
||||
hidden-theme (ctob/make-hidden-token-theme :sets [set-name])
|
||||
active-theme-paths (some-> tokens-lib ctob/get-active-theme-paths)
|
||||
add-to-hidden-theme? (= active-theme-paths #{ctob/hidden-token-theme-path})
|
||||
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)))
|
||||
|
||||
:else base-changes))
|
||||
;; Either update or add token to existing set
|
||||
(if-let [prev-token (ctob/get-token token-set (or prev-token-name (:name token)))]
|
||||
(pcb/update-token (pcb/empty-changes) (:name token-set) token prev-token)
|
||||
(do
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name "create-tokens"}))
|
||||
(pcb/add-token (pcb/empty-changes) (:name token-set) token))))]
|
||||
(-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/set-token set-name (or prev-token-name (:name token)) token)))]
|
||||
|
||||
(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))))))
|
||||
|
||||
(defn delete-token
|
||||
|
@ -282,7 +282,7 @@
|
|||
(let [data (dsh/lookup-file-data state)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(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))))))
|
||||
|
||||
(defn duplicate-token
|
||||
|
|
Loading…
Add table
Reference in a new issue