mirror of
https://github.com/penpot/penpot.git
synced 2026-07-27 00:18:17 +00:00
🎉 Allow the user to choose the tokens-source of a file
This commit is contained in:
parent
76e60b177c
commit
209330a5c1
@ -1091,10 +1091,10 @@
|
||||
|
||||
(defn set-tokens-source
|
||||
[changes library-id]
|
||||
(assert-file-data! changes)
|
||||
(let [file-data (::file-data (meta changes))
|
||||
file-id (:id file-data)
|
||||
prev-val (:tokens-source file-data)]
|
||||
(assert-library! changes)
|
||||
(let [library-data (::library-data (meta changes))
|
||||
file-id (:id library-data)
|
||||
prev-val (:tokens-source library-data)]
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :set-tokens-source
|
||||
:file-id file-id
|
||||
|
||||
@ -463,13 +463,43 @@
|
||||
(update :tokens-status #(or % (ctos/make-tokens-status)))))
|
||||
|
||||
(defn get-tokens-source
|
||||
"Return the current tokens source of the file. When there is no explicit :tokens-source attribute,
|
||||
the source is the file itself."
|
||||
[file-data]
|
||||
(:tokens-source file-data))
|
||||
(or (:tokens-source file-data) (:id file-data)))
|
||||
|
||||
(defn set-tokens-source
|
||||
[file-data tokens-source]
|
||||
(assoc file-data :tokens-source tokens-source))
|
||||
|
||||
(defn tokens-source?
|
||||
"Returns true if the given id is the current tokens source of the file-data.
|
||||
When no tokens-source is set, the file's own id is considered the source if there are any tokens in it."
|
||||
[file-data id]
|
||||
(assert (uuid? id) "expected valid uuid")
|
||||
(let [source (:tokens-source file-data)
|
||||
tokens-lib (:tokens-lib file-data)
|
||||
has-tokens? (and (some? tokens-lib)
|
||||
(not (ctob/empty-lib? tokens-lib)))]
|
||||
(if (= id (:id file-data))
|
||||
(and has-tokens?
|
||||
(or (nil? source) (= source id)))
|
||||
(= source id))))
|
||||
|
||||
(defn tokens-provider?
|
||||
"Returns true if the file MAY become a tokens source. This is if the file has tokens and has
|
||||
not configured another tokens source."
|
||||
[file-data]
|
||||
(and (some? (:tokens-lib file-data))
|
||||
(or (nil? (:tokens-source file-data))
|
||||
(= (:tokens-source file-data) (:id file-data)))))
|
||||
|
||||
(defn editable-tokens?
|
||||
"Returns true if the file-data owns its tokens (no external source or source is itself)."
|
||||
[file-data]
|
||||
(let [source (:tokens-source file-data)]
|
||||
(or (nil? source) (= source (:id file-data)))))
|
||||
|
||||
(defn get-tokens-lib
|
||||
[file-data]
|
||||
(:tokens-lib file-data))
|
||||
@ -656,7 +686,9 @@
|
||||
(conj force-set-id))]
|
||||
(reduce (fn [tokens set-id]
|
||||
(let [set (ctob/get-set tokens-lib set-id)]
|
||||
(merge tokens (ctob/get-tokens- set))))
|
||||
(if set
|
||||
(merge tokens (ctob/get-tokens- set))
|
||||
tokens)))
|
||||
(d/ordered-map)
|
||||
ordered-active)))
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.common.types.tokens-status :as ctos]
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.datafy :refer [datafy]]
|
||||
[clojure.test :as t]))
|
||||
|
||||
;; Helper functions
|
||||
@ -235,25 +234,25 @@
|
||||
(t/is (ctos/tokens-status? (:tokens-status file-data')))))
|
||||
|
||||
(t/testing "ensure-tokens-lib should not add a tokens-lib if there is a tokens-source"
|
||||
(let [tokens-source (uuid/next)
|
||||
(let [source-id (uuid/next)
|
||||
tokens-status (ctos/make-tokens-status)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(assoc-in [:data :tokens-source] tokens-source)
|
||||
(assoc-in [:data :tokens-source] source-id)
|
||||
(assoc-in [:data :tokens-status] tokens-status))
|
||||
file-data (ctf/file-data file)
|
||||
file-data' (cfo/ensure-tokens-lib file-data)]
|
||||
(t/is (not (contains? file-data' :tokens-lib)))
|
||||
(t/is (= tokens-source (:tokens-source file-data')))
|
||||
(t/is (= source-id (:tokens-source file-data')))
|
||||
(t/is (= tokens-status (:tokens-status file-data')))))
|
||||
|
||||
(t/testing "ensure-tokens-lib should not add a tokens-lib if there is a tokens-source, but should add a tokens-status if it's missing"
|
||||
(let [tokens-source (uuid/next)
|
||||
(let [source-id (uuid/next)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(assoc-in [:data :tokens-source] tokens-source))
|
||||
(assoc-in [:data :tokens-source] source-id))
|
||||
file-data (ctf/file-data file)
|
||||
file-data' (cfo/ensure-tokens-lib file-data)]
|
||||
(t/is (not (contains? file-data' :tokens-lib)))
|
||||
(t/is (= tokens-source (:tokens-source file-data')))
|
||||
(t/is (= source-id (:tokens-source file-data')))
|
||||
(t/is (contains? file-data' :tokens-status))
|
||||
(t/is (ctos/tokens-status? (:tokens-status file-data'))))))
|
||||
|
||||
@ -268,20 +267,224 @@
|
||||
|
||||
(t/deftest test-get-tokens-source
|
||||
(t/testing "returns tokens-source from file data"
|
||||
(let [file-id (thi/new-id! :tokens-source)
|
||||
file-data {:tokens-source file-id}]
|
||||
(t/is (= file-id (cfo/get-tokens-source file-data)))))
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(assoc-in [:data :tokens-source] source-id))]
|
||||
(t/is (= source-id (cfo/get-tokens-source (:data file))))))
|
||||
|
||||
(t/testing "returns nil when no tokens-source"
|
||||
(t/is (nil? (cfo/get-tokens-source {})))))
|
||||
(t/testing "returns file id when no tokens-source"
|
||||
(let [file (thf/sample-file :file1)]
|
||||
(t/is (= (:id file) (cfo/get-tokens-source file))))))
|
||||
|
||||
(t/deftest test-set-tokens-source
|
||||
(t/testing "sets tokens-source on file data"
|
||||
(let [file-id (thi/new-id! :tokens-source)
|
||||
file-data {:other :data}
|
||||
file-data' (cfo/set-tokens-source file-data file-id)]
|
||||
(t/is (= file-id (:tokens-source file-data')))
|
||||
(t/is (= :data (:other file-data'))))))
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (thf/sample-file :file1)
|
||||
file-data (:data file)
|
||||
file-data' (cfo/set-tokens-source file-data source-id)]
|
||||
(t/is (= source-id (:tokens-source file-data'))))))
|
||||
|
||||
(t/deftest test-tokens-source?
|
||||
(t/testing "no tokens, no tokens-source, ask for file id -> false"
|
||||
(let [file (thf/sample-file :file1)
|
||||
file-data (:data file)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "empty tokens-lib, no tokens-source, ask for file id -> false"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (:data file)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "tokens, no tokens-source, ask for file id -> true"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib)
|
||||
(tht/update-tokens-lib
|
||||
#(-> %
|
||||
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))
|
||||
(ctob/add-token (thi/id :set-a) (ctob/make-token :id (thi/new-id! :tok1) :name "spacing" :type :spacing :value "8px")))))
|
||||
file-data (:data file)]
|
||||
(t/is (true? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "no tokens, no tokens source, ask for other id -> false"
|
||||
(let [file (thf/sample-file :file1)
|
||||
file-data (:data file)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
(t/testing "empty tokens-lib, no tokens source, ask for other id -> false"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (:data file)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
(t/testing "tokens, no tokens source, ask for other id -> false"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib)
|
||||
(tht/update-tokens-lib
|
||||
#(-> %
|
||||
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))
|
||||
(ctob/add-token (thi/id :set-a) (ctob/make-token :id (thi/new-id! :tok1) :name "spacing" :type :spacing :value "8px")))))
|
||||
file-data (:data file)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
;; ---
|
||||
|
||||
(t/testing "no tokens, tokens source = file id, ask for file id -> false" ;; This case should not occur
|
||||
(let [file (thf/sample-file :file1)
|
||||
file-data (cfo/set-tokens-source (:data file) (:id (:data file)))]
|
||||
(t/is (false? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "empty tokens-lib, tokens source = file id, ask for file id -> false" ;; This case should not occur
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (cfo/set-tokens-source (:data file) (:id (:data file)))]
|
||||
(t/is (false? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "tokens, tokens source = file id, ask for file id -> true"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib)
|
||||
(tht/update-tokens-lib
|
||||
#(-> %
|
||||
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))
|
||||
(ctob/add-token (thi/id :set-a) (ctob/make-token :id (thi/new-id! :tok1) :name "spacing" :type :spacing :value "8px")))))
|
||||
file-data (cfo/set-tokens-source (:data file) (:id (:data file)))]
|
||||
(t/is (true? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "no tokens, tokens source = file id, ask for other id -> false" ;; This case should not occur
|
||||
(let [file (thf/sample-file :file1)
|
||||
file-data (cfo/set-tokens-source (:data file) (:id (:data file)))]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
(t/testing "empty tokens-lib, tokens source = file id, ask for other id -> false" ;; This case should not occur
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (cfo/set-tokens-source (:data file) (:id (:data file)))]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
(t/testing "tokens, tokens source = file id, ask for other id -> false"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib)
|
||||
(tht/update-tokens-lib
|
||||
#(-> %
|
||||
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))
|
||||
(ctob/add-token (thi/id :set-a) (ctob/make-token :id (thi/new-id! :tok1) :name "spacing" :type :spacing :value "8px")))))
|
||||
file-data (cfo/set-tokens-source (:data file) (:id (:data file)))]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
;; ---
|
||||
|
||||
(t/testing "no tokens, tokens source = other id, ask for file id -> false"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (thf/sample-file :file1)
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "empty tokens-lib, tokens source = other id, ask for file id -> false"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "tokens, tokens source = other id, ask for file id -> false"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib)
|
||||
(tht/update-tokens-lib
|
||||
#(-> %
|
||||
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))
|
||||
(ctob/add-token (thi/id :set-a) (ctob/make-token :id (thi/new-id! :tok1) :name "spacing" :type :spacing :value "8px")))))
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (:id file-data))))))
|
||||
|
||||
(t/testing "no tokens, tokens source = other id, ask for this same id -> true"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (thf/sample-file :file1)
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (true? (cfo/tokens-source? file-data source-id)))))
|
||||
|
||||
(t/testing "empty tokens-lib, tokens source = other id, ask for this same id -> true"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (true? (cfo/tokens-source? file-data source-id)))))
|
||||
|
||||
(t/testing "tokens, tokens source = other id, ask for this same id -> true"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib)
|
||||
(tht/update-tokens-lib
|
||||
#(-> %
|
||||
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))
|
||||
(ctob/add-token (thi/id :set-a) (ctob/make-token :id (thi/new-id! :tok1) :name "spacing" :type :spacing :value "8px")))))
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (true? (cfo/tokens-source? file-data source-id)))))
|
||||
|
||||
(t/testing "no tokens, tokens source = other id, ask for a different id -> false"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (thf/sample-file :file1)
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
(t/testing "empty tokens-lib, tokens source = other id, ask for a different id -> false"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next))))))
|
||||
|
||||
(t/testing "tokens, tokens source = other id, ask for a different id -> false"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib)
|
||||
(tht/update-tokens-lib
|
||||
#(-> %
|
||||
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))
|
||||
(ctob/add-token (thi/id :set-a) (ctob/make-token :id (thi/new-id! :tok1) :name "spacing" :type :spacing :value "8px")))))
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (false? (cfo/tokens-source? file-data (uuid/next)))))))
|
||||
|
||||
(t/deftest test-tokens-provider?
|
||||
(t/testing "returns false if it has no tokens"
|
||||
(let [file (thf/sample-file :file1)
|
||||
file-data (:data file)]
|
||||
(t/is (false? (cfo/tokens-provider? file-data)))))
|
||||
|
||||
(t/testing "returns true if it has tokens and no tokens-source"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (:data file)]
|
||||
(t/is (true? (cfo/tokens-provider? file-data)))))
|
||||
|
||||
(t/testing "returns true if it has tokens and tokens-source is its own id"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (cfo/set-tokens-source (:data file) (:id file))]
|
||||
(t/is (true? (cfo/tokens-provider? file-data)))))
|
||||
|
||||
(t/testing "returns false if it has tokens and tokens-source is other id"
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(tht/add-tokens-lib))
|
||||
file-data (cfo/set-tokens-source (:data file) (uuid/next))]
|
||||
(t/is (false? (cfo/tokens-provider? file-data))))))
|
||||
|
||||
(t/deftest test-editable-tokens?
|
||||
(t/testing "returns true when file-data has no tokens-source"
|
||||
(let [file (thf/sample-file :file1)
|
||||
file-data (:data file)]
|
||||
(t/is (true? (cfo/editable-tokens? file-data)))))
|
||||
|
||||
(t/testing "returns true when tokens-source is the file's own id"
|
||||
(let [file (thf/sample-file :file1)
|
||||
file-data (cfo/set-tokens-source (:data file) (:id (:data file)))]
|
||||
(t/is (true? (cfo/editable-tokens? file-data)))))
|
||||
|
||||
(t/testing "returns false when tokens-source is a different uuid"
|
||||
(let [source-id (thi/new-id! :tokens-source)
|
||||
file (thf/sample-file :file1)
|
||||
file-data (cfo/set-tokens-source (:data file) source-id)]
|
||||
(t/is (false? (cfo/editable-tokens? file-data))))))
|
||||
|
||||
(t/deftest test-get-tokens-status
|
||||
(t/testing "returns tokens-status from file data"
|
||||
|
||||
@ -38,10 +38,11 @@
|
||||
([state file-id]
|
||||
(dm/get-in state [:files file-id :data])))
|
||||
|
||||
;; TODO perhaps this is not necessary, lookup-tokens-lib should be enough
|
||||
(defn lookup-tokens-source-data
|
||||
[state]
|
||||
(let [current-file-data (lookup-file-data state)
|
||||
tokens-source-id (or (cfo/get-tokens-source current-file-data) (:id current-file-data))]
|
||||
tokens-source-id (cfo/get-tokens-source current-file-data)]
|
||||
(lookup-file-data state tokens-source-id)))
|
||||
|
||||
(defn lookup-tokens-lib
|
||||
|
||||
@ -1628,10 +1628,6 @@
|
||||
(map first)
|
||||
set)]
|
||||
(rx/concat
|
||||
(when (contains? cf/flags :token-lib-sync)
|
||||
(rx/of (dch/commit-changes (-> (pcb/empty-changes nil)
|
||||
(pcb/with-file-data file-data)
|
||||
(pcb/set-tokens-source library-id)))))
|
||||
(->> (rp/cmd! :link-file-to-library {:file-id file-id :library-id library-id})
|
||||
(rx/merge-map (fn [libraries-to-load]
|
||||
(as-> libraries-to-load $
|
||||
|
||||
@ -420,6 +420,17 @@
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn set-tokens-source
|
||||
[library-id]
|
||||
(ptk/reify ::set-tokens-source
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (dsh/lookup-file-data state)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/set-tokens-source library-id))]
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
|
||||
(defn delete-token-set
|
||||
[id]
|
||||
(ptk/reify ::delete-token-set
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cfo]
|
||||
[app.common.files.variant :as cfv]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
@ -24,6 +25,7 @@
|
||||
[app.main.data.team :as dtm]
|
||||
[app.main.data.workspace.colors :as mdc]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.render :refer [component-svg]]
|
||||
[app.main.store :as st]
|
||||
@ -262,7 +264,7 @@
|
||||
|
||||
unlink-library
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(mf/deps file-id local-library)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
@ -270,7 +272,11 @@
|
||||
(when (= library-id @selected)
|
||||
(reset! selected :file))
|
||||
(st/emit! (dwl/unlink-file-from-library file-id library-id)
|
||||
(dwl/sync-file file-id library-id)))))
|
||||
(dwl/sync-file file-id library-id))
|
||||
;; When the unlinked library is the current tokens source,
|
||||
;; we must reset it to the local library.
|
||||
(when (cfo/tokens-source? local-library library-id)
|
||||
(st/emit! (dwtl/set-tokens-source (:id local-library)))))))
|
||||
|
||||
import-tokens
|
||||
(mf/use-fn
|
||||
@ -283,6 +289,14 @@
|
||||
:tokens/import-from-library {:file-id file-id
|
||||
:library-id library-id})))))
|
||||
|
||||
set-as-tokens-source
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(st/emit! (dwtl/set-tokens-source library-id)))))
|
||||
|
||||
on-delete-accept
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
@ -335,7 +349,16 @@
|
||||
[:div {:class (stl/css :item-content)}
|
||||
[:div {:class (stl/css :item-title)} (tr "workspace.libraries.file-library")]
|
||||
[:ul {:class (stl/css :item-contents)}
|
||||
[:> library-description* {:summary summary}]]]
|
||||
[:> library-description* {:summary summary}]]
|
||||
(when (contains? cf/flags :token-lib-sync)
|
||||
(if (cfo/tokens-source? local-library (:id local-library))
|
||||
[:div (tr "workspace.libraries.tokens-source")]
|
||||
(when (not= (cfo/get-tokens-source local-library) (:id local-library))
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:data-library-id (dm/str (:id local-library))
|
||||
:on-click set-as-tokens-source}
|
||||
(tr "workspace.libraries.set-as-tokens-source")])))]
|
||||
|
||||
(if ^boolean is-shared
|
||||
[:> button* {:variant "secondary"
|
||||
@ -366,16 +389,28 @@
|
||||
[:div {:class (stl/css :connected-to-wrapper)}
|
||||
[:span "(" (tr "workspace.libraries.connected-to") " "]
|
||||
[:span {:class (stl/css :connected-to-values)} (str/join ", " connected-to-names)]
|
||||
[:span ")"]])])]]
|
||||
[:span ")"]])])]
|
||||
(when (contains? cf/flags :token-lib-sync)
|
||||
(when (cfo/tokens-source? local-library id)
|
||||
[:div (tr "workspace.libraries.tokens-source")]))]
|
||||
|
||||
[:div {:class (stl/css :library-actions)}
|
||||
(when ^boolean has-tokens?
|
||||
[:> icon-button*
|
||||
{:type "button"
|
||||
:aria-label (tr "workspace.tokens.import-tokens")
|
||||
:icon i/import-export
|
||||
:data-library-id (dm/str id)
|
||||
:variant "secondary"
|
||||
:on-click import-tokens}])
|
||||
(if (contains? cf/flags :token-lib-sync)
|
||||
(when (and (cfo/tokens-provider? (:data library))
|
||||
(not (cfo/tokens-source? local-library id)))
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:data-library-id (dm/str id)
|
||||
:on-click set-as-tokens-source}
|
||||
(tr "workspace.libraries.set-as-tokens-source")])
|
||||
(when ^boolean has-tokens?
|
||||
[:> icon-button*
|
||||
{:type "button"
|
||||
:aria-label (tr "workspace.tokens.import-tokens")
|
||||
:icon i/import-export
|
||||
:data-library-id (dm/str id)
|
||||
:variant "secondary"
|
||||
:on-click import-tokens}]))
|
||||
|
||||
[:> icon-button* {:type "button"
|
||||
:aria-label (tr "workspace.libraries.unlink-library-btn")
|
||||
|
||||
@ -8,8 +8,10 @@
|
||||
(:require
|
||||
[app.common.files.tokens :as cfo]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.changes :as dch]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
@ -53,6 +55,31 @@
|
||||
"Stops on `send-update-indices` function being called, which should be the last function of an event chain."
|
||||
(stop-on ::end))
|
||||
|
||||
(defn watch-undo-stack
|
||||
"Maintain the workspace undo stack by watching for commit events.
|
||||
Must be emitted before the events under test so undo entries are populated."
|
||||
[]
|
||||
(ptk/reify ::watch-undo-stack
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stopper-s (->> stream (rx/filter (ptk/type? ::watch-undo-stack)))]
|
||||
(->> stream
|
||||
(rx/filter dch/commit?)
|
||||
(rx/map deref)
|
||||
(rx/filter #(= :local (:source %)))
|
||||
(rx/mapcat
|
||||
(fn [{:keys [save-undo? undo-changes redo-changes undo-group tags stack-undo? selected-before]}]
|
||||
(if (and save-undo? (seq undo-changes))
|
||||
(rx/of (dwu/append-undo
|
||||
{:undo-changes undo-changes
|
||||
:redo-changes redo-changes
|
||||
:undo-group undo-group
|
||||
:tags tags
|
||||
:selected-before selected-before}
|
||||
stack-undo?))
|
||||
(rx/empty))))
|
||||
(rx/take-until stopper-s))))))
|
||||
|
||||
;; Support for async events in tests
|
||||
;; https://chat.kaleidos.net/penpot-partners/pl/tz1yoes3w3fr9qanxqpuhoz3ch
|
||||
(defn run-store
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
(ns frontend-tests.tokens.logic.token-actions-test
|
||||
(:require
|
||||
[app.common.files.tokens :as cfo]
|
||||
[app.common.test-helpers.compositions :as ctho]
|
||||
[app.common.test-helpers.files :as cthf]
|
||||
[app.common.test-helpers.ids-map :as cthi]
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
[app.common.types.tokens-status :as ctos]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[frontend-tests.helpers.pages :as thp]
|
||||
[frontend-tests.helpers.state :as ths]
|
||||
@ -123,4 +124,32 @@
|
||||
sets' (ctob/get-sets tokens-lib')]
|
||||
|
||||
(t/testing "Set has been deleted"
|
||||
(t/is (= (count sets') 0)))))))))
|
||||
(t/is (= (count sets') 0)))))))))
|
||||
|
||||
(t/deftest set-tokens-source
|
||||
(t/async
|
||||
done
|
||||
(let [file (setup-file-with-token-lib)
|
||||
store (ths/setup-store file)
|
||||
library-id (uuid/next)]
|
||||
|
||||
;; Phase 1: set tokens-source with undo watcher active
|
||||
(tohs/run-store
|
||||
store identity
|
||||
[(tohs/watch-undo-stack)
|
||||
(dwtl/set-tokens-source library-id)]
|
||||
(fn [new-state]
|
||||
(let [file-data' (-> (ths/get-file-from-state new-state) :data)]
|
||||
(t/testing "tokens-source is set to the library id"
|
||||
(t/is (= library-id (:tokens-source file-data'))))))
|
||||
(tohs/stop-on ::dwtl/set-tokens-source))
|
||||
|
||||
;; Phase 2: undo and verify restoration
|
||||
(tohs/run-store
|
||||
store done
|
||||
[dwu/undo]
|
||||
(fn [undone-state]
|
||||
(let [file-data'' (-> (ths/get-file-from-state undone-state) :data)]
|
||||
(t/testing "tokens-source is restored to nil"
|
||||
(t/is (nil? (:tokens-source file-data''))))))
|
||||
(tohs/stop-on ::dwu/undo)))))
|
||||
|
||||
@ -7239,6 +7239,14 @@ msgstr "some templates in here"
|
||||
msgid "workspace.libraries.file-library"
|
||||
msgstr "File library"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:336
|
||||
msgid "workspace.libraries.tokens-source"
|
||||
msgstr "Tokens source"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:336
|
||||
msgid "workspace.libraries.set-as-tokens-source"
|
||||
msgstr "Set as tokens source"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:100, src/app/main/ui/workspace/libraries.cljs:124
|
||||
msgid "workspace.libraries.graphics"
|
||||
msgid_plural "workspace.libraries.graphics"
|
||||
|
||||
@ -7072,6 +7072,14 @@ msgstr "algunas plantillas aquí"
|
||||
msgid "workspace.libraries.file-library"
|
||||
msgstr "Biblioteca del archivo"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:336
|
||||
msgid "workspace.libraries.tokens-source"
|
||||
msgstr "Fuente de tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:336
|
||||
msgid "workspace.libraries.set-as-tokens-source"
|
||||
msgstr "Activar fuente de tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:100, src/app/main/ui/workspace/libraries.cljs:124
|
||||
msgid "workspace.libraries.graphics"
|
||||
msgid_plural "workspace.libraries.graphics"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user