0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-12 15:51:37 -05:00

💄 Add cosmetic refactor to dashboard fonts react components

This commit is contained in:
Andrey Antukh 2024-03-06 12:46:30 +01:00
parent 131fc95ab0
commit 1134f16ffa

View file

@ -25,108 +25,143 @@
[cuerdas.core :as str] [cuerdas.core :as str]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(defn- use-set-page-title (defn- use-page-title
[team section] [team section]
(mf/use-effect (mf/with-effect [team]
(mf/deps team) (when team
(fn [] (let [tname (if (:is-default team)
(when team (tr "dashboard.your-penpot")
(let [tname (if (:is-default team) (:name team))]
(tr "dashboard.your-penpot") (case section
(:name team))] :fonts (dom/set-html-title (tr "title.dashboard.fonts" tname))
(case section :providers (dom/set-html-title (tr "title.dashboard.font-providers" tname)))))))
:fonts (dom/set-html-title (tr "title.dashboard.fonts" tname))
:providers (dom/set-html-title (tr "title.dashboard.font-providers" tname)))))))) (defn- bad-font-family-tmp?
[font]
(and (contains? font :font-family-tmp)
(str/blank? (:font-family-tmp font))))
(mf/defc header (mf/defc header
{::mf/wrap [mf/memo]} {::mf/props :obj
[{:keys [section team] :as props}] ::mf/memo true
(use-set-page-title team section) ::mf/private true}
[{:keys [section team]}]
(use-page-title team section)
[:header {:class (stl/css :dashboard-header)} [:header {:class (stl/css :dashboard-header)}
[:div#dashboard-fonts-title {:class (stl/css :dashboard-title)} [:div#dashboard-fonts-title {:class (stl/css :dashboard-title)}
[:h1 (tr "labels.fonts")]]]) [:h1 (tr "labels.fonts")]]])
(mf/defc font-variant-display-name (mf/defc font-variant-display-name
{::mf/props :obj
::mf/private true}
[{:keys [variant]}] [{:keys [variant]}]
[:* [:*
[:span (cm/font-weight->name (:font-weight variant))] [:span (cm/font-weight->name (:font-weight variant))]
(when (not= "normal" (:font-style variant)) (when (not= "normal" (:font-style variant))
[:span " " (str/capital (:font-style variant))])]) [:span " " (str/capital (:font-style variant))])])
(mf/defc fonts-upload (mf/defc uploaded-fonts
{::mf/props :obj
::mf/private true}
[{:keys [team installed-fonts] :as props}] [{:keys [team installed-fonts] :as props}]
(let [fonts* (mf/use-state {}) (let [fonts* (mf/use-state {})
fonts (deref fonts*) fonts (deref fonts*)
input-ref (mf/use-ref) font-vals (mf/with-memo [fonts]
uploading (mf/use-state #{}) (->> fonts
(into [] (map val))
(not-empty)))
bad-font-family-tmp? team-id (:id team)
(mf/use-fn
(fn [font]
(and (contains? font :font-family-tmp)
(str/blank? (:font-family-tmp font)))))
disable-upload-all? (some bad-font-family-tmp? (vals fonts)) input-ref (mf/use-ref)
handle-click uploading* (mf/use-state #{})
uploading (deref uploading*)
disable-upload-all?
(some bad-font-family-tmp? fonts)
problematic-fonts?
(some :height-warning? (vals fonts))
on-click
(mf/use-fn #(dom/click (mf/ref-val input-ref))) (mf/use-fn #(dom/click (mf/ref-val input-ref)))
handle-selected on-selected
(mf/use-fn (mf/use-fn
(mf/deps team installed-fonts) (mf/deps team-id installed-fonts)
(fn [blobs] (fn [blobs]
(->> (df/process-upload blobs (:id team)) (->> (df/process-upload blobs team-id)
(rx/subs! (fn [result] (rx/subs! (fn [result]
(swap! fonts* df/merge-and-group-fonts installed-fonts result)) (swap! fonts* df/merge-and-group-fonts installed-fonts result))
(fn [error] (fn [error]
(js/console.error "error" error)))))) (js/console.error "error" error))))))
on-upload on-upload*
(mf/use-fn (mf/use-fn
(mf/deps team) (fn [{:keys [id] :as item}]
(fn [item] (swap! uploading* conj id)
(swap! uploading conj (:id item))
(->> (rp/cmd! :create-font-variant item) (->> (rp/cmd! :create-font-variant item)
(rx/delay-at-least 2000) (rx/delay-at-least 2000)
(rx/subs! (fn [font] (rx/subs! (fn [font]
(swap! fonts* dissoc (:id item)) (swap! fonts* dissoc id)
(swap! uploading disj (:id item)) (swap! uploading* disj id)
(st/emit! (df/add-font font))) (st/emit! (df/add-font font)))
(fn [error] (fn [error]
(js/console.log "error" error)))))) (js/console.log "error" error))))))
on-upload-all on-upload
(fn [items] (mf/use-fn
(run! on-upload items)) (mf/deps fonts on-upload*)
(fn [event]
(let [id (-> (dom/get-current-target event)
(dom/get-data "id")
(parse-uuid))
item (get fonts id)]
(on-upload* item))))
on-blur-name on-blur-name
(fn [id event] (mf/use-fn
(let [name (dom/get-target-val event)] (mf/deps installed-fonts)
(when-not (str/blank? name) (fn [event]
(swap! fonts* df/rename-and-regroup id name installed-fonts)))) (let [target (dom/get-current-target event)
id (-> target
(dom/get-data "id")
(parse-uuid))
name (dom/get-value target)]
(when-not (str/blank? name)
(swap! fonts* df/rename-and-regroup id name installed-fonts)))))
on-change-name on-change-name
(fn [id event] (mf/use-fn
(let [name (dom/get-target-val event)] (fn [event]
(swap! fonts* update-in [id] #(assoc % :font-family-tmp name)))) (let [target (dom/get-current-target event)
id (-> target
(dom/get-data "id")
(parse-uuid))
name (dom/get-value target)]
(swap! fonts* update id assoc :font-family-tmp name))))
on-delete on-delete
(mf/use-fn (mf/use-fn
(mf/deps team) (mf/deps team)
(fn [{:keys [id] :as item}] (fn [event]
(swap! fonts* dissoc id))) (let [id (-> (dom/get-current-target event)
(dom/get-data "id")
(parse-uuid))]
(swap! fonts* dissoc id))))
on-dismiss-all on-upload-all
(fn [items] (mf/use-fn
(run! on-delete items)) (mf/deps font-vals)
(fn [_]
(run! on-upload* font-vals)))
problematic-fonts? (some :height-warning? (vals fonts)) on-dismis-all
(mf/use-fn
handle-upload-all (mf/deps fonts)
(mf/use-fn (mf/deps fonts) #(on-upload-all (vals fonts))) (fn [_]
(run! on-delete (vals fonts))))]
handle-dismiss-all
(mf/use-fn (mf/deps fonts) #(on-dismiss-all (vals fonts)))]
[:div {:class (stl/css :dashboard-fonts-upload)} [:div {:class (stl/css :dashboard-fonts-upload)}
[:div {:class (stl/css :dashboard-fonts-hero)} [:div {:class (stl/css :dashboard-fonts-hero)}
@ -135,14 +170,14 @@
[:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}] [:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}]
[:button {:class (stl/css :btn-primary) [:button {:class (stl/css :btn-primary)
:on-click handle-click :on-click on-click
:tab-index "0"} :tab-index "0"}
[:span (tr "labels.add-custom-font")] [:span (tr "labels.add-custom-font")]
[:& file-uploader {:input-id "font-upload" [:& file-uploader {:input-id "font-upload"
:accept cm/str-font-types :accept cm/str-font-types
:multi true :multi true
:ref input-ref :ref input-ref
:on-selected handle-selected}]] :on-selected on-selected}]]
[:& context-notification {:content (tr "dashboard.fonts.hero-text2") [:& context-notification {:content (tr "dashboard.fonts.hero-text2")
:type :default :type :default
@ -154,31 +189,32 @@
:is-html true}])]] :is-html true}])]]
[:* [:*
(when (some? (vals fonts)) (when (seq fonts)
[:div {:class (stl/css :font-item :table-row)} [:div {:class (stl/css :font-item :table-row)}
[:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals fonts))))] [:span (tr "dashboard.fonts.fonts-added" (i18n/c (count fonts)))]
[:div {:class (stl/css :table-field :options)} [:div {:class (stl/css :table-field :options)}
[:button {:class (stl/css-case :btn-primary true [:button {:class (stl/css-case
:disabled disable-upload-all?) :btn-primary true
:on-click handle-upload-all :disabled disable-upload-all?)
:on-click on-upload-all
:data-test "upload-all" :data-test "upload-all"
:disabled disable-upload-all?} :disabled disable-upload-all?}
[:span (tr "dashboard.fonts.upload-all")]] [:span (tr "dashboard.fonts.upload-all")]]
[:button {:class (stl/css :btn-secondary) [:button {:class (stl/css :btn-secondary)
:on-click handle-dismiss-all :on-click on-dismis-all
:data-test "dismiss-all"} :data-test "dismiss-all"}
[:span (tr "dashboard.fonts.dismiss-all")]]]]) [:span (tr "dashboard.fonts.dismiss-all")]]]])
(for [item (sort-by :font-family (vals fonts))] (for [{:keys [id] :as item} (sort-by :font-family font-vals)]
(let [uploading? (contains? @uploading (:id item)) (let [uploading? (contains? uploading id)
disable-upload? (or uploading? disable-upload? (or uploading? (bad-font-family-tmp? item))]
(bad-font-family-tmp? item))]
[:div {:class (stl/css :font-item :table-row) [:div {:class (stl/css :font-item :table-row)
:key (:id item)} :key (dm/str id)}
[:div {:class (stl/css :table-field :family)} [:div {:class (stl/css :table-field :family)}
[:input {:type "text" [:input {:type "text"
:on-blur #(on-blur-name (:id item) %) :data-id (dm/str id)
:on-change #(on-change-name (:id item) %) :on-blur on-blur-name
:on-change on-change-name
:default-value (:font-family item)}]] :default-value (:font-family item)}]]
[:div {:class (stl/css :table-field :variants)} [:div {:class (stl/css :table-field :variants)}
[:span {:class (stl/css :label)} [:span {:class (stl/css :label)}
@ -190,115 +226,151 @@
[:div {:class (stl/css :table-field :options)} [:div {:class (stl/css :table-field :options)}
(when (:height-warning? item) (when (:height-warning? item)
[:span {:class (stl/css :icon :failure)} i/msg-neutral-refactor]) [:span {:class (stl/css :icon :failure)}
i/msg-neutral-refactor])
[:button {:on-click #(on-upload item) [:button {:on-click on-upload
:class (stl/css-case :btn-primary true :data-id (dm/str id)
:upload-button true :class (stl/css-case
:disabled disable-upload?) :btn-primary true
:upload-button true
:disabled disable-upload?)
:disabled disable-upload?} :disabled disable-upload?}
(if uploading? (if ^boolean uploading?
(tr "labels.uploading") (tr "labels.uploading")
(tr "labels.upload"))] (tr "labels.upload"))]
[:span {:class (stl/css :icon :close) [:span {:class (stl/css :icon :close)
:on-click #(on-delete item)} i/close-refactor]]]))]])) :data-id (dm/str id)
:on-click on-delete}
i/close-refactor]]]))]]))
(mf/defc installed-font-context-menu
{::mf/props :obj
::mf/private true}
[{:keys [is-open on-close on-edit on-delete]}]
(let [options (mf/with-memo [on-edit on-delete]
[{:option-name (tr "labels.edit")
:id "font-edit"
:option-handler on-edit}
{:option-name (tr "labels.delete")
:id "font-delete"
:option-handler on-delete}])]
[:& context-menu-a11y
{:on-close on-close
:show is-open
:fixed? false
:min-width? true
:top -15
:left -115
:options options
:workspace? false}]))
(mf/defc installed-font (mf/defc installed-font
[{:keys [font-id variants] :as props}] {::mf/props :obj
::mf/private true
::mf/memo true}
[{:keys [font-id variants]}]
(let [font (first variants) (let [font (first variants)
variants (sort-by (fn [item] menu-open* (mf/use-state false)
[(:font-weight item) menu-open? (deref menu-open*)
(if (= "normal" (:font-style item)) 1 2)]) edition* (mf/use-state false)
variants) edition? (deref edition*)
open-menu? (mf/use-state false)
edit? (mf/use-state false)
state* (mf/use-state (:font-family font)) state* (mf/use-state (:font-family font))
font-family (deref state*) font-family (deref state*)
variants
(mf/with-memo [variants]
(sort-by (fn [item]
[(:font-weight item)
(if (= "normal" (:font-style item)) 1 2)])
variants))
on-change on-change
(mf/use-callback (mf/use-fn
(fn [event] (fn [event]
(reset! state* (dom/get-target-val event)))) (reset! state* (dom/get-target-val event))))
on-edit
(mf/use-fn #(reset! edition* true))
on-menu-open
(mf/use-fn #(reset! menu-open* true))
on-menu-close
(mf/use-fn #(reset! menu-open* false))
on-save on-save
(mf/use-callback (mf/use-fn
(mf/deps font-family) (mf/deps font-family)
(fn [_] (fn [_]
(reset! edition* false)
(when-not (str/blank? font-family) (when-not (str/blank? font-family)
(st/emit! (df/update-font {:id font-id :name font-family}))) (st/emit! (df/update-font {:id font-id :name font-family})))))
(reset! edit? false)))
on-key-down on-key-down
(mf/use-callback (mf/use-fn
(mf/deps on-save) (mf/deps on-save)
(fn [event] (fn [event]
(when (kbd/enter? event) (when (kbd/enter? event)
(on-save event)))) (on-save event))))
on-cancel on-cancel
(mf/use-callback (mf/use-fn
(fn [_] (fn [_]
(reset! edit? false) (reset! edition* false)
(reset! state* (:font-family font)))) (reset! state* (:font-family font))))
delete-font-fn on-delete-font
(mf/use-callback (mf/use-fn
(mf/deps font-id) (mf/deps font-id)
(fn [] (fn []
(st/emit! (df/delete-font font-id)))) (let [options {:type :confirm
:title (tr "modals.delete-font.title")
delete-variant-fn :message (tr "modals.delete-font.message")
(mf/use-callback :accept-label (tr "labels.delete")
(fn [id] :on-accept (fn [_props]
(st/emit! (df/delete-font-variant id)))) (st/emit! (df/delete-font font-id)))}]
(st/emit! (modal/show options)))))
on-delete
(mf/use-callback
(mf/deps delete-font-fn)
(fn []
(st/emit! (modal/show
{:type :confirm
:title (tr "modals.delete-font.title")
:message (tr "modals.delete-font.message")
:accept-label (tr "labels.delete")
:on-accept (fn [_props] (delete-font-fn))}))))
on-delete-variant on-delete-variant
(mf/use-callback (mf/use-fn
(mf/deps delete-variant-fn) (fn [event]
(fn [id] (let [id (-> (dom/get-current-target event)
(st/emit! (modal/show (dom/get-data "id")
{:type :confirm (parse-uuid))
:title (tr "modals.delete-font-variant.title") options {:type :confirm
:message (tr "modals.delete-font-variant.message") :title (tr "modals.delete-font-variant.title")
:accept-label (tr "labels.delete") :message (tr "modals.delete-font-variant.message")
:on-accept (fn [_props] :accept-label (tr "labels.delete")
(delete-variant-fn id))}))))] :on-accept (fn [_props]
(st/emit! (df/delete-font-variant id)))}]
(st/emit! (modal/show options)))))]
[:div {:class (stl/css :font-item :table-row)} [:div {:class (stl/css :font-item :table-row)}
[:div {:class (stl/css :table-field :family)} [:div {:class (stl/css :table-field :family)}
(if @edit? (if ^boolean edition?
[:input {:type "text" [:input {:type "text"
:auto-focus true
:default-value font-family :default-value font-family
:on-key-down on-key-down :on-key-down on-key-down
:on-change on-change}] :on-change on-change}]
[:span (:font-family font)])] [:span (:font-family font)])]
[:div {:class (stl/css :table-field :variants)} [:div {:class (stl/css :table-field :variants)}
(for [item variants] (for [{:keys [id] :as item} variants]
[:div {:class (stl/css :variant) [:div {:class (stl/css :variant)
:key (dm/str (:id item) "-variant")} :key (dm/str id)}
[:span {:class (stl/css :label)} [:span {:class (stl/css :label)}
[:& font-variant-display-name {:variant item}]] [:& font-variant-display-name {:variant item}]]
[:span [:span
{:class (stl/css :icon :close) {:class (stl/css :icon :close)
:on-click #(on-delete-variant (:id item))} :data-id (dm/str id)
:on-click on-delete-variant}
i/add-refactor]])] i/add-refactor]])]
(if @edit? (if ^boolean edition?
[:div {:class (stl/css :table-field :options)} [:div {:class (stl/css :table-field :options)}
[:button [:button
{:disabled (str/blank? font-family) {:disabled (str/blank? font-family)
@ -307,27 +379,19 @@
:btn-disabled (str/blank? font-family))} :btn-disabled (str/blank? font-family))}
(tr "labels.save")] (tr "labels.save")]
[:button {:class (stl/css :icon :close) [:button {:class (stl/css :icon :close)
:on-click on-cancel} i/close-refactor]] :on-click on-cancel}
i/close-refactor]]
[:div {:class (stl/css :table-field :options)} [:div {:class (stl/css :table-field :options)}
[:span {:class (stl/css :icon) [:span {:class (stl/css :icon)
:on-click #(reset! open-menu? true)} :on-click on-menu-open}
i/menu-refactor] i/menu-refactor]
[:& context-menu-a11y {:on-close #(reset! open-menu? false) [:& installed-font-context-menu
:show @open-menu? {:on-close on-menu-close
:fixed? false :is-open menu-open?
:min-width? true :on-delete on-delete-font
:top -15 :on-edit on-edit}]])]))
:left -115
:options [{:option-name (tr "labels.edit")
:id "font-edit"
:option-handler #(reset! edit? true)}
{:option-name (tr "labels.delete")
:id "font-delete"
:option-handler on-delete}]
:workspace? false}]])]))
(mf/defc installed-fonts (mf/defc installed-fonts
[{:keys [fonts] :as props}] [{:keys [fonts] :as props}]
@ -377,7 +441,7 @@
[:* [:*
[:& header {:team team :section :fonts}] [:& header {:team team :section :fonts}]
[:section {:class (stl/css :dashboard-container :dashboard-fonts)} [:section {:class (stl/css :dashboard-container :dashboard-fonts)}
[:& fonts-upload {:team team :installed-fonts fonts}] [:& uploaded-fonts {:team team :installed-fonts fonts}]
[:& installed-fonts {:team team :fonts fonts}]]])) [:& installed-fonts {:team team :fonts fonts}]]]))
(mf/defc font-providers-page (mf/defc font-providers-page