mirror of
https://github.com/penpot/penpot.git
synced 2025-03-31 09:01:20 -05:00
Merge pull request #4765 from penpot/niwinz-refactor-forms
♻️ Refactor forms (spec -> schema)
This commit is contained in:
commit
7ed25d2dba
63 changed files with 883 additions and 1185 deletions
|
@ -9,7 +9,7 @@
|
|||
data resources."
|
||||
(:refer-clojure :exclude [read-string hash-map merge name update-vals
|
||||
parse-double group-by iteration concat mapcat
|
||||
parse-uuid max min])
|
||||
parse-uuid max min regexp?])
|
||||
#?(:cljs
|
||||
(:require-macros [app.common.data]))
|
||||
|
||||
|
@ -641,6 +641,13 @@
|
|||
;; Utilities
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn regexp?
|
||||
"Return `true` if `x` is a regexp pattern
|
||||
instance."
|
||||
[x]
|
||||
#?(:cljs (cljs.core/regexp? x)
|
||||
:clj (instance? java.util.regex.Pattern x)))
|
||||
|
||||
(defn nilf
|
||||
"Returns a new function that if you pass nil as any argument will
|
||||
return nil"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
[cuerdas.core :as str]
|
||||
[malli.core :as m]
|
||||
[malli.dev.pretty :as mdp]
|
||||
[malli.dev.virhe :as v]
|
||||
[malli.error :as me]
|
||||
[malli.generator :as mg]
|
||||
[malli.registry :as mr]
|
||||
|
@ -44,6 +45,14 @@
|
|||
[o]
|
||||
(m/schema? o))
|
||||
|
||||
(defn properties
|
||||
[s]
|
||||
(m/properties s))
|
||||
|
||||
(defn type-properties
|
||||
[s]
|
||||
(m/type-properties s))
|
||||
|
||||
(defn lazy-schema?
|
||||
[s]
|
||||
(satisfies? ILazySchema s))
|
||||
|
@ -96,6 +105,10 @@
|
|||
[exp]
|
||||
(malli.error/error-value exp {:malli.error/mask-valid-values '...}))
|
||||
|
||||
(defn optional-keys
|
||||
[schema]
|
||||
(mu/optional-keys schema default-options))
|
||||
|
||||
(def default-transformer
|
||||
(let [default-decoder
|
||||
{:compile (fn [s _registry]
|
||||
|
@ -144,6 +157,8 @@
|
|||
(m/encode s val options transformer)))
|
||||
|
||||
(defn decode
|
||||
([s val]
|
||||
(m/decode s val default-options default-transformer))
|
||||
([s val transformer]
|
||||
(m/decode s val default-options transformer))
|
||||
([s val options transformer]
|
||||
|
@ -180,9 +195,10 @@
|
|||
(fn [v] (@vfn v))))
|
||||
|
||||
(defn lazy-decoder
|
||||
[s transformer]
|
||||
(let [vfn (delay (decoder (if (delay? s) (deref s) s) transformer))]
|
||||
(fn [v] (@vfn v))))
|
||||
([s] (lazy-decoder s default-transformer))
|
||||
([s transformer]
|
||||
(let [vfn (delay (decoder (if (delay? s) (deref s) s) transformer))]
|
||||
(fn [v] (@vfn v)))))
|
||||
|
||||
(defn humanize-explain
|
||||
[{:keys [schema errors value]} & {:keys [length level]}]
|
||||
|
@ -197,9 +213,29 @@
|
|||
:level (d/nilv level 8)
|
||||
:length (d/nilv length 12)})))))
|
||||
|
||||
|
||||
(defmethod v/-format ::schemaless-explain
|
||||
[_ {:keys [schema] :as explanation} printer]
|
||||
{:body [:group
|
||||
(v/-block "Value" (v/-visit (me/error-value explanation printer) printer) printer) :break :break
|
||||
(v/-block "Errors" (v/-visit (me/humanize (me/with-spell-checking explanation)) printer) printer) :break :break
|
||||
(v/-block "Schema" (v/-visit schema printer) printer)]})
|
||||
|
||||
|
||||
(defmethod v/-format ::explain
|
||||
[_ {:keys [schema] :as explanation} printer]
|
||||
{:body [:group
|
||||
(v/-block "Value" (v/-visit (me/error-value explanation printer) printer) printer) :break :break
|
||||
(v/-block "Errors" (v/-visit (me/humanize (me/with-spell-checking explanation)) printer) printer) :break :break
|
||||
(v/-block "Schema" (v/-visit schema printer) printer)]})
|
||||
|
||||
|
||||
(defn pretty-explain
|
||||
[s d]
|
||||
(mdp/explain (schema s) d))
|
||||
[explain & {:keys [variant message]
|
||||
:or {variant ::explain
|
||||
message "Validation Error"}}]
|
||||
(let [explain (fn [] (me/with-error-messages explain))]
|
||||
((mdp/prettifier variant message explain default-options))))
|
||||
|
||||
(defmacro ignoring
|
||||
[expr]
|
||||
|
@ -287,7 +323,7 @@
|
|||
(throw (ex-info hint options))))))
|
||||
|
||||
(defn validate-fn
|
||||
"Create a predefined validate function"
|
||||
"Create a predefined validate function that raises an expception"
|
||||
[s]
|
||||
(let [schema (if (lazy-schema? s) s (define s))]
|
||||
(partial fast-validate! schema)))
|
||||
|
@ -307,6 +343,7 @@
|
|||
hint (get options :hint "schema validation error")]
|
||||
(throw (ex-info hint options)))))))
|
||||
|
||||
;; FIXME: revisit
|
||||
(defn conform!
|
||||
[schema value]
|
||||
(assert (lazy-schema? schema) "expected `schema` to satisfy ILazySchema protocol")
|
||||
|
@ -428,23 +465,33 @@
|
|||
[s]
|
||||
(if (string? s)
|
||||
(re-matches email-re s)
|
||||
s))
|
||||
nil))
|
||||
|
||||
(defn email-string?
|
||||
[s]
|
||||
(and (string? s)
|
||||
(re-seq email-re s)))
|
||||
|
||||
;; FIXME: add proper email generator
|
||||
(define! ::email
|
||||
{:type ::email
|
||||
:pred (fn [s]
|
||||
(and (string? s)
|
||||
(< (count s) 250)
|
||||
(re-seq email-re s)))
|
||||
{:type :string
|
||||
:pred email-string?
|
||||
:property-pred
|
||||
(fn [{:keys [max] :as props}]
|
||||
(if (some? max)
|
||||
(fn [value]
|
||||
(<= (count value) max))
|
||||
(constantly true)))
|
||||
|
||||
:type-properties
|
||||
{:title "email"
|
||||
:description "string with valid email address"
|
||||
:error/message "expected valid email"
|
||||
:gen/gen (-> :string sg/generator)
|
||||
:error/code "errors.invalid-email"
|
||||
:gen/gen (sg/email)
|
||||
::oapi/type "string"
|
||||
::oapi/format "email"
|
||||
::oapi/decode parse-email}})
|
||||
::oapi/decode
|
||||
(fn [v]
|
||||
(or (parse-email v) v))}})
|
||||
|
||||
(def non-empty-strings-xf
|
||||
(comp
|
||||
|
@ -452,6 +499,121 @@
|
|||
(remove str/empty?)
|
||||
(remove str/blank?)))
|
||||
|
||||
;; NOTE: this is general purpose set spec and should be used over the other
|
||||
|
||||
(define! ::set
|
||||
{:type :set
|
||||
:min 0
|
||||
:max 1
|
||||
:compile
|
||||
(fn [{:keys [coerce kind max min] :as props} children _]
|
||||
(let [xform (if coerce
|
||||
(comp non-empty-strings-xf (map coerce))
|
||||
non-empty-strings-xf)
|
||||
kind (or (last children) kind)
|
||||
pred (cond
|
||||
(fn? kind) kind
|
||||
(nil? kind) any?
|
||||
:else (validator kind))
|
||||
|
||||
pred (cond
|
||||
(and max min)
|
||||
(fn [value]
|
||||
(let [size (count value)]
|
||||
(and (set? value)
|
||||
(<= min size max)
|
||||
(every? pred value))))
|
||||
|
||||
min
|
||||
(fn [value]
|
||||
(let [size (count value)]
|
||||
(and (set? value)
|
||||
(<= min size)
|
||||
(every? pred value))))
|
||||
|
||||
max
|
||||
(fn [value]
|
||||
(let [size (count value)]
|
||||
(and (set? value)
|
||||
(<= size max)
|
||||
(every? pred value))))
|
||||
|
||||
:else
|
||||
(fn [value]
|
||||
(every? pred value)))]
|
||||
|
||||
{:pred pred
|
||||
:type-properties
|
||||
{:title "set"
|
||||
:description "Set of Strings"
|
||||
:error/message "should be a set of strings"
|
||||
:gen/gen (-> kind sg/generator sg/set)
|
||||
::oapi/type "array"
|
||||
::oapi/format "set"
|
||||
::oapi/items {:type "string"}
|
||||
::oapi/unique-items true
|
||||
::oapi/decode (fn [v]
|
||||
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
||||
(into #{} xform v)))}}))})
|
||||
|
||||
|
||||
(define! ::vec
|
||||
{:type :vector
|
||||
:min 0
|
||||
:max 1
|
||||
:compile
|
||||
(fn [{:keys [coerce kind max min] :as props} children _]
|
||||
(let [xform (if coerce
|
||||
(comp non-empty-strings-xf (map coerce))
|
||||
non-empty-strings-xf)
|
||||
|
||||
kind (or (last children) kind)
|
||||
pred (cond
|
||||
(fn? kind) kind
|
||||
(nil? kind) any?
|
||||
:else (validator kind))
|
||||
|
||||
pred (cond
|
||||
(and max min)
|
||||
(fn [value]
|
||||
(let [size (count value)]
|
||||
(and (set? value)
|
||||
(<= min size max)
|
||||
(every? pred value))))
|
||||
|
||||
min
|
||||
(fn [value]
|
||||
(let [size (count value)]
|
||||
(and (set? value)
|
||||
(<= min size)
|
||||
(every? pred value))))
|
||||
|
||||
max
|
||||
(fn [value]
|
||||
(let [size (count value)]
|
||||
(and (set? value)
|
||||
(<= size max)
|
||||
(every? pred value))))
|
||||
|
||||
:else
|
||||
(fn [value]
|
||||
(every? pred value)))]
|
||||
|
||||
{:pred pred
|
||||
:type-properties
|
||||
{:title "set"
|
||||
:description "Set of Strings"
|
||||
:error/message "should be a set of strings"
|
||||
:gen/gen (-> kind sg/generator sg/set)
|
||||
::oapi/type "array"
|
||||
::oapi/format "set"
|
||||
::oapi/items {:type "string"}
|
||||
::oapi/unique-items true
|
||||
::oapi/decode (fn [v]
|
||||
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
||||
(into [] xform v)))}}))})
|
||||
|
||||
|
||||
(define! ::set-of-strings
|
||||
{:type ::set-of-strings
|
||||
:pred #(and (set? %) (every? string? %))
|
||||
|
@ -634,6 +796,8 @@
|
|||
(define! ::fn
|
||||
[:schema fn?])
|
||||
|
||||
;; FIXME: deprecated, replace with ::text
|
||||
|
||||
(define! ::word-string
|
||||
{:type ::word-string
|
||||
:pred #(and (string? %) (not (str/blank? %)))
|
||||
|
@ -649,16 +813,102 @@
|
|||
(define! ::uri
|
||||
{:type ::uri
|
||||
:pred u/uri?
|
||||
:property-pred
|
||||
(fn [{:keys [min max prefix] :as props}]
|
||||
(if (seq props)
|
||||
(fn [value]
|
||||
(let [value (str value)
|
||||
size (count value)]
|
||||
|
||||
(and
|
||||
(cond
|
||||
(and min max)
|
||||
(<= min size max)
|
||||
|
||||
min
|
||||
(<= min size)
|
||||
|
||||
max
|
||||
(<= size max))
|
||||
|
||||
(cond
|
||||
(d/regexp? prefix)
|
||||
(some? (re-seq prefix value))
|
||||
|
||||
:else
|
||||
true))))
|
||||
|
||||
(constantly true)))
|
||||
|
||||
:type-properties
|
||||
{:title "uri"
|
||||
:description "URI formatted string"
|
||||
:error/message "expected URI instance"
|
||||
:error/code "errors.invalid-uri"
|
||||
:gen/gen (sg/uri)
|
||||
::oapi/type "string"
|
||||
::oapi/format "uri"
|
||||
::oapi/decode (comp u/uri str/trim)}})
|
||||
|
||||
(def! ::plugin-data
|
||||
(define! ::text
|
||||
{:type :string
|
||||
:pred #(and (string? %) (not (str/blank? %)))
|
||||
:property-pred
|
||||
(fn [{:keys [min max] :as props}]
|
||||
(if (seq props)
|
||||
(fn [value]
|
||||
(let [size (count value)]
|
||||
(cond
|
||||
(and min max)
|
||||
(<= min size max)
|
||||
|
||||
min
|
||||
(<= min size)
|
||||
|
||||
max
|
||||
(<= size max))))
|
||||
(constantly true)))
|
||||
|
||||
:type-properties
|
||||
{:title "string"
|
||||
:description "not whitespace string"
|
||||
:gen/gen (sg/word-string)
|
||||
:error/code "errors.invalid-text"
|
||||
:error/fn
|
||||
(fn [{:keys [value schema]}]
|
||||
(let [{:keys [max min] :as props} (properties schema)]
|
||||
(cond
|
||||
(and (string? value)
|
||||
(number? max)
|
||||
(> (count value) max))
|
||||
["errors.field-max-length" max]
|
||||
|
||||
(and (string? value)
|
||||
(number? min)
|
||||
(< (count value) min))
|
||||
["errors.field-min-length" min]
|
||||
|
||||
(and (string? value)
|
||||
(str/blank? value))
|
||||
"errors.field-not-all-whitespace")))}})
|
||||
|
||||
(define! ::password
|
||||
{:type :string
|
||||
:pred
|
||||
(fn [value]
|
||||
(and (string? value)
|
||||
(>= (count value) 8)
|
||||
(not (str/blank? value))))
|
||||
:type-properties
|
||||
{:title "password"
|
||||
:gen/gen (->> (sg/word-string)
|
||||
(sg/filter #(>= (count %) 8)))
|
||||
:error/code "errors.password-too-short"
|
||||
::oapi/type "string"
|
||||
::oapi/format "password"}})
|
||||
|
||||
|
||||
;; FIXME: this should not be here
|
||||
(define! ::plugin-data
|
||||
[:map-of {:gen/max 5} :string :string])
|
||||
|
||||
;; ---- PREDICATES
|
||||
|
|
|
@ -77,10 +77,23 @@
|
|||
|
||||
(defn word-string
|
||||
[]
|
||||
(->> (tg/such-that #(re-matches #"\w+" %)
|
||||
tg/string-alphanumeric
|
||||
50)
|
||||
(tg/such-that (complement str/blank?))))
|
||||
(as-> tg/string-alphanumeric $$
|
||||
(tg/such-that (fn [v] (re-matches #"\w+" v)) $$ 50)
|
||||
(tg/such-that (fn [v]
|
||||
(and (not (str/blank? v))
|
||||
(not (re-matches #"^\d+.*" v))))
|
||||
$$
|
||||
50)))
|
||||
|
||||
|
||||
(defn email
|
||||
[]
|
||||
(->> (word-string)
|
||||
(tg/such-that (fn [v] (>= (count v) 4)))
|
||||
(tg/fmap str/lower)
|
||||
(tg/fmap (fn [v]
|
||||
(str v "@example.net")))))
|
||||
|
||||
|
||||
(defn uri
|
||||
[]
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
(ns app.main.ui.auth.login
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.logging :as log]
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.config :as cf]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.users :as du]
|
||||
|
@ -25,7 +24,6 @@
|
|||
[app.util.keyboard :as k]
|
||||
[app.util.router :as rt]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def show-alt-login-buttons?
|
||||
|
@ -64,28 +62,18 @@
|
|||
:else
|
||||
(st/emit! (msg/error (tr "errors.generic"))))))))
|
||||
|
||||
(s/def ::email ::us/email)
|
||||
(s/def ::password ::us/not-empty-string)
|
||||
(s/def ::invitation-token ::us/not-empty-string)
|
||||
|
||||
(s/def ::login-form
|
||||
(s/keys :req-un [::email ::password]
|
||||
:opt-un [::invitation-token]))
|
||||
|
||||
(defn handle-error-messages
|
||||
[errors _data]
|
||||
(d/update-when errors :email
|
||||
(fn [{:keys [code] :as error}]
|
||||
(cond-> error
|
||||
(= code ::us/email)
|
||||
(assoc :message (tr "errors.email-invalid"))))))
|
||||
(def ^:private schema:login-form
|
||||
[:map {:title "LoginForm"}
|
||||
[:email [::sm/email {:error/code "errors.invalid-email"}]]
|
||||
[:password [:string {:min 1}]]
|
||||
[:invitation-token {:optional true}
|
||||
[:string {:min 1}]]])
|
||||
|
||||
(mf/defc login-form
|
||||
[{:keys [params on-success-callback origin] :as props}]
|
||||
(let [initial (mf/use-memo (mf/deps params) (constantly params))
|
||||
(let [initial (mf/with-memo [params] params)
|
||||
error (mf/use-state false)
|
||||
form (fm/use-form :spec ::login-form
|
||||
:validators [handle-error-messages]
|
||||
form (fm/use-form :schema schema:login-form
|
||||
:initial initial)
|
||||
|
||||
on-error
|
||||
|
|
|
@ -7,39 +7,29 @@
|
|||
(ns app.main.ui.auth.recovery
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::password-1 ::us/not-empty-string)
|
||||
(s/def ::password-2 ::us/not-empty-string)
|
||||
(s/def ::token ::us/not-empty-string)
|
||||
|
||||
(s/def ::recovery-form
|
||||
(s/keys :req-un [::password-1
|
||||
::password-2]))
|
||||
|
||||
(defn- password-equality
|
||||
[errors data]
|
||||
(let [password-1 (:password-1 data)
|
||||
password-2 (:password-2 data)]
|
||||
(cond-> errors
|
||||
(and password-1 password-2
|
||||
(not= password-1 password-2))
|
||||
(assoc :password-2 {:message "errors.password-invalid-confirmation"})
|
||||
|
||||
(and password-1 (> 8 (count password-1)))
|
||||
(assoc :password-1 {:message "errors.password-too-short"}))))
|
||||
(def ^:private schema:recovery-form
|
||||
[:and
|
||||
[:map {:title "RecoveryForm"}
|
||||
[:token ::sm/text]
|
||||
[:password-1 ::sm/password]
|
||||
[:password-2 ::sm/password]]
|
||||
[:fn {:error/code "errors.password-invalid-confirmation"
|
||||
:error/field :password-2}
|
||||
(fn [{:keys [password-1 password-2]}]
|
||||
(= password-1 password-2))]])
|
||||
|
||||
(defn- on-error
|
||||
[_form _error]
|
||||
(st/emit! (msg/error (tr "auth.notifications.invalid-token-error"))))
|
||||
(st/emit! (msg/error (tr "errors.invalid-recovery-token"))))
|
||||
|
||||
(defn- on-success
|
||||
[_]
|
||||
|
@ -56,14 +46,13 @@
|
|||
|
||||
(mf/defc recovery-form
|
||||
[{:keys [params] :as props}]
|
||||
(let [form (fm/use-form :spec ::recovery-form
|
||||
:validators [password-equality
|
||||
(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
|
||||
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))]
|
||||
(let [form (fm/use-form :schema schema:recovery-form
|
||||
:initial params)]
|
||||
|
||||
[:& fm/form {:on-submit on-submit
|
||||
:class (stl/css :recovery-form)
|
||||
:form form}
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "password"
|
||||
:name :password-1
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
(ns app.main.ui.auth.recovery-request
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.store :as st]
|
||||
|
@ -17,30 +16,24 @@
|
|||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::email ::us/email)
|
||||
(s/def ::recovery-request-form (s/keys :req-un [::email]))
|
||||
(defn handle-error-messages
|
||||
[errors _data]
|
||||
(d/update-when errors :email
|
||||
(fn [{:keys [code] :as error}]
|
||||
(cond-> error
|
||||
(= code :missing)
|
||||
(assoc :message (tr "errors.email-invalid"))))))
|
||||
(def ^:private schema:recovery-request-form
|
||||
[:map {:title "RecoverRequestForm"}
|
||||
[:email ::sm/email]])
|
||||
|
||||
(mf/defc recovery-form
|
||||
[{:keys [on-success-callback] :as props}]
|
||||
(let [form (fm/use-form :spec ::recovery-request-form
|
||||
:validators [handle-error-messages]
|
||||
(let [form (fm/use-form :schema schema:recovery-request-form
|
||||
:initial {})
|
||||
submitted (mf/use-state false)
|
||||
|
||||
default-success-finish #(st/emit! (msg/info (tr "auth.notifications.recovery-token-sent")))
|
||||
default-success-finish
|
||||
(mf/use-fn
|
||||
#(st/emit! (msg/info (tr "auth.notifications.recovery-token-sent"))))
|
||||
|
||||
on-success
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [cdata _]
|
||||
(reset! submitted false)
|
||||
(if (nil? on-success-callback)
|
||||
|
@ -48,7 +41,7 @@
|
|||
(on-success-callback (:email cdata)))))
|
||||
|
||||
on-error
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [data cause]
|
||||
(reset! submitted false)
|
||||
(let [code (-> cause ex-data :code)]
|
||||
|
@ -65,7 +58,7 @@
|
|||
(rx/throw cause)))))
|
||||
|
||||
on-submit
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(reset! submitted true)
|
||||
(let [cdata (:clean-data @form)
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
(ns app.main.ui.auth.register
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.config :as cf]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.users :as du]
|
||||
|
@ -22,67 +21,42 @@
|
|||
[app.util.router :as rt]
|
||||
[app.util.storage :as sto]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; --- PAGE: Register
|
||||
|
||||
(defn- validate-password-length
|
||||
[errors data]
|
||||
(let [password (:password data)]
|
||||
(cond-> errors
|
||||
(> 8 (count password))
|
||||
(assoc :password {:message "errors.password-too-short"}))))
|
||||
|
||||
(defn- validate-email
|
||||
[errors _]
|
||||
(d/update-when errors :email
|
||||
(fn [{:keys [code] :as error}]
|
||||
(cond-> error
|
||||
(= code ::us/email)
|
||||
(assoc :message (tr "errors.email-invalid"))))))
|
||||
|
||||
(s/def ::fullname ::us/not-empty-string)
|
||||
(s/def ::password ::us/not-empty-string)
|
||||
(s/def ::email ::us/email)
|
||||
(s/def ::invitation-token ::us/not-empty-string)
|
||||
(s/def ::terms-privacy ::us/boolean)
|
||||
|
||||
(s/def ::register-form
|
||||
(s/keys :req-un [::password ::email]
|
||||
:opt-un [::invitation-token]))
|
||||
|
||||
(defn- on-prepare-register-error
|
||||
[form cause]
|
||||
(let [{:keys [type code]} (ex-data cause)]
|
||||
(condp = [type code]
|
||||
[:restriction :registration-disabled]
|
||||
(st/emit! (msg/error (tr "errors.registration-disabled")))
|
||||
|
||||
[:restriction :email-domain-is-not-allowed]
|
||||
(st/emit! (msg/error (tr "errors.email-domain-not-allowed")))
|
||||
|
||||
[:validation :email-as-password]
|
||||
(swap! form assoc-in [:errors :password]
|
||||
{:message "errors.email-as-password"})
|
||||
|
||||
(st/emit! (msg/error (tr "errors.generic"))))))
|
||||
|
||||
(defn- on-prepare-register-success
|
||||
[params]
|
||||
(st/emit! (rt/nav :auth-register-validate {} params)))
|
||||
(def ^:private schema:register-form
|
||||
[:map {:title "RegisterForm"}
|
||||
[:password ::sm/password]
|
||||
[:email ::sm/email]
|
||||
[:invitation-token {:optional true} ::sm/text]])
|
||||
|
||||
(mf/defc register-form
|
||||
{::mf/props :obj}
|
||||
[{:keys [params on-success-callback]}]
|
||||
(let [initial (mf/use-memo (mf/deps params) (constantly params))
|
||||
form (fm/use-form :spec ::register-form
|
||||
:validators [validate-password-length
|
||||
validate-email
|
||||
(fm/validate-not-empty :password (tr "auth.password-not-empty"))]
|
||||
form (fm/use-form :schema schema:register-form
|
||||
:initial initial)
|
||||
|
||||
submitted? (mf/use-state false)
|
||||
|
||||
on-error
|
||||
(mf/use-fn
|
||||
(fn [form cause]
|
||||
(let [{:keys [type code]} (ex-data cause)]
|
||||
(condp = [type code]
|
||||
[:restriction :registration-disabled]
|
||||
(st/emit! (msg/error (tr "errors.registration-disabled")))
|
||||
|
||||
[:restriction :email-domain-is-not-allowed]
|
||||
(st/emit! (msg/error (tr "errors.email-domain-not-allowed")))
|
||||
|
||||
[:validation :email-as-password]
|
||||
(swap! form assoc-in [:errors :password]
|
||||
{:code "errors.email-as-password"})
|
||||
|
||||
(st/emit! (msg/error (tr "errors.generic")))))))
|
||||
|
||||
on-submit
|
||||
(mf/use-fn
|
||||
(mf/deps on-success-callback)
|
||||
|
@ -90,16 +64,14 @@
|
|||
(reset! submitted? true)
|
||||
(let [cdata (:clean-data @form)
|
||||
on-success (fn [data]
|
||||
(if (nil? on-success-callback)
|
||||
(on-prepare-register-success data)
|
||||
(on-success-callback data)))
|
||||
on-error (fn [data]
|
||||
(on-prepare-register-error form data))]
|
||||
(if (fn? on-success-callback)
|
||||
(on-success-callback data)
|
||||
(st/emit! (rt/nav :auth-register-validate {} data))))]
|
||||
|
||||
(->> (rp/cmd! :prepare-register-profile cdata)
|
||||
(rx/map #(merge % params))
|
||||
(rx/finalize #(reset! submitted? false))
|
||||
(rx/subs! on-success on-error)))))]
|
||||
(rx/subs! on-success (partial on-error form))))))]
|
||||
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
|
@ -164,33 +136,6 @@
|
|||
|
||||
;; --- PAGE: register validation
|
||||
|
||||
(defn- on-register-success
|
||||
[data]
|
||||
(cond
|
||||
(some? (:invitation-token data))
|
||||
(let [token (:invitation-token data)]
|
||||
(st/emit! (rt/nav :auth-verify-token {} {:token token})))
|
||||
|
||||
(:is-active data)
|
||||
(st/emit! (du/login-from-register))
|
||||
|
||||
:else
|
||||
(do
|
||||
(swap! sto/storage assoc ::email (:email data))
|
||||
(st/emit! (rt/nav :auth-register-success)))))
|
||||
|
||||
(s/def ::accept-terms-and-privacy (s/and ::us/boolean true?))
|
||||
(s/def ::accept-newsletter-subscription ::us/boolean)
|
||||
|
||||
(if (contains? cf/flags :terms-and-privacy-checkbox)
|
||||
(s/def ::register-validate-form
|
||||
(s/keys :req-un [::token ::fullname ::accept-terms-and-privacy]
|
||||
:opt-un [::accept-newsletter-subscription]))
|
||||
(s/def ::register-validate-form
|
||||
(s/keys :req-un [::token ::fullname]
|
||||
:opt-un [::accept-terms-and-privacy
|
||||
::accept-newsletter-subscription])))
|
||||
|
||||
(mf/defc terms-and-privacy
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
|
@ -210,34 +155,48 @@
|
|||
:default-checked false
|
||||
:label terms-label}]]))
|
||||
|
||||
(def ^:private schema:register-validate-form
|
||||
[:map {:title "RegisterValidateForm"}
|
||||
[:token ::sm/text]
|
||||
[:fullname [::sm/text {:max 250}]]
|
||||
[:accept-terms-and-privacy {:optional (not (contains? cf/flags :terms-and-privacy-checkbox))}
|
||||
[:and :boolean [:= true]]]])
|
||||
|
||||
(mf/defc register-validate-form
|
||||
{::mf/props :obj}
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
[{:keys [params on-success-callback]}]
|
||||
(let [validators (mf/with-memo []
|
||||
[(fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))])
|
||||
|
||||
form (fm/use-form :spec ::register-validate-form
|
||||
:validators validators
|
||||
:initial params)
|
||||
|
||||
(let [form (fm/use-form :schema schema:register-validate-form :initial params)
|
||||
submitted? (mf/use-state false)
|
||||
|
||||
on-success
|
||||
(mf/use-fn
|
||||
(mf/deps on-success-callback)
|
||||
(fn [params]
|
||||
(if (nil? on-success-callback)
|
||||
(on-register-success params)
|
||||
(on-success-callback (:email params)))))
|
||||
(if (fn? on-success-callback)
|
||||
(on-success-callback (:email params))
|
||||
|
||||
(cond
|
||||
(some? (:invitation-token params))
|
||||
(let [token (:invitation-token params)]
|
||||
(st/emit! (rt/nav :auth-verify-token {} {:token token})))
|
||||
|
||||
(:is-active params)
|
||||
(st/emit! (du/login-from-register))
|
||||
|
||||
:else
|
||||
(do
|
||||
(swap! sto/storage assoc ::email (:email params))
|
||||
(st/emit! (rt/nav :auth-register-success)))))))
|
||||
|
||||
on-error
|
||||
(mf/use-fn
|
||||
(fn [_cause]
|
||||
(fn [_]
|
||||
(st/emit! (msg/error (tr "errors.generic")))))
|
||||
|
||||
on-submit
|
||||
(mf/use-fn
|
||||
(mf/deps on-success on-error)
|
||||
(fn [form _]
|
||||
(reset! submitted? true)
|
||||
(let [params (:clean-data @form)]
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
|
@ -96,7 +95,7 @@
|
|||
(let [show-buttons? (mf/use-state false)
|
||||
content (mf/use-state "")
|
||||
|
||||
disabled? (or (fm/all-spaces? @content)
|
||||
disabled? (or (str/blank? @content)
|
||||
(str/empty-or-nil? @content))
|
||||
|
||||
on-focus
|
||||
|
@ -155,7 +154,7 @@
|
|||
pos-x (* (:x position) zoom)
|
||||
pos-y (* (:y position) zoom)
|
||||
|
||||
disabled? (or (fm/all-spaces? content)
|
||||
disabled? (or (str/blank? content)
|
||||
(str/empty-or-nil? content))
|
||||
|
||||
on-esc
|
||||
|
@ -225,7 +224,7 @@
|
|||
(mf/deps @content)
|
||||
(fn [] (on-submit @content)))
|
||||
|
||||
disabled? (or (fm/all-spaces? @content)
|
||||
disabled? (or (str/blank? @content)
|
||||
(str/empty-or-nil? @content))]
|
||||
|
||||
[:div {:class (stl/css :edit-form)}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
[cljs.core :as c]
|
||||
[clojure.string]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
@ -26,7 +25,9 @@
|
|||
(def use-form fm/use-form)
|
||||
|
||||
(mf/defc input
|
||||
[{:keys [label help-icon disabled form hint trim children data-testid on-change-value placeholder show-success?] :as props}]
|
||||
[{:keys [label help-icon disabled form hint trim children data-testid on-change-value placeholder show-success? show-error]
|
||||
:or {show-error true}
|
||||
:as props}]
|
||||
(let [input-type (get props :type "text")
|
||||
input-name (get props :name)
|
||||
more-classes (get props :class)
|
||||
|
@ -152,11 +153,14 @@
|
|||
children])
|
||||
|
||||
(cond
|
||||
(and touched? (:message error))
|
||||
[:div {:id (dm/str "error-" input-name)
|
||||
:class (stl/css :error)
|
||||
:data-testid (clojure.string/join [data-testid "-error"])}
|
||||
(tr (:message error))]
|
||||
(and touched? (:code error) show-error)
|
||||
(let [code (:code error)]
|
||||
[:div {:id (dm/str "error-" input-name)
|
||||
:class (stl/css :error)
|
||||
:data-testid (dm/str data-testid "-error")}
|
||||
(if (vector? code)
|
||||
(tr (nth code 0) (i18n/c (nth code 1)))
|
||||
(tr code))])
|
||||
|
||||
(string? hint)
|
||||
[:div {:class (stl/css :hint)} hint])]]))
|
||||
|
@ -207,8 +211,8 @@
|
|||
[:label {:class (stl/css :textarea-label)} label]
|
||||
[:> :textarea props]
|
||||
(cond
|
||||
(and touched? (:message error))
|
||||
[:span {:class (stl/css :error)} (tr (:message error))]
|
||||
(and touched? (:code error))
|
||||
[:span {:class (stl/css :error)} (tr (:code error))]
|
||||
|
||||
(string? hint)
|
||||
[:span {:class (stl/css :hint)} hint])]))
|
||||
|
@ -550,41 +554,3 @@
|
|||
[:span {:class (stl/css :text)} (:text item)]
|
||||
[:button {:class (stl/css :icon)
|
||||
:on-click #(remove-item! item)} i/close]]])])]))
|
||||
|
||||
;; --- Validators
|
||||
|
||||
(defn all-spaces?
|
||||
[value]
|
||||
(let [trimmed (str/trim value)]
|
||||
(str/empty? trimmed)))
|
||||
|
||||
(def max-length-allowed 250)
|
||||
(def max-uri-length-allowed 2048)
|
||||
|
||||
(defn max-length?
|
||||
[value length]
|
||||
(> (count value) length))
|
||||
|
||||
(defn validate-length
|
||||
[field length errors-msg]
|
||||
(fn [errors data]
|
||||
(cond-> errors
|
||||
(max-length? (get data field) length)
|
||||
(assoc field {:message errors-msg}))))
|
||||
|
||||
(defn validate-not-empty
|
||||
[field error-msg]
|
||||
(fn [errors data]
|
||||
(cond-> errors
|
||||
(all-spaces? (get data field))
|
||||
(assoc field {:message error-msg}))))
|
||||
|
||||
(defn validate-not-all-spaces
|
||||
[field error-msg]
|
||||
(fn [errors data]
|
||||
(let [value (get data field)]
|
||||
(cond-> errors
|
||||
(and
|
||||
(all-spaces? value)
|
||||
(> (count value) 0))
|
||||
(assoc field {:message error-msg})))))
|
||||
|
|
|
@ -7,25 +7,24 @@
|
|||
(ns app.main.ui.dashboard.change-owner
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::member-id ::us/uuid)
|
||||
(s/def ::leave-modal-form
|
||||
(s/keys :req-un [::member-id]))
|
||||
(def ^:private schema:leave-modal-form
|
||||
[:map {:title "LeaveModalForm"}
|
||||
[:member-id ::sm/uuid]])
|
||||
|
||||
(mf/defc leave-and-reassign-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :leave-and-reassign}
|
||||
[{:keys [profile team accept]}]
|
||||
(let [form (fm/use-form :spec ::leave-modal-form :initial {})
|
||||
(let [form (fm/use-form :schema schema:leave-modal-form :initial {})
|
||||
members-map (mf/deref refs/dashboard-team-members)
|
||||
members (vals members-map)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.spec :as us]
|
||||
[app.config :as cfg]
|
||||
[app.main.data.dashboard :as dd]
|
||||
|
@ -33,7 +34,6 @@
|
|||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
||||
(def ^:private arrow-icon
|
||||
(i/icon-xref :arrow (stl/css :arrow-icon)))
|
||||
|
||||
|
@ -131,6 +131,12 @@
|
|||
(s/def ::invite-member-form
|
||||
(s/keys :req-un [::role ::emails ::team-id]))
|
||||
|
||||
(def ^:private schema:invite-member-form
|
||||
[:map {:title "InviteMemberForm"}
|
||||
[:role :keyword]
|
||||
[:emails [::sm/set {:kind ::sm/email :min 1}]]
|
||||
[:team-id ::sm/uuid]])
|
||||
|
||||
(mf/defc invite-members-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :invite-members
|
||||
|
@ -139,9 +145,14 @@
|
|||
(let [members-map (mf/deref refs/dashboard-team-members)
|
||||
perms (:permissions team)
|
||||
|
||||
roles (mf/use-memo (mf/deps perms) #(get-available-roles perms))
|
||||
initial (mf/use-memo (constantly {:role "editor" :team-id (:id team)}))
|
||||
form (fm/use-form :spec ::invite-member-form
|
||||
roles (mf/with-memo [perms]
|
||||
(get-available-roles perms))
|
||||
team-id (:id team)
|
||||
|
||||
initial (mf/with-memo [team-id]
|
||||
{:role "editor" :team-id team-id})
|
||||
|
||||
form (fm/use-form :schema schema:invite-member-form
|
||||
:initial initial)
|
||||
error-text (mf/use-state "")
|
||||
|
||||
|
@ -746,10 +757,11 @@
|
|||
;; WEBHOOKS SECTION
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(s/def ::uri ::us/uri)
|
||||
(s/def ::mtype ::us/not-empty-string)
|
||||
(s/def ::webhook-form
|
||||
(s/keys :req-un [::uri ::mtype]))
|
||||
(def ^:private schema:webhook-form
|
||||
[:map {:title "WebhookForm"}
|
||||
[:uri [::sm/uri {:max 4069 :prefix #"^http[s]?://"
|
||||
:error/code "errors.webhooks.invalid-uri"}]]
|
||||
[:mtype ::sm/text]])
|
||||
|
||||
(def valid-webhook-mtypes
|
||||
[{:label "application/json" :value "application/json"}
|
||||
|
@ -763,12 +775,12 @@
|
|||
{::mf/register modal/components
|
||||
::mf/register-as :webhook}
|
||||
[{:keys [webhook] :as props}]
|
||||
;; FIXME: this is a workaround because input fields do not support rendering hooks
|
||||
(let [initial (mf/use-memo (fn [] (or (some-> webhook (update :uri str))
|
||||
{:is-active false :mtype "application/json"})))
|
||||
form (fm/use-form :spec ::webhook-form
|
||||
:initial initial
|
||||
:validators [(fm/validate-length :uri fm/max-uri-length-allowed (tr "team.webhooks.max-length"))])
|
||||
|
||||
(let [initial (mf/with-memo []
|
||||
(or (some-> webhook (update :uri str))
|
||||
{:is-active false :mtype "application/json"}))
|
||||
form (fm/use-form :schema schema:webhook-form
|
||||
:initial initial)
|
||||
on-success
|
||||
(mf/use-fn
|
||||
(fn [_]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.main.ui.dashboard.team-form
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.dashboard :as dd]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.modal :as modal]
|
||||
|
@ -19,12 +19,11 @@
|
|||
[app.util.keyboard :as kbd]
|
||||
[app.util.router :as rt]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::name ::us/not-empty-string)
|
||||
(s/def ::team-form
|
||||
(s/keys :req-un [::name]))
|
||||
(def ^:private schema:team-form
|
||||
[:map {:title "TeamForm"}
|
||||
[:name [::sm/text {:max 250}]]])
|
||||
|
||||
(defn- on-create-success
|
||||
[_form response]
|
||||
|
@ -68,24 +67,23 @@
|
|||
(on-update-submit form)
|
||||
(on-create-submit form))))
|
||||
|
||||
(mf/defc team-form-modal {::mf/register modal/components
|
||||
::mf/register-as :team-form}
|
||||
(mf/defc team-form-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :team-form}
|
||||
[{:keys [team] :as props}]
|
||||
(let [initial (mf/use-memo (fn [] (or team {})))
|
||||
form (fm/use-form :spec ::team-form
|
||||
:validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))]
|
||||
form (fm/use-form :schema schema:team-form
|
||||
:initial initial)
|
||||
handle-keydown
|
||||
(mf/use-callback
|
||||
(mf/deps)
|
||||
(mf/use-fn
|
||||
(fn [e]
|
||||
(when (kbd/enter? e)
|
||||
(dom/prevent-default e)
|
||||
(dom/stop-propagation e)
|
||||
(on-submit form e))))
|
||||
|
||||
on-close #(st/emit! (modal/hide))]
|
||||
on-close
|
||||
(mf/use-fn #(st/emit! (modal/hide)))]
|
||||
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.events :as-alias ev]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
@ -56,25 +56,20 @@
|
|||
(tr "labels.start"))
|
||||
:class (stl/css :next-button)}]]]))
|
||||
|
||||
(s/def ::questions-form-step-1
|
||||
(s/keys :req-un [::planning
|
||||
::expected-use]
|
||||
:opt-un [::planning-other]))
|
||||
(def ^:private schema:questions-form-1
|
||||
[:and
|
||||
|
||||
(defn- step-1-form-validator
|
||||
[errors data]
|
||||
(let [planning (:planning data)
|
||||
planning-other (:planning-other data)]
|
||||
(cond-> errors
|
||||
(and (= planning "other")
|
||||
(str/blank? planning-other))
|
||||
(assoc :planning-other {:code "missing"})
|
||||
[:map {:title "QuestionsFormStep1"}
|
||||
[:planning ::sm/text]
|
||||
[:expected-use [:enum "work" "education" "personal"]]
|
||||
[:planning-other {:optional true}
|
||||
[::sm/text {:max 512}]]]
|
||||
|
||||
(not= planning "other")
|
||||
(assoc :planning-other nil)
|
||||
|
||||
(str/blank? planning)
|
||||
(assoc :planning {:code "missing"}))))
|
||||
[:fn {:error/field :planning-other}
|
||||
(fn [{:keys [planning planning-other]}]
|
||||
(or (not= planning "other")
|
||||
(and (= planning "other")
|
||||
(not (str/blank? planning-other)))))]])
|
||||
|
||||
(mf/defc step-1
|
||||
{::mf/props :obj}
|
||||
|
@ -143,24 +138,24 @@
|
|||
[:& fm/input {:name :planning-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "labels.other")
|
||||
:show-error false
|
||||
:label ""}])]]))
|
||||
|
||||
(s/def ::questions-form-step-2
|
||||
(s/keys :req-un [::experience-design-tool]
|
||||
:opt-un [::experience-design-tool-other]))
|
||||
(def ^:private schema:questions-form-2
|
||||
[:and
|
||||
[:map {:title "QuestionsFormStep2"}
|
||||
[:experience-design-tool
|
||||
[:enum "figma" "sketch" "adobe-xd" "canva" "invision" "other"]]
|
||||
[:experience-design-tool-other {:optional true}
|
||||
[::sm/text {:max 512}]]]
|
||||
|
||||
(defn- step-2-form-validator
|
||||
[errors data]
|
||||
(let [experience (:experience-design-tool data)
|
||||
experience-other (:experience-design-tool-other data)]
|
||||
|
||||
(cond-> errors
|
||||
(and (= experience "other")
|
||||
(str/blank? experience-other))
|
||||
(assoc :experience-design-tool-other {:code "missing"})
|
||||
|
||||
(not= experience "other")
|
||||
(assoc :experience-design-tool-other nil))))
|
||||
[:fn {:error/field :experience-design-tool-other}
|
||||
(fn [data]
|
||||
(let [experience (:experience-design-tool data)
|
||||
experience-other (:experience-design-tool-other data)]
|
||||
(or (not= experience "other")
|
||||
(and (= experience "other")
|
||||
(not (str/blank? experience-other))))))]])
|
||||
|
||||
(mf/defc step-2
|
||||
{::mf/props :obj}
|
||||
|
@ -180,7 +175,7 @@
|
|||
(conj {:label (tr "labels.other-short") :value "other" :icon i/curve})))
|
||||
|
||||
current-experience
|
||||
(dm/get-in @form [:clean-data :experience-design-tool])
|
||||
(dm/get-in @form [:data :experience-design-tool])
|
||||
|
||||
on-design-tool-change
|
||||
(mf/use-fn
|
||||
|
@ -212,33 +207,34 @@
|
|||
[:& fm/input {:name :experience-design-tool-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "labels.other")
|
||||
:show-error false
|
||||
:label ""}])]]))
|
||||
|
||||
(s/def ::questions-form-step-3
|
||||
(s/keys :req-un [::team-size ::role ::responsability]
|
||||
:opt-un [::role-other ::responsability-other]))
|
||||
|
||||
(defn- step-3-form-validator
|
||||
[errors data]
|
||||
(let [role (:role data)
|
||||
role-other (:role-other data)
|
||||
responsability (:responsability data)
|
||||
responsability-other (:responsability-other data)]
|
||||
(def ^:private schema:questions-form-3
|
||||
[:and
|
||||
[:map {:title "QuestionsFormStep3"}
|
||||
[:team-size
|
||||
[:enum "more-than-50" "31-50" "11-30" "2-10" "freelancer" "personal-project"]]
|
||||
[:role
|
||||
[:enum "designer" "developer" "student-teacher" "graphic-design" "marketing" "manager" "other"]]
|
||||
[:responsability
|
||||
[:enum "team-leader" "team-member" "freelancer" "ceo-founder" "director" "student-teacher" "other"]]
|
||||
|
||||
(cond-> errors
|
||||
(and (= role "other")
|
||||
(str/blank? role-other))
|
||||
(assoc :role-other {:code "missing"})
|
||||
[:role-other {:optional true} [::sm/text {:max 512}]]
|
||||
[:responsability-other {:optional true} [::sm/text {:max 512}]]]
|
||||
|
||||
(not= role "other")
|
||||
(assoc :role-other nil)
|
||||
[:fn {:error/field :role-other}
|
||||
(fn [{:keys [role role-other]}]
|
||||
(or (not= role "other")
|
||||
(and (= role "other")
|
||||
(not (str/blank? role-other)))))]
|
||||
|
||||
(and (= responsability "other")
|
||||
(str/blank? responsability-other))
|
||||
(assoc :responsability-other {:code "missing"})
|
||||
|
||||
(not= responsability "other")
|
||||
(assoc :responsability-other nil))))
|
||||
[:fn {:error/field :responsability-other}
|
||||
(fn [{:keys [responsability responsability-other]}]
|
||||
(or (not= responsability "other")
|
||||
(and (= responsability "other")
|
||||
(not (str/blank? responsability-other)))))]])
|
||||
|
||||
(mf/defc step-3
|
||||
{::mf/props :obj}
|
||||
|
@ -264,7 +260,6 @@
|
|||
{:label (tr "labels.director") :value "director"}])
|
||||
(conj {:label (tr "labels.other-short") :value "other"})))
|
||||
|
||||
|
||||
team-size-options
|
||||
(mf/with-memo []
|
||||
[{:label (tr "labels.select-option") :value "" :key "team-size" :disabled true}
|
||||
|
@ -301,6 +296,7 @@
|
|||
[:& fm/input {:name :role-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "labels.other")
|
||||
:show-error false
|
||||
:label ""}])]
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
|
@ -314,6 +310,7 @@
|
|||
[:& fm/input {:name :responsability-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "labels.other")
|
||||
:show-error false
|
||||
:label ""}])]
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
|
@ -323,21 +320,18 @@
|
|||
:select-class (stl/css :select-class)
|
||||
:name :team-size}]]]))
|
||||
|
||||
(s/def ::questions-form-step-4
|
||||
(s/keys :req-un [::start-with]
|
||||
:opt-un [::start-with-other]))
|
||||
(def ^:private schema:questions-form-4
|
||||
[:and
|
||||
[:map {:title "QuestionsFormStep4"}
|
||||
[:start-with
|
||||
[:enum "ui" "wireframing" "prototyping" "ds" "code" "other"]]
|
||||
[:start-with-other {:optional true} [::sm/text {:max 512}]]]
|
||||
|
||||
(defn- step-4-form-validator
|
||||
[errors data]
|
||||
(let [start (:start-with data)
|
||||
start-other (:start-with-other data)]
|
||||
(cond-> errors
|
||||
(and (= start "other")
|
||||
(str/blank? start-other))
|
||||
(assoc :start-with-other {:code "missing"})
|
||||
|
||||
(not= start "other")
|
||||
(assoc :start-with-other nil))))
|
||||
[:fn {:error/field :start-with-other}
|
||||
(fn [{:keys [start-with start-with-other]}]
|
||||
(or (not= start-with "other")
|
||||
(and (= start-with "other")
|
||||
(not (str/blank? start-with-other)))))]])
|
||||
|
||||
(mf/defc step-4
|
||||
{::mf/props :obj}
|
||||
|
@ -386,23 +380,21 @@
|
|||
[:& fm/input {:name :start-with-other
|
||||
:class (stl/css :input-spacing)
|
||||
:label ""
|
||||
:show-error false
|
||||
:placeholder (tr "labels.other")}])]]))
|
||||
|
||||
(s/def ::questions-form-step-5
|
||||
(s/keys :req-un [::referer]
|
||||
:opt-un [::referer-other]))
|
||||
(def ^:private schema:questions-form-5
|
||||
[:and
|
||||
[:map {:title "QuestionsFormStep5"}
|
||||
[:referer
|
||||
[:enum "youtube" "event" "search" "social" "article" "other"]]
|
||||
[:referer-other {:optional true} [::sm/text {:max 512}]]]
|
||||
|
||||
(defn- step-5-form-validator
|
||||
[errors data]
|
||||
(let [referer (:referer data)
|
||||
referer-other (:referer-other data)]
|
||||
(cond-> errors
|
||||
(and (= referer "other")
|
||||
(str/blank? referer-other))
|
||||
(assoc :referer-other {:code "missing"})
|
||||
|
||||
(not= referer "other")
|
||||
(assoc :referer-other nil))))
|
||||
[:fn {:error/field :referer-other}
|
||||
(fn [{:keys [referer referer-other]}]
|
||||
(or (not= referer "other")
|
||||
(and (= referer "other")
|
||||
(not (str/blank? referer-other)))))]])
|
||||
|
||||
(mf/defc step-5
|
||||
{::mf/props :obj}
|
||||
|
@ -444,6 +436,7 @@
|
|||
[:& fm/input {:name :referer-other
|
||||
:class (stl/css :input-spacing)
|
||||
:label ""
|
||||
:show-error false
|
||||
:placeholder (tr "labels.other")}])]]))
|
||||
|
||||
(mf/defc questions-modal
|
||||
|
@ -456,28 +449,23 @@
|
|||
;; and we want to keep the filled info
|
||||
step-1-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-1-form-validator]
|
||||
:spec ::questions-form-step-1)
|
||||
:schema schema:questions-form-1)
|
||||
|
||||
step-2-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-2-form-validator]
|
||||
:spec ::questions-form-step-2)
|
||||
:schema schema:questions-form-2)
|
||||
|
||||
step-3-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-3-form-validator]
|
||||
:spec ::questions-form-step-3)
|
||||
:schema schema:questions-form-3)
|
||||
|
||||
step-4-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-4-form-validator]
|
||||
:spec ::questions-form-step-4)
|
||||
:schema schema:questions-form-4)
|
||||
|
||||
step-5-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-5-form-validator]
|
||||
:spec ::questions-form-step-5)
|
||||
:schema schema:questions-form-5)
|
||||
|
||||
on-next
|
||||
(mf/use-fn
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.dashboard :as dd]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.messages :as msg]
|
||||
|
@ -18,7 +18,6 @@
|
|||
[app.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
[cljs.spec.alpha :as s]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
@ -55,11 +54,10 @@
|
|||
[:p {:class (stl/css :modal-desc)}
|
||||
(tr "onboarding.team-modal.create-team-feature-5")]]]])
|
||||
|
||||
|
||||
(s/def ::emails (s/and ::us/set-of-valid-emails))
|
||||
(s/def ::role ::us/keyword)
|
||||
(s/def ::invite-form
|
||||
(s/keys :req-un [::role ::emails]))
|
||||
(def ^:private schema:invite-form
|
||||
[:map {:title "InviteForm"}
|
||||
[:role :keyword]
|
||||
[:emails [::sm/set {:kind ::sm/email}]]])
|
||||
|
||||
(defn- get-available-roles
|
||||
[]
|
||||
|
@ -73,7 +71,7 @@
|
|||
#(do {:role "editor"
|
||||
:name name}))
|
||||
|
||||
form (fm/use-form :spec ::invite-form
|
||||
form (fm/use-form :schema schema:invite-form
|
||||
:initial initial)
|
||||
|
||||
params (:clean-data @form)
|
||||
|
@ -151,7 +149,7 @@
|
|||
:name :emails
|
||||
:auto-focus? true
|
||||
:trim true
|
||||
:valid-item-fn us/parse-email
|
||||
:valid-item-fn sm/parse-email
|
||||
:caution-item-fn #{}
|
||||
:label (tr "modals.invite-member.emails")
|
||||
:on-submit on-submit}]]
|
||||
|
@ -172,18 +170,16 @@
|
|||
|
||||
[:div {:class (stl/css :paginator)} "2/2"]]))
|
||||
|
||||
(def ^:private schema:team-form
|
||||
[:map {:title "TeamForm"}
|
||||
[:name [::sm/text {:max 250}]]])
|
||||
|
||||
(mf/defc team-form-step-1
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
[{:keys [on-submit]}]
|
||||
(let [validators (mf/with-memo []
|
||||
[(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))])
|
||||
|
||||
form (fm/use-form
|
||||
:spec ::team-form
|
||||
:initial {}
|
||||
:validators validators)
|
||||
(let [form (fm/use-form :schema schema:team-form
|
||||
:initial {})
|
||||
|
||||
on-submit*
|
||||
(mf/use-fn
|
||||
|
@ -240,10 +236,6 @@
|
|||
|
||||
[:div {:class (stl/css :paginator)} "1/2"]]))
|
||||
|
||||
(s/def ::name ::us/not-empty-string)
|
||||
(s/def ::team-form
|
||||
(s/keys :req-un [::name]))
|
||||
|
||||
(mf/defc onboarding-team-modal
|
||||
{::mf/props :obj}
|
||||
[]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.main.ui.settings.access-tokens
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.users :as du]
|
||||
|
@ -20,8 +20,6 @@
|
|||
[app.util.keyboard :as kbd]
|
||||
[app.util.time :as dt]
|
||||
[app.util.webapi :as wapi]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
@ -40,17 +38,10 @@
|
|||
(def token-created-ref
|
||||
(l/derived :access-token-created st/state))
|
||||
|
||||
(s/def ::name ::us/not-empty-string)
|
||||
(s/def ::expiration-date ::us/not-empty-string)
|
||||
(s/def ::access-token-form
|
||||
(s/keys :req-un [::name ::expiration-date]))
|
||||
|
||||
(defn- name-validator
|
||||
[errors data]
|
||||
(let [name (:name data)]
|
||||
(cond-> errors
|
||||
(str/blank? name)
|
||||
(assoc :name {:message (tr "dashboard.access-tokens.errors-required-name")}))))
|
||||
(def ^:private schema:form
|
||||
[:map {:title "AccessTokenForm"}
|
||||
[:name [::sm/text {:max 250}]]
|
||||
[:expiration-date [::sm/text {:max 250}]]])
|
||||
|
||||
(def initial-data
|
||||
{:name "" :expiration-date "never"})
|
||||
|
@ -61,10 +52,8 @@
|
|||
[]
|
||||
(let [form (fm/use-form
|
||||
:initial initial-data
|
||||
:spec ::access-token-form
|
||||
:validators [name-validator
|
||||
(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))])
|
||||
:schema schema:form)
|
||||
|
||||
created (mf/deref token-created-ref)
|
||||
created? (mf/use-state false)
|
||||
locale (mf/deref i18n/locale)
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
(ns app.main.ui.settings.change-email
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dma]
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.users :as du]
|
||||
|
@ -20,24 +18,8 @@
|
|||
[app.main.ui.notifications.context-notification :refer [context-notification]]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::email-1 ::us/email)
|
||||
(s/def ::email-2 ::us/email)
|
||||
|
||||
(defn- email-equality
|
||||
[errors data]
|
||||
(let [email-1 (:email-1 data)
|
||||
email-2 (:email-2 data)]
|
||||
(cond-> errors
|
||||
(and email-1 email-2 (not= email-1 email-2))
|
||||
(assoc :email-2 {:message (tr "errors.email-invalid-confirmation")
|
||||
:code :different-emails}))))
|
||||
|
||||
(s/def ::email-change-form
|
||||
(s/keys :req-un [::email-1 ::email-2]))
|
||||
|
||||
(defn- on-error
|
||||
[form error]
|
||||
(case (:code (ex-data error))
|
||||
|
@ -71,30 +53,32 @@
|
|||
:on-success (partial on-success profile)}]
|
||||
(st/emit! (du/request-email-change (with-meta params mdata)))))
|
||||
|
||||
(def ^:private schema:email-change-form
|
||||
[:and
|
||||
[:map {:title "EmailChangeForm"}
|
||||
[:email-1 ::sm/email]
|
||||
[:email-2 ::sm/email]]
|
||||
[:fn {:error/code "errors.invalid-email-confirmation"
|
||||
:error/field :email-2}
|
||||
(fn [data]
|
||||
(let [email-1 (:email-1 data)
|
||||
email-2 (:email-2 data)]
|
||||
(= email-1 email-2)))]])
|
||||
|
||||
(mf/defc change-email-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :change-email}
|
||||
[]
|
||||
(let [profile (mf/deref refs/profile)
|
||||
form (fm/use-form :spec ::email-change-form
|
||||
:validators [email-equality]
|
||||
form (fm/use-form :schema schema:email-change-form
|
||||
:initial profile)
|
||||
on-close
|
||||
(mf/use-callback #(st/emit! (modal/hide)))
|
||||
(mf/use-fn #(st/emit! (modal/hide)))
|
||||
|
||||
on-submit
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps profile)
|
||||
(partial on-submit profile))
|
||||
|
||||
on-email-change
|
||||
(mf/use-callback
|
||||
(fn [_ _]
|
||||
(let [different-emails-error? (= (dma/get-in @form [:errors :email-2 :code]) :different-emails)
|
||||
email-1 (dma/get-in @form [:clean-data :email-1])
|
||||
email-2 (dma/get-in @form [:clean-data :email-2])]
|
||||
(when (and different-emails-error? (= email-1 email-2))
|
||||
(swap! form d/dissoc-in [:errors :email-2])))))]
|
||||
(partial on-submit profile))]
|
||||
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
|
@ -118,16 +102,14 @@
|
|||
:name :email-1
|
||||
:label (tr "modals.change-email.new-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]
|
||||
:show-success? true}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "email"
|
||||
:name :email-2
|
||||
:label (tr "modals.change-email.confirm-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]]
|
||||
:show-success? true}]]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"Feedback form."
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.repo :as rp]
|
||||
|
@ -17,25 +17,22 @@
|
|||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::content ::us/not-empty-string)
|
||||
(s/def ::subject ::us/not-empty-string)
|
||||
|
||||
(s/def ::feedback-form
|
||||
(s/keys :req-un [::subject ::content]))
|
||||
(def ^:private schema:feedback-form
|
||||
[:map {:title "FeedbackForm"}
|
||||
[:subject [::sm/text {:max 250}]]
|
||||
[:content [::sm/text {:max 5000}]]])
|
||||
|
||||
(mf/defc feedback-form
|
||||
{::mf/private true}
|
||||
[]
|
||||
(let [profile (mf/deref refs/profile)
|
||||
form (fm/use-form :spec ::feedback-form
|
||||
:validators [(fm/validate-length :subject fm/max-length-allowed (tr "auth.name.too-long"))
|
||||
(fm/validate-not-empty :subject (tr "auth.name.not-all-space"))])
|
||||
form (fm/use-form :schema schema:feedback-form)
|
||||
loading (mf/use-state false)
|
||||
|
||||
on-succes
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps profile)
|
||||
(fn [_]
|
||||
(reset! loading false)
|
||||
|
@ -43,7 +40,7 @@
|
|||
(swap! form assoc :data {} :touched {} :errors {})))
|
||||
|
||||
on-error
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps profile)
|
||||
(fn [{:keys [code] :as error}]
|
||||
(reset! loading false)
|
||||
|
@ -52,7 +49,7 @@
|
|||
(st/emit! (msg/error (tr "errors.generic"))))))
|
||||
|
||||
on-submit
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps profile)
|
||||
(fn [form _]
|
||||
(reset! loading true)
|
||||
|
@ -106,8 +103,8 @@
|
|||
|
||||
(mf/defc feedback-page
|
||||
[]
|
||||
(mf/use-effect
|
||||
#(dom/set-html-title (tr "title.settings.feedback")))
|
||||
(mf/with-effect []
|
||||
(dom/set-html-title (tr "title.settings.feedback")))
|
||||
|
||||
[:div {:class (stl/css :dashboard-settings)}
|
||||
[:div {:class (stl/css :form-container)}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
(ns app.main.ui.settings.options
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.refs :as refs]
|
||||
|
@ -15,14 +14,12 @@
|
|||
[app.main.ui.components.forms :as fm]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::lang (s/nilable ::us/string))
|
||||
(s/def ::theme (s/nilable ::us/not-empty-string))
|
||||
|
||||
(s/def ::options-form
|
||||
(s/keys :opt-un [::lang ::theme]))
|
||||
(def ^:private schema:options-form
|
||||
[:map {:title "OptionsForm"}
|
||||
[:lang {:optional true} [:string {:max 20}]]
|
||||
[:theme {:optional true} [:string {:max 250}]]])
|
||||
|
||||
(defn- on-success
|
||||
[profile]
|
||||
|
@ -41,7 +38,7 @@
|
|||
(let [profile (mf/deref refs/profile)
|
||||
initial (mf/with-memo [profile]
|
||||
(update profile :lang #(or % "")))
|
||||
form (fm/use-form :spec ::options-form
|
||||
form (fm/use-form :schema schema:options-form
|
||||
:initial initial)]
|
||||
|
||||
[:& fm/form {:class (stl/css :options-form)
|
||||
|
|
|
@ -7,14 +7,13 @@
|
|||
(ns app.main.ui.settings.password
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.users :as udu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn- on-error
|
||||
|
@ -22,10 +21,10 @@
|
|||
(case (:code (ex-data error))
|
||||
:old-password-not-match
|
||||
(swap! form assoc-in [:errors :password-old]
|
||||
{:message (tr "errors.wrong-old-password")})
|
||||
{:code "errors.wrong-old-password"})
|
||||
:email-as-password
|
||||
(swap! form assoc-in [:errors :password-1]
|
||||
{:message (tr "errors.email-as-password")})
|
||||
{:code "errors.email-as-password"})
|
||||
|
||||
(let [msg (tr "generic.error")]
|
||||
(st/emit! (msg/error msg)))))
|
||||
|
@ -47,40 +46,29 @@
|
|||
:on-error (partial on-error form)})]
|
||||
(st/emit! (udu/update-password params))))
|
||||
|
||||
(s/def ::password-1 ::us/not-empty-string)
|
||||
(s/def ::password-2 ::us/not-empty-string)
|
||||
(s/def ::password-old (s/nilable ::us/string))
|
||||
|
||||
(defn- password-equality
|
||||
[errors data]
|
||||
(let [password-1 (:password-1 data)
|
||||
password-2 (:password-2 data)]
|
||||
|
||||
(cond-> errors
|
||||
(and password-1 password-2 (not= password-1 password-2))
|
||||
(assoc :password-2 {:message (tr "errors.password-invalid-confirmation")})
|
||||
|
||||
(and password-1 (> 8 (count password-1)))
|
||||
(assoc :password-1 {:message (tr "errors.password-too-short")}))))
|
||||
|
||||
(s/def ::password-form
|
||||
(s/keys :req-un [::password-1
|
||||
::password-2
|
||||
::password-old]))
|
||||
(def ^:private schema:password-form
|
||||
[:and
|
||||
[:map {:title "PasswordForm"}
|
||||
[:password-1 ::sm/password]
|
||||
[:password-2 ::sm/password]
|
||||
[:password-old ::sm/password]]
|
||||
[:fn {:error/code "errors.password-invalid-confirmation"
|
||||
:error/field :password-2}
|
||||
(fn [{:keys [password-1 password-2]}]
|
||||
(= password-1 password-2))]])
|
||||
|
||||
(mf/defc password-form
|
||||
[]
|
||||
(let [initial (mf/use-memo (constantly {:password-old nil}))
|
||||
form (fm/use-form :spec ::password-form
|
||||
:validators [(fm/validate-not-all-spaces :password-old (tr "auth.password-not-empty"))
|
||||
(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
|
||||
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))
|
||||
password-equality]
|
||||
:initial initial)]
|
||||
(let [initial (mf/with-memo []
|
||||
{:password-old ""
|
||||
:password-1 ""
|
||||
:password-2 ""})
|
||||
form (fm/use-form :schema schema:password-form
|
||||
:initial initial)]
|
||||
|
||||
[:& fm/form {:class (stl/css :password-form)
|
||||
:on-submit on-submit
|
||||
:form form}
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input
|
||||
{:type "password"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.main.ui.settings.profile
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.config :as cf]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.modal :as modal]
|
||||
|
@ -18,14 +18,12 @@
|
|||
[app.main.ui.components.forms :as fm]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::fullname ::us/not-empty-string)
|
||||
(s/def ::email ::us/email)
|
||||
|
||||
(s/def ::profile-form
|
||||
(s/keys :req-un [::fullname ::email]))
|
||||
(def ^:private schema:profile-form
|
||||
[:map {:title "ProfileForm"}
|
||||
[:fullname [::sm/text {:max 250}]]
|
||||
[:email ::sm/email]])
|
||||
|
||||
(defn- on-submit
|
||||
[form _event]
|
||||
|
@ -37,19 +35,18 @@
|
|||
;; --- Profile Form
|
||||
|
||||
(mf/defc profile-form
|
||||
{::mf/private true}
|
||||
[]
|
||||
(let [profile (mf/deref refs/profile)
|
||||
form (fm/use-form :spec ::profile-form
|
||||
:initial profile
|
||||
:validators [(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))
|
||||
(fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))])
|
||||
form (fm/use-form :schema schema:profile-form
|
||||
:initial profile)
|
||||
|
||||
handle-show-change-email
|
||||
(mf/use-callback
|
||||
on-show-change-email
|
||||
(mf/use-fn
|
||||
#(modal/show! :change-email {}))
|
||||
|
||||
handle-show-delete-account
|
||||
(mf/use-callback
|
||||
on-show-delete-account
|
||||
(mf/use-fn
|
||||
#(modal/show! :delete-account {}))]
|
||||
|
||||
[:& fm/form {:on-submit on-submit
|
||||
|
@ -62,7 +59,7 @@
|
|||
:label (tr "dashboard.your-name")}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)
|
||||
:on-click handle-show-change-email}
|
||||
:on-click on-show-change-email}
|
||||
[:& fm/input
|
||||
{:type "email"
|
||||
:name :email
|
||||
|
@ -71,7 +68,7 @@
|
|||
|
||||
[:div {:class (stl/css :options)}
|
||||
[:div.change-email
|
||||
[:a {:on-click handle-show-change-email}
|
||||
[:a {:on-click on-show-change-email}
|
||||
(tr "dashboard.change-email")]]]]
|
||||
|
||||
[:> fm/submit-button*
|
||||
|
@ -81,17 +78,25 @@
|
|||
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-item)}
|
||||
[:a {:on-click handle-show-delete-account
|
||||
[:a {:on-click on-show-delete-account
|
||||
:data-testid "remove-acount-btn"}
|
||||
(tr "dashboard.remove-account")]]]]))
|
||||
|
||||
;; --- Profile Photo Form
|
||||
|
||||
(mf/defc profile-photo-form []
|
||||
(let [file-input (mf/use-ref nil)
|
||||
profile (mf/deref refs/profile)
|
||||
photo (cf/resolve-profile-photo-url profile)
|
||||
on-image-click #(dom/click (mf/ref-val file-input))
|
||||
(mf/defc profile-photo-form
|
||||
{::mf/private true}
|
||||
[]
|
||||
(let [input-ref (mf/use-ref nil)
|
||||
profile (mf/deref refs/profile)
|
||||
|
||||
photo
|
||||
(mf/with-memo [profile]
|
||||
(cf/resolve-profile-photo-url profile))
|
||||
|
||||
on-image-click
|
||||
(mf/use-fn
|
||||
#(dom/click (mf/ref-val input-ref)))
|
||||
|
||||
on-file-selected
|
||||
(fn [file]
|
||||
|
@ -104,15 +109,17 @@
|
|||
[:img {:src photo}]
|
||||
[:& file-uploader {:accept "image/jpeg,image/png"
|
||||
:multi false
|
||||
:ref file-input
|
||||
:ref input-ref
|
||||
:on-selected on-file-selected
|
||||
:data-testid "profile-image-input"}]]]))
|
||||
|
||||
;; --- Profile Page
|
||||
|
||||
(mf/defc profile-page []
|
||||
(mf/defc profile-page
|
||||
[]
|
||||
(mf/with-effect []
|
||||
(dom/set-html-title (tr "title.settings.profile")))
|
||||
|
||||
[:div {:class (stl/css :dashboard-settings)}
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:h2 (tr "labels.profile")]
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.spec :as us]
|
||||
[app.common.schema :as sm]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.store :as st]
|
||||
|
@ -18,7 +18,6 @@
|
|||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc asset-group-title
|
||||
|
@ -92,21 +91,18 @@
|
|||
(compare key1 key2))))
|
||||
assets)))
|
||||
|
||||
(s/def ::asset-name ::us/not-empty-string)
|
||||
(s/def ::name-group-form
|
||||
(s/keys :req-un [::asset-name]))
|
||||
(def ^:private schema:group-form
|
||||
[:map {:title "GroupForm"}
|
||||
[:name [::sm/text {:max 250}]]])
|
||||
|
||||
(mf/defc name-group-dialog
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :name-group-dialog}
|
||||
[{:keys [path last-path accept] :as ctx
|
||||
:or {path "" last-path ""}}]
|
||||
(let [initial (mf/use-memo
|
||||
(mf/deps last-path)
|
||||
(constantly {:asset-name last-path}))
|
||||
form (fm/use-form :spec ::name-group-form
|
||||
:validators [(fm/validate-not-empty :asset-name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :asset-name fm/max-length-allowed (tr "auth.name.too-long"))]
|
||||
(let [initial (mf/with-memo [last-path]
|
||||
{:asset-name last-path})
|
||||
form (fm/use-form :schema schema:group-form
|
||||
:initial initial)
|
||||
|
||||
create? (empty? path)
|
||||
|
@ -117,7 +113,7 @@
|
|||
(mf/use-fn
|
||||
(mf/deps form)
|
||||
(fn [_]
|
||||
(let [asset-name (get-in @form [:clean-data :asset-name])]
|
||||
(let [asset-name (get-in @form [:clean-data :name])]
|
||||
(if create?
|
||||
(accept asset-name)
|
||||
(accept path asset-name))
|
||||
|
@ -135,7 +131,7 @@
|
|||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:& fm/form {:form form :on-submit on-accept}
|
||||
[:& fm/input {:name :asset-name
|
||||
[:& fm/input {:name :name
|
||||
:class (stl/css :input-wrapper)
|
||||
:auto-focus? true
|
||||
:label (tr "workspace.assets.group-name")
|
||||
|
|
|
@ -8,119 +8,146 @@
|
|||
(:refer-clojure :exclude [uuid])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.spec :as us]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.schema :as sm]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[malli.core :as m]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; --- Handlers Helpers
|
||||
|
||||
(defn- interpret-problem
|
||||
[acc {:keys [path pred via] :as problem}]
|
||||
(cond
|
||||
(and (empty? path)
|
||||
(list? pred)
|
||||
(= (first (last pred)) 'cljs.core/contains?))
|
||||
(let [field (last (last pred))
|
||||
path (conj path field)
|
||||
root (first via)]
|
||||
(assoc-in acc path {:code :missing :type :builtin :root root :field field}))
|
||||
(defn- interpret-schema-problem
|
||||
[acc {:keys [schema in value] :as problem}]
|
||||
(let [props (merge (m/type-properties schema)
|
||||
(m/properties schema))
|
||||
field (or (first in) (:error/field props))]
|
||||
|
||||
(and (seq path) (seq via))
|
||||
(let [field (first path)
|
||||
code (last via)
|
||||
root (first via)]
|
||||
(assoc-in acc path {:code code :type :builtin :root root :field field}))
|
||||
(if (contains? acc field)
|
||||
acc
|
||||
(cond
|
||||
(nil? value)
|
||||
(assoc acc field {:code "errors.field-missing"})
|
||||
|
||||
:else acc))
|
||||
(contains? props :error/code)
|
||||
(assoc acc field {:code (:error/code props)})
|
||||
|
||||
(declare create-form-mutator)
|
||||
(contains? props :error/message)
|
||||
(assoc acc field {:code (:error/message props)})
|
||||
|
||||
(defn use-form
|
||||
[& {:keys [initial] :as opts}]
|
||||
(let [state (mf/useState 0)
|
||||
render (aget state 1)
|
||||
(contains? props :error/fn)
|
||||
(let [v-fn (:error/fn props)
|
||||
code (v-fn problem)]
|
||||
(assoc acc field {:code code}))
|
||||
|
||||
get-state (mf/use-callback
|
||||
(mf/deps initial)
|
||||
(fn []
|
||||
{:data (if (fn? initial) (initial) initial)
|
||||
:errors {}
|
||||
:touched {}}))
|
||||
(contains? props :error/validators)
|
||||
(let [validators (:error/validators props)
|
||||
props (reduce #(%2 %1 value) props validators)]
|
||||
(assoc acc field {:code (d/nilv (:error/code props) "errors.invalid-data")}))
|
||||
|
||||
state-ref (mf/use-ref (get-state))
|
||||
form (mf/use-memo (mf/deps initial) #(create-form-mutator state-ref render get-state opts))]
|
||||
:else
|
||||
(assoc acc field {:code "errors.invalid-data"})))))
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps initial)
|
||||
(defn- use-rerender-fn
|
||||
[]
|
||||
(let [state (mf/useState 0)
|
||||
render-fn (aget state 1)]
|
||||
(mf/use-fn
|
||||
(mf/deps render-fn)
|
||||
(fn []
|
||||
(if (fn? initial)
|
||||
(swap! form update :data merge (initial))
|
||||
(swap! form update :data merge initial))))
|
||||
(render-fn inc)))))
|
||||
|
||||
form))
|
||||
(defn- apply-validators
|
||||
[validators state errors]
|
||||
(reduce (fn [errors validator-fn]
|
||||
(merge errors (validator-fn errors (:data state))))
|
||||
errors
|
||||
validators))
|
||||
|
||||
(defn- wrap-update-fn
|
||||
[f {:keys [spec validators]}]
|
||||
(defn- collect-schema-errors
|
||||
[schema validators state]
|
||||
(let [explain (sm/explain schema (:data state))
|
||||
errors (->> (reduce interpret-schema-problem {} (:errors explain))
|
||||
(apply-validators validators state))]
|
||||
|
||||
(-> (:errors state)
|
||||
(merge errors)
|
||||
(d/without-nils)
|
||||
(not-empty))))
|
||||
|
||||
(defn- wrap-update-schema-fn
|
||||
[f {:keys [schema validators]}]
|
||||
(fn [& args]
|
||||
(let [state (apply f args)
|
||||
cleaned (s/conform spec (:data state))
|
||||
problems (when (= ::s/invalid cleaned)
|
||||
(::s/problems (s/explain-data spec (:data state))))
|
||||
|
||||
errors (reduce interpret-problem {} problems)
|
||||
|
||||
|
||||
errors (reduce (fn [errors vf]
|
||||
(merge errors (vf errors (:data state))))
|
||||
errors
|
||||
validators)
|
||||
errors (merge (:errors state) errors)
|
||||
errors (d/without-nils errors)]
|
||||
|
||||
(let [state (apply f args)
|
||||
cleaned (sm/decode schema (:data state))
|
||||
valid? (sm/validate schema cleaned)
|
||||
errors (when-not valid?
|
||||
(collect-schema-errors schema validators state))]
|
||||
|
||||
(assoc state
|
||||
:errors errors
|
||||
:clean-data (when (not= cleaned ::s/invalid) cleaned)
|
||||
:valid (and (empty? errors)
|
||||
(not= cleaned ::s/invalid))))))
|
||||
:clean-data (when valid? cleaned)
|
||||
:valid (and (not errors) valid?)))))
|
||||
|
||||
(defn- create-form-mutator
|
||||
[state-ref render get-state opts]
|
||||
[internal-state rerender-fn wrap-update-fn initial opts]
|
||||
(reify
|
||||
IDeref
|
||||
(-deref [_]
|
||||
(mf/ref-val state-ref))
|
||||
(mf/ref-val internal-state))
|
||||
|
||||
IReset
|
||||
(-reset! [_ new-value]
|
||||
(if (nil? new-value)
|
||||
(mf/set-ref-val! state-ref (get-state))
|
||||
(mf/set-ref-val! state-ref new-value))
|
||||
(render inc))
|
||||
(mf/set-ref-val! internal-state (if (fn? initial) (initial) initial))
|
||||
(mf/set-ref-val! internal-state new-value))
|
||||
(rerender-fn))
|
||||
|
||||
ISwap
|
||||
(-swap! [_ f]
|
||||
(let [f (wrap-update-fn f opts)]
|
||||
(mf/set-ref-val! state-ref (f (mf/ref-val state-ref)))
|
||||
(render inc)))
|
||||
|
||||
(mf/set-ref-val! internal-state (f (mf/ref-val internal-state)))
|
||||
(rerender-fn)))
|
||||
|
||||
(-swap! [_ f x]
|
||||
(let [f (wrap-update-fn f opts)]
|
||||
(mf/set-ref-val! state-ref (f (mf/ref-val state-ref) x))
|
||||
(render inc)))
|
||||
(mf/set-ref-val! internal-state (f (mf/ref-val internal-state) x))
|
||||
(rerender-fn)))
|
||||
|
||||
(-swap! [_ f x y]
|
||||
(let [f (wrap-update-fn f opts)]
|
||||
(mf/set-ref-val! state-ref (f (mf/ref-val state-ref) x y))
|
||||
(render inc)))
|
||||
(mf/set-ref-val! internal-state (f (mf/ref-val internal-state) x y))
|
||||
(rerender-fn)))
|
||||
|
||||
(-swap! [_ f x y more]
|
||||
(let [f (wrap-update-fn f opts)]
|
||||
(mf/set-ref-val! state-ref (apply f (mf/ref-val state-ref) x y more))
|
||||
(render inc)))))
|
||||
(mf/set-ref-val! internal-state (apply f (mf/ref-val internal-state) x y more))
|
||||
(rerender-fn)))))
|
||||
|
||||
(defn use-form
|
||||
[& {:keys [initial] :as opts}]
|
||||
(let [rerender-fn (use-rerender-fn)
|
||||
|
||||
internal-state
|
||||
(mf/use-ref nil)
|
||||
|
||||
form-mutator
|
||||
(mf/with-memo [initial]
|
||||
(create-form-mutator internal-state rerender-fn wrap-update-schema-fn initial opts))]
|
||||
|
||||
;; Initialize internal state once
|
||||
(mf/with-effect []
|
||||
(mf/set-ref-val! internal-state
|
||||
{:data {}
|
||||
:errors {}
|
||||
:touched {}}))
|
||||
|
||||
(mf/with-effect [initial]
|
||||
(if (fn? initial)
|
||||
(swap! form-mutator update :data merge (initial))
|
||||
(swap! form-mutator update :data merge initial)))
|
||||
|
||||
form-mutator))
|
||||
|
||||
(defn on-input-change
|
||||
([form field value]
|
||||
|
@ -150,8 +177,8 @@
|
|||
(mf/defc field-error
|
||||
[{:keys [form field type]
|
||||
:as props}]
|
||||
(let [{:keys [message] :as error} (get-in form [:errors field])
|
||||
touched? (get-in form [:touched field])
|
||||
(let [{:keys [message] :as error} (dm/get-in form [:errors field])
|
||||
touched? (dm/get-in form [:touched field])
|
||||
show? (and touched? error message
|
||||
(cond
|
||||
(nil? type) true
|
||||
|
@ -164,12 +191,6 @@
|
|||
|
||||
(defn error-class
|
||||
[form field]
|
||||
(when (and (get-in form [:errors field])
|
||||
(get-in form [:touched field]))
|
||||
(when (and (dm/get-in form [:errors field])
|
||||
(dm/get-in form [:touched field]))
|
||||
"invalid"))
|
||||
|
||||
;; --- Form Specs and Conformers
|
||||
|
||||
(s/def ::email ::us/email)
|
||||
(s/def ::not-empty-string ::us/not-empty-string)
|
||||
(s/def ::color ::us/rgb-color-str)
|
||||
|
|
|
@ -76,20 +76,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Die naam moet 'n ander karakter as spasie bevat."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Die naam moet hoogstens 250 karakters bevat."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Tik 'n nuwe wagwoord in"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Die hersteltoken is ongeldig."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -118,10 +110,6 @@ msgstr "Wagwoord"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Ten minste 8 karakters"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Wagwoord moet 'n ander karakter as spasie bevat."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Privaatheidsbeleid"
|
||||
|
||||
|
@ -275,7 +263,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Genereer nuwe token"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Toegangstoken is suksesvol geskep."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -286,10 +274,6 @@ msgstr "Druk die knoppie \"Genereer nuwe token\" om een te genereer."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Jy het tot dusver geen tokens nie."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Die naam word vereis"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 dae"
|
||||
|
|
|
@ -78,7 +78,7 @@ msgid "auth.new-password"
|
|||
msgstr "اكتب كلمة مرور جديدة"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "رمز الاسترداد غير صالح."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -743,11 +743,11 @@ msgstr "يحتوي البريد الإلكتروني «%s» على العديد
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "أدخل بريدًا إلكترونيًا صالحًا من فضلك"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "يجب أن يتطابق البريد الإلكتروني للتأكيد"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2292,10 +2292,6 @@ msgstr "زيادة عدسة التكبير"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "كبر المحدد"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "يجب الا يزيد اسم الويبهوك على 2048 حرفا"
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpotعنوان ملفات لوحة القيادة"
|
||||
|
@ -4307,14 +4303,6 @@ msgstr "الرمز منسوخ"
|
|||
msgid "auth.login-tagline"
|
||||
msgstr "Penpot هو أداة تصميم مجانية ومفتوحة المصدر للتعاون بين التصميم والبرمجة"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "يجب أن يحتوي الاسم على بعض الأحرف غير الفراغات."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "يجب أن يحتوي الاسم على 250 حرفًا كحد أقصى."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.empty.add-one"
|
||||
msgstr "اضغط على الزر \"إنشاء رمز جديد\" لإنشاء واحد."
|
||||
|
@ -4332,5 +4320,5 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "قم بإنشاء رمز جديد"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "تم إنشاء رمز الوصول بنجاح."
|
||||
|
|
|
@ -77,5 +77,5 @@ msgid "auth.new-password"
|
|||
msgstr "নতুন পাসওয়ার্ড টাইপ করুন"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "রিকভারি টোকেন সঠিক নয়।"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "Escriviu una contrasenya nova"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "El codi de recuperació no és vàlid."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -722,7 +722,7 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "El correu «%s» té molts informes de retorn permanents."
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "El correu de confirmació ha de coincidir"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -76,20 +76,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Název musí obsahovat jiný znak než mezeru."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Název musí obsahovat maximálně 250 znaků."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Zadejte nové heslo"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Token pro obnovení je neplatný."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -116,10 +108,6 @@ msgstr "Heslo"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Minimálně 8 znaků"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Heslo musí obsahovat jiný znak než mezeru."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Zásady ochrany osobních údajů"
|
||||
|
||||
|
@ -278,7 +266,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Generovat nový token"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Přístupový token byl úspěšně vytvořen."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -291,10 +279,6 @@ msgstr ""
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Zatím nemáte žádné tokeny."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Jméno je povinné"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 dní"
|
||||
|
@ -865,11 +849,11 @@ msgstr "E-mail «%s» má mnoho trvalých zpráv o nedoručitelnosti."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Zadejte prosím platný email"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Potvrzovací e-mail se musí shodovat"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2974,10 +2958,6 @@ msgstr "Zvětšení zoomu"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Přiblížit na vybrané"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Název webhooku musí obsahovat maximálně 2048 znaků."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "Indtast et nyt kodeord"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Genopretningspoletten er ugyldig."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
|
|
@ -86,32 +86,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Der Name darf keine Leerzeichen enthalten."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Der Name darf höchstens 250 Zeichen lang sein."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Geben Sie ein neues Passwort ein"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Der Wiederherstellungscode ist ungültig."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -141,10 +121,6 @@ msgstr "Passwort"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Mindestens 8 Zeichen"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Das Passwort darf keine Leerzeichen enthalten."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Datenschutzerklärung"
|
||||
|
||||
|
@ -305,7 +281,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Neues Token generieren"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Der Zugangstoken wurde erfolgreich erstellt."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -318,10 +294,6 @@ msgstr ""
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Du hast bisher keine Token."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Der Name ist erforderlich"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 Tage"
|
||||
|
@ -921,11 +893,11 @@ msgstr ""
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Geben Sie bitte eine gültige E-Mail-Adresse ein"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Bestätigungs-E-Mail muss übereinstimmen"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -3099,10 +3071,6 @@ msgstr "Ansicht mit Zoomwerkzeug vergrößern"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zur Auswahl zoomen"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Der Name des Webhooks darf höchstens 2048 Zeichen lang sein."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -77,7 +77,7 @@ msgid "auth.new-password"
|
|||
msgstr "Πληκτρολογήστε έναν νέο κωδικό πρόσβασης."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Ο κωδικός ανάκτησης δεν είναι έγκυρος."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -384,7 +384,7 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "Το email «%s» έχει πολλές μόνιμες αναφορές αναπήδησης."
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Το email επιβεβαίωσης πρέπει να ταιριάζει"
|
||||
|
||||
#: src/app/main/ui/auth/verify_token.cljs,
|
||||
|
|
|
@ -98,19 +98,24 @@ msgid "auth.login-with-oidc-submit"
|
|||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgid "errors.field-not-all-whitespace"
|
||||
msgstr "The name must contain some character other than space."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "The name must contain at most 250 characters."
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/setti ngs/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "errors.field-max-length"
|
||||
msgstr[0] "Must contain at most 1 characters."
|
||||
msgstr[1] "Must contain at most %s characters."
|
||||
|
||||
msgid "errors.field-min-length"
|
||||
msgstr[0] "Must contain at least 1 character."
|
||||
msgstr[1] "Must contain at least %s characters."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Type a new password"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "The recovery token is invalid."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -137,10 +142,6 @@ msgstr "Password"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "At least 8 characters"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Password must contain some character other than space."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Privacy policy"
|
||||
|
||||
|
@ -309,7 +310,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Generate new token"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Access token created successfully."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -320,10 +321,6 @@ msgstr "Press the button \"Generate new token\" to generate one."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "You have no tokens so far."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "The name is required"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 days"
|
||||
|
@ -898,11 +895,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "The email «%s» has many permanent bounce reports."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Enter a valid email please"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Confirmation email must match"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -3131,10 +3128,6 @@ msgstr "Zoom lense increase"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zoom to selected"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "The webhook name must contain at most 2048 characters."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -98,19 +98,24 @@ msgid "auth.login-with-oidc-submit"
|
|||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "El nombre debe contener algún carácter diferente de espacio"
|
||||
msgid "errors.field-not-all-whitespace"
|
||||
msgstr "Debe contener algún carácter diferente de espacio."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "El nombre debe contener como máximo 250 caracteres."
|
||||
msgid "errors.field-max-length"
|
||||
msgstr[0] "Debe contener como máximo 1 caracter."
|
||||
msgstr[1] "Debe contener como máximo %s caracteres."
|
||||
|
||||
msgid "errors.field-min-length"
|
||||
msgstr[0] "Debe contener como mínimo 1 caracter."
|
||||
msgstr[1] "Debe contener como mínimo %s caracteres."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Introduce la nueva contraseña"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "El código de recuperación no es válido."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -139,10 +144,6 @@ msgstr "Contraseña"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "8 caracteres como mínimo"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "La contraseña debe contener algún caracter diferente de espacio"
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Política de privacidad"
|
||||
|
||||
|
@ -315,7 +316,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Generar nuevo token"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Access token creado con éxito."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -326,10 +327,6 @@ msgstr "Pulsa el botón \"Generar nuevo token\" para generar uno."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Todavía no tienes ningún token."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "El nombre es obligatorio"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 días"
|
||||
|
@ -924,11 +921,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "El correo electrónico «%s» tiene varios reportes de rebote permanente."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Por favor, escribe un email válido"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "El correo de confirmación debe coincidir"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -3188,10 +3185,6 @@ msgstr "Incrementar zoom a objetivo"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zoom a selección"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "El nombre del webhook debe contener como máximo 2048 caracteres."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -77,19 +77,20 @@ msgid "auth.login-with-oidc-submit"
|
|||
msgstr "Open ID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgid "errors.field-not-all-whitespace"
|
||||
msgstr "El nombre debe contener algún carácter distinto al del espacio."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "El nombre debe contener como máximo 250 caracteres."
|
||||
msgid "errors.field-max-length"
|
||||
msgstr[0] "El nombre debe contener como máximo 1 caracter."
|
||||
msgstr[1] "El nombre debe contener como máximo %s caracteres."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Escribe una nueva contraseña"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "El token de recuperación no es válido."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -118,10 +119,6 @@ msgstr "Contraseña"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Al menos 8 carácteres"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "La contraseña debe contener algún carácter que no sea espacio."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Política de privacidad"
|
||||
|
||||
|
@ -280,7 +277,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Generar nuevo token"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Token de acceso creado correctamente."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -291,10 +288,6 @@ msgstr "Presione el botón \"Generar nuevo token\" para generar uno."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "No tienes tokens hasta el momento."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "El nombre es requerido"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 días"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "Sartu Pasahitz berria"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Berreskuratzeko kodea ez da zuzena."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -758,11 +758,11 @@ msgstr "«%s» helbideak ez ditu mezuak ondo jasotzen, itzuli egiten ditu."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Mesedez, idatzi eposta helbide zuzen bat"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Egiaztapenereko epostak bat etorri behar du aurrekoarekin"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "یک رمزعبور جدید تایپ کنید"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "توکن بازیابی نامعتبر است."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -728,7 +728,7 @@ msgid "errors.email-as-password"
|
|||
msgstr "شما نمیتوانید از ایمیل خود به عنوان رمزعبور استفاده کنید"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "ایمیل تأیید باید مطابقت داشته باشد"
|
||||
|
||||
#: src/app/main/ui/auth/verify_token.cljs,
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "Syötä uusi salasana"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Palautustunnus on virheellinen."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
|
|
@ -76,20 +76,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Le nom doit contenir au moins un caractère autre que l'espace."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Le nom ne doit pas contenir plus de 250 caractères."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Saisissez un nouveau mot de passe"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Le code de récupération n’est pas valide."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -116,10 +108,6 @@ msgstr "Mot de passe"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Au moins 8 caractères"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Le mot de passe doit contenir au moins un caractère autre que l'espace."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Politique de confidentialité"
|
||||
|
||||
|
@ -271,7 +259,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Générer un nouveau jeton"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Jeton d'accès créé avec succès."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -282,10 +270,6 @@ msgstr "Pressez le bouton \"Générer un nouveau jeton\" pour en générer un."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Vous n'avez pas encore de jeton."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Le nom est requis"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 jours"
|
||||
|
@ -874,11 +858,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "L'adresse e-mail « %s » a un taux de rebond trop élevé."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Veuillez entrer une adresse mail valide"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "L’adresse e‑mail de confirmation doit correspondre"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2930,10 +2914,6 @@ msgstr "Augmenter le zoom"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zoomer sur la sélection"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Le nom du webhook ne peut pas contenir plus de 2048 caractères."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "Escribe un contrasinal novo"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "O código de recuperación non é correcto."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
|
|
@ -76,20 +76,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "shaidar buxewa"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "dole suna ya qumshi waxansu alamimon rubutu, sannan tazara."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "suna dole ya qunshi alamomin rubutu 250."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "sanya sabuwar lambar tsaro"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "lambar tsaron da ka sanya ba daidai ba ce."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -252,7 +244,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "samo sabuwar lambar tsaro"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "ka sami lambar tsaron da aka yi."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -265,10 +257,6 @@ msgstr ""
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "ba ka da wasu lambobin tsaro yanzu."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "ana buqatar suna"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "kwanaki 180"
|
||||
|
@ -819,11 +807,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "imel «%s» na da bayanan matsaloli na dindindin."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "sanya imel mai amfani"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "tabbata imel xinka ya yi daidai"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2790,10 +2778,6 @@ msgstr "Zuko karuwar ido"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zuko wanda aka zaba"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Sunan shafin yanar gizon zai kunshi a mafi yawa haruffa 2048."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Tukunyar aje biro"
|
||||
|
|
|
@ -83,32 +83,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID Connect"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "השם חייב להכיל תווים שאינם רווחים."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "השם חייב להכיל 250 תווים לכל היותר."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "נא להקליד סיסמה חדשה"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "אסימון השחזור שגוי."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -135,10 +115,6 @@ msgstr "סיסמה"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "8 תווים לפחות"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "הסיסמה חייבת להכיל תווים שאינם רווחים."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "מדיניות פרטיות"
|
||||
|
||||
|
@ -293,7 +269,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "יצירת אסימון חדש"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "אסימון הגישה נוצר בהצלחה."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -304,10 +280,6 @@ msgstr "נא ללחוץ על הכפתור „יצירת אסימון חדש”
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "אין לך אסימונים עדיין."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "השם הוא בגדר חובה"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 יום"
|
||||
|
@ -889,11 +861,11 @@ msgstr "לכתובת הדוא״ל „%s” יש יותר מדי דוחות הח
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "נא למלא כתובת דוא״ל תקפה בבקשה"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "כתובת הדוא״ל לאימות חייבת להיות תואמת"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -3009,10 +2981,6 @@ msgstr "הגדלת עדשת תקריב"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "התמקדות על הנבחר"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "אורך שם ההתליה הוא עד 2048 תווים."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -80,7 +80,7 @@ msgid "auth.new-password"
|
|||
msgstr "Unesi novu lozinku"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Token za oporavak je nevažeći."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -715,7 +715,7 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "E-pmail «%s» ima mnogo trajnih izvješća o odbijanju."
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "E-mail za potvrdu mora odgovarati"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -76,32 +76,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID Connect"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Nama harus berisi beberapa karakter selain spasi."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Nama harus berisi setidaknya 250 karakter."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Ketik kata sandi baru"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Token pemulihan tidak sah."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -129,10 +109,6 @@ msgstr "Kata sandi"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Setidaknya 8 karakter"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Kata sandi harus berisi beberapa karakter selain spasi."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Kebijakan privasi"
|
||||
|
||||
|
@ -291,7 +267,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Buat token baru"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Token akses berhasil dibuat."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -302,10 +278,6 @@ msgstr "Tekan tombol \"Buat token baru\" untuk membuat token."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Anda belum memiliki token."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Nama diperlukan"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 hari"
|
||||
|
@ -878,11 +850,11 @@ msgstr "Surel “%s” memiliki banyak laporan lompatan permanen."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Silakan menyediakan surel yang valid"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Surel konfirmasi harus cocok"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2964,10 +2936,6 @@ msgstr "Tambahkan lensa zum"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zum ke terpilih"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Nama webhook berisi sampai 2048 karakter."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -70,20 +70,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "Mepe ID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Aha ga-enweriri ụfọdụ mkpụrụ edemede karịa oghere ."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Aha ga-enweriri ọ karịa mkpụrụ okwu narị abụọ na iri ise"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Pinye akara mpịbanye ọhụrụ"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Ọdịmara e nweghachitere adabaghị ."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -106,10 +98,6 @@ msgstr "Sonyere n'otu nke ọma"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Ọ karịa mkpụrụ ederede asatọ"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Akara mpịbanye ga-enweriri ụfọdụ leta/akara mpị karịa oghere ."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Iwu oñiño onwe"
|
||||
|
||||
|
@ -245,17 +233,13 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Mepụta ọdịmara ọhụrụ"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Mmepụtara ọdịmara nnweta gara nke ọma ."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.empty.add-one"
|
||||
msgstr "Pịa mpi \"Nweta ọdịmara ọhụrụ \" inweta otu ."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "A chọrọ aha"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "Mkpụrụ ụbọchị narị na iri asatọ"
|
||||
|
@ -724,11 +708,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "Ozi-n «%s» nwere ọtụtụ ozi nkọwa mbịaghachigide."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Debanye aha ozi-n dabara adaba"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Ozi-n nnabata ga-adabrịrị"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "Inserisci una nuova password"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Il codice di recupero non è valido."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -706,7 +706,7 @@ msgid "errors.email-as-password"
|
|||
msgstr "Non è possibile utilizzare il tuo indirizzo e-mail come password"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "L'indirizzo e-mail di conferma deve corrispondere"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -77,7 +77,7 @@ msgid "auth.new-password"
|
|||
msgstr "新しいパスワードを入力"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "リカバリコードが無効です。"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -519,7 +519,7 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "メールアドレス «%s» には多くの受信失敗レポートがあります。"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "メールアドレスは同じものを入力する必要があります"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -683,7 +683,7 @@ msgstr "데모 서비스입니다. 실제 작업에 사용하지 마십시오.
|
|||
"주기적으로 삭제될 것입니다."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "복구 토큰이 유효하지 않습니다."
|
||||
|
||||
msgid "common.share-link.destroy-link"
|
||||
|
@ -717,14 +717,6 @@ msgstr "개인용 엑세스 토큰"
|
|||
msgid "dashboard.access-tokens.expired-on"
|
||||
msgstr "%s에 만료되었습니다"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "이름은 최대 250자까지만 입력 가능합니다."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "이름을 입력하십시오"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.copied-success"
|
||||
msgstr "복사된 토큰"
|
||||
|
@ -754,8 +746,10 @@ msgid "auth.login-tagline"
|
|||
msgstr "펜팟은 디자인과 코딩의 협업을 위한 무료 오픈소스 디자인 도구입니다"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "비밀번호는 공백 이외의 글자를 포함해야 합니다."
|
||||
#, markdown
|
||||
msgid "auth.terms-privacy-agreement-md"
|
||||
msgstr "새로운 계정을 생성하시면, 사용자는 펜팟의 [서비스 정책](%s)과 [개인 정보 "
|
||||
"정책](%s)에 동의하는 것으로 간주됩니다."
|
||||
|
||||
#: src/app/main/ui/dashboard/projects.cljs
|
||||
msgid "dasboard.team-hero.text"
|
||||
|
@ -774,16 +768,12 @@ msgstr "실습용 튜토리얼"
|
|||
msgid "auth.login-account-title"
|
||||
msgstr "내 계정에 로그인하기"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "이름은 공백 이외의 글자를 포함해야 합니다."
|
||||
|
||||
#: src/app/main/ui/dashboard/projects.cljs
|
||||
msgid "dasboard.tutorial-hero.info"
|
||||
msgstr "본 실습용 튜토리얼을 통해 펜팟의 기본 기능에 대하여 재미있게 학습하십시오."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "엑세스 토큰이 성공적으로 생성되었습니다."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
|
|
@ -83,7 +83,7 @@ msgstr "Įveskite naują slaptažodį"
|
|||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
#, fuzzy
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Atkūrimo prieigos raktas neteisingas."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
|
|
@ -85,20 +85,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "AtvērtoID (OpenID)"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Nosaukumam jāsatur simboli, kas nav atstarpe."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Nosaukumus nedrīkst pārsniegt 250 simbolus."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Ierakstiet jaunu paroli"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Atkopšanas tekstvienība nav derīga."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -127,10 +119,6 @@ msgstr "Parole"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Vismaz 8 rakstzīmes"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Parolē ir jābūt arī citām rakstzīmēm bez atstarpes."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Privātuma politika"
|
||||
|
||||
|
@ -287,7 +275,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Izveidot jaunu pilnvaru"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Piekļuves pilnvara ir veiksmīgi izveidota."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -298,10 +286,6 @@ msgstr "Jānospiež poga \"Izveidot jaunu pilnvaru\", lai izveidotu kādu."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Pagaidām vēl nav pilnvaru."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Nosaukums ir obligāts"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 dienas"
|
||||
|
@ -890,11 +874,11 @@ msgstr "E-pastam “%s” ir daudz pastāvīgu atlēcienu atskaišu."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Lūgums ievadīt derīgu e-pasta adresi"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Apstiprinājuma e-pastam jāatbilst"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -3062,10 +3046,6 @@ msgstr "Tālummaiņas palielinājums"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Tālummainīt uz atlasi"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Tīmekļa aizķeres nosaukumā drīkst būt ne vairāk kā 2048 rakstzīmes."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "പുതിയൊരു പാസ്വേഡ് ചേർക്കുക"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "റിക്കവറി ടോക്കൺ അസാധുവാണ്."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
|
|
@ -62,20 +62,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID Connect"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Nama mesti mengandungi beberapa aksara selain ruang."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Nama mesti mengandungi paling banyak 250 aksara."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Taip kata laluan baharu"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Token pemulihan adalah tidak sah."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -102,10 +94,6 @@ msgstr "Kata laluan"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Sekurang-kurangnya 8 aksara"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Kata laluan mesti mengandungi beberapa aksara selain daripada ruang."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Dasar privasi"
|
||||
|
||||
|
@ -263,7 +251,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Jana token baru"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Token capaian berjaya dihasilkan."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -274,10 +262,6 @@ msgstr "Tekan butang \"Jana token baharu\" untuk menjana token."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Anda tidak mempunyai token setakat ini."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Nama diperlukan"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 hari"
|
||||
|
@ -840,11 +824,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "E-mel «%s» mempunyai banyak laporan lantunan kekal."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Sila masukkan e-mel yang sah"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "E-mel pengesahan mesti sepadan"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -28,7 +28,7 @@ msgid "auth.new-password"
|
|||
msgstr "Skriv inn et nytt passord"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Gjenopprettelsessymbolet er ugyldig."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs
|
||||
|
|
|
@ -86,32 +86,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "De naam mag geen spatie bevatten."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "De naam mag maximaal 250 tekens bevatten."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Typ een nieuw wachtwoord"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "De herstelbewijsstuk is ongeldig."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -138,10 +118,6 @@ msgstr "Wachtwoord"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Minimaal 8 tekens"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Het wachtwoord mag geen spatie bevatten."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Privacybeleid"
|
||||
|
||||
|
@ -301,7 +277,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Nieuw toegangsbewijs aanmaken"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Toegangsbewijs is succesvol aangemaakt."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -312,10 +288,6 @@ msgstr "Klik op de knop \"Nieuw toegangsbewijs aanmaken\" om er een aan te maken
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Je hebt nog geen toegangsbewijzen."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "De naam is verplicht"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 dagen"
|
||||
|
@ -909,11 +881,11 @@ msgstr "Het emailadres «%s» heeft veel permanente bounce-rapporten."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Voer een geldig e-mailadres in"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Bevestigingsmail moet overeenkomen"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -3056,10 +3028,6 @@ msgstr "Zoomlens vergroten"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zoomen naar selectie"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "De webhooknaam mag maximaal 2048 tekens bevatten."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -82,7 +82,7 @@ msgid "auth.new-password"
|
|||
msgstr "Wpisz nowe hasło"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Token odzyskiwania jest nieprawidłowy."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -732,11 +732,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "Email «%s» zawiera wiele stałych raportów o odrzuceniu."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Podaj prawidłowy adres e-mail"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "E-mail potwierdzający musi być zgodny"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "Digite uma nova senha"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "O código de recuperação é inválido."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -731,11 +731,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "O e-mail «%s» tem muitos relatórios de devolução permanentes."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Por favor, insira um email válido"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "E-mail de confirmação deve ser o mesmo"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -76,32 +76,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID Connect"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "O nome deve conter pelo menos um caractere que não seja um espaço."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "O nome deve conter um máximo de 250 caracteres."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Escreve uma nova palavra-passe"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "O token de recuperação é inválido."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -128,11 +108,6 @@ msgstr "Palavra-passe"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Mínimo de 8 caracteres"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr ""
|
||||
"A palavra-passe deve conter pelo menos um caractere que não seja um espaço."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Política de privacidade"
|
||||
|
||||
|
@ -291,7 +266,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Gerar novo token"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Token de acesso criado com sucesso."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -302,10 +277,6 @@ msgstr "Clica no botão \"Gerar novo token\" para gerar um."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Ainda não tens nenhum token."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "O nome é obrigatório"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 dias"
|
||||
|
@ -887,11 +858,11 @@ msgstr "O e-mail «%s» tem muitos relatórios de rejeição permanentes."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Por favor introduz um email válido"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "O e-mail de confirmação deve combinar"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2989,10 +2960,6 @@ msgstr "Aumentar zoom na lupa"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Zoom para selecionados"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "O nome do webhook deve conter um máximo de 2048 caracteres."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -77,20 +77,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "Numele trebuie să conțină un caracter altul decât spațiu."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "Numele trebuie să conțină cel mult 250 caractere."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Introduceți o parolă nouă"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Codul de recuperare nu este valid."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -119,10 +111,6 @@ msgstr "Parola"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "Cel puțin 8 caractere"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Parola trebuie să conțină un caracter altul decât spațiu."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Politica de Confidențialitate"
|
||||
|
||||
|
@ -277,7 +265,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Generați jeton nou"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Jeton de acces creat cu succes."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -288,10 +276,6 @@ msgstr "Apăsați butonul 'Generați jeton nou' pentru a genera unul."
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Nu aveți încă jetoane."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "Numele este obligatoriu"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 zile"
|
||||
|
@ -872,11 +856,11 @@ msgstr "Adresa de email «%s» are multe rapoarte permanente de respingere."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Vă rugăm să introduceți un e-mail valid"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "E-mailul de confirmare trebuie să se potrivească"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2893,10 +2877,6 @@ msgstr "Creștere obiectiv de zoom"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Mărește la selecție"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Numele webhook-ului trebuie să conțină maxim 2048 caractere."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -79,7 +79,7 @@ msgid "auth.new-password"
|
|||
msgstr "Введите новый пароль"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Неверный код восстановления."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -745,7 +745,7 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "Эл. почта «%s» постоянно недоступна."
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Эл. почта для подтверждения должна совпадать"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
|
|
@ -81,7 +81,7 @@ msgid "auth.new-password"
|
|||
msgstr "புதிய கடவுச்சொல்லை உள்ளிடவும்"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "மீட்பு டோக்கன் செல்லுபடியாகாது."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
|
|
@ -86,20 +86,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "İsim boşluk dışında bir karakter içermelidir."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "İsim en fazla 250 karakter içermelidir."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "Yeni bir parola gir"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Kurtarma jetonu geçerli değil."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -126,10 +118,6 @@ msgstr "Parola"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "En az 8 karakter"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "Parola boşluk dışında bir karakter içermelidir."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "Gizlilik politikası"
|
||||
|
||||
|
@ -289,7 +277,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "Yeni belirteç oluştur"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "Erişim belirteci başarıyla oluşturuldu."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -300,10 +288,6 @@ msgstr "Bir belirteç oluşturmak için \"Yeni belirteç oluştur\" düğmesine
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "Şu ana kadar hiç belirteciniz yok."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "İsim gereklidir"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180 gün"
|
||||
|
@ -895,11 +879,11 @@ msgstr "«%s» adresi için çok fazla geri dönme raporu var."
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Lütfen geçerli bir e-posta adresi girin"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Doğrulama e-postası eşleşmiyor"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -3048,10 +3032,6 @@ msgstr "Görüntüyü büyült"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Seçilene yakınlaştır"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Webhook adı en fazla 2048 karakter içermelidir."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -58,7 +58,7 @@ msgid "auth.new-password"
|
|||
msgstr "Введіть новий пароль"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "Невірний код відновлення."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
|
|
@ -72,16 +72,12 @@ msgstr "LDAP"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "ṣílẹ̀kuǹ ìdánimọ̀"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "orúkọ kò gbọdọ̀ ju àádọ́jọ́ lẹ́tà lọ."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "tẹ ọ̀rọ̀ ìgbaniwọlé tuntun"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "àmì àtúnwárí ti díbàjẹ́."
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -110,10 +106,6 @@ msgstr "ọ̀rọ̀- ìgbaniwọlé"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "kò gbọdọ̀ ju ohun kíkọ mẹ́jọ lọ"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "ọ̀rọ̀-ìgbaniwọlé gbọ́dọ̀ ní nǹkan kíkọ láìsí àlàfo."
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "ìpamọ ètò ìmúló"
|
||||
|
||||
|
@ -252,7 +244,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "ṣe ìpilẹ̀sẹ̀ àmì tókìnnì"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "ṣe àyẹ̀wò àmì tókìnnì tí o ṣẹ̀dá bó ṣeyẹ."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -263,10 +255,6 @@ msgstr "tẹ bọ́tìnnì \" ṣe ìpilẹ̀sẹ̀ àmì tókìnnì tuntun\" l
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "o kò tí ì ní àmì tókínnì títí di ìsinsìn yìí."
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "a nílò orúkọ"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "ọgọ́saǹ-ań ọjọ́"
|
||||
|
@ -793,11 +781,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "Ímeèlì «%s» ti ní ìjábọ̀ ọ̀pọ̀ọlọpọ̀ ìta-bọn-ọ̀n ti pẹ́."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "Tẹ àti wọlé pẹ̀lú ímeèlì tó wúlo jọ̀wọ́"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "Ímeèlì tí a ti mọ̀dájú gbọ́dọ̀ báramu"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2643,10 +2631,6 @@ msgstr "Lílọ̀soké lẹnsi sisun"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "Yiyan pelu sun-un"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Orúkọ̀ webhook kò gbọ́dọ̀ kọjà awọ́n óhun kíkọ́ 2048."
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -72,32 +72,12 @@ msgstr "LDAP登录"
|
|||
msgid "auth.login-with-oidc-submit"
|
||||
msgstr "OpenID登录"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "姓名必须包含一些空格以外的字符。"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/dashboard/team_form.cljs,
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs,
|
||||
#: src/app/main/ui/settings/access_tokens.cljs,
|
||||
#: src/app/main/ui/settings/feedback.cljs,
|
||||
#: src/app/main/ui/settings/profile.cljs,
|
||||
#: src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "姓名最多包含250个字符。"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.new-password"
|
||||
msgstr "输入新的密码"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "恢复令牌无效。"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -124,10 +104,6 @@ msgstr "密码"
|
|||
msgid "auth.password-length-hint"
|
||||
msgstr "至少8位字符"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "密码必须包含一些空格以外的字符。"
|
||||
|
||||
msgid "auth.privacy-policy"
|
||||
msgstr "隐私政策"
|
||||
|
||||
|
@ -279,7 +255,7 @@ msgid "dashboard.access-tokens.create"
|
|||
msgstr "生成新令牌"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "成功创建访问令牌。"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -290,10 +266,6 @@ msgstr "点击“生成新令牌”按钮来生成一个。"
|
|||
msgid "dashboard.access-tokens.empty.no-access-tokens"
|
||||
msgstr "你目前还没有令牌。"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "名称是必填项"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-180-days"
|
||||
msgstr "180天"
|
||||
|
@ -850,11 +822,11 @@ msgstr "电子邮件“%s”收到了非常多的永久退信报告。"
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "请输入有效的电子邮件"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "确认电子邮件必须保持一致"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2877,10 +2849,6 @@ msgstr "变焦镜头放大"
|
|||
msgid "shortcuts.zoom-selected"
|
||||
msgstr "缩放到选定对象"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "team.webhooks.max-length"
|
||||
msgstr "Webhook的名称最多包含2048个字符。"
|
||||
|
||||
#: src/app/main/ui/dashboard/files.cljs
|
||||
msgid "title.dashboard.files"
|
||||
msgstr "%s - Penpot"
|
||||
|
|
|
@ -77,7 +77,7 @@ msgid "auth.new-password"
|
|||
msgstr "輸入新密碼"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
msgid "auth.notifications.invalid-token-error"
|
||||
msgid "errors.invalid-recovery-token"
|
||||
msgstr "此 Recovery token 是無效的。"
|
||||
|
||||
#: src/app/main/ui/auth/recovery.cljs
|
||||
|
@ -684,11 +684,11 @@ msgid "errors.email-has-permanent-bounces"
|
|||
msgstr "電子郵件«%s»有許多永久退件報告。"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/login.cljs, src/app/main/ui/auth/recovery_request.cljs
|
||||
msgid "errors.email-invalid"
|
||||
msgid "errors.invalid-email"
|
||||
msgstr "請輸入一個有效的電郵地址"
|
||||
|
||||
#: src/app/main/ui/settings/change_email.cljs
|
||||
msgid "errors.email-invalid-confirmation"
|
||||
msgid "errors.invalid-email-confirmation"
|
||||
msgstr "電郵地址必須相同"
|
||||
|
||||
msgid "errors.email-spam-or-permanent-bounces"
|
||||
|
@ -2343,7 +2343,7 @@ msgid "dashboard.access-tokens.empty.add-one"
|
|||
msgstr "按下\"產生新 Token\" 按鈕來產生一個。"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.create.success"
|
||||
msgid "dashboard.access-tokens.create-success"
|
||||
msgstr "已成功建立 Access Token。"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
|
@ -2354,10 +2354,6 @@ msgstr "沒有到期時間"
|
|||
msgid "dashboard.access-tokens.copied-success"
|
||||
msgstr "已複製 Token"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.errors-required-name"
|
||||
msgstr "名稱是必填的"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.token-will-expire"
|
||||
msgstr "權杖將於 %s 到期"
|
||||
|
@ -2365,14 +2361,6 @@ msgstr "權杖將於 %s 到期"
|
|||
msgid "dashboard.export.options.merge.title"
|
||||
msgstr "將共享資料庫的內容加入檔案資料庫"
|
||||
|
||||
#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.not-all-space"
|
||||
msgstr "名稱內必須包含空白以外的文字。"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
|
||||
msgid "auth.name.too-long"
|
||||
msgstr "名稱最多包含 250 個字元。"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.expiration-90-days"
|
||||
msgstr "90 天"
|
||||
|
@ -2408,10 +2396,6 @@ msgstr "Penpot 是用於設計與開發協作,免費且開源的設計工具"
|
|||
msgid "branding-illustrations-marketing-pieces"
|
||||
msgstr "...品牌設計、插畫、行銷素材等。"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.password-not-empty"
|
||||
msgstr "密碼必須包含空白以外的字元。"
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "dashboard.access-tokens.personal"
|
||||
msgstr "個人存取權杖"
|
||||
|
|
Loading…
Add table
Reference in a new issue