From 86aaa4a9331693c834242a4143e0abcba7601739 Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Wed, 20 Jul 2022 06:27:21 -0700 Subject: [PATCH] Minor refactoring to simplify consumer. May be better to use macro. --- src/cljs/auto_ap/forms.cljs | 16 +- src/cljs/auto_ap/forms/builder.cljs | 220 +++++++++--------- src/cljs/auto_ap/status.cljs | 1 - .../views/pages/admin/clients/form.cljs | 11 +- .../auto_ap/views/pages/invoices/form.cljs | 2 +- 5 files changed, 119 insertions(+), 131 deletions(-) diff --git a/src/cljs/auto_ap/forms.cljs b/src/cljs/auto_ap/forms.cljs index 36e79bb4..84d3b2ee 100644 --- a/src/cljs/auto_ap/forms.cljs +++ b/src/cljs/auto_ap/forms.cljs @@ -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 diff --git a/src/cljs/auto_ap/forms/builder.cljs b/src/cljs/auto_ap/forms/builder.cljs index 8c165a6a..c5753e0c 100644 --- a/src/cljs/auto_ap/forms/builder.cljs +++ b/src/cljs/auto_ap/forms/builder.cljs @@ -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])))) diff --git a/src/cljs/auto_ap/status.cljs b/src/cljs/auto_ap/status.cljs index d468b8e9..6e1c78ed 100644 --- a/src/cljs/auto_ap/status.cljs +++ b/src/cljs/auto_ap/status.cljs @@ -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}))) diff --git a/src/cljs/auto_ap/views/pages/admin/clients/form.cljs b/src/cljs/auto_ap/views/pages/admin/clients/form.cljs index 4bc15327..196fff4e 100644 --- a/src/cljs/auto_ap/views/pages/admin/clients/form.cljs +++ b/src/cljs/auto_ap/views/pages/admin/clients/form.cljs @@ -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} diff --git a/src/cljs/auto_ap/views/pages/invoices/form.cljs b/src/cljs/auto_ap/views/pages/invoices/form.cljs index 36d94b31..8f7d9b68 100644 --- a/src/cljs/auto_ap/views/pages/invoices/form.cljs +++ b/src/cljs/auto_ap/views/pages/invoices/form.cljs @@ -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"]]]])])