made client form great
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
;; TODO ONLY validate on blur
|
||||
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
|
||||
nil)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
(ns auto-ap.views.components
|
||||
(:require [reagent.core :as r]
|
||||
[clojure.string :as str]
|
||||
[auto-ap.views.components.multi :as multi]))
|
||||
[auto-ap.views.components.multi :as multi]
|
||||
[auto-ap.views.components.number :as number]))
|
||||
|
||||
|
||||
(defn checkbox [{:keys [on-change
|
||||
@@ -35,3 +36,5 @@
|
||||
^{:key k} [:option {:value k} v])]]])
|
||||
|
||||
(def multi-field-v2 multi/multi-field-v2)
|
||||
|
||||
(def number-input number/number-input)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
(let [prop-value (if (seq prop-value)
|
||||
prop-value
|
||||
[])]
|
||||
(println "PROP VALUE IS")
|
||||
[form-builder/virtual-builder {:value prop-value
|
||||
:schema schema
|
||||
:on-change on-change}
|
||||
@@ -60,7 +61,7 @@
|
||||
[:button.button.is-outline
|
||||
{:type "button"
|
||||
:on-click (fn [e]
|
||||
(on-change (conj prop-value {::key next-key}))
|
||||
(on-change (conj prop-value {::key (random-uuid)}))
|
||||
(.stopPropagation e)
|
||||
(.preventDefault e))}
|
||||
[:span.icon [:i.fa.fa-plus]]
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
:value text
|
||||
:type "number"
|
||||
:step "1"
|
||||
:style {:width "5em"}
|
||||
:style (or (:style props)
|
||||
{:width "5em"})
|
||||
:size 3)]]]))
|
||||
|
||||
(defn number-input []
|
||||
|
||||
@@ -27,13 +27,18 @@
|
||||
[react-signature-canvas]
|
||||
[vimsical.re-frame.cofx.inject :as inject]
|
||||
[auto-ap.schema :as schema]
|
||||
[auto-ap.views.components :as com]
|
||||
[malli.core :as m]))
|
||||
|
||||
(def signature-canvas (r/adapt-react-class (.-default react-signature-canvas)))
|
||||
|
||||
(def location-schema (m/schema [:map
|
||||
[:location schema/not-empty-string]]))
|
||||
|
||||
(def name-match-schema (m/schema [:map
|
||||
[:match schema/not-empty-string]]))
|
||||
(def location-match-schema (m/schema [:map
|
||||
[:match schema/not-empty-string]
|
||||
[:location schema/not-empty-string]]))
|
||||
(def email-schema [:map
|
||||
[:email schema/not-empty-string]
|
||||
[:description schema/not-empty-string]])
|
||||
@@ -42,7 +47,12 @@
|
||||
[:name schema/not-empty-string]
|
||||
[:code schema/code-string]
|
||||
[:locations [:sequential location-schema]]
|
||||
[:emails [:sequential email-schema]]])
|
||||
[:emails {:optional true}
|
||||
[:maybe [:sequential email-schema]]]
|
||||
[:matches {:optional true}
|
||||
[:maybe [:sequential name-match-schema]]]
|
||||
[:location-matches {:optional true}
|
||||
[:maybe [:sequential location-match-schema]]]])
|
||||
|
||||
(defn upload-replacement-button [{:keys [on-change]} text]
|
||||
(let [button (atom nil)]
|
||||
@@ -164,10 +174,8 @@
|
||||
:bank-accounts (map-indexed (fn [i {:keys [number name check-number plaid-account intuit-bank-account include-in-reports type id code numeric-code start-date bank-name routing bank-code new? sort-order visible yodlee-account-id locations yodlee-account use-date-instead-of-post-date]}]
|
||||
{:number number
|
||||
:name name
|
||||
:check-number (when-not (str/blank? check-number)
|
||||
(js/parseInt check-number))
|
||||
:numeric-code (when-not (str/blank? numeric-code)
|
||||
(js/parseInt numeric-code))
|
||||
:check-number check-number
|
||||
:numeric-code numeric-code
|
||||
:include-in-reports include-in-reports
|
||||
:start-date start-date
|
||||
:type type
|
||||
@@ -176,8 +184,6 @@
|
||||
:visible visible
|
||||
:locations (mapv :location locations)
|
||||
:use-date-instead-of-post-date use-date-instead-of-post-date
|
||||
:yodlee-account-id (when-not (str/blank? yodlee-account-id)
|
||||
(js/parseInt yodlee-account-id))
|
||||
:yodlee-account (:id yodlee-account)
|
||||
:plaid-account (:id plaid-account)
|
||||
:intuit-bank-account (:id intuit-bank-account)
|
||||
@@ -212,7 +218,8 @@
|
||||
:client-location (:client-location sl)}))))
|
||||
(update :locations #(mapv (fn [l] {:location l
|
||||
:id (random-uuid)}) %))
|
||||
(update :matches #(mapv (fn [l] {:match l}) %))
|
||||
(update :matches #(mapv (fn [l] {:match l
|
||||
:id (random-uuid)}) %))
|
||||
(update :bank-accounts
|
||||
(fn [bas]
|
||||
(mapv (fn [ba]
|
||||
@@ -367,182 +374,132 @@
|
||||
(when active?
|
||||
[:div.card-content
|
||||
[:label.label "General"]
|
||||
[horizontal-field
|
||||
nil
|
||||
[level/left-stack
|
||||
[:div.control
|
||||
[:p.help "Account Code"]
|
||||
(if new?
|
||||
[:div.field.has-addons.is-extended
|
||||
[:div.field.has-addons
|
||||
[:p.control [:a.button.is-static (:code new-client) "-" ]]
|
||||
[:p.control
|
||||
[form-builder/raw-field
|
||||
[:input.input {:type "code"
|
||||
:field [:code]
|
||||
:spec ::entity/code}]]]]
|
||||
[form-builder/raw-field-v2 {:field :code}
|
||||
[:input.input {:type "text"}]]]]
|
||||
[:div.field [:p.control code]])]
|
||||
|
||||
|
||||
|
||||
[form-builder/field
|
||||
[form-builder/field-v2 {:field :name}
|
||||
"Nickname"
|
||||
[:input.input {:placeholder "BOA Checking #1"
|
||||
:type "text"
|
||||
:field [:name]}]]
|
||||
[horizontal-field
|
||||
nil
|
||||
[form-builder/field
|
||||
"Numeric Code"
|
||||
[:input.input {:placeholder "20101"
|
||||
:type "text"
|
||||
:field [:numeric-code]}]]]
|
||||
[form-builder/field
|
||||
:type "text"}]]
|
||||
[form-builder/field-v2 {:field :numeric-code}
|
||||
"Numeric Code"
|
||||
[com/number-input {:placeholder "20101"
|
||||
:style {:width "8em"}}]]
|
||||
[form-builder/field-v2 {:field :start-date}
|
||||
"Start date"
|
||||
[date-picker {:type "date"
|
||||
:output :cljs-date
|
||||
:field [:start-date]}]]]
|
||||
[date-picker {:output :cljs-date}]]]
|
||||
|
||||
(when (#{:check ":check"} type )
|
||||
[:div
|
||||
|
||||
[:label.label "Bank"]
|
||||
[horizontal-field
|
||||
nil
|
||||
[form-builder/field
|
||||
[level/left-stack
|
||||
[form-builder/field-v2 {:field :bank-name}
|
||||
"Bank Name"
|
||||
[:input.input {:placeholder "Bank of America"
|
||||
:type "text"
|
||||
:field [:bank-name]}]]
|
||||
[form-builder/field
|
||||
:type "text"}]]
|
||||
[form-builder/field-v2 {:field [:routing]}
|
||||
"Routing #"
|
||||
[:input.input {:placeholder "104819123"
|
||||
:style {:width "9em"}
|
||||
:type "text"
|
||||
:field [:routing]}]]
|
||||
[form-builder/field
|
||||
:type "text"}]]
|
||||
[form-builder/field-v2 {:field :bank-code}
|
||||
"Bank code"
|
||||
[:input.input {:placeholder "12/10123"
|
||||
:type "text"
|
||||
:field [:bank-code]}]]]
|
||||
:type "text"}]]]
|
||||
|
||||
[horizontal-field
|
||||
nil
|
||||
[form-builder/field
|
||||
[level/left-stack
|
||||
[form-builder/field-v2 {:field :number}
|
||||
"Account #"
|
||||
[:input.input {:placeholder "123456789"
|
||||
:type "text"
|
||||
:style {:width "20em"}
|
||||
:field [:number]}]]
|
||||
:style {:width "20em"}}]]
|
||||
|
||||
[form-builder/field
|
||||
[form-builder/field-v2 {:field :check-number}
|
||||
"Check Number"
|
||||
[:input.input {:placeholder "10000"
|
||||
:style {:width "6em"}
|
||||
:type "text"
|
||||
:field [:check-number]}]]]
|
||||
[form-builder/field
|
||||
"Yodlee Account"
|
||||
[:input.input {:placeholder "Yodlee Account #"
|
||||
:type "text"
|
||||
:field [:yodlee-account-id]}]]
|
||||
[form-builder/field
|
||||
[com/number-input {:style {:width "8em"}
|
||||
:placeholder "10000"}]]]
|
||||
|
||||
[form-builder/field-v2 {:field :yodlee-account}
|
||||
"Yodlee Account (new)"
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::yodlee-accounts (:id new-client)])
|
||||
:entity->text (fn [m] (str (:name m) " - " (:number m)))
|
||||
:type "typeahead-v3"
|
||||
:field [:yodlee-account]}]]
|
||||
[:div.field
|
||||
[:label.checkbox
|
||||
[form-builder/raw-field
|
||||
[:input {:type "checkbox"
|
||||
:field [:use-date-instead-of-post-date]}]]
|
||||
" (Yodlee only) Use 'date' instead of 'postDate'"]]
|
||||
:entity->text (fn [m] (str (:name m) " - " (:number m)))}]]
|
||||
|
||||
[form-builder/field
|
||||
|
||||
[form-builder/raw-field-v2 {:field :use-date-instead-of-post-date}
|
||||
[com/checkbox {:label " (Yodlee only) Use 'date' instead of 'postDate'"}]]
|
||||
|
||||
[form-builder/field-v2 {:field :intuit-bank-account}
|
||||
"Intuit Bank Account"
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/intuit-bank-accounts])
|
||||
:entity->text (fn [m] (str (:name m)))
|
||||
:type "typeahead-v3"
|
||||
:field [:intuit-bank-account]}]]
|
||||
[form-builder/field
|
||||
:entity->text (fn [m] (str (:name m)))}]]
|
||||
[form-builder/field-v2 {:field :plaid-accounti}
|
||||
"Plaid Account"
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::plaid-accounts (:id new-client)])
|
||||
:entity->text (fn [m] (str (:name m)))
|
||||
:type "typeahead-v3"
|
||||
:field [:plaid-account]}]]])
|
||||
:entity->text (fn [m] (str (:name m)))}]]])
|
||||
|
||||
(when (#{:credit ":credit"} type )
|
||||
[:div
|
||||
|
||||
|
||||
[:label.label "Account"]
|
||||
[horizontal-field
|
||||
nil
|
||||
[form-builder/field
|
||||
"Bank Name"
|
||||
[:input.input {:placeholder "Bank of America"
|
||||
:type "text"
|
||||
:field [:bank-name]}]]]
|
||||
|
||||
[form-builder/field-v2 {:field :bank-name}
|
||||
"Bank Name"
|
||||
[:input.input {:placeholder "Bank of America"
|
||||
:type "text"}]]
|
||||
|
||||
[horizontal-field
|
||||
nil
|
||||
[form-builder/field
|
||||
"Account #"
|
||||
[:input.input {:placeholder "123456789"
|
||||
:type "text"
|
||||
:field [:number]}]]]
|
||||
|
||||
[form-builder/field
|
||||
"Yodlee Account"
|
||||
[:input.input {:placeholder "Yodlee Account #"
|
||||
[form-builder/field-v2 {:field :number}
|
||||
"Account #"
|
||||
[:input.input {:placeholder "123456789"
|
||||
:type "text"
|
||||
:field [:yodlee-account-id]}]]
|
||||
[form-builder/field
|
||||
:style {:width "20em"}}]]
|
||||
|
||||
[form-builder/field-v2 {:field :yodlee-account}
|
||||
"Yodlee Account (new)"
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::yodlee-accounts (:id new-client)])
|
||||
:entity->text (fn [m] (str (:name m) " - " (:number m)))
|
||||
:type "typeahead-v3"
|
||||
:field [:yodlee-account]}]]
|
||||
[:div.field
|
||||
[:label.checkbox
|
||||
[form-builder/raw-field
|
||||
[:input {:type "checkbox"
|
||||
:field [:use-date-instead-of-post-date]}]]
|
||||
" (Yodlee only) Use 'date' instead of 'postDate'"]]
|
||||
[form-builder/field
|
||||
:entity->text (fn [m] (str (:name m) " - " (:number m)))}]]
|
||||
|
||||
[form-builder/raw-field-v2 {:field :use-date-instead-of-post-date}
|
||||
[com/checkbox {:label "(Yodlee only) Use 'date' instead of 'postDate'"}]
|
||||
[:input {:type "checkbox"
|
||||
:field [:use-date-instead-of-post-date]}]]
|
||||
|
||||
[form-builder/field-v2 {:field :intuit-bank-account}
|
||||
"Intuit Bank Account"
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/intuit-bank-accounts])
|
||||
:entity->text (fn [m] (str (:name m)))
|
||||
:type "typeahead-v3"
|
||||
:field [:intuit-bank-account]}]]
|
||||
[form-builder/field
|
||||
:entity->text (fn [m] (str (:name m)))}]]
|
||||
|
||||
[form-builder/field-v2 {:field :plaid-account}
|
||||
"Plaid Account"
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::plaid-accounts (:id new-client)])
|
||||
:entity->text (fn [m] (str (:name m)))
|
||||
:type "typeahead-v3"
|
||||
:field [:plaid-account]}]]])
|
||||
:entity->text (fn [m] (str (:name m)))}]]])
|
||||
[:div.field
|
||||
[:label.label "Locations"]
|
||||
[:div.control
|
||||
[:p.help "If this account is location-specific, add the valid locations"]
|
||||
[form-builder/raw-field
|
||||
[multi-field {:type "multi-field"
|
||||
:field [:locations]
|
||||
:template [[:select.select {:type "select"
|
||||
:style {:width "7em"}
|
||||
:allow-nil? true
|
||||
:field [:location]
|
||||
:spec (set (map :location (get-in new-client [:locations])))}
|
||||
[:<>
|
||||
[:option ""]
|
||||
[:<> (map (fn [l] ^{:key (:location l)}
|
||||
[:option {:value (:location l)} (:location l)])
|
||||
(get-in new-client [:locations]))]]]]}]]]]
|
||||
[:div.field
|
||||
[:label.checkbox
|
||||
[form-builder/raw-field
|
||||
[:input {:type "checkbox"
|
||||
:field [:include-in-reports]}]]
|
||||
" Include in reports"]]])
|
||||
[form-builder/raw-field-v2 {:field :locations}
|
||||
[com/multi-field-v2 {:template [[form-builder/raw-field {:key :location}
|
||||
[com/select-field {:options (map (fn [l]
|
||||
[(:location l) (:location l)])
|
||||
(get-in new-client [:locations]))
|
||||
:allow-nil? true
|
||||
:style {:width "7em"}
|
||||
}]]]
|
||||
:schema [:sequential location-schema]
|
||||
:key-fn :id}]]]]
|
||||
|
||||
[form-builder/raw-field-v2 {:field :include-in-reports}
|
||||
[com/checkbox {:label "Include in reports"}]
|
||||
]
|
||||
])
|
||||
|
||||
(when active?
|
||||
[:footer.card-footer
|
||||
@@ -609,28 +566,32 @@
|
||||
[form-builder/raw-field-v2 {:field :address}
|
||||
[address2-field]]]]])
|
||||
|
||||
;; TODO Name matches, locations, bank account locations are all "single field multis", and require weird mounting and
|
||||
;; unmounting. A new field could sort that out easily
|
||||
(defn matching-section []
|
||||
[form-builder/section {:title "Matching"}
|
||||
[form-builder/field
|
||||
[form-builder/field-v2 {:field :matches}
|
||||
"Name matches"
|
||||
[multi-field {:type "multi-field"
|
||||
:field :matches
|
||||
:template [[:input.input {:field [:match]
|
||||
:placeholder "Harry's burger joint"
|
||||
:style { :width "15em"}}]]}]]
|
||||
[com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field [:match]}
|
||||
[:input.input {:placeholder "Harry's burger joint"
|
||||
:style { :width "15em"}}]]]
|
||||
:key-fn :id
|
||||
:next-key (random-uuid)
|
||||
:schema [:sequential name-match-schema]}]]
|
||||
|
||||
|
||||
[form-builder/field
|
||||
[form-builder/field-v2 {:field :location-matches}
|
||||
"Location Matches"
|
||||
[multi-field {:type "multi-field"
|
||||
:field :location-matches
|
||||
:template [[:input.input {:field [:match]
|
||||
:placeholder "Downtown"
|
||||
:style { :width "15em"}}]
|
||||
[:input.input {:field [:location]
|
||||
:placeholder "DT"
|
||||
:max-length 2
|
||||
:style { :width "4em"}}]]}]]])
|
||||
[com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :match}
|
||||
[:input.input {:placeholder "Downtown"
|
||||
:style { :width "15em"}}]]
|
||||
[form-builder/raw-field-v2 {:field :location}
|
||||
[:input.input {:placeholder "DT"
|
||||
:max-length 2
|
||||
:style { :width "4em"}}]]]
|
||||
:schema [:sequential location-match-schema]
|
||||
:next-key (random-uuid)
|
||||
:key-fn :id}]]])
|
||||
|
||||
(defn bank-accounts-section []
|
||||
(let [{new-client :data} @(re-frame/subscribe [::forms/form ::form])]
|
||||
|
||||
Reference in New Issue
Block a user