0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-24 07:46:13 -05:00

Improve efficiency of grouping and sorting token types

This commit is contained in:
Andrey Antukh 2025-02-04 20:29:39 +01:00
parent e4bf2bd9ad
commit 831b0baddd
3 changed files with 59 additions and 38 deletions

View file

@ -35,6 +35,7 @@
[app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token :as wtt]
[app.main.ui.workspace.tokens.token-pill :refer [token-pill*]] [app.main.ui.workspace.tokens.token-pill :refer [token-pill*]]
[app.main.ui.workspace.tokens.token-types :as wtty] [app.main.ui.workspace.tokens.token-types :as wtty]
[app.util.array :as array]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[app.util.webapi :as wapi] [app.util.webapi :as wapi]
@ -74,10 +75,12 @@
(mf/defc token-group* (mf/defc token-group*
{::mf/private true} {::mf/private true}
[{:keys [type tokens selected-shapes token-type-props active-theme-tokens]}] [{:keys [type tokens selected-shapes active-theme-tokens]}]
(let [open? (mf/deref (-> (l/key type) (let [open? (mf/deref (-> (l/key type)
(l/derived lens:token-type-open-status))) (l/derived lens:token-type-open-status)))
{:keys [modal attributes all-attributes title]} token-type-props
{:keys [modal attributes all-attributes title] :as token-type-props}
(get wtty/token-types type)
tokens tokens
(mf/with-memo [tokens] (mf/with-memo [tokens]
@ -150,7 +153,6 @@
[:> token-pill* [:> token-pill*
{:key (:name token) {:key (:name token)
:token-type-props token-type-props
:token (d/nilv theme-token token) :token (d/nilv theme-token token)
:selected-shapes selected-shapes :selected-shapes selected-shapes
:active-theme-tokens active-theme-tokens :active-theme-tokens active-theme-tokens
@ -163,19 +165,23 @@
:on-context-menu on-context-menu}]))]])]])) :on-context-menu on-context-menu}]))]])]]))
(defn- get-sorted-token-groups (defn- get-sorted-token-groups
"Separate token-types into groups of `:empty` or `:filled` depending if tokens exist for that type. "Separate token-types into groups of `empty` or `filled` depending if
Sort each group alphabetically (by their `:token-key`)." tokens exist for that type. Sort each group alphabetically (by
[tokens] their type)."
(let [tokens-by-type (ctob/group-by-type tokens) [tokens-by-type]
{:keys [empty filled]} (->> wtty/token-types (loop [empty #js []
(map (fn [[token-key token-type-props]] filled #js []
{:token-key token-key types (-> wtty/token-types keys seq)]
:token-type-props token-type-props (if-let [type (first types)]
:tokens (get tokens-by-type token-key [])})) (if (not-empty (get tokens-by-type type))
(group-by (fn [{:keys [tokens]}] (recur empty
(if (empty? tokens) :empty :filled))))] (array/conj! filled type)
{:empty (sort-by :token-key empty) (rest types))
:filled (sort-by :token-key filled)})) (recur (array/conj! empty type)
filled
(rest types)))
[(seq (array/sort! empty))
(seq (array/sort! filled))])))
(mf/defc themes-header (mf/defc themes-header
[_props] [_props]
@ -283,31 +289,39 @@
selected-token-set-name selected-token-set-name
(mf/deref refs/workspace-selected-token-set-name) (mf/deref refs/workspace-selected-token-set-name)
token-groups tokens-by-type
(mf/with-memo [tokens selected-token-set-tokens] (mf/with-memo [tokens selected-token-set-tokens]
(-> (select-keys tokens (keys selected-token-set-tokens)) (let [tokens (reduce-kv (fn [tokens k _]
(get-sorted-token-groups)))] (if (contains? selected-token-set-tokens k)
tokens
(dissoc tokens k)))
tokens
tokens)]
(ctob/group-by-type tokens)))
[empty-group filled-group]
(mf/with-memo [tokens-by-type]
(get-sorted-token-groups tokens-by-type))]
[:* [:*
[:& token-context-menu] [:& token-context-menu]
[:& title-bar {:all-clickable true [:& title-bar {:all-clickable true
:title (tr "workspace.token.tokens-section-title" selected-token-set-name)}] :title (tr "workspace.token.tokens-section-title" selected-token-set-name)}]
(for [{:keys [token-key token-type-props tokens]} (:filled token-groups)] (for [type filled-group]
[:> token-group* {:key token-key (let [tokens (get tokens-by-type type)]
:type token-key [:> token-group* {:key (name type)
:type type
:selected-shapes selected-shapes :selected-shapes selected-shapes
:active-theme-tokens active-theme-tokens :active-theme-tokens active-theme-tokens
:tokens tokens :tokens tokens}]))
:token-type-props token-type-props}])
(for [{:keys [token-key token-type-props tokens]} (:empty token-groups)] (for [type empty-group]
[:> token-group* {:key token-key [:> token-group* {:key (name type)
:type token-key :type type
:selected-shapes selected-shapes :selected-shapes selected-shapes
:active-theme-tokens active-theme-tokens :active-theme-tokens active-theme-tokens
:tokens tokens :tokens []}])]))
:token-type-props token-type-props}])]))
(mf/defc import-export-button (mf/defc import-export-button
{::mf/wrap-props false} {::mf/wrap-props false}

View file

@ -9,6 +9,7 @@
[app.main.ui.ds.foundations.assets.icon :refer [icon*]] [app.main.ui.ds.foundations.assets.icon :refer [icon*]]
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]] [app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]]
[app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token :as wtt]
[app.main.ui.workspace.tokens.token-types :as wtty]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[cuerdas.core :as str] [cuerdas.core :as str]
@ -95,9 +96,9 @@
(defn- generate-tooltip (defn- generate-tooltip
"Generates a tooltip for a given token" "Generates a tooltip for a given token"
[is-viewer shape token-type-props token half-applied no-valid-value ref-not-in-active-set] [is-viewer shape token half-applied no-valid-value ref-not-in-active-set]
(let [{:keys [name value resolved-value type]} token (let [{:keys [name value resolved-value type]} token
{:keys [title]} token-type-props {:keys [title] :as token-type-props} (get wtty/token-types (:type token))
applied-tokens (:applied-tokens shape) applied-tokens (:applied-tokens shape)
app-token-vals (set (vals applied-tokens)) app-token-vals (set (vals applied-tokens))
app-token-keys (keys applied-tokens) app-token-keys (keys applied-tokens)
@ -142,7 +143,7 @@
(contains? active-tokens match))) (contains? active-tokens match)))
(mf/defc token-pill* (mf/defc token-pill*
[{:keys [on-click token full-applied on-context-menu half-applied selected-shapes token-type-props active-theme-tokens]}] [{:keys [on-click token full-applied on-context-menu half-applied selected-shapes active-theme-tokens]}]
(let [{:keys [name value errors]} token (let [{:keys [name value errors]} token
is-reference? (wtt/is-reference? token) is-reference? (wtt/is-reference? token)
@ -203,8 +204,7 @@
(mf/deps selected-shapes is-viewer) (mf/deps selected-shapes is-viewer)
(fn [event] (fn [event]
(let [node (dom/get-current-target event) (let [node (dom/get-current-target event)
title (generate-tooltip is-viewer (first selected-shapes) title (generate-tooltip is-viewer (first selected-shapes) token
token-type-props token
half-applied no-valid-value ref-not-in-active-set)] half-applied no-valid-value ref-not-in-active-set)]
(dom/set-attribute! node "title" title))))] (dom/set-attribute! node "title" title))))]

View file

@ -6,9 +6,10 @@
(ns app.util.array (ns app.util.array
"A collection of helpers for work with javascript arrays." "A collection of helpers for work with javascript arrays."
(:refer-clojure :exclude [conj! conj filter map reduce find]) (:refer-clojure :exclude [conj! conj filter map reduce find sort])
(:require (:require
[cljs.core :as c])) [cljs.core :as c]
[goog.array :as garray]))
(defn conj (defn conj
"A conj like function for js arrays." "A conj like function for js arrays."
@ -67,3 +68,9 @@
(defn find (defn find
[f v] [f v]
(.find ^js/Array v f)) (.find ^js/Array v f))
(defn sort!
[a]
(garray/sort a compare)
a)