From 03ea5414bebb0e2c587934922028bc6660751184 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Mon, 21 Oct 2024 17:14:17 +0200 Subject: [PATCH] :recycle: Review create and edit modal --- frontend/src/app/main/data/tokens.cljs | 1 - .../src/app/main/ui/ds/buttons/_buttons.scss | 18 ++ .../app/main/ui/ds/buttons/icon_button.cljs | 6 +- .../app/main/ui/ds/buttons/icon_button.scss | 4 + .../ui/ds/buttons/icon_button.stories.jsx | 8 +- .../app/main/ui/workspace/tokens/form.cljs | 262 +++++++++++------- .../app/main/ui/workspace/tokens/form.scss | 47 ++-- .../app/main/ui/workspace/tokens/modals.cljs | 24 +- .../app/main/ui/workspace/tokens/modals.scss | 13 +- .../app/main/ui/workspace/tokens/sidebar.cljs | 24 +- frontend/translations/en.po | 25 ++ frontend/translations/es.po | 25 ++ 12 files changed, 310 insertions(+), 147 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index b657d0c66..e7ae337f5 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -279,7 +279,6 @@ ptk/WatchEvent (watch [it state _] (let [data (get state :workspace-data) - _ (prn "paso por aquí") changes (-> (pcb/empty-changes it) (pcb/with-library-data data) (pcb/delete-token set-name token-name))] diff --git a/frontend/src/app/main/ui/ds/buttons/_buttons.scss b/frontend/src/app/main/ui/ds/buttons/_buttons.scss index b489b4df9..07038c823 100644 --- a/frontend/src/app/main/ui/ds/buttons/_buttons.scss +++ b/frontend/src/app/main/ui/ds/buttons/_buttons.scss @@ -130,3 +130,21 @@ box-shadow: inset 0 0 #{px2rem(10)} #{px2rem(2)} rgba(0, 0, 0, 0.2); } } + +%base-button-action { + --button-bg-color: transparent; + --button-fg-color: var(--color-foreground-secondary); + + --button-hover-bg-color: transparent; + --button-hover-fg-color: var(--color-accent-primary); + + --button-active-bg-color: var(--color-background-quaternary); + + --button-disabled-bg-color: transparent; + --button-disabled-fg-color: var(--color-accent-primary-muted); + + --button-focus-bg-color: transparent; + --button-focus-fg-color: var(--color-accent-primary); + --button-focus-inner-ring-color: transparent; + --button-focus-outer-ring-color: var(--color-accent-primary); +} diff --git a/frontend/src/app/main/ui/ds/buttons/icon_button.cljs b/frontend/src/app/main/ui/ds/buttons/icon_button.cljs index dadb285af..630c52016 100644 --- a/frontend/src/app/main/ui/ds/buttons/icon_button.cljs +++ b/frontend/src/app/main/ui/ds/buttons/icon_button.cljs @@ -12,9 +12,6 @@ [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]] [rumext.v2 :as mf])) -(def button-variants (set '("primary" "secondary" "ghost" "destructive"))) - - (def ^:private schema:icon-button [:map [:class {:optional true} :string] @@ -22,7 +19,7 @@ [:and :string [:fn #(contains? icon-list %)]]] [:aria-label :string] [:variant {:optional true} - [:maybe [:enum "primary" "secondary" "ghost" "destructive"]]]]) + [:maybe [:enum "primary" "secondary" "ghost" "destructive" "action"]]]]) (mf/defc icon-button* {::mf/props :obj @@ -33,6 +30,7 @@ :icon-button-primary (= variant "primary") :icon-button-secondary (= variant "secondary") :icon-button-ghost (= variant "ghost") + :icon-button-action (= variant "action") :icon-button-destructive (= variant "destructive"))) props (mf/spread-props props {:class class :title aria-label})] [:> "button" props [:> icon* {:id icon :aria-label aria-label}]])) \ No newline at end of file diff --git a/frontend/src/app/main/ui/ds/buttons/icon_button.scss b/frontend/src/app/main/ui/ds/buttons/icon_button.scss index 1a10c3775..eed4d8f5b 100644 --- a/frontend/src/app/main/ui/ds/buttons/icon_button.scss +++ b/frontend/src/app/main/ui/ds/buttons/icon_button.scss @@ -31,3 +31,7 @@ .icon-button-destructive { @extend %base-button-destructive; } + +.icon-button-action { + @extend %base-button-action; +} diff --git a/frontend/src/app/main/ui/ds/buttons/icon_button.stories.jsx b/frontend/src/app/main/ui/ds/buttons/icon_button.stories.jsx index 17cb4b2fb..321aa7b7a 100644 --- a/frontend/src/app/main/ui/ds/buttons/icon_button.stories.jsx +++ b/frontend/src/app/main/ui/ds/buttons/icon_button.stories.jsx @@ -26,7 +26,7 @@ export default { }, disabled: { control: "boolean" }, variant: { - options: ["primary", "secondary", "ghost", "destructive"], + options: ["primary", "secondary", "ghost", "destructive", "action"], control: { type: "select" }, }, }, @@ -59,6 +59,12 @@ export const Ghost = { }, }; +export const Action = { + args: { + variant: "action", + }, +}; + export const Destructive = { args: { variant: "destructive", diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index dee3b0215..677439a04 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -10,12 +10,16 @@ ["lodash.debounce" :as debounce] [app.common.colors :as c] [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.types.tokens-lib :as ctob] [app.main.data.modal :as modal] [app.main.data.tokens :as dt] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.color-bullet :refer [color-bullet]] + [app.main.ui.ds.buttons.button :refer [button*]] + [app.main.ui.ds.foundations.assets.icon :as i] + [app.main.ui.ds.foundations.typography.text :refer [text*]] [app.main.ui.workspace.colorpicker :as colorpicker] [app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector]] [app.main.ui.workspace.tokens.common :as tokens.common] @@ -25,6 +29,7 @@ [app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.update :as wtu] [app.util.dom :as dom] + [app.util.i18n :refer [tr]] [cuerdas.core :as str] [malli.core :as m] [malli.error :as me] @@ -124,7 +129,7 @@ Token names should only contain letters and digits separated by . characters.")} [name-ref token tokens callback & {:keys [timeout] :or {timeout 160}}] (let [timeout-id-ref (mf/use-ref nil) debounced-resolver-callback - (mf/use-callback + (mf/use-fn (mf/deps token callback tokens) (fn [value] (let [timeout-id (js/Symbol) @@ -178,19 +183,22 @@ Token names should only contain letters and digits separated by . characters.")} [{:keys [result-or-errors]}] (let [{:keys [errors]} result-or-errors empty-message? (or (nil? result-or-errors) - (wte/has-error-code? :error/empty-input errors))] - [:div {:class (stl/css-case :resolved-value true - :resolved-value-placeholder empty-message? - :resolved-value-error (seq errors))} - (cond - empty-message? "Enter token value" - errors (->> (wte/humanize-errors errors) - (str/join "\n")) - :else [:p result-or-errors])])) + (wte/has-error-code? :error/empty-input errors)) + message (cond + empty-message? (dm/str (tr "workspace.token.resolved-value") "-") + errors (->> (wte/humanize-errors errors) + (str/join "\n")) + :else (dm/str (tr "workspace.token.resolved-value") result-or-errors))] + [:> text* {:as "p" + :typography "body-small" + :class (stl/css-case :resolved-value true + :resolved-value-placeholder empty-message? + :resolved-value-error (seq errors))} + message])) (mf/defc form {::mf/wrap-props false} - [{:keys [token token-type]}] + [{:keys [token token-type action selected-token-set-id]}] (let [validate-name? (mf/use-state (not (:id token))) token (or token {:type token-type}) color? (wtt/color-token? token) @@ -212,25 +220,31 @@ Token names should only contain letters and digits separated by . characters.")} ;; Name name-ref (mf/use-var (:name token)) name-errors (mf/use-state nil) - validate-name (mf/use-callback - (mf/deps selected-set-tokens-tree) - (fn [value] - (let [schema (token-name-schema {:token token - :tokens-tree selected-set-tokens-tree})] - (m/explain schema (finalize-name value))))) - on-update-name-debounced (mf/use-callback - (debounce (fn [e] - (let [value (dom/get-target-val e) - errors (validate-name value)] + validate-name + (mf/use-fn + (mf/deps selected-set-tokens-tree) + (fn [value] + (let [schema (token-name-schema {:token token + :tokens-tree selected-set-tokens-tree})] + (m/explain schema (finalize-name value))))) + + on-update-name-debounced + (mf/use-fn + (debounce (fn [e] + (let [value (dom/get-target-val e) + errors (validate-name value)] ;; Prevent showing error when just going to another field on a new token - (when-not (and validate-name? (str/empty? value)) - (reset! validate-name? false) - (reset! name-errors errors)))))) - on-update-name (mf/use-callback - (mf/deps on-update-name-debounced) - (fn [e] - (reset! name-ref (dom/get-target-val e)) - (on-update-name-debounced e))) + (when-not (and validate-name? (str/empty? value)) + (reset! validate-name? false) + (reset! name-errors errors)))))) + + on-update-name + (mf/use-fn + (mf/deps on-update-name-debounced) + (fn [e] + (reset! name-ref (dom/get-target-val e)) + (on-update-name-debounced e))) + valid-name-field? (and (not @name-errors) (valid-name? @name-ref)) @@ -241,27 +255,29 @@ Token names should only contain letters and digits separated by . characters.")} value-input-ref (mf/use-ref nil) value-ref (mf/use-var (:value token)) token-resolve-result (mf/use-state (get-in resolved-tokens [(wtt/token-identifier token) :resolved-value])) - set-resolve-value (mf/use-callback - (fn [token-or-err] - (let [error? (:errors token-or-err) - v (if error? - token-or-err - (:resolved-value token-or-err))] - (when color? (reset! color (if error? nil v))) - (reset! token-resolve-result v)))) + set-resolve-value + (mf/use-fn + (fn [token-or-err] + (let [error? (:errors token-or-err) + v (if error? + token-or-err + (:resolved-value token-or-err))] + (when color? (reset! color (if error? nil v))) + (reset! token-resolve-result v)))) on-update-value-debounced (use-debonced-resolve-callback name-ref token active-theme-tokens set-resolve-value) - on-update-value (mf/use-callback + on-update-value (mf/use-fn (mf/deps on-update-value-debounced) (fn [e] (let [value (dom/get-target-val e)] (reset! value-ref value) (on-update-value-debounced value)))) - on-update-color (mf/use-callback + on-update-color (mf/use-fn (mf/deps on-update-value-debounced) (fn [hex-value] (reset! value-ref hex-value) (set! (.-value (mf/ref-val value-input-ref)) hex-value) (on-update-value-debounced hex-value))) + value-error? (seq (:errors @token-resolve-result)) valid-value-field? (and (not value-error?) @@ -270,17 +286,18 @@ Token names should only contain letters and digits separated by . characters.")} ;; Description description-ref (mf/use-var (:description token)) description-errors (mf/use-state nil) - validate-descripion (mf/use-callback #(m/explain token-description-schema %)) - on-update-description-debounced (mf/use-callback + validate-descripion (mf/use-fn #(m/explain token-description-schema %)) + on-update-description-debounced (mf/use-fn (debounce (fn [e] (let [value (dom/get-target-val e) errors (validate-descripion value)] (reset! description-errors errors))))) - on-update-description (mf/use-callback - (mf/deps on-update-description-debounced) - (fn [e] - (reset! description-ref (dom/get-target-val e)) - (on-update-description-debounced e))) + on-update-description + (mf/use-fn + (mf/deps on-update-description-debounced) + (fn [e] + (reset! description-ref (dom/get-target-val e)) + (on-update-description-debounced e))) valid-description-field? (not @description-errors) ;; Form @@ -288,41 +305,62 @@ Token names should only contain letters and digits separated by . characters.")} (not valid-value-field?) (not valid-description-field?)) - on-submit (mf/use-callback - (mf/deps validate-name validate-descripion token resolved-tokens) - (fn [e] - (dom/prevent-default e) + on-submit + (mf/use-fn + (mf/deps validate-name validate-descripion token resolved-tokens) + (fn [e] + (dom/prevent-default e) ;; We have to re-validate the current form values before submitting ;; because the validation is asynchronous/debounced ;; and the user might have edited a valid form to make it invalid, ;; and press enter before the next validations could return. - (let [final-name (finalize-name @name-ref) - valid-name?+ (-> (validate-name final-name) schema-validation->promise) - final-value (finalize-value @value-ref) - final-description @description-ref - valid-description?+ (some-> final-description validate-descripion schema-validation->promise)] - (-> (p/all [valid-name?+ - valid-description?+ - (validate-token-value+ {:value final-value - :name-value final-name - :token token - :tokens resolved-tokens})]) - (p/finally (fn [result err] + (let [final-name (finalize-name @name-ref) + valid-name?+ (-> (validate-name final-name) schema-validation->promise) + final-value (finalize-value @value-ref) + final-description @description-ref + valid-description?+ (some-> final-description validate-descripion schema-validation->promise)] + (-> (p/all [valid-name?+ + valid-description?+ + (validate-token-value+ {:value final-value + :name-value final-name + :token token + :tokens resolved-tokens})]) + (p/finally (fn [result err] ;; The result should be a vector of all resolved validations ;; We do not handle the error case as it will be handled by the components validations - (when (and (seq result) (not err)) - (st/emit! (dt/update-create-token {:token (ctob/make-token :name final-name - :type (or (:type token) token-type) - :value final-value - :description final-description) - :prev-token-name (:name token)})) - (st/emit! (wtu/update-workspace-tokens)) - (modal/hide!))))))))] - [:form - {:class (stl/css :form-wrapper) - :on-submit on-submit} + (when (and (seq result) (not err)) + (st/emit! (dt/update-create-token {:token (ctob/make-token :name final-name + :type (or (:type token) token-type) + :value final-value + :description final-description) + :prev-token-name (:name token)})) + (st/emit! (wtu/update-workspace-tokens)) + (modal/hide!)))))))) + on-delete-token + (mf/use-fn + (mf/deps selected-token-set-id) + (fn [e] + (dom/prevent-default e) + (modal/hide!) + (st/emit! (dt/delete-token selected-token-set-id (:name token))))) + + on-cancel + (mf/use-fn + (fn [e] + (dom/prevent-default e) + (modal/hide!)))] + + [:form {:class (stl/css :form-wrapper) + :on-submit on-submit} [:div {:class (stl/css :token-rows)} - [:div + [:> text* {:as "span" :typography "headline-medium"} + (if (= action "edit") + (tr "workspace.token.edit-token") + (tr "workspace.token.create-token" token-type))] + + [:div {:class (stl/css :input-row)} + ;; This should be remove when labeled-imput is modified + [:span "Name"] [:& tokens.common/labeled-input {:label "Name" :error? @name-errors :input-props {:default-value @name-ref @@ -332,37 +370,59 @@ Token names should only contain letters and digits separated by . characters.")} (for [error (->> (:errors @name-errors) (map #(-> (assoc @name-errors :errors [%]) (me/humanize))))] - [:p {:key error - :class (stl/css :error)} + [:> text* {:as "p" + :key error + :typography "body-small" + :class (stl/css :error)} error])] - [:& tokens.common/labeled-input {:label "Value" - :input-props {:default-value @value-ref - :on-blur on-update-value - :on-change on-update-value - :ref value-input-ref} - :render-right (when color? - (mf/fnc [] - [:div {:class (stl/css :color-bullet) - :on-click #(swap! color-ramp-open? not)} - (if-let [hex (some-> @color tinycolor/valid-color tinycolor/->hex)] - [:& color-bullet {:color hex - :mini? true}] - [:div {:class (stl/css :color-bullet-placeholder)}])]))}] - (when @color-ramp-open? - [:& ramp {:color (some-> (or @token-resolve-result (:value token)) - (tinycolor/valid-color)) - :on-change on-update-color}]) - [:& token-value-or-errors {:result-or-errors @token-resolve-result}] - [:div + [:div {:class (stl/css :input-row)} + ;; This should be remove when labeled-imput is modified + [:span "value"] + [:& tokens.common/labeled-input {:label "Value" + :input-props {:default-value @value-ref + :on-blur on-update-value + :on-change on-update-value + :ref value-input-ref} + :render-right (when color? + (mf/fnc [] + [:div {:class (stl/css :color-bullet) + :on-click #(swap! color-ramp-open? not)} + (if-let [hex (some-> @color tinycolor/valid-color tinycolor/->hex)] + [:& color-bullet {:color hex + :mini? true}] + [:div {:class (stl/css :color-bullet-placeholder)}])]))}] + (when @color-ramp-open? + [:& ramp {:color (some-> (or @token-resolve-result (:value token)) + (tinycolor/valid-color)) + :on-change on-update-color}]) + [:& token-value-or-errors {:result-or-errors @token-resolve-result}]] + + + [:div {:class (stl/css :input-row)} + ;; This should be remove when labeled-imput is modified + [:span "Description"] [:& tokens.common/labeled-input {:label "Description" :input-props {:default-value @description-ref :on-change on-update-description}}] (when @description-errors - [:p {:class (stl/css :error)} + [:> text* {:as "p" + :typography "body-small" + :class (stl/css :error)} (me/humanize @description-errors)])] - [:div {:class (stl/css :button-row)} - [:button {:class (stl/css :button) - :type "submit" - :disabled disabled?} - "Save"]]]])) + + [:div {:class (stl/css-case :button-row true + :with-delete (= action "edit"))} + (when (= action "edit") + [:> button* {:on-click on-delete-token + :class (stl/css :delete-btn) + :icon i/delete + :variant "secondary"} + (tr "labels.delete")]) + [:> button* {:on-click on-cancel + :variant "secondary"} + (tr "labels.cancel")] + [:> button* {:type "submit" + :variant "primary" + :disabled disabled?} + (tr "labels.save")]]]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/form.scss b/frontend/src/app/main/ui/workspace/tokens/form.scss index 4d1b37c86..dd35014ac 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.scss +++ b/frontend/src/app/main/ui/workspace/tokens/form.scss @@ -8,49 +8,56 @@ @import "./common.scss"; .form-wrapper { - width: $s-260; + width: $s-384; } .button-row { - display: flex; - flex-direction: column; - margin-top: $s-16; + display: grid; + grid-template-columns: auto auto; + justify-content: end; + gap: $s-12; + padding-block-start: $s-8; +} + +.with-delete { + grid-template-columns: 1fr auto auto; +} + +.delete-btn { + justify-self: start; } .token-rows { display: flex; flex-direction: column; - gap: $s-8; + gap: $s-16; +} + +.input-row { + display: flex; + flex-direction: column; + gap: $s-4; } .error { - @include bodySmallTypography; - margin-top: $s-6; + padding: $s-4 $s-6; margin-bottom: 0; color: var(--status-color-error-500); } .resolved-value { - @include bodySmallTypography; + --input-hint-color: var(--color-foreground-primary); + margin-bottom: 0; padding: $s-4 $s-6; - font-weight: medium; - min-height: 1lh; - - color: var(--color-foreground-primary); - border: 1px solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent); - - p { - font-size: $fs-12; - margin: 0; - } + color: var(--input-hint-color); } .resolved-value-placeholder { - color: var(--color-foreground-secondary); + --input-hint-color: var(--color-foreground-secondary); } .resolved-value-error { - color: var(--status-color-error-500); + --input-hint-color: var(--status-color-error-500); } .color-bullet { diff --git a/frontend/src/app/main/ui/workspace/tokens/modals.cljs b/frontend/src/app/main/ui/workspace/tokens/modals.cljs index 5e4358d34..06ef35af9 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals.cljs @@ -8,9 +8,12 @@ (:require-macros [app.main.style :as stl]) (:require [app.main.data.modal :as modal] - [app.main.ui.workspace.tokens.modals.themes :as wtmt] [app.main.refs :as refs] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.workspace.tokens.form :refer [form]] + [app.main.ui.workspace.tokens.modals.themes :as wtmt] + [app.util.i18n :refer [tr]] [okulary.core :as l] [rumext.v2 :as mf])) @@ -40,12 +43,21 @@ (mf/defc token-update-create-modal {::mf/wrap-props false} - [{:keys [x y position token token-type] :as _args}] - (let [wrapper-style (use-viewport-position-style x y position)] - [:div - {:class (stl/css :shadow) - :style wrapper-style} + [{:keys [x y position token token-type action selected-token-set-id] :as _args}] + (let [wrapper-style (use-viewport-position-style x y position) + close-modal (mf/use-fn + (fn [] + (modal/hide!)))] + [:div {:class (stl/css :token-modal-wrapper) + :style wrapper-style} + [:> icon-button* {:on-click close-modal + :class (stl/css :close-btn) + :icon i/close + :variant "action" + :aria-label (tr "labels.close")}] [:& form {:token token + :action action + :selected-token-set-id selected-token-set-id :token-type token-type}]])) (mf/defc token-themes-modal diff --git a/frontend/src/app/main/ui/workspace/tokens/modals.scss b/frontend/src/app/main/ui/workspace/tokens/modals.scss index cb16e1ec2..b1e924616 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals.scss @@ -6,14 +6,19 @@ @import "refactor/common-refactor.scss"; -.shadow { +.token-modal-wrapper { @extend .modal-container-base; - width: auto; - max-width: auto; - min-width: auto; @include menuShadow; position: absolute; + width: auto; + min-width: auto; z-index: 11; overflow-y: auto; overflow-x: hidden; } + +.close-btn { + position: absolute; + top: $s-6; + right: $s-6; +} diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index d36b56199..e2c522f4c 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -10,8 +10,8 @@ [app.common.data :as d] [app.common.transit :as t] [app.common.types.tokens-lib :as ctob] - [app.main.data.notifications :as ntf] [app.main.data.modal :as modal] + [app.main.data.notifications :as ntf] [app.main.data.tokens :as dt] [app.main.refs :as refs] [app.main.store :as st] @@ -33,6 +33,7 @@ [app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token-types :as wtty] [app.util.dom :as dom] + [app.util.i18n :refer [tr]] [app.util.webapi :as wapi] [beicon.v2.core :as rx] [cuerdas.core :as str] @@ -60,8 +61,8 @@ :title (cond errors? (sd/humanize-errors token) :else (->> [(str "Token: " name) - (str "Original value: " value) - (str "Resolved value: " resolved-value)] + (str (tr "workspace.token.original-value") value) + (str (tr "workspace.token.resolved-value") resolved-value)] (str/join "\n"))) :on-click on-click :on-context-menu on-context-menu @@ -111,6 +112,7 @@ #(st/emit! (dt/set-token-type-section-open type (not open?)))) on-popover-open-click (mf/use-fn (fn [event] + (mf/deps type title) (let [{:keys [key fields]} modal] (dom/stop-propagation event) (st/emit! (dt/set-token-type-section-open type true)) @@ -118,6 +120,8 @@ :y (.-clientY ^js event) :position :right :fields fields + :title title + :action "create" :token-type type})))) on-token-pill-click (mf/use-fn @@ -175,16 +179,16 @@ :on-click (fn [e] (dom/stop-propagation e) (modal/show! :tokens/themes {}))} - (if create? "Create" "Edit")]) + (if create? (tr "labels.create") (tr "labels.edit"))]) (mf/defc themes-header [_props] (let [ordered-themes (mf/deref refs/workspace-token-themes-no-hidden)] - [:div {:class (stl/css :themes-wrapper)} - [:span {:class (stl/css :themes-header)} "Themes"] - [:div {:class (stl/css :theme-select-wrapper)} - [:& theme-select] - [:& edit-button {:create? (empty? ordered-themes)}]]])) + [:div {:class (stl/css :themes-wrapper)} + [:span {:class (stl/css :themes-header)} (tr "labels.themes")] + [:div {:class (stl/css :theme-select-wrapper)} + [:& theme-select] + [:& edit-button {:create? (empty? ordered-themes)}]]])) (mf/defc add-set-button [{:keys [on-open]}] @@ -207,7 +211,7 @@ [:& title-bar {:collapsable true :collapsed (not @open?) :all-clickable true - :title "SETS" + :title (tr "labels.sets") :on-collapsed #(swap! open? not)} [:& add-set-button {:on-open on-open}]]] (when @open? diff --git a/frontend/translations/en.po b/frontend/translations/en.po index b0b931a05..bdec8767d 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -1993,6 +1993,14 @@ msgstr "Team Leader" msgid "labels.team-member" msgstr "Team member" +#: src/app/main/ui/workspace/tokens/sidebar.cljs +msgid "labels.themes" +msgstr "Themes" + +#: src/app/main/ui/workspace/tokens/sidebar.cljs +msgid "labels.sets" +msgstr "Sets" + #: src/app/main/ui/dashboard/sidebar.cljs:992, src/app/main/ui/workspace/main_menu.cljs:118 msgid "labels.tutorials" msgstr "Tutorials" @@ -6139,3 +6147,20 @@ msgstr "Update" #, unused msgid "workspace.viewport.click-to-close-path" msgstr "Click to close the path" + + +#: src/app/main/ui/workspace/tokens/form.cljs +msgid "workspace.token.create-token" +msgstr "Create new %s token" + +#: src/app/main/ui/workspace/tokens/form.cljs +msgid "workspace.token.edit-token" +msgstr "Edit token" + +#: src/app/main/ui/workspace/tokens/form.cljs +msgid "workspace.token.resolved-value" +msgstr "Resolved value: " + +#: src/app/main/ui/workspace/tokens/sidebar.cljs +msgid "workspace.token.original-value" +msgstr "Original value: " \ No newline at end of file diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 7400fd0b9..02b19d584 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -1991,6 +1991,14 @@ msgstr "Líder de equipo" msgid "labels.team-member" msgstr "Miembro de equipo" +#: src/app/main/ui/workspace/tokens/sidebar.cljs +msgid "labels.themes" +msgstr "Temas" + +#: src/app/main/ui/workspace/tokens/sidebar.cljs +msgid "labels.sets" +msgstr "Sets" + #: src/app/main/ui/dashboard/sidebar.cljs:992, src/app/main/ui/workspace/main_menu.cljs:118 msgid "labels.tutorials" msgstr "Tutoriales" @@ -6126,3 +6134,20 @@ msgstr "Pulsar para cerrar la ruta" msgid "errors.maximum-invitations-by-request-reached" msgstr "Se ha alcanzado el número máximo (%s) de correos electrónicos que se pueden invitar en una sola solicitud" + + +#: src/app/main/ui/workspace/tokens/form.cljs +msgid "workspace.token.create-token" +msgstr "Crear un token de %s" + +#: src/app/main/ui/workspace/tokens/form.cljs +msgid "workspace.token.edit-token" +msgstr "Editar token" + +#: src/app/main/ui/workspace/tokens/form.cljs +msgid "workspace.token.resolved-value" +msgstr "Valor resuelto: " + +#: src/app/main/ui/workspace/tokens/sidebar.cljs +msgid "workspace.token.original-value" +msgstr "Valor original: " \ No newline at end of file