Minor refactoring to simplify consumer. May be better to use macro.
This commit is contained in:
@@ -30,13 +30,15 @@
|
|||||||
([db form data]
|
([db form data]
|
||||||
(start-form db form data nil))
|
(start-form db form data nil))
|
||||||
([db form data complete-listener]
|
([db form data complete-listener]
|
||||||
(assoc-in db [::forms form] {:error nil
|
(-> db
|
||||||
:active? true
|
(assoc-in [::forms form] {:error nil
|
||||||
:id (random-uuid)
|
:active? true
|
||||||
:visited #{}
|
:id (random-uuid)
|
||||||
:status nil
|
:visited #{}
|
||||||
:data data
|
:status nil
|
||||||
:complete-listener complete-listener})))
|
:data data
|
||||||
|
:complete-listener complete-listener})
|
||||||
|
(assoc-in [::status/status form] nil))))
|
||||||
|
|
||||||
(defn triggers-saved [form data-key]
|
(defn triggers-saved [form data-key]
|
||||||
(i/->interceptor
|
(i/->interceptor
|
||||||
|
|||||||
@@ -34,13 +34,20 @@
|
|||||||
(get-in field-path)
|
(get-in field-path)
|
||||||
first))
|
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]}]
|
(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)
|
(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"))
|
(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])
|
(let [data-sub (or data-sub [::forms/form id])
|
||||||
change-event (when-not on-change
|
change-event (when-not on-change
|
||||||
(or change-event [::forms/change id]))
|
(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)
|
data (or value data)
|
||||||
status @(re-frame/subscribe [::status/single id])
|
status @(re-frame/subscribe [::status/single id])
|
||||||
can-submit (if can-submit @(re-frame/subscribe can-submit)
|
can-submit (if can-submit @(re-frame/subscribe can-submit)
|
||||||
@@ -57,7 +64,7 @@
|
|||||||
:submit-event submit-event
|
:submit-event submit-event
|
||||||
:problems problems
|
:problems problems
|
||||||
:attempted-submit? attempted-submit?
|
:attempted-submit? attempted-submit?
|
||||||
:error error
|
:error (-> status :error first :message)
|
||||||
:status status
|
:status status
|
||||||
:id id
|
:id id
|
||||||
:data data
|
:data data
|
||||||
@@ -144,75 +151,71 @@
|
|||||||
(conj path))))
|
(conj path))))
|
||||||
|
|
||||||
(defn raw-error-v2 [{:keys [field]}]
|
(defn raw-error-v2 [{:keys [field]}]
|
||||||
[:> Consumer {}
|
(consume Consumer
|
||||||
(fn [consume-form]
|
["visited" "attempted-submit?" "problems" "error-messages"]
|
||||||
(r/as-element
|
(fn [visited attempted-submit? problems error-messages]
|
||||||
[:> FormScopeConsumer {}
|
(consume FormScopeConsumer
|
||||||
(fn [form-scope]
|
["form-scope"]
|
||||||
(r/as-element
|
(fn [form-scope]
|
||||||
(let [full-field-path (cond
|
(let [full-field-path (cond
|
||||||
(sequential? field)
|
(sequential? field)
|
||||||
(into form-scope field)
|
(into form-scope field)
|
||||||
|
|
||||||
field
|
field
|
||||||
(conj form-scope field)
|
(conj form-scope field)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
nil)
|
nil)
|
||||||
visited? (get (aget consume-form "visited") full-field-path)
|
visited? (get visited full-field-path)]
|
||||||
attempted-submit? (aget consume-form "attempted-submit?")]
|
(when-let [error-message (and
|
||||||
(when-let [error-message (and
|
(or visited? attempted-submit?)
|
||||||
(or visited? attempted-submit?)
|
(spec-error-message problems full-field-path error-messages))]
|
||||||
(spec-error-message (aget consume-form "problems") full-field-path (aget consume-form "error-messages")))]
|
[:div
|
||||||
[:div
|
[:p.help.has-text-danger error-message]])))))))
|
||||||
[:p.help.has-text-danger error-message]]))))]))])
|
|
||||||
|
|
||||||
(defn raw-field-v2 [{:keys [field] :as props}]
|
(defn raw-field-v2 [{:keys [field] :as props}]
|
||||||
(when-not field
|
(when-not field
|
||||||
(throw (ex-info (str "Missing field") (clj->js {:props props}))))
|
(throw (ex-info (str "Missing field") (clj->js {:props props}))))
|
||||||
(let [[child] (r/children (r/current-component))]
|
(let [[child] (r/children (r/current-component))]
|
||||||
[:> Consumer {}
|
(consume Consumer
|
||||||
(fn [consume-form]
|
["visited" "attempted-submit?" "data" "on-change" "change-event" "blur-event" "problems"]
|
||||||
(r/as-element
|
(fn [visited attempted-submit? data on-change change-event blur-event problems]
|
||||||
[:> FormScopeConsumer {}
|
(consume FormScopeConsumer
|
||||||
(fn [form-scope]
|
["form-scope"]
|
||||||
(r/as-element
|
(fn [form-scope]
|
||||||
(update child 1 (fn [child-props]
|
(update child 1 (fn [child-props]
|
||||||
(let [
|
(let [
|
||||||
full-field-path (cond
|
full-field-path (cond
|
||||||
(sequential? field)
|
(sequential? field)
|
||||||
(into form-scope field)
|
(into form-scope field)
|
||||||
|
|
||||||
field
|
field
|
||||||
(conj form-scope 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"
|
|
||||||
|
|
||||||
:else
|
: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]}]
|
(defn with-scope [{:keys [scope]}]
|
||||||
(r/create-element FormScopeProvider #js {:value scope}
|
(r/create-element FormScopeProvider #js {:value scope}
|
||||||
(r/as-element (into [:<>]
|
(r/as-element (into [:<>]
|
||||||
@@ -220,17 +223,17 @@
|
|||||||
|
|
||||||
(defn vertical-control [{:keys [is-small? required?]}]
|
(defn vertical-control [{:keys [is-small? required?]}]
|
||||||
(let [[label & children] (r/children (r/current-component))]
|
(let [[label & children] (r/children (r/current-component))]
|
||||||
[:> Consumer {}
|
(consume Consumer
|
||||||
(fn [consume]
|
["fullwidth?"]
|
||||||
(r/as-element
|
(fn [fullwidth?]
|
||||||
[:div.field
|
[:div.field
|
||||||
(if (aget consume "fullwidth?")
|
(if fullwidth?
|
||||||
[:p.help label]
|
[:p.help label]
|
||||||
[:label.label
|
[:label.label
|
||||||
(if required?
|
(if required?
|
||||||
[:span label [:span.has-text-danger " *"]]
|
[:span label [:span.has-text-danger " *"]]
|
||||||
label)])
|
label)])
|
||||||
(into [:div.control ] children)]))]))
|
(into [:div.control ] children)]))))
|
||||||
|
|
||||||
(defn field []
|
(defn field []
|
||||||
(let [props (r/props (r/current-component))
|
(let [props (r/props (r/current-component))
|
||||||
@@ -251,20 +254,20 @@
|
|||||||
(defn field-v2 []
|
(defn field-v2 []
|
||||||
(let [props (r/props (r/current-component))
|
(let [props (r/props (r/current-component))
|
||||||
[label child] (r/children (r/current-component))]
|
[label child] (r/children (r/current-component))]
|
||||||
[:> Consumer {}
|
(consume Consumer
|
||||||
(fn [consume]
|
["fullwidth?"]
|
||||||
(r/as-element
|
(fn [fullwidth?]
|
||||||
[:div.field
|
[:div.field
|
||||||
(when label
|
(when label
|
||||||
(if (aget consume "fullwidth?")
|
(if fullwidth?
|
||||||
[:p.help label]
|
[:p.help label]
|
||||||
[:label.label
|
[:label.label
|
||||||
(if (:required? props)
|
(if (:required? props)
|
||||||
[:span label [:span.has-text-danger " *"]]
|
[:span label [:span.has-text-danger " *"]]
|
||||||
label)]))
|
label)]))
|
||||||
[:div.control [raw-field-v2 props child]]
|
[:div.control [raw-field-v2 props child]]
|
||||||
[:div
|
[:div
|
||||||
[raw-error-v2 {:field (:field props)}]]]))]))
|
[raw-error-v2 {:field (:field props)}]]]))))
|
||||||
|
|
||||||
(defn horizontal-control []
|
(defn horizontal-control []
|
||||||
(let [[label & children] (r/children (r/current-component))]
|
(let [[label & children] (r/children (r/current-component))]
|
||||||
@@ -292,34 +295,27 @@
|
|||||||
|
|
||||||
(defn submit-button [{:keys [class]}]
|
(defn submit-button [{:keys [class]}]
|
||||||
(let [[child] (r/children (r/current-component))]
|
(let [[child] (r/children (r/current-component))]
|
||||||
[:> Consumer {}
|
(consume
|
||||||
(fn [consume]
|
Consumer
|
||||||
(let [status (aget consume "status")
|
["status" "can-submit" "fullwidth?"]
|
||||||
can-submit (aget consume "can-submit")
|
(fn [status can-submit fullwidth?]
|
||||||
fullwidth? (aget consume "fullwidth?")]
|
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
|
||||||
(r/as-element
|
(not can-submit))
|
||||||
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
|
:class (cond-> (or class [])
|
||||||
(not can-submit))
|
(status/class-for status) (into (status/class-for status))
|
||||||
:class (cond-> (or class [])
|
fullwidth? (conj "is-fullwidth")) }
|
||||||
(status/class-for status) (conj (status/class-for status))
|
child]))))
|
||||||
fullwidth? (conj "is-fullwidth")) }
|
|
||||||
child])))]))
|
|
||||||
|
|
||||||
(defn hidden-submit-button []
|
(defn hidden-submit-button []
|
||||||
[:> Consumer {}
|
(consume Consumer ["status" "can-submit"]
|
||||||
(fn [consume]
|
(fn [status can-submit]
|
||||||
(let [status (aget consume "status")
|
[:div {:style {:display "none"}}
|
||||||
can-submit (aget consume "can-submit")]
|
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
|
||||||
(r/as-element
|
(not can-submit))}]])))
|
||||||
[:div {:style {:display "none"}}
|
|
||||||
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
|
|
||||||
(not can-submit))}]])))])
|
|
||||||
|
|
||||||
(defn error-notification []
|
(defn error-notification []
|
||||||
(let [[child] (r/children (r/current-component))]
|
(consume Consumer ["error"]
|
||||||
[:> Consumer {}
|
(fn [error]
|
||||||
(fn [consume]
|
(when error
|
||||||
(r/as-element
|
^{:key error}
|
||||||
(when-let [error (aget consume "error")]
|
[:div.has-text-danger.animated.fadeInUp {} error]))))
|
||||||
^{:key error}
|
|
||||||
[:div.has-text-danger.animated.fadeInUp {} error])))]))
|
|
||||||
|
|||||||
@@ -117,7 +117,6 @@
|
|||||||
::error
|
::error
|
||||||
[(re-frame/path [::status]) ]
|
[(re-frame/path [::status]) ]
|
||||||
(fn [db [_ single error]]
|
(fn [db [_ single error]]
|
||||||
(println "STATUS" single error)
|
|
||||||
(assoc db single {:state :error
|
(assoc db single {:state :error
|
||||||
:info nil
|
:info nil
|
||||||
:error error})))
|
:error error})))
|
||||||
|
|||||||
@@ -101,14 +101,6 @@
|
|||||||
[upload-replacement-button {:on-change on-change} "Upload signature"]]]))
|
[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
|
(re-frame/reg-sub
|
||||||
::new-client-request
|
::new-client-request
|
||||||
:<- [::forms/form ::form]
|
:<- [::forms/form ::form]
|
||||||
@@ -749,8 +741,7 @@
|
|||||||
|
|
||||||
^{:key (or (:id new-client)
|
^{:key (or (:id new-client)
|
||||||
"new")}
|
"new")}
|
||||||
[form-builder/builder {:can-submit [::can-submit]
|
[form-builder/builder {:submit-event [::save-new-client ]
|
||||||
:submit-event [::save-new-client ]
|
|
||||||
:id ::form
|
:id ::form
|
||||||
:fullwidth? false}
|
:fullwidth? false}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,6 @@
|
|||||||
(- (:total (:original data)) (:outstanding-balance (:original data))))
|
(- (:total (:original data)) (:outstanding-balance (:original data))))
|
||||||
account-total (reduce + 0 (map :amount (:expense-accounts data)))]
|
account-total (reduce + 0 (map :amount (:expense-accounts data)))]
|
||||||
(and
|
(and
|
||||||
(m/validate schema data)
|
|
||||||
(or (not min-total) (>= (:total data) min-total))
|
(or (not min-total) (>= (:total data) min-total))
|
||||||
(or (not (:id data))
|
(or (not (:id data))
|
||||||
(dollars= (Math/abs (:total data)) (Math/abs account-total)))))))
|
(dollars= (Math/abs (:total data)) (Math/abs account-total)))))))
|
||||||
@@ -440,6 +439,7 @@
|
|||||||
(list
|
(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 "-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]))))]]])
|
^{:key (str id "-debit")} [:a.dropdown-item {:on-click (dispatch-event [::save-requested [::add-and-print id :debit]])} "Debit from " name]))))]]])
|
||||||
|
|
||||||
[:div.column
|
[:div.column
|
||||||
[form-builder/submit-button {:class ["is-fullwidth"]}
|
[form-builder/submit-button {:class ["is-fullwidth"]}
|
||||||
"Save"]]]])])
|
"Save"]]]])])
|
||||||
|
|||||||
Reference in New Issue
Block a user