Minor refactoring to simplify consumer. May be better to use macro.

This commit is contained in:
2022-07-20 06:27:21 -07:00
parent 9b5b7bef53
commit 86aaa4a933
5 changed files with 119 additions and 131 deletions

View File

@@ -30,13 +30,15 @@
([db form data]
(start-form db form data nil))
([db form data complete-listener]
(assoc-in db [::forms form] {:error nil
:active? true
:id (random-uuid)
:visited #{}
:status nil
:data data
:complete-listener complete-listener})))
(-> db
(assoc-in [::forms form] {:error nil
:active? true
:id (random-uuid)
:visited #{}
:status nil
:data data
:complete-listener complete-listener})
(assoc-in [::status/status form] nil))))
(defn triggers-saved [form data-key]
(i/->interceptor

View File

@@ -34,13 +34,20 @@
(get-in field-path)
first))
(defn consume [consumer-component fields f]
[:> consumer-component {}
(fn [consumed]
(r/as-element
(apply f (for [field fields]
(aget consumed field)))))])
(defn builder [{:keys [value on-change can-submit data-sub error-messages change-event submit-event id fullwidth? schema validation-error-string]}]
(when (and change-event on-change)
(throw "Either the form is to be managed by ::forms, or it should have value and on-change passed in"))
(let [data-sub (or data-sub [::forms/form id])
change-event (when-not on-change
(or change-event [::forms/change id]))
{:keys [data error visited attempted-submit?] form-key :id} @(re-frame/subscribe data-sub)
{:keys [data visited attempted-submit?] form-key :id} @(re-frame/subscribe data-sub)
data (or value data)
status @(re-frame/subscribe [::status/single id])
can-submit (if can-submit @(re-frame/subscribe can-submit)
@@ -57,7 +64,7 @@
:submit-event submit-event
:problems problems
:attempted-submit? attempted-submit?
:error error
:error (-> status :error first :message)
:status status
:id id
:data data
@@ -144,75 +151,71 @@
(conj path))))
(defn raw-error-v2 [{:keys [field]}]
[:> Consumer {}
(fn [consume-form]
(r/as-element
[:> FormScopeConsumer {}
(fn [form-scope]
(r/as-element
(let [full-field-path (cond
(sequential? field)
(into form-scope field)
(consume Consumer
["visited" "attempted-submit?" "problems" "error-messages"]
(fn [visited attempted-submit? problems error-messages]
(consume FormScopeConsumer
["form-scope"]
(fn [form-scope]
(let [full-field-path (cond
(sequential? field)
(into form-scope field)
field
(conj form-scope field)
field
(conj form-scope field)
:else
nil)
visited? (get (aget consume-form "visited") full-field-path)
attempted-submit? (aget consume-form "attempted-submit?")]
(when-let [error-message (and
(or visited? attempted-submit?)
(spec-error-message (aget consume-form "problems") full-field-path (aget consume-form "error-messages")))]
[:div
[:p.help.has-text-danger error-message]]))))]))])
:else
nil)
visited? (get visited full-field-path)]
(when-let [error-message (and
(or visited? attempted-submit?)
(spec-error-message problems full-field-path error-messages))]
[:div
[:p.help.has-text-danger error-message]])))))))
(defn raw-field-v2 [{:keys [field] :as props}]
(when-not field
(throw (ex-info (str "Missing field") (clj->js {:props props}))))
(let [[child] (r/children (r/current-component))]
[:> Consumer {}
(fn [consume-form]
(r/as-element
[:> FormScopeConsumer {}
(fn [form-scope]
(r/as-element
(update child 1 (fn [child-props]
(let [
full-field-path (cond
(sequential? field)
(into form-scope field)
(consume Consumer
["visited" "attempted-submit?" "data" "on-change" "change-event" "blur-event" "problems"]
(fn [visited attempted-submit? data on-change change-event blur-event problems]
(consume FormScopeConsumer
["form-scope"]
(fn [form-scope]
(update child 1 (fn [child-props]
(let [
full-field-path (cond
(sequential? field)
(into form-scope field)
field
(conj form-scope field)
:else
nil)
visited? (get (aget consume-form "visited") full-field-path)
attempted-submit? (aget consume-form "attempted-submit?")
value (get-in (aget consume-form "data") full-field-path)
on-change (aget consume-form "on-change")]
(-> child-props
(assoc :on-change
(if on-change
(partial form-change-handler (aget consume-form "data") full-field-path (aget consume-form "on-change"))
(partial change-handler full-field-path (aget consume-form "change-event")))
:on-blur (partial blur-handler full-field-path (aget consume-form "blur-event"))
:value value)
(update :class (fn [class]
(str class
(cond
(and (not visited?) (not attempted-submit?))
""
(not (valid-field? (aget consume-form "problems") full-field-path))
" is-danger"
value
"is-success"
field
(conj form-scope field)
:else
""))))))))))]))]))
nil)
visited? (get visited full-field-path)
value (get-in data full-field-path)]
(-> child-props
(assoc :on-change
(if on-change
(partial form-change-handler data full-field-path on-change)
(partial change-handler full-field-path change-event))
:on-blur (partial blur-handler full-field-path blur-event)
:value value)
(update :class (fn [class]
(str class
(cond
(and (not visited?) (not attempted-submit?))
""
(not (valid-field? problems full-field-path))
" is-danger"
value
"is-success"
:else
""))))))))))))))
(defn with-scope [{:keys [scope]}]
(r/create-element FormScopeProvider #js {:value scope}
(r/as-element (into [:<>]
@@ -220,17 +223,17 @@
(defn vertical-control [{:keys [is-small? required?]}]
(let [[label & children] (r/children (r/current-component))]
[:> Consumer {}
(fn [consume]
(r/as-element
[:div.field
(if (aget consume "fullwidth?")
[:p.help label]
[:label.label
(if required?
[:span label [:span.has-text-danger " *"]]
label)])
(into [:div.control ] children)]))]))
(consume Consumer
["fullwidth?"]
(fn [fullwidth?]
[:div.field
(if fullwidth?
[:p.help label]
[:label.label
(if required?
[:span label [:span.has-text-danger " *"]]
label)])
(into [:div.control ] children)]))))
(defn field []
(let [props (r/props (r/current-component))
@@ -251,20 +254,20 @@
(defn field-v2 []
(let [props (r/props (r/current-component))
[label child] (r/children (r/current-component))]
[:> Consumer {}
(fn [consume]
(r/as-element
[:div.field
(when label
(if (aget consume "fullwidth?")
[:p.help label]
[:label.label
(if (:required? props)
[:span label [:span.has-text-danger " *"]]
label)]))
[:div.control [raw-field-v2 props child]]
[:div
[raw-error-v2 {:field (:field props)}]]]))]))
(consume Consumer
["fullwidth?"]
(fn [fullwidth?]
[:div.field
(when label
(if fullwidth?
[:p.help label]
[:label.label
(if (:required? props)
[:span label [:span.has-text-danger " *"]]
label)]))
[:div.control [raw-field-v2 props child]]
[:div
[raw-error-v2 {:field (:field props)}]]]))))
(defn horizontal-control []
(let [[label & children] (r/children (r/current-component))]
@@ -292,34 +295,27 @@
(defn submit-button [{:keys [class]}]
(let [[child] (r/children (r/current-component))]
[:> Consumer {}
(fn [consume]
(let [status (aget consume "status")
can-submit (aget consume "can-submit")
fullwidth? (aget consume "fullwidth?")]
(r/as-element
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
(not can-submit))
:class (cond-> (or class [])
(status/class-for status) (conj (status/class-for status))
fullwidth? (conj "is-fullwidth")) }
child])))]))
(consume
Consumer
["status" "can-submit" "fullwidth?"]
(fn [status can-submit fullwidth?]
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
(not can-submit))
:class (cond-> (or class [])
(status/class-for status) (into (status/class-for status))
fullwidth? (conj "is-fullwidth")) }
child]))))
(defn hidden-submit-button []
[:> Consumer {}
(fn [consume]
(let [status (aget consume "status")
can-submit (aget consume "can-submit")]
(r/as-element
[:div {:style {:display "none"}}
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
(not can-submit))}]])))])
(consume Consumer ["status" "can-submit"]
(fn [status can-submit]
[:div {:style {:display "none"}}
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
(not can-submit))}]])))
(defn error-notification []
(let [[child] (r/children (r/current-component))]
[:> Consumer {}
(fn [consume]
(r/as-element
(when-let [error (aget consume "error")]
^{:key error}
[:div.has-text-danger.animated.fadeInUp {} error])))]))
(consume Consumer ["error"]
(fn [error]
(when error
^{:key error}
[:div.has-text-danger.animated.fadeInUp {} error]))))

View File

@@ -117,7 +117,6 @@
::error
[(re-frame/path [::status]) ]
(fn [db [_ single error]]
(println "STATUS" single error)
(assoc db single {:state :error
:info nil
:error error})))

View File

@@ -101,14 +101,6 @@
[upload-replacement-button {:on-change on-change} "Upload signature"]]]))
])))
(re-frame/reg-sub
::can-submit
:<- [::new-client-request]
(fn [_ _]
true
#_(s/valid? ::entity/client r)))
(re-frame/reg-sub
::new-client-request
:<- [::forms/form ::form]
@@ -749,8 +741,7 @@
^{:key (or (:id new-client)
"new")}
[form-builder/builder {:can-submit [::can-submit]
:submit-event [::save-new-client ]
[form-builder/builder {:submit-event [::save-new-client ]
:id ::form
:fullwidth? false}

View File

@@ -57,7 +57,6 @@
(- (:total (:original data)) (:outstanding-balance (:original data))))
account-total (reduce + 0 (map :amount (:expense-accounts data)))]
(and
(m/validate schema data)
(or (not min-total) (>= (:total data) min-total))
(or (not (:id data))
(dollars= (Math/abs (:total data)) (Math/abs account-total)))))))
@@ -440,6 +439,7 @@
(list
^{:key (str id "-check")} [:a.dropdown-item {:on-click (dispatch-event [::save-requested [::add-and-print id :check]])} "Print checks from " name]
^{:key (str id "-debit")} [:a.dropdown-item {:on-click (dispatch-event [::save-requested [::add-and-print id :debit]])} "Debit from " name]))))]]])
[:div.column
[form-builder/submit-button {:class ["is-fullwidth"]}
"Save"]]]])])