supports validation on complete
This commit is contained in:
@@ -108,7 +108,7 @@
|
|||||||
|
|
||||||
(add-shutdown-hook! shutdown-mount)
|
(add-shutdown-hook! shutdown-mount)
|
||||||
(start-server :port 9000 :bind "0.0.0.0" #_#_:handler (cider-nrepl-handler))
|
(start-server :port 9000 :bind "0.0.0.0" #_#_:handler (cider-nrepl-handler))
|
||||||
(alter-var-root #'nrepl.middleware.print/*print-fn* (constantly clojure.pprint/pprint))
|
#_(alter-var-root #'nrepl.middleware.print/*print-fn* (constantly clojure.pprint/pprint))
|
||||||
(apply mount/start-without without)))
|
(apply mount/start-without without)))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
|
|||||||
@@ -83,6 +83,10 @@
|
|||||||
(fn [db [_ form & paths]]
|
(fn [db [_ form & paths]]
|
||||||
(update-in db [::forms form :visited] (fn [v]
|
(update-in db [::forms form :visited] (fn [v]
|
||||||
(set (into v paths))))))
|
(set (into v paths))))))
|
||||||
|
(re-frame/reg-event-db
|
||||||
|
::attempted-submit
|
||||||
|
(fn [db [_ form & paths]]
|
||||||
|
(assoc-in db [::forms form :attempted-submit?] true)))
|
||||||
|
|
||||||
(defn change-handler [form customize-fn]
|
(defn change-handler [form customize-fn]
|
||||||
(fn [db [_ & path-pairs]]
|
(fn [db [_ & path-pairs]]
|
||||||
|
|||||||
@@ -34,45 +34,49 @@
|
|||||||
(get-in field-path)
|
(get-in field-path)
|
||||||
first))
|
first))
|
||||||
|
|
||||||
(defn builder [{:keys [value on-change can-submit data-sub error-messages change-event submit-event id fullwidth? schema] :as z}]
|
(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] form-key :id} @(re-frame/subscribe data-sub)
|
{:keys [data error 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)
|
||||||
true)
|
true)
|
||||||
problems (when schema
|
problems (when schema
|
||||||
(m/explain schema data))]
|
(m/explain schema data))]
|
||||||
|
(r/create-element Provider #js {:value #js {:can-submit can-submit
|
||||||
|
:error-messages (or error-messages
|
||||||
(r/create-element Provider #js {:value #js {:can-submit can-submit
|
|
||||||
:error-messages (or error-messages
|
|
||||||
nil)
|
nil)
|
||||||
:on-change on-change
|
:on-change on-change
|
||||||
:change-event change-event
|
:change-event change-event
|
||||||
:blur-event [::forms/visited id]
|
:blur-event [::forms/visited id]
|
||||||
:visited visited
|
:visited visited
|
||||||
:submit-event submit-event
|
:submit-event submit-event
|
||||||
:problems problems
|
:problems problems
|
||||||
:error error
|
:attempted-submit? attempted-submit?
|
||||||
:status status
|
:error error
|
||||||
:id id
|
:status status
|
||||||
:data data
|
:id id
|
||||||
:fullwidth? fullwidth?}}
|
:data data
|
||||||
|
:fullwidth? fullwidth?}}
|
||||||
(r/as-element
|
(r/as-element
|
||||||
^{:key form-key}
|
^{:key form-key}
|
||||||
[:form {:on-submit (fn [e]
|
[:form {:on-submit (fn [e]
|
||||||
(when (.-stopPropagation e)
|
(when (.-stopPropagation e)
|
||||||
(.stopPropagation e)
|
(.stopPropagation e)
|
||||||
(.preventDefault e))
|
(.preventDefault e))
|
||||||
(when can-submit
|
(if (and schema (not (m/validate schema data)))
|
||||||
(re-frame/dispatch-sync (vec (conj submit-event {})))))}
|
(do
|
||||||
|
(re-frame/dispatch-sync [::status/dispose-single id])
|
||||||
|
(re-frame/dispatch [::status/error id [{:message (or validation-error-string "Please fix the errors and try again.")}]])
|
||||||
|
(re-frame/dispatch [::forms/attempted-submit id]))
|
||||||
|
(when can-submit
|
||||||
|
(re-frame/dispatch-sync (vec (conj submit-event {}))))))}
|
||||||
(into [:fieldset {:disabled (boolean (= :loading (:state status)))}]
|
(into [:fieldset {:disabled (boolean (= :loading (:state status)))}]
|
||||||
(r/children (r/current-component)))]
|
(r/children (r/current-component)))]
|
||||||
))))
|
))))
|
||||||
|
|
||||||
(defn virtual-builder []
|
(defn virtual-builder []
|
||||||
@@ -155,9 +159,10 @@
|
|||||||
|
|
||||||
:else
|
:else
|
||||||
nil)
|
nil)
|
||||||
visited? (get (aget consume-form "visited") full-field-path)]
|
visited? (get (aget consume-form "visited") full-field-path)
|
||||||
|
attempted-submit? (aget consume-form "attempted-submit?")]
|
||||||
(when-let [error-message (and
|
(when-let [error-message (and
|
||||||
visited?
|
(or visited? attempted-submit?)
|
||||||
(spec-error-message (aget consume-form "problems") full-field-path (aget consume-form "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]]))))]))])
|
||||||
@@ -184,6 +189,7 @@
|
|||||||
:else
|
:else
|
||||||
nil)
|
nil)
|
||||||
visited? (get (aget consume-form "visited") full-field-path)
|
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)
|
value (get-in (aget consume-form "data") full-field-path)
|
||||||
on-change (aget consume-form "on-change")]
|
on-change (aget consume-form "on-change")]
|
||||||
(-> child-props
|
(-> child-props
|
||||||
@@ -196,7 +202,7 @@
|
|||||||
(update :class (fn [class]
|
(update :class (fn [class]
|
||||||
(str class
|
(str class
|
||||||
(cond
|
(cond
|
||||||
(not visited?)
|
(and (not visited?) (not attempted-submit?))
|
||||||
""
|
""
|
||||||
(not (valid-field? (aget consume-form "problems") full-field-path))
|
(not (valid-field? (aget consume-form "problems") full-field-path))
|
||||||
" is-danger"
|
" is-danger"
|
||||||
@@ -317,5 +323,3 @@
|
|||||||
(when-let [error (aget consume "error")]
|
(when-let [error (aget consume "error")]
|
||||||
^{:key error}
|
^{:key error}
|
||||||
[:div.has-text-danger.animated.fadeInUp {} error])))]))
|
[:div.has-text-danger.animated.fadeInUp {} error])))]))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@
|
|||||||
::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})))
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
[auto-ap.forms.builder :as form-builder]
|
[auto-ap.forms.builder :as form-builder]
|
||||||
[auto-ap.schema :as schema]
|
[auto-ap.schema :as schema]
|
||||||
[auto-ap.utils :refer [dollars-0?]]
|
[auto-ap.utils :refer [dollars-0?]]
|
||||||
|
[auto-ap.views.components :as com]
|
||||||
[auto-ap.views.components.button-radio :as button-radio]
|
[auto-ap.views.components.button-radio :as button-radio]
|
||||||
[auto-ap.views.components.level :refer [left-stack]]
|
[auto-ap.views.components.level :refer [left-stack]]
|
||||||
[auto-ap.views.components.money-field :refer [money-field]]
|
[auto-ap.views.components.money-field :refer [money-field]]
|
||||||
@@ -232,18 +233,7 @@
|
|||||||
[:location schema/not-empty-string]
|
[:location schema/not-empty-string]
|
||||||
[:amount schema/money]]]))
|
[:amount schema/money]]]))
|
||||||
|
|
||||||
(defn select-field [{:keys [options allow-nil? class] :as props}]
|
|
||||||
[:div.select {:class class}
|
|
||||||
[:select (-> props
|
|
||||||
(dissoc :allow-nil? :class :options)
|
|
||||||
(update :value (fn [v] (if (str/blank? v)
|
|
||||||
""
|
|
||||||
v))))
|
|
||||||
[:<>
|
|
||||||
(when allow-nil?
|
|
||||||
[:option {:value nil}])
|
|
||||||
(for [[k v] options]
|
|
||||||
^{:key k} [:option {:value k} v])]]])
|
|
||||||
|
|
||||||
(defn expense-accounts-field-v2 [{value :value on-change :on-change expense-accounts :value client :client max-value :max locations :locations disabled :disabled percentage-only? :percentage-only? :or {percentage-only? false}}]
|
(defn expense-accounts-field-v2 [{value :value on-change :on-change expense-accounts :value client :client max-value :max locations :locations disabled :disabled percentage-only? :percentage-only? :or {percentage-only? false}}]
|
||||||
[form-builder/virtual-builder {:value value
|
[form-builder/virtual-builder {:value value
|
||||||
@@ -306,7 +296,7 @@
|
|||||||
[form-builder/field-v2 {:required? true
|
[form-builder/field-v2 {:required? true
|
||||||
:field [index :location]}
|
:field [index :location]}
|
||||||
"Location"
|
"Location"
|
||||||
[select-field {:options (if (:location account)
|
[com/select-field {:options (if (:location account)
|
||||||
[[(:location account) (:location account)]]
|
[[(:location account) (:location account)]]
|
||||||
(map (fn [l] [l l])
|
(map (fn [l] [l l])
|
||||||
locations))
|
locations))
|
||||||
|
|||||||
@@ -72,13 +72,6 @@
|
|||||||
[:or [:maybe :string]
|
[:or [:maybe :string]
|
||||||
[:maybe keyword?]]]]))
|
[:maybe keyword?]]]]))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
::can-submit
|
|
||||||
:<- [::forms/form ::vendor-form]
|
|
||||||
(fn [form]
|
|
||||||
(m/validate schema (:data form))))
|
|
||||||
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::save-complete
|
::save-complete
|
||||||
[(forms/triggers-stop ::vendor-form)]
|
[(forms/triggers-stop ::vendor-form)]
|
||||||
@@ -89,55 +82,58 @@
|
|||||||
::save
|
::save
|
||||||
[with-user with-is-admin? (forms/triggers-loading ::vendor-form) (forms/in-form ::vendor-form)]
|
[with-user with-is-admin? (forms/triggers-loading ::vendor-form) (forms/in-form ::vendor-form)]
|
||||||
(fn [{:keys [user is-admin?] {{:keys [name hidden print-as terms invoice-reminder-schedule primary-contact automatically-paid-when-due schedule-payment-dom secondary-contact address default-account terms-overrides account-overrides id legal-entity-tin legal-entity-tin-type legal-entity-first-name legal-entity-last-name legal-entity-middle-name legal-entity-1099-type] :as data} :data} :db} _]
|
(fn [{:keys [user is-admin?] {{:keys [name hidden print-as terms invoice-reminder-schedule primary-contact automatically-paid-when-due schedule-payment-dom secondary-contact address default-account terms-overrides account-overrides id legal-entity-tin legal-entity-tin-type legal-entity-first-name legal-entity-last-name legal-entity-middle-name legal-entity-1099-type] :as data} :data} :db} _]
|
||||||
(let [query [:upsert-vendor
|
(if (m/validate schema data)
|
||||||
{:vendor (cond-> {:id id
|
(let [query [:upsert-vendor
|
||||||
:name name
|
{:vendor (cond-> {:id id
|
||||||
:print-as print-as
|
:name name
|
||||||
:terms (or terms
|
:print-as print-as
|
||||||
nil)
|
:terms (or terms
|
||||||
:default-account-id (:id default-account)
|
nil)
|
||||||
:address address
|
:default-account-id (:id default-account)
|
||||||
:primary-contact primary-contact
|
:address address
|
||||||
:secondary-contact secondary-contact
|
:primary-contact primary-contact
|
||||||
:invoice-reminder-schedule invoice-reminder-schedule}
|
:secondary-contact secondary-contact
|
||||||
is-admin? (assoc :hidden hidden
|
:invoice-reminder-schedule invoice-reminder-schedule}
|
||||||
:terms-overrides (mapv
|
is-admin? (assoc :hidden hidden
|
||||||
(fn [{:keys [client terms id]}]
|
:terms-overrides (mapv
|
||||||
{:id id
|
(fn [{:keys [client terms id]}]
|
||||||
:client-id (:id client)
|
{:id id
|
||||||
:terms (or (str->int terms) 0)})
|
:client-id (:id client)
|
||||||
terms-overrides)
|
:terms (or (str->int terms) 0)})
|
||||||
:account-overrides (mapv
|
terms-overrides)
|
||||||
(fn [{:keys [client account id]}]
|
:account-overrides (mapv
|
||||||
{:id id
|
(fn [{:keys [client account id]}]
|
||||||
:client-id (:id client)
|
{:id id
|
||||||
:account-id (:id account)})
|
:client-id (:id client)
|
||||||
account-overrides)
|
:account-id (:id account)})
|
||||||
:schedule-payment-dom (mapv
|
account-overrides)
|
||||||
(fn [{:keys [client dom id]}]
|
:schedule-payment-dom (mapv
|
||||||
{:id id
|
(fn [{:keys [client dom id]}]
|
||||||
:client-id (:id client)
|
{:id id
|
||||||
:dom (or (str->int dom)
|
:client-id (:id client)
|
||||||
0)})
|
:dom (or (str->int dom)
|
||||||
schedule-payment-dom)
|
0)})
|
||||||
:automatically-paid-when-due (mapv
|
schedule-payment-dom)
|
||||||
(comp :id :client)
|
:automatically-paid-when-due (mapv
|
||||||
automatically-paid-when-due)
|
(comp :id :client)
|
||||||
:legal-entity-first-name legal-entity-first-name
|
automatically-paid-when-due)
|
||||||
:legal-entity-middle-name legal-entity-middle-name
|
:legal-entity-first-name legal-entity-first-name
|
||||||
:legal-entity-last-name legal-entity-last-name
|
:legal-entity-middle-name legal-entity-middle-name
|
||||||
:legal-entity-tin legal-entity-tin
|
:legal-entity-last-name legal-entity-last-name
|
||||||
:legal-entity-tin-type (some-> legal-entity-tin-type clojure.core/name not-empty keyword)
|
:legal-entity-tin legal-entity-tin
|
||||||
:legal-entity-1099-type (some-> legal-entity-1099-type clojure.core/name not-empty keyword)
|
:legal-entity-tin-type (some-> legal-entity-tin-type clojure.core/name not-empty keyword)
|
||||||
))}
|
:legal-entity-1099-type (some-> legal-entity-1099-type clojure.core/name not-empty keyword)))}
|
||||||
common/default-read]]
|
common/default-read]]
|
||||||
{ :graphql
|
{ :graphql
|
||||||
{:token user
|
{:token user
|
||||||
:owns-state {:single ::vendor-form}
|
:owns-state {:single ::vendor-form}
|
||||||
:query-obj {:venia/operation
|
:query-obj {:venia/operation
|
||||||
{:operation/type :mutation
|
{:operation/type :mutation
|
||||||
:operation/name "UpsertVendor"} :venia/queries [{:query/data query}]}
|
:operation/name "UpsertVendor"} :venia/queries [{:query/data query}]}
|
||||||
:on-success [::save-complete]}})))
|
:on-success [::save-complete]}})
|
||||||
|
|
||||||
|
{:dispatch-n [[::forms/attempted-submit ::vendor-form]
|
||||||
|
[::status/error ::vendor-form [{:message "Please fix the errors and try again."}]]]})))
|
||||||
|
|
||||||
(defn pull-left []
|
(defn pull-left []
|
||||||
(into [:div {:style {:position "relative"
|
(into [:div {:style {:position "relative"
|
||||||
@@ -178,7 +174,6 @@
|
|||||||
(let [is-admin? @(re-frame/subscribe [::subs/is-admin?])
|
(let [is-admin? @(re-frame/subscribe [::subs/is-admin?])
|
||||||
clients @(re-frame/subscribe [::subs/client-refs])]
|
clients @(re-frame/subscribe [::subs/client-refs])]
|
||||||
[form-builder/builder {:submit-event [::save]
|
[form-builder/builder {:submit-event [::save]
|
||||||
:can-submit [::can-submit]
|
|
||||||
:id ::vendor-form
|
:id ::vendor-form
|
||||||
:schema schema}
|
:schema schema}
|
||||||
[form-builder/field-v2 {:field :name
|
[form-builder/field-v2 {:field :name
|
||||||
@@ -282,7 +277,6 @@
|
|||||||
[contact-field {:name "Secondary"
|
[contact-field {:name "Secondary"
|
||||||
:field [:secondary-contact]}]]
|
:field [:secondary-contact]}]]
|
||||||
|
|
||||||
|
|
||||||
(when is-admin?
|
(when is-admin?
|
||||||
[form-builder/section {:title "Legal Entity"}
|
[form-builder/section {:title "Legal Entity"}
|
||||||
[form-builder/vertical-control
|
[form-builder/vertical-control
|
||||||
@@ -334,27 +328,23 @@
|
|||||||
::vendor-selected
|
::vendor-selected
|
||||||
[with-user (forms/in-form ::select-vendor-form)]
|
[with-user (forms/in-form ::select-vendor-form)]
|
||||||
(fn [{{:keys [data]} :db :keys [user]} _]
|
(fn [{{:keys [data]} :db :keys [user]} _]
|
||||||
{:graphql {:token user
|
(if (:vendor data)
|
||||||
:query-obj {:venia/queries [[:vendor-by-id
|
{:graphql {:token user
|
||||||
{:id (:id (:vendor data))}
|
:query-obj {:venia/queries [[:vendor-by-id
|
||||||
common/default-read]]}
|
{:id (:id (:vendor data))}
|
||||||
:owns-state {:single ::select-vendor-form}
|
common/default-read]]}
|
||||||
:on-success (fn [r]
|
:owns-state {:single ::select-vendor-form}
|
||||||
[::started (:vendor-by-id r)])}}))
|
:on-success (fn [r]
|
||||||
|
[::started (:vendor-by-id r)])}}
|
||||||
(re-frame/reg-sub
|
{:dispatch-n [[::forms/attempted-submit ::select-vendor-form]
|
||||||
::can-submit-select-vendor-form
|
[::status/error ::select-vendor-form [{:message "Please select a vendor."}]]]})))
|
||||||
:<- [::forms/field ::select-vendor-form [:vendor]]
|
|
||||||
(fn [vendor]
|
|
||||||
(if vendor
|
|
||||||
true
|
|
||||||
false)))
|
|
||||||
|
|
||||||
|
|
||||||
(defn select-vendor-form-content []
|
(defn select-vendor-form-content []
|
||||||
[form-builder/builder {:submit-event [::vendor-selected]
|
[form-builder/builder {:submit-event [::vendor-selected]
|
||||||
:can-submit [::can-submit-select-vendor-form]
|
:id ::select-vendor-form
|
||||||
:id ::select-vendor-form}
|
:validation-error-string "Please select a vendor."
|
||||||
|
:schema [:map
|
||||||
|
[:vendor schema/reference]]}
|
||||||
[form-builder/field-v2 {:field :vendor
|
[form-builder/field-v2 {:field :vendor
|
||||||
:required? true}
|
:required? true}
|
||||||
"Vendor to edit"
|
"Vendor to edit"
|
||||||
@@ -384,11 +374,11 @@
|
|||||||
{:title "Vendor"
|
{:title "Vendor"
|
||||||
:body [vendor-dialog]
|
:body [vendor-dialog]
|
||||||
:class "semi-wide"
|
:class "semi-wide"
|
||||||
|
:status-from [::status/single ::vendor-form]
|
||||||
:confirm {:value "Save Vendor"
|
:confirm {:value "Save Vendor"
|
||||||
:status-from [::status/single ::vendor-form]
|
:status-from [::status/single ::vendor-form]
|
||||||
:class "is-primary"
|
:class "is-primary"
|
||||||
:on-click (dispatch-event [::save])
|
:on-click (dispatch-event [::save])
|
||||||
:can-submit [::can-submit]
|
|
||||||
:close-event [::status/completed ::vendor-form]}}]}))
|
:close-event [::status/completed ::vendor-form]}}]}))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
@@ -402,5 +392,4 @@
|
|||||||
:status-from [::status/single ::select-vendor-form]
|
:status-from [::status/single ::select-vendor-form]
|
||||||
:class "is-primary"
|
:class "is-primary"
|
||||||
:on-click (dispatch-event [::vendor-selected])
|
:on-click (dispatch-event [::vendor-selected])
|
||||||
:can-submit [::can-submit-select-vendor-form]
|
|
||||||
:close-event [::status/completed ::select-vendor-form]}}]}))
|
:close-event [::status/completed ::select-vendor-form]}}]}))
|
||||||
|
|||||||
Reference in New Issue
Block a user