♻️ Extract token value validation to source resolve function

This commit is contained in:
Xavier Julian 2026-04-23 12:35:53 +02:00
parent 9067dd3d04
commit a21b6198c3
4 changed files with 32 additions and 30 deletions

View File

@ -29,7 +29,6 @@
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[app.util.object :as obj] [app.util.object :as obj]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
[cljs.pprint :as pp]
[cuerdas.core :as str] [cuerdas.core :as str]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -39,6 +38,10 @@
(and (string? token-name) (and (string? token-name)
(re-matches cto/token-name-validation-regex token-name)) (re-matches cto/token-name-validation-regex token-name))
valid-token-ref?
(or (str/blank? value)
(re-matches cto/token-ref-validation-regex value))
token token
{:value value {:value value
:name (if (or (not valid-token-name?) (str/blank? token-name)) :name (if (or (not valid-token-name?) (str/blank? token-name))
@ -50,18 +53,21 @@
(dissoc (:name prev-token)) (dissoc (:name prev-token))
(update (:name token) #(ctob/make-token (merge % prev-token token))))] (update (:name token) #(ctob/make-token (merge % prev-token token))))]
(->> (if (contains? cf/flags :tokenscript) (if-not valid-token-ref?
(rx/of (ts/resolve-tokens tokens)) (rx/of {:error {:error/fn #(str (tr "workspace.tokens.invalid-value" %))
(sd/resolve-tokens-interactive tokens)) :error/value value}})
(rx/mapcat (->> (if (contains? cf/flags :tokenscript)
(fn [resolved-tokens] (rx/of (ts/resolve-tokens tokens))
(let [{:keys [errors resolved-value] :as resolved-token} (get resolved-tokens (:name token)) (sd/resolve-tokens-interactive tokens))
resolved-value (if (contains? cf/flags :tokenscript) (rx/mapcat
(ts/tokenscript-symbols->penpot-unit resolved-value) (fn [resolved-tokens]
resolved-value)] (let [{:keys [errors resolved-value] :as resolved-token} (get resolved-tokens (:name token))
(if resolved-value resolved-value (if (contains? cf/flags :tokenscript)
(rx/of {:value resolved-value}) (ts/tokenscript-symbols->penpot-unit resolved-value)
(rx/of {:error (first errors)})))))))) resolved-value)]
(if resolved-value
(rx/of {:value resolved-value})
(rx/of {:error (first errors)})))))))))
(mf/defc value-combobox* (mf/defc value-combobox*
[{:keys [name tokens token token-type empty-to-end ref] :rest props}] [{:keys [name tokens token token-type empty-to-end ref] :rest props}]
@ -106,7 +112,6 @@
(mf/with-memo [raw-tokens-by-type token-type] (mf/with-memo [raw-tokens-by-type token-type]
(csu/filter-tokens-for-input raw-tokens-by-type token-type)) (csu/filter-tokens-for-input raw-tokens-by-type token-type))
visible-options visible-options
(mf/with-memo [filtered-tokens-by-type token] (mf/with-memo [filtered-tokens-by-type token]
(if token (if token
@ -280,21 +285,15 @@
(fn [error] (fn [error]
((:error/fn error) (:error/value error)))))) ((:error/fn error) (:error/value error))))))
(rx/subs! (fn [{:keys [error value]}] (rx/subs! (fn [{:keys [error value]}]
(let [touched? (get-in @form [:touched name]) (let [touched? (get-in @form [:touched name])]
current-value (get-in @form [:data name] "")
valid-ref? (re-matches cto/token-ref-validation-regex current-value)]
(when touched? (when touched?
(if error (if error
(do (do
(swap! form assoc-in [:extra-errors name] {:message error}) (swap! form assoc-in [:extra-errors name] {:message error})
(reset! hint* {:message error :type "error"})) (reset! hint* {:message error :type "error"}))
(if (and (not (str/blank? current-value)) (not valid-ref?)) (let [message (tr "workspace.tokens.resolved-value" value)]
(let [message (tr "workspace.tokens.invalid-value" (str current-value))] (swap! form update :extra-errors dissoc name)
(swap! form assoc-in [:extra-errors name] {:message message}) (reset! hint* {:message message :type "hint"}))))))))]
(reset! hint* {:message message :type "error"}))
(let [message (tr "workspace.tokens.resolved-value" value)]
(swap! form update :extra-errors dissoc name)
(reset! hint* {:message message :type "hint"})))))))))]
(fn [] (fn []
(rx/dispose! subs)))) (rx/dispose! subs))))

View File

@ -35,11 +35,16 @@
(mf/with-memo [token-path tokens-in-selected-set] (mf/with-memo [token-path tokens-in-selected-set]
(-> (ctob/tokens-tree tokens-in-selected-set) (-> (ctob/tokens-tree tokens-in-selected-set)
(d/dissoc-in token-path))) (d/dissoc-in token-path)))
props props
(mf/spread-props props {:token-type token-type (if (contains? cf/flags :token-combobox)
:tokens-tree-in-selected-set tokens-tree-in-selected-set (mf/spread-props props {:token-type token-type
:token token :tokens-tree-in-selected-set tokens-tree-in-selected-set
:input-component token.controls/value-combobox*}) :token token
:input-component token.controls/value-combobox*})
(mf/spread-props props {:token-type token-type
:tokens-tree-in-selected-set tokens-tree-in-selected-set
:token token}))
text-case-props (if (contains? cf/flags :token-combobox) text-case-props (if (contains? cf/flags :token-combobox)
(mf/spread-props props {:input-value-placeholder (tr "workspace.tokens.text-case-value-enter") (mf/spread-props props {:input-value-placeholder (tr "workspace.tokens.text-case-value-enter")
:input-component token.controls/value-combobox*}) :input-component token.controls/value-combobox*})

View File

@ -69,7 +69,6 @@
(let [make-schema (or make-schema #(-> (cfo/make-token-schema % token-type) (let [make-schema (or make-schema #(-> (cfo/make-token-schema % token-type)
(sm/dissoc-key :id))) (sm/dissoc-key :id)))
input-component (or input-component token.controls/input*) input-component (or input-component token.controls/input*)
_ (prn "Rendering generic form with input-component:" input-component)
validate-token (or validator default-validate-token) validate-token (or validator default-validate-token)
active-tab* (mf/use-state #(if (cfo/is-reference? token) :reference :composite)) active-tab* (mf/use-state #(if (cfo/is-reference? token) :reference :composite))

View File

@ -11,7 +11,6 @@
padding-block-end: var(--sp-s); padding-block-end: var(--sp-s);
display: flex; display: flex;
gap: var(--sp-s);
flex-wrap: wrap; flex-wrap: wrap;
padding-inline-start: calc(var(--node-spacing)); padding-inline-start: calc(var(--node-spacing));