improved two major forms.

This commit is contained in:
2022-07-19 15:10:33 -07:00
parent 483e9ad311
commit 0baab4eaf0
14 changed files with 431 additions and 355 deletions

View File

@@ -142,10 +142,6 @@
(re-frame/reg-event-fx
::set-active-route
(fn [{:keys [db]} [_ handler params route-params]]
(println "HANDELR IS" handler (:user db))
(cond
(and (not= :login handler) (not (:user db)))
{:redirect (bidi/path-for routes/routes :login)

View File

@@ -7,7 +7,8 @@
[auto-ap.forms :as forms]
[auto-ap.status :as status]
[malli.core :as m]
[malli.error :as me]))
[malli.error :as me]
[clojure.string :as str]))
(defonce ^js/React.Context form-context (react/createContext "default"))
(def ^js/React.Provider Provider (. form-context -Provider))
@@ -161,7 +162,9 @@
[:div
[:p.help.has-text-danger error-message]]))))]))])
(defn raw-field-v2 [{:keys [field]}]
(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]
@@ -188,7 +191,6 @@
(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]
@@ -198,8 +200,12 @@
""
(not (valid-field? (aget consume-form "problems") full-field-path))
" is-danger"
value
"is-success"
:else
"is-success"))))))))))]))]))
""))))))))))]))]))
(defn with-scope [{:keys [scope]}]
(r/create-element FormScopeProvider #js {:value scope}

View File

@@ -11,6 +11,8 @@
(def money (m/schema [float? {:error/message "Invalid money"}]))
(def not-empty-string (m/schema [:re {:error/message "Required"} #"\S+"]))
(def keyword (m/schema [:fn (fn [d]
(keyword? d))]))
(def expense-account (m/schema [:map
[:id :string]

View File

@@ -22,6 +22,12 @@
(when (:user db)
(sort-by :name (vals (:clients db))))))
(re-frame/reg-sub
::client-refs
:<- [::clients]
(fn [c]
(map #(select-keys % [:id :name]) c)))
(re-frame/reg-sub
::all-accounts
(fn [db]

View File

@@ -0,0 +1,34 @@
(ns auto-ap.views.components
(:require [reagent.core :as r]
[clojure.string :as str]))
(defn checkbox [{:keys [on-change
value
label]
:as props}]
(into [:label.checkbox
[:input (-> props
(assoc
:type "checkbox"
:on-change (fn []
(on-change (not value)))
:checked value)
(dissoc :value))]
" " label
]
(r/children (r/current-component))))
(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])]]])

View File

@@ -1,108 +1,34 @@
(ns auto-ap.views.components.address
(:require [auto-ap.entities.address :as address]
[auto-ap.views.utils :refer [dispatch-value-change dispatch-event bind-field horizontal-field]]
[auto-ap.forms.builder :as form-builder]))
[auto-ap.forms.builder :as form-builder]
[auto-ap.views.components.level :as level]))
(defn address-field [{:keys [event field subscription]}]
[:span
[horizontal-field
nil
[:div.control
[:p.help "Address"]
[bind-field
[:input.input.is-expanded {:type "text"
:placeholder "1700 Pennsylvania Ave"
:field (conj field :street1)
:spec ::address/street1
:event event
:subscription subscription}]]]]
[horizontal-field
nil
[:div.control
[bind-field
[:input.input.is-expanded {:type "text"
:placeholder "Suite 400"
:field (conj field :street2)
:spec ::address/street2
:event event
:subscription subscription}]]]]
[horizontal-field
nil
[:div.control
[:p.help "City"]
[bind-field
[:input.input.is-expanded {:type "text"
:placeholder "Cupertino"
:field (conj field :city)
:spec ::address/city
:event event
:subscription subscription}]]]
[:div.control
[:p.help "State"]
[bind-field
[:input.input {:type "text"
:placeholder "CA"
:field (conj field :state)
:spec ::address/state
:size 2
:max-length "2"
:event event
:subscription subscription}]]]
[:div.control
[:p.help "Zip"]
[bind-field
[:input.input {:type "text"
:field (conj field :zip)
:spec ::address/zip
:event event
:subscription subscription
:placeholder "95014"}]]]]])
(defn address2-field []
[:span
[horizontal-field
nil
[:div.control
(defn address2-field [{:keys [value on-change]}]
[form-builder/virtual-builder {:value (or value {})
:on-change on-change}
[:div
[form-builder/field-v2 {:field :street1}
[:p.help "Street Address"]
[form-builder/raw-field
[:input.input.is-expanded {:type "text"
:placeholder "1700 Pennsylvania Ave"
:field [:street1]
:spec ::address/street1}]]]]
[horizontal-field
nil
[:div.control
[form-builder/raw-field
[:input.input.is-expanded {:type "text"
:placeholder "Suite 400"
:field [:street2]
:spec ::address/street2}]]]]
[horizontal-field
nil
[:div.control
[:p.help "City"]
[form-builder/raw-field
[:input.input.is-expanded {:type "text"
[:input.input.is-expanded {:type "text"
:placeholder "1700 Pennsylvania Ave"}]]
[form-builder/raw-field-v2 {:field :street2}
[:input.input.is-expanded {:type "text"
:placeholder "Suite 400"}]]
[level/left-stack
[form-builder/field-v2 {:field :city}
[:p.help "City"]
[:input.input.is-expanded {:type "text"
:placeholder "Cupertino"
:field [:city]
:spec ::address/city}]]]
[:div.control
[:p.help "State"]
[form-builder/raw-field
[:input.input {:type "text"
:placeholder "CA"
:field [:state]
:spec ::address/state
:size 2
:max-length "2"}]]]
[:div.control
[:p.help "Zip"]
[form-builder/raw-field
[:input.input {:type "text"
:field [:zip]
:spec ::address/zip
:placeholder "95014"}]]]]])
:field [:city]
:spec ::address/city}]]
[form-builder/field-v2 {:field :state}
[:p.help "State"]
[:input.input {:type "text"
:placeholder "CA"
:size 2
:max-length "2"}]]
[form-builder/field-v2 {:field :zip}
[:p.help "Zip"]
[:input.input {:type "text"
:placeholder "95014"}]]]]])

View File

@@ -1,5 +1,6 @@
(ns auto-ap.views.components.bank-account-filter
(:require
[auto-ap.views.utils :refer [->$]]
[auto-ap.subs :as subs]
[re-frame.core :as re-frame]))

View File

@@ -0,0 +1,68 @@
(ns auto-ap.views.components.multi
(:require
[cemerick.url]
#_{:clj-kondo/ignore [:unused-namespace]}
[reagent.core :as reagent]
[react :as react]
[auto-ap.entities.shared :as shared]
[auto-ap.views.utils :refer [appearing-group]]
[auto-ap.forms.builder :as form-builder]))
(defn multi-field-v2-internal [{:keys [template key-fn next-key allow-change? disable-new? disable-remove? schema on-change disabled new-text] prop-value :value :as props} ]
(let [prop-value (if (seq prop-value)
prop-value
[])]
[form-builder/virtual-builder {:value prop-value
:schema schema
:on-change on-change}
[:fieldset {:disabled disabled}
[:div {:style {:margin-bottom "0.25em"}}
(into [appearing-group]
(for [[i override] (map vector (range) prop-value)
:let [is-disabled? (if (= false allow-change?)
(not (boolean (::new? override)))
nil)]]
^{:key (or (key-fn override)
(::key override))}
[form-builder/with-scope {:scope [i]}
^{:key (or (key-fn override)
(::key override))}
[:div.level {:style {:margin-bottom "0.25em"}}
[:div.level-left {:style {:padding "0.5em 1em"}
:class (when-not (key-fn override)
"has-background-info-light")}
(let [template (if (fn? template)
(template override)
template)]
(for [[idx template] (map vector (range ) template)]
^{:key idx}
[:div.level-item
template]))
(when-not disable-remove?
[:div.level-item
[:a.button.level-item
{:disabled is-disabled?
:on-click (fn []
(on-change (into []
(for [[idx item] (map vector (range) prop-value)
:when (not= idx i)]
item))))}
[:span.icon [:span.icon-remove]]]])]]]))
(when-not disable-new?
[:button.button.is-outline
{:type "button"
:on-click (fn [e]
(on-change (conj prop-value {::key next-key}))
(.stopPropagation e)
(.preventDefault e))}
[:span.icon [:i.fa.fa-plus]]
[:span (or new-text "New")]])]]]))
(defn multi-field-v2 []
(into
[:f> multi-field-v2-internal
(reagent/props (reagent/current-component))]
(reagent/children (reagent/current-component))))

View File

@@ -0,0 +1,43 @@
(ns auto-ap.views.components.number
(:require [react :as react]
[reagent.core :as r]))
(defn number-internal [props]
(let [[text set-text ] (react/useState (some-> props :value str))
[value set-value ] (react/useState (some-> props :value))
coerce-value (fn [new-value]
(let [new-value (js/parseInt new-value)]
(cond
(nil? new-value)
nil
(js/Number.isNaN new-value)
nil
:else
new-value)))]
(react/useEffect (fn []
(let [prop-value (:value props)]
(when (not (= prop-value value))
(set-value prop-value)
(if prop-value
(set-text (str prop-value))
(set-text ""))))))
[:div.field.has-addons
[:div.control
[:input.input (assoc props
:on-change (fn [e]
((:on-change props)
(coerce-value (.. e -target -value))))
:value text
:type "number"
:step "1"
:style {:width "5em"}
:size 3)]]]))
(defn number-input []
[:f> number-internal
(r/props (r/current-component))])

View File

@@ -7,26 +7,76 @@
[auto-ap.status :as status]
[auto-ap.views.components.level :refer [left-stack]]
[auto-ap.subs :as subs]
[auto-ap.views.components :as com]
[auto-ap.views.components.address :refer [address2-field]]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.components.number :refer [number-input]]
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
[auto-ap.views.components.typeahead.vendor
:refer [search-backed-typeahead]]
[auto-ap.views.pages.admin.vendors.common :as common]
[auto-ap.views.components.multi :refer [multi-field-v2]]
[auto-ap.views.utils
:refer [dispatch-event multi-field str->int with-is-admin? with-user]]
[clojure.spec.alpha :as s]
[re-frame.core :as re-frame]
[reagent.core :as r]))
[reagent.core :as r]
[malli.core :as m]
[auto-ap.schema :as schema]
[malli.error :as me]))
;; Remaining cleanup todos:
;; test minification
(def terms-override-schema (m/schema [:map
[:client schema/reference]
[:terms :int]]))
(def automatically-paid-schema (m/schema [:map
[:client schema/reference]]))
(def schedule-payment-dom-schema (m/schema [:map
[:client schema/reference]
[:dom [:int {:max 30}]]]))
(def account-override-schema (m/schema [:map
[:client schema/reference]
[:account schema/reference]]))
(def schema (m/schema [:map [:name schema/not-empty-string]
[:print-as {:optional true}
[:maybe :string]]
[:hidden {:optional true}
[:maybe :boolean]]
[:terms {:optional true}
[:maybe :int]]
[:terms-overrides {:optional true}
[:maybe [:sequential terms-override-schema]]]
[:schedule-payment-dom {:optional true}
[:maybe [:sequential schedule-payment-dom-schema]]]
[:default-account schema/reference]
[:account-overrides {:optional true}
[:sequential account-override-schema]]
[:legal-entity-first-name {:optional true}
[:maybe :string]]
[:legal-entity-middle-name {:optional true}
[:maybe :string]]
[:legal-entity-last-name {:optional true}
[:maybe :string]]
[:legal-entity-tin {:optional true}
[:maybe :string]]
[:legal-entity-tin-type {:optional true}
[:or [:maybe :string]
[:maybe keyword?]]]
[:legal-entity-1099-type {:optional true}
[:or [:maybe :string]
[:maybe keyword?]]]]))
(re-frame/reg-sub
::can-submit
:<- [::forms/form ::vendor-form]
(fn [form]
(s/valid? ::entity/vendor (:data form))))
(m/validate schema (:data form))))
(re-frame/reg-event-fx
@@ -39,56 +89,55 @@
::save
[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} _]
(when (s/valid? ::entity/vendor data)
(let [query [:upsert-vendor
{:vendor (cond-> {:id id
:name name
:print-as print-as
:terms (or (str->int terms)
(let [query [:upsert-vendor
{:vendor (cond-> {:id id
:name name
:print-as print-as
:terms (or terms
nil)
:default-account-id (:id default-account)
:address address
:primary-contact primary-contact
:secondary-contact secondary-contact
:invoice-reminder-schedule invoice-reminder-schedule}
is-admin? (assoc :hidden hidden
:terms-overrides (mapv
(fn [{:keys [client terms id]}]
{:id id
:client-id (:id client)
:terms (or (str->int terms) 0)})
terms-overrides)
:account-overrides (mapv
(fn [{:keys [client account id]}]
{:id id
:client-id (:id client)
:account-id (:id account)})
account-overrides)
:schedule-payment-dom (mapv
(fn [{:keys [client dom id]}]
{:id id
:client-id (:id client)
:dom (or (str->int dom)
0)})
schedule-payment-dom)
:automatically-paid-when-due (mapv
(comp :id :client)
automatically-paid-when-due)
:legal-entity-first-name legal-entity-first-name
:legal-entity-middle-name legal-entity-middle-name
:legal-entity-last-name legal-entity-last-name
:legal-entity-tin legal-entity-tin
: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]]
{ :graphql
{:token user
:owns-state {:single ::vendor-form}
:query-obj {:venia/operation
{:operation/type :mutation
:operation/name "UpsertVendor"} :venia/queries [{:query/data query}]}
:on-success [::save-complete]}}))))
:default-account-id (:id default-account)
:address address
:primary-contact primary-contact
:secondary-contact secondary-contact
:invoice-reminder-schedule invoice-reminder-schedule}
is-admin? (assoc :hidden hidden
:terms-overrides (mapv
(fn [{:keys [client terms id]}]
{:id id
:client-id (:id client)
:terms (or (str->int terms) 0)})
terms-overrides)
:account-overrides (mapv
(fn [{:keys [client account id]}]
{:id id
:client-id (:id client)
:account-id (:id account)})
account-overrides)
:schedule-payment-dom (mapv
(fn [{:keys [client dom id]}]
{:id id
:client-id (:id client)
:dom (or (str->int dom)
0)})
schedule-payment-dom)
:automatically-paid-when-due (mapv
(comp :id :client)
automatically-paid-when-due)
:legal-entity-first-name legal-entity-first-name
:legal-entity-middle-name legal-entity-middle-name
:legal-entity-last-name legal-entity-last-name
:legal-entity-tin legal-entity-tin
: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]]
{ :graphql
{:token user
:owns-state {:single ::vendor-form}
:query-obj {:venia/operation
{:operation/type :mutation
:operation/name "UpsertVendor"} :venia/queries [{:query/data query}]}
:on-success [::save-complete]}})))
(defn pull-left []
(into [:div {:style {:position "relative"
@@ -103,10 +152,8 @@
[form-builder/vertical-control {:is-small? true}
"Name"
[:div.control.has-icons-left
[form-builder/raw-field
[:input.input.is-expanded {:type "text"
:field :name
:spec ::contact/name}]]
[form-builder/raw-field-v2 {:field :name}
[:input.input.is-expanded {:type "text"}]]
[:span.icon.is-small.is-left
[:i.fa.fa-user]]]]
[form-builder/vertical-control {:is-small? true}
@@ -115,137 +162,118 @@
[:div.control.has-icons-left
[:span.icon.is-small.is-left
[:i.fa.fa-envelope]]
[form-builder/raw-field
[:input.input {:type "email"
:field :email
:spec ::contact/email}]]]]
[form-builder/raw-field-v2 {:field :email}
[:input.input {:type "email"}]]]]
[form-builder/vertical-control {:is-small? true}
"Phone"
[:div.control.has-icons-left
[form-builder/raw-field
[:input.input {:type "phone"
:field :phone
:spec ::contact/phone}]]
[form-builder/raw-field-v2 {:field :phone}
[:input.input {:type "phone"}]]
[:span.icon.is-small.is-left
[:i.fa.fa-phone]]]]]]])
(defn form-content [{:keys [data]}]
(let [is-admin? @(re-frame/subscribe [::subs/is-admin?])
clients @(re-frame/subscribe [::subs/clients])]
clients @(re-frame/subscribe [::subs/client-refs])]
[form-builder/builder {:submit-event [::save]
:can-submit [::can-submit]
:id ::vendor-form}
[form-builder/field
[:span "Name " [:span.has-text-danger "*"]]
[:input.input {:type "text"
:auto-focus true
:field :name
:spec ::entity/name}]]
:id ::vendor-form
:schema schema}
[form-builder/field-v2 {:field :name
:required true}
"Name"
[:input.input {:auto-focus true}]]
[form-builder/field
[form-builder/field-v2 {:field :print-as}
"Print Checks As"
[:input.input {:type "text"
:field :print-as
:spec ::entity/print-as}]]
[:input.input]]
(when is-admin?
[:div.field
[:label.checkbox
[form-builder/raw-field
[:input {:type "checkbox"
:field [:hidden]
:spec ::entity/hidden}]]
" Hidden"]])
[form-builder/raw-field-v2 {:field :hidden}
[com/checkbox {:label "Hidden"}]])
[form-builder/section {:title "Terms"}
[form-builder/field
[form-builder/field-v2 {:field :terms}
"Terms"
[:input.input {:type "number"
:step "1"
:style {:width "4em"}
:field [:terms]
:size 3
:spec ::entity/terms}]]
[number-input ]]
(when is-admin?
[form-builder/field
[form-builder/field-v2 {:field [:terms-overrides]}
"Overrides"
[multi-field {:type "multi-field"
:field [:terms-overrides]
:template [[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "13em"}
:type "typeahead-v3"
:field [:client]}]
[:input.input {:type "number"
:step "1"
:style {:width "4em"}
:field [:terms]
:size 3
:spec ::entity/terms}]]}]])
]
[multi-field-v2 {:template [[form-builder/raw-field-v2 {:field [:client]}
[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "13em"}
:type "typeahead-v3"
}]]
[form-builder/raw-field-v2 {:field :terms}
[number-input]]]
:schema [:sequential terms-override-schema]
:key-fn :id
:next-key (random-uuid)
:new-text "New Terms Override"}]])]
(when is-admin?
[form-builder/section {:title "Schedule payment when due"}
[form-builder/field
[form-builder/field-v2 {:field [:automatically-paid-when-due]}
"Client"
[multi-field {:type "multi-field"
:field [:automatically-paid-when-due]
:template [[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "13em"}
:type "typeahead-v3"
:field [:client]}]]}]]])
[multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :client}
[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "13em"}}]]]
:schema [:sequential automatically-paid-schema]
:key-fn :id
:next-key (random-uuid)
:new-text "Schedule another client"}]]])
(when is-admin?
[form-builder/section {:title "Schedule payment on day of month"}
[form-builder/field
[form-builder/field-v2 {:field [:schedule-payment-dom]}
"Overrides"
[multi-field {:type "multi-field"
:field [:schedule-payment-dom]
:template [[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "13em"}
:type "typeahead-v3"
:field [:client]}]
[:input.input {:type "number"
:step "1"
:style {:width "4em"}
:field [:dom]
:size 3
:spec ::entity/terms}]]}]]])
[multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :client}
[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "13em"}}]]
[form-builder/raw-field-v2 {:field :dom}
[number-input]]]
:schema [:sequential schedule-payment-dom-schema]
:key-fn :id
:next-key (random-uuid)
:new-text "Schedule another client"}]]])
[form-builder/section {:title "Expense Accounts"}
[form-builder/field
"Default *"
[form-builder/field-v2 {:field :default-account
:required? true}
"Default"
[search-backed-typeahead {:search-query (fn [i]
[:search_account
{:query i}
[:name :id]])
:type "typeahead-v3"
:style {:width "19em"}
:field [:default-account]}]]
:style {:width "19em"}}]]
(when is-admin?
[form-builder/field
[form-builder/field-v2 {:field [:account-overrides]}
"Overrides"
[multi-field {:type "multi-field"
:field [:account-overrides]
:template (fn [entity]
[[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "19em"}
:type "typeahead-v3"
:field [:client]}]
[search-backed-typeahead {:search-query (fn [i]
[:search_account
{:query i
:client_id (:id (:client entity))}
[:name :id]])
:type "typeahead-v3"
:style {:width "15em"}
:field [:account]}]])}]])]
[multi-field-v2 {:template (fn [entity]
[[form-builder/raw-field-v2 {:field :client}
[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "19em"}
}]]
[form-builder/raw-field-v2 {:field :account}
[search-backed-typeahead {:search-query (fn [i]
[:search_account
{:query i
:client_id (:id (:client entity))}
[:name :id]])
:style {:width "15em"}}]]])
:schema [:sequential account-override-schema]
:key-fn :id
:next-key (random-uuid)
:new-text "Add override"}]])]
[form-builder/with-scope {:scope [:address ]}
[form-builder/section {:title "Address"}
[:div {:style {:width "30em"}}
[form-builder/section {:title "Address"}
[:div {:style {:width "30em"}}
[form-builder/raw-field-v2 {:field :address}
[address2-field]]]]
[form-builder/section {:title "Contact"}
@@ -261,55 +289,40 @@
"Name"
[left-stack
[:div.control
[form-builder/raw-field
[form-builder/raw-field-v2 {:field :legal-entity-first-name}
[:input.input {:type "text"
:placeholder "First Name"
:field [:legal-entity-first-name]
:spec ::contact/name}]]]
:placeholder "First Name"}]]]
[:div.control
[form-builder/raw-field
[form-builder/raw-field-v2 {:field :legal-entity-middle-name}
[:input.input {:type "text"
:placeholder "Middle Name"
:field [:legal-entity-middle-name]
:spec ::contact/name}]]]
:placeholder "Middle Name"}]]]
[:div.control
[form-builder/raw-field
[form-builder/raw-field-v2 {:field :legal-entity-last-name}
[:input.input {:type "text"
:placeholder "Last Name"
:field [:legal-entity-last-name]
:spec ::contact/name}]]]]]
:placeholder "Last Name"}]]]]]
[form-builder/vertical-control
"TIN"
[left-stack
[form-builder/raw-field
[form-builder/raw-field-v2 {:field :legal-entity-tin}
[:input.input {:type "text"
:placeholder "SSN or EIN"
:field [:legal-entity-tin]
:size "12"
:spec ::contact/name}]]
}]]
[:div.control
[:div.select
[form-builder/raw-field
[:select {:type "select"
:field [:legal-entity-tin-type]}
[:option {:value nil} ""]
[:option {:value "ein"} "EIN"]
[:option {:value "ssn"} "SSN"]]]]]]]
[form-builder/raw-field-v2 {:field :legal-entity-tin-type}
[com/select-field {:options [["ein" "EIN"]
["ssn" "SSN"]]
:allow-nil? true}]]]]]
[form-builder/vertical-control
[form-builder/field-v2 {:field :legal-entity-1099-type}
"1099 Type"
[:div.control
[:div.select
[form-builder/raw-field
[:select {:type "select"
:field [:legal-entity-1099-type]}
[:option {:value nil} ""]
[:option {:value "none"} "Don't 1099"]
[:option {:value "misc"} "Misc"]
[:option {:value "landlord"} "Landlord"]]]]]]])
[com/select-field {:options [["none" "Don't 1099"]
["misc" "Misc"]
["landlord" "Landlord"]]
:allow-nil? true}]]])
[form-builder/hidden-submit-button]]))
(defn vendor-dialog [ ]
@@ -342,15 +355,15 @@
[form-builder/builder {:submit-event [::vendor-selected]
:can-submit [::can-submit-select-vendor-form]
:id ::select-vendor-form}
[form-builder/field
[form-builder/field-v2 {:field :vendor
:required? true}
"Vendor to edit"
[search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:type "typeahead-v3"
:auto-focus true
:field [:vendor]}]]
:style {:width "20em"}
:auto-focus true}]]
[form-builder/hidden-submit-button]])
@@ -360,6 +373,7 @@
(fn [{:keys [db]} [_ vendor]]
{:db (-> db (forms/start-form ::vendor-form (-> vendor
(update :automatically-paid-when-due #(mapv (fn [apwd]
apwd
{:id (:id apwd)
:client apwd})
%))

View File

@@ -595,12 +595,11 @@
:placeholder "Manager"
:field [:description]}]]}]]
[form-builder/with-scope {:scope [:address ]}
[:div.field
[:label.label "Address"]
[:div.control
[:div {:style {:width "30em"}}
[address2-field]]]]]])
[form-builder/vertical-control
"Address"
[:div {:style {:width "30em"}}
[form-builder/raw-field-v2 {:field :address}
[address2-field]]]]])
(defn matching-section []
[form-builder/section {:title "Matching"}

View File

@@ -1,25 +1,15 @@
(ns auto-ap.views.pages.admin.users
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[clojure.string :as str]
[auto-ap.subs :as subs]
[auto-ap.events :as events]
[auto-ap.entities.clients :as entity]
[auto-ap.views.components.address :refer [address-field]]
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
[auto-ap.views.pages.admin.users.table :as table]
[auto-ap.views.components.layouts :refer [side-bar-layout]]
[auto-ap.views.utils :refer [login-url dispatch-value-change bind-field horizontal-field dispatch-event]]
[auto-ap.views.components.grid :as grid]
[auto-ap.utils :refer [by replace-by]]
[cljs.reader :as edn]
[auto-ap.routes :as routes]
[bidi.bidi :as bidi]
[auto-ap.status :as status]
[auto-ap.views.pages.admin.users.form :as form]
[auto-ap.effects.forward :as forward]))
(:require
[auto-ap.effects.forward :as forward]
[auto-ap.status :as status]
[auto-ap.utils :refer [replace-by]]
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
[auto-ap.views.components.grid :as grid]
[auto-ap.views.components.layouts :refer [side-bar-layout]]
[auto-ap.views.pages.admin.users.form :as form]
[auto-ap.views.pages.admin.users.table :as table]
[re-frame.core :as re-frame]
[reagent.core :as reagent]))
(re-frame/reg-sub
::params

View File

@@ -1,26 +1,15 @@
(ns auto-ap.views.pages.admin.yodlee2
(:require [re-frame.core :as re-frame]
[auto-ap.forms :as forms]
[reagent.core :as reagent]
[clojure.string :as str]
[cljs-time.format :as f]
[cljs-time.core :as time]
[auto-ap.subs :as subs]
[auto-ap.events :as events]
[auto-ap.entities.clients :as entity]
[auto-ap.views.components.layouts :refer [side-bar-layout]]
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
[auto-ap.views.components.address :refer [address-field]]
[auto-ap.views.utils :refer [login-url dispatch-event dispatch-value-change bind-field horizontal-field str->date date->str with-user]]
[auto-ap.views.components.modal :as modal]
[auto-ap.status :as status]
[cljs.reader :as edn]
[auto-ap.routes :as routes]
[bidi.bidi :as bidi]
[auto-ap.views.pages.admin.yodlee2.table :as table]
[auto-ap.views.pages.admin.yodlee2.form :as form]
[auto-ap.views.components.grid :as grid]
[auto-ap.effects.forward :as forward]))
(:require
[auto-ap.effects.forward :as forward]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
[auto-ap.views.components.grid :as grid]
[auto-ap.views.components.layouts :refer [side-bar-layout]]
[auto-ap.views.pages.admin.yodlee2.table :as table]
[auto-ap.views.utils :refer [dispatch-event]]
[re-frame.core :as re-frame]
[reagent.core :as reagent]))
(re-frame/reg-sub
::authentication

View File

@@ -157,13 +157,13 @@
(for [child children]
^{:key (:key (meta child))}
[transition
{:timeout 300
{:timeout 200
:exit true
:in true #_ (= current-stack- (:key (meta child)))}
(clj->js (fn [state]
(r/as-element
[:div {:style {
:transition "opacity 300ms ease-in-out"
:transition "opacity 150ms ease-in-out"
:opacity (cond
(= "entered" state)
1.0
@@ -264,17 +264,19 @@
[:span.icon [:span.icon-remove]]]])
]])]))))
(defmethod do-bind "select" [dom {:keys [field allow-nil? subscription event class spec] :as keys} & rest]
(let [field (if (keyword? field) [field] field)
event (if (keyword? event) [event] event)
keys (assoc keys
:on-change (dispatch-value-change (conj event field))
keys (assoc keys
:on-change (dispatch-value-change (conj event field))
:value (or (get-in subscription field) "")
:class (str class
(when (and spec (not (s/valid? spec (get-in subscription field))))
" is-danger")))
keys (dissoc keys :field :subscription :event :spec)
:value (or (get-in subscription field) "")
:class (str class
(when (and spec (not (s/valid? spec (get-in subscription field))))
" is-danger")))
keys (dissoc keys :field :subscription :event :spec)
options (if allow-nil?
(with-keys (conj rest [:option {:value nil}]))
(with-keys rest))]