mirror of
https://github.com/penpot/penpot.git
synced 2026-09-23 20:36:15 +00:00
✨ Expand the token tree after importing it (#10664)
Imported token sets were collapsed, hiding what had just been imported. Fixes #9819 Signed-off-by: Akshit Nassa <akshitnassa412@gmail.com> Co-authored-by: Akshit Nassa <akshitnassa412@gmail.com> Co-authored-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
e62546a03a
commit
4968dc2f1d
@ -165,6 +165,49 @@
|
||||
[:workspace-tokens :unfolded-token-types]
|
||||
(make-unfolded-token-types-state file-id set-id #{}))))))
|
||||
|
||||
(defn- get-token-types-by-set
|
||||
"Returns a map of set id to the token types present on that set of `lib`."
|
||||
[lib]
|
||||
(reduce (fn [result token-set]
|
||||
(let [set-id (ctob/get-id token-set)
|
||||
types (into #{} (map :type) (vals (ctob/get-tokens lib set-id)))]
|
||||
(cond-> result
|
||||
(seq types) (assoc set-id types))))
|
||||
{}
|
||||
(ctob/get-sets lib)))
|
||||
|
||||
(defn- unfold-token-types-in-storage
|
||||
[file-id types-by-set]
|
||||
(swap! storage/user update :app.main.ui.workspace.tokens/unfolded-token-types
|
||||
(fn [stored]
|
||||
(reduce-kv (fn [stored set-id types]
|
||||
(update-in stored [file-id set-id]
|
||||
#(-> (set %) (into types) (vec))))
|
||||
stored
|
||||
types-by-set))))
|
||||
|
||||
(defn unfold-token-types
|
||||
"Unfolds all the token types present on every set of `lib`, keeping the ones
|
||||
already unfolded. The token sections restore their fold state from the storage
|
||||
on mount and on set selection, so it also needs to be persisted there."
|
||||
[lib]
|
||||
(ptk/reify ::unfold-token-types
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [file-id (:current-file-id state)
|
||||
selected (get-in state [:workspace-tokens :selected-token-set-id])
|
||||
;; The panel keeps the selected set if it is part of the imported
|
||||
;; library, and falls back to its first set otherwise.
|
||||
set-id (or (some->> selected (ctob/get-set lib) (ctob/get-id))
|
||||
(some->> (ctob/get-sets lib) (first) (ctob/get-id)))]
|
||||
(unfold-token-types-in-storage file-id (get-token-types-by-set lib))
|
||||
(cond-> state
|
||||
(some? set-id)
|
||||
(assoc-in [:workspace-tokens :unfolded-token-types]
|
||||
(make-unfolded-token-types-state
|
||||
file-id set-id
|
||||
(get-unfolded-token-types-from-storage file-id set-id))))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; TOKENS TREE - Toggle tree nodes
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -422,6 +465,7 @@
|
||||
(pcb/set-tokens-lib lib)
|
||||
(pcb/set-tokens-status status))]
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(unfold-token-types lib)
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn set-tokens-source
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.data.workspace.wasm-text :as dwwt]
|
||||
[app.util.storage :as storage]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[cuerdas.core :as str]
|
||||
[frontend-tests.helpers.pages :as thp]
|
||||
@ -1266,3 +1267,122 @@
|
||||
(t/is (pos? (thw/call-count :set-shape-text-content)))
|
||||
(t/is (pos? (thw/call-count :get-text-dimensions))))))
|
||||
debounce-text-stop)))))
|
||||
|
||||
;; Coverage for issue #9819 (token tree collapsed after import).
|
||||
;;
|
||||
;; The fold state of the token type sections lives in
|
||||
;; `[:workspace-tokens :unfolded-token-types]` and is persisted in the user
|
||||
;; storage. The sections restore that state from storage on mount and when the
|
||||
;; selected set changes, so importing a library has to unfold the imported
|
||||
;; token types on both places, otherwise the tree shows up collapsed.
|
||||
|
||||
(defn- unfolded-token-types
|
||||
[state]
|
||||
(get-in state [:workspace-tokens :unfolded-token-types :types]))
|
||||
|
||||
(defn- reset-unfolded-token-types-storage! []
|
||||
(swap! storage/user dissoc :app.main.ui.workspace.tokens/unfolded-token-types))
|
||||
|
||||
(defn- setup-imported-lib []
|
||||
(-> (ctob/make-tokens-lib)
|
||||
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :imported-set-a)
|
||||
:name "Imported A"))
|
||||
(ctob/add-token (cthi/id :imported-set-a)
|
||||
(ctob/make-token {:name "borderRadius.sm"
|
||||
:value "12"
|
||||
:type :border-radius}))
|
||||
(ctob/add-token (cthi/id :imported-set-a)
|
||||
(ctob/make-token {:name "color.primary"
|
||||
:value "#ff0000"
|
||||
:type :color}))
|
||||
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :imported-set-b)
|
||||
:name "Imported B"))
|
||||
(ctob/add-token (cthi/id :imported-set-b)
|
||||
(ctob/make-token {:name "spacing.md"
|
||||
:value "16"
|
||||
:type :spacing}))))
|
||||
|
||||
(t/deftest test-import-tokens-lib-unfolds-token-types
|
||||
(t/testing "importing a tokens library unfolds the token types of the shown set"
|
||||
(t/async
|
||||
done
|
||||
(reset-unfolded-token-types-storage!)
|
||||
(let [file (setup-file-with-empty-lib)
|
||||
store (ths/setup-store file)
|
||||
lib (setup-imported-lib)
|
||||
events [(dwtl/import-tokens-lib lib)]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
(t/is (= #{:border-radius :color} (unfolded-token-types new-state)))
|
||||
(t/is (= (cthi/id :imported-set-a)
|
||||
(get-in new-state [:workspace-tokens :unfolded-token-types :set-id])))
|
||||
(t/is (= (:id file)
|
||||
(get-in new-state [:workspace-tokens :unfolded-token-types :file-id])))))))))
|
||||
|
||||
(t/deftest test-import-tokens-lib-persists-unfolded-token-types
|
||||
(t/testing "the unfolded token types survive the storage restore done on section mount"
|
||||
(t/async
|
||||
done
|
||||
(reset-unfolded-token-types-storage!)
|
||||
(let [file (setup-file-with-empty-lib)
|
||||
store (ths/setup-store file)
|
||||
lib (setup-imported-lib)
|
||||
;; Mirrors what the UI does after an import: the tokens panel selects
|
||||
;; the first set and every token section restores its fold state from
|
||||
;; storage on mount.
|
||||
events [(dwtl/import-tokens-lib lib)
|
||||
(dwtl/set-selected-token-set-id (cthi/id :imported-set-a))
|
||||
(dwtl/restore-unfolded-token-types)]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
(t/is (= #{:border-radius :color} (unfolded-token-types new-state)))))))))
|
||||
|
||||
(t/deftest test-import-tokens-lib-unfolds-every-imported-set
|
||||
(t/testing "switching to another imported set also shows it unfolded"
|
||||
(t/async
|
||||
done
|
||||
(reset-unfolded-token-types-storage!)
|
||||
(let [file (setup-file-with-empty-lib)
|
||||
store (ths/setup-store file)
|
||||
lib (setup-imported-lib)
|
||||
events [(dwtl/import-tokens-lib lib)
|
||||
(dwtl/set-selected-token-set-id (cthi/id :imported-set-b))]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
(t/is (= #{:spacing} (unfolded-token-types new-state)))))))))
|
||||
|
||||
(t/deftest test-import-tokens-lib-keeps-previously-unfolded-types
|
||||
(t/testing "importing does not fold token types the user had already unfolded"
|
||||
(t/async
|
||||
done
|
||||
(reset-unfolded-token-types-storage!)
|
||||
(let [file (setup-file-with-tokens)
|
||||
store (ths/setup-store file)
|
||||
lib (-> (get-in file [:data :tokens-lib])
|
||||
(ctob/add-token (cthi/id :set-a)
|
||||
(ctob/make-token {:name "color.primary"
|
||||
:value "#ff0000"
|
||||
:type :color})))
|
||||
events [(dwtl/set-selected-token-set-id (cthi/id :set-a))
|
||||
(dwtl/open-token-type :opacity)
|
||||
(dwtl/import-tokens-lib lib)]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
(t/is (= #{:border-radius :color :opacity} (unfolded-token-types new-state)))))))))
|
||||
|
||||
(t/deftest test-import-empty-tokens-lib
|
||||
(t/testing "importing a library without sets does not fail nor unfold anything"
|
||||
(t/async
|
||||
done
|
||||
(reset-unfolded-token-types-storage!)
|
||||
(let [file (setup-file-with-empty-lib)
|
||||
store (ths/setup-store file)
|
||||
events [(dwtl/import-tokens-lib (ctob/make-tokens-lib))]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
(t/is (empty? (unfolded-token-types new-state)))))))))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user