diff --git a/src/clj/auto_ap/datomic/transactions.clj b/src/clj/auto_ap/datomic/transactions.clj index 4d2b4e35..f59ea98c 100644 --- a/src/clj/auto_ap/datomic/transactions.clj +++ b/src/clj/auto_ap/datomic/transactions.clj @@ -247,6 +247,7 @@ :transaction/bank-account [:bank-account/name :bank-account/code :bank-account/yodlee-account-id :db/id :bank-account/locations :bank-account/current-balance] :transaction/vendor [:db/id :vendor/name] :transaction/matched-rule [:db/id :transaction-rule/note] + :transaction/forecast-match [:db/id :forecasted-transaction/identifier] :transaction/accounts [:transaction-account/amount :db/id :transaction-account/location diff --git a/src/cljs/auto_ap/forms.cljs b/src/cljs/auto_ap/forms.cljs index cedb5029..de4f6b71 100644 --- a/src/cljs/auto_ap/forms.cljs +++ b/src/cljs/auto_ap/forms.cljs @@ -100,12 +100,6 @@ (re-frame/reg-event-db ::check-problems (fn [db [_ form schema]] - (println "Checking problems" - form - (get-in db [::forms form :data]) - (keys (get-in db [::forms])) - schema - (m/explain schema (get-in db [::forms form :data]))) (assoc-in db [::forms form :problems] (when schema (m/explain schema (get-in db [::forms form :data])))))) diff --git a/src/cljs/auto_ap/forms/builder.cljs b/src/cljs/auto_ap/forms/builder.cljs index 2fd5a0fe..3c6a3093 100644 --- a/src/cljs/auto_ap/forms/builder.cljs +++ b/src/cljs/auto_ap/forms/builder.cljs @@ -89,11 +89,13 @@ (into [:fieldset {:disabled (boolean (= :loading (:state status)))}] (r/children (r/current-component)))] )))) - +;; TODO make virtual builder operate as a cursor and an input instead of a whole new thing +;; make it inherit the outer form, avoiding creating new forms (defn virtual-builder [] (let [starting-key (random-uuid) key (r/atom starting-key)] - (fn [{:keys [value on-change can-submit error-messages fullwidth? schema]}] + (re-frame/dispatch [::forms/start-form starting-key []]) + (fn [{:keys [value on-change can-submit error-messages fullwidth? schema attempted-submit?]}] (let [data-sub [::forms/form @key] {:keys [data error problems visited]} @(re-frame/subscribe data-sub) data (or value data)] @@ -101,11 +103,12 @@ :error-messages (or error-messages nil) ;; wrap to make sure raw form updates too - :on-change (fn [v] + :on-change (fn [v o] (re-frame/dispatch-sync [::forms/reset @key v]) - (on-change v)) + (on-change v o)) :blur-event [::blurred schema @key ] :problems problems + :attempted-submit? attempted-submit? :visited visited :error error :id @key @@ -206,7 +209,6 @@ nil) visited? (get visited full-field-path) value (get-in data full-field-path)] - (println "VISITED " visited full-field-path problems) (-> child-props (assoc :on-change (if on-change @@ -246,22 +248,6 @@ label)]) (into [:div.control ] children)])))) -(defn field [] - (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 {} child]]]))])) - (defn field-v2 [] (let [props (r/props (r/current-component)) [label child] (r/children (r/current-component))] @@ -280,23 +266,6 @@ [:div [raw-error-v2 {:field (:field props)}]]])))) -(defn horizontal-control [] - (let [[label & children] (r/children (r/current-component))] - [:div.field.is-horizontal - (when label - [:div.field-label [:label.label label]]) - [:div.field-body - (for [[i child] (map vector (range) children)] - ^{:key i} - [:div.field - child])]])) - -(defn horizontal-field [] - (let [[label child] (r/children (r/current-component))] - [horizontal-control - label - [raw-field {} child]])) - (defn section [{:keys [title]}] [:<> [:h4.is-4.title title] diff --git a/src/cljs/auto_ap/schema.cljs b/src/cljs/auto_ap/schema.cljs index 58b76f55..b3ae551e 100644 --- a/src/cljs/auto_ap/schema.cljs +++ b/src/cljs/auto_ap/schema.cljs @@ -21,3 +21,6 @@ [:account reference] [:location :string] [:amount money]])) + + +(def approval-status (m/schema [:enum :unapproved :requires-feedback :approved :excluded])) diff --git a/src/cljs/auto_ap/views/components.cljs b/src/cljs/auto_ap/views/components.cljs index 80b7a82b..b5de7fee 100644 --- a/src/cljs/auto_ap/views/components.cljs +++ b/src/cljs/auto_ap/views/components.cljs @@ -4,7 +4,8 @@ [auto-ap.views.components.multi :as multi] [auto-ap.views.components.money-field :as money] [auto-ap.views.components.number :as number] - [auto-ap.views.components.typeahead.vendor :as typeahead])) + [auto-ap.views.components.typeahead.vendor :as typeahead] + [auto-ap.views.components.button-radio :as br])) (defn checkbox [{:keys [on-change @@ -49,6 +50,16 @@ (for [[k v] options] ^{:key k} [:option {:value k} v])]]]) +(defn switch-input [{:keys [id label on-change value class]}] + [:<> + [:input.switch {:type "checkbox" + :id id + :on-change (fn [] + (on-change (not value))) + :checked (boolean value) + :class class}] + [:label {:for id} label]]) + (def multi-field-v2 multi/multi-field-v2) (def number-input number/number-input) @@ -58,4 +69,4 @@ (def search-backed-typeahead typeahead/search-backed-typeahead) (def entity-typeahead typeahead/typeahead-v3) -(def button-radio-input auto-ap.views.components.button-radio/button-radio) +(def button-radio-input br/button-radio) diff --git a/src/cljs/auto_ap/views/components/expense_accounts_field.cljs b/src/cljs/auto_ap/views/components/expense_accounts_field.cljs index 9b15e7e6..bfe1c2af 100644 --- a/src/cljs/auto_ap/views/components/expense_accounts_field.cljs +++ b/src/cljs/auto_ap/views/components/expense_accounts_field.cljs @@ -240,7 +240,8 @@ :schema schema :on-change (fn [expense-accounts original-expense-accounts] (let [updated-expense-accounts - (for [[before-account after-account] (map vector original-expense-accounts expense-accounts)] + (for [[before-account after-account] (map vector (concat original-expense-accounts + (repeat nil)) expense-accounts)] (cond-> after-account (not= (:id (:account before-account)) (:id (:account after-account))) diff --git a/src/cljs/auto_ap/views/components/multi.cljs b/src/cljs/auto_ap/views/components/multi.cljs index fb71622b..1c57ff05 100644 --- a/src/cljs/auto_ap/views/components/multi.cljs +++ b/src/cljs/auto_ap/views/components/multi.cljs @@ -9,7 +9,8 @@ [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} ] +;; TODO just embrace the fact that it will need to be remounted, and use index based keys +(defn multi-field-v2-internal [{:keys [template key-fn 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 [])] @@ -18,17 +19,23 @@ :on-change on-change} [:fieldset {:disabled disabled} [:div {:style {:margin-bottom "0.25em"}} - (into [appearing-group] + (into [(if key-fn + appearing-group + [:<>])] (for [[i override] (map vector (range) prop-value) - :let [extant? (boolean (key-fn override)) + :let [extant? (if key-fn + (boolean (key-fn override)) + true) is-disabled? (boolean (and (= false allow-change?) extant?))]] - ^{:key (or (key-fn override) - (::key override))} + ^{:key (or (when key-fn (key-fn override)) + (::key override) + i)} [form-builder/with-scope {:scope [i]} - ^{:key (or (key-fn override) - (::key override))} + ^{:key (or (when key-fn (key-fn override)) + (::key override) + i)} [:div.level {:style {:margin-bottom "0.25em"}} [:div.level-left {:style {:padding "0.5em 1em"} :class (when-not extant? diff --git a/src/cljs/auto_ap/views/pages/admin/rules/form.cljs b/src/cljs/auto_ap/views/pages/admin/rules/form.cljs index 2eafab72..e43ec1de 100644 --- a/src/cljs/auto_ap/views/pages/admin/rules/form.cljs +++ b/src/cljs/auto_ap/views/pages/admin/rules/form.cljs @@ -269,7 +269,7 @@ [:vendor {:optional true} [:maybe schema/reference]] [:transaction-approval-status {:optional true} - [:maybe [:enum :unapproved :requires-feedback :approved :excluded]]] + [:maybe schema/approval-status]] [:note {:optional true} [:maybe :string]]])) diff --git a/src/cljs/auto_ap/views/pages/admin/users/form.cljs b/src/cljs/auto_ap/views/pages/admin/users/form.cljs index 15963f4b..91a3a67f 100644 --- a/src/cljs/auto_ap/views/pages/admin/users/form.cljs +++ b/src/cljs/auto_ap/views/pages/admin/users/form.cljs @@ -11,29 +11,6 @@ [malli.core :as m] [re-frame.core :as re-frame])) -(re-frame/reg-event-fx - ::saving - [with-user (forms/in-form ::form)] - (fn [{:keys [db user]} [_]] - {:graphql - {:token user - :owns-state {:single ::form} - :query-obj {:venia/operation {:operation/type :mutation - :operation/name "EditUser"} - :venia/queries [{:query/data [:edit-user - {:edit-user (-> (:data db) - (update :clients #(map (comp :id :client) %)) - (select-keys #{:id :name :clients :role}))} - [:id :name :role [:clients [:id :name]]]]}]} - :on-success [::saved]}})) - -(re-frame/reg-event-fx - ::saved - (forms/triggers-stop ::form) - (fn [_ _] - {:dispatch [::modal/modal-closed]})) - - (def client-schema (m/schema [:map [:client schema/reference]])) @@ -46,11 +23,40 @@ [:maybe [:sequential client-schema]]]])) +(re-frame/reg-event-fx + ::saving + [with-user (forms/in-form ::form)] + (fn [{:keys [db user]} [_]] + (if (m/validate user-schema (:data db)) + {:graphql + {:token user + :owns-state {:single ::form} + :query-obj {:venia/operation {:operation/type :mutation + :operation/name "EditUser"} + :venia/queries [{:query/data [:edit-user + {:edit-user (-> (:data db) + (update :clients #(map (comp :id :client) %)) + (select-keys #{:id :name :clients :role}))} + [:id :name :role [:clients [:id :name]]]]}]} + :on-success [::saved]}} + + {:dispatch-n [[::forms/attempted-submit ::form] + [::status/error ::form [{:message "Please fix the errors and try again."}]]]}) + )) + +(re-frame/reg-event-fx + ::saved + (forms/triggers-stop ::form) + (fn [_ _] + {:dispatch [::modal/modal-closed]})) + + + + (defn form [] (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form]) clients @(re-frame/subscribe [::subs/clients])] - (println data) [:<> [form-builder/builder {:submit-event [::saving] :id ::form diff --git a/src/cljs/auto_ap/views/pages/admin/vendors/merge_dialog.cljs b/src/cljs/auto_ap/views/pages/admin/vendors/merge_dialog.cljs index cb33c74c..1328c22d 100644 --- a/src/cljs/auto_ap/views/pages/admin/vendors/merge_dialog.cljs +++ b/src/cljs/auto_ap/views/pages/admin/vendors/merge_dialog.cljs @@ -1,43 +1,40 @@ (ns auto-ap.views.pages.admin.vendors.merge-dialog (:require [auto-ap.forms :as forms] + [auto-ap.forms.builder :as form-builder] + [auto-ap.schema :as schema] [auto-ap.status :as status] [auto-ap.subs :as subs] + [auto-ap.views.components :as com] [auto-ap.views.components.modal :as modal] - [auto-ap.views.components.typeahead.vendor - :refer [search-backed-typeahead]] [auto-ap.views.utils :refer [dispatch-event]] - [re-frame.core :as re-frame] - [auto-ap.forms.builder :as form-builder])) + [malli.core :as m] + [re-frame.core :as re-frame])) -(re-frame/reg-sub - ::can-submit - :<- [::forms/form ::form] - (fn [{:keys [data]}] - (and (:from data) - (:to data)))) +(def merge-schema + (m/schema [:map + [:from schema/reference] + [:to schema/reference]])) (defn form [] - [form-builder/builder {:submit-event [::save] - :can-submit [::can-submit] - :id ::form} - [form-builder/field "Form Vendor (will be deleted)" - [search-backed-typeahead {:search-query (fn [i] - [:search_vendor - {:query i} - [:name :id]]) - :type "typeahead-v3" - :auto-focus true - :field [:from]}]] + [form-builder/builder {:submit-event [::try-save] + :id ::form + :schema merge-schema} + [form-builder/field-v2 {:field :from} + "Form Vendor (will be deleted)" + [com/search-backed-typeahead {:search-query (fn [i] + [:search_vendor + {:query i} + [:name :id]]) + :auto-focus true}]] - [form-builder/field "To Vendor" - [search-backed-typeahead {:search-query (fn [i] - [:search_vendor - {:query i} - [:name :id]]) - :type "typeahead-v3" - :field [:to]}]] + [form-builder/field-v2 {:field :to} + "To Vendor" + [com/search-backed-typeahead {:search-query (fn [i] + [:search_vendor + {:query i} + [:name :id]])}]] [form-builder/hidden-submit-button]]) (re-frame/reg-event-fx @@ -48,8 +45,7 @@ :confirm {:value "Merge" :status-from [::status/single ::form] :class "is-primary" - :on-click (dispatch-event [::save]) - :can-submit [::can-submit] + :on-click (dispatch-event [::try-save]) :close-event [::status/completed ::form]}}] :db (forms/start-form db ::form {})})) @@ -73,3 +69,12 @@ {:from (:id from) :to (:id to)} []]}]} :on-success [::complete]}}))) + +(re-frame/reg-event-fx + ::try-save + [(forms/in-form ::form)] + (fn [{:keys [db]}] + (if (not (m/validate merge-schema (:data db))) + {:dispatch-n [[::status/error ::form [{:message "Please correct any errors and try again"}]] + [::forms/attempted-submit ::form]]} + {:dispatch [::save]}))) diff --git a/src/cljs/auto_ap/views/pages/invoices/advanced_print_checks.cljs b/src/cljs/auto_ap/views/pages/invoices/advanced_print_checks.cljs index 1f0d052a..99c6cb79 100644 --- a/src/cljs/auto_ap/views/pages/invoices/advanced_print_checks.cljs +++ b/src/cljs/auto_ap/views/pages/invoices/advanced_print_checks.cljs @@ -2,59 +2,48 @@ (:require [auto-ap.forms :as forms] [auto-ap.forms.builder :as form-builder] + [auto-ap.schema :as schema] [auto-ap.status :as status] [auto-ap.subs :as subs] + [auto-ap.views.components :as com] [auto-ap.views.components.modal :as modal] + [auto-ap.views.components.money-field :refer [money-field]] [auto-ap.views.pages.invoices.common :refer [does-amount-exceed-outstanding? invoice-read]] - [auto-ap.views.components.money-field :refer [money-field]] - [auto-ap.views.utils :refer [dispatch-event horizontal-field with-user]] - [re-frame.core :as re-frame] - [auto-ap.views.components :as com] + [auto-ap.views.utils :refer [coerce-float dispatch-event with-user]] [malli.core :as m] - [auto-ap.schema :as schema])) - -(re-frame/reg-sub - ::can-submit - :<- [::forms/form ::form] - (fn [{ {:keys [invoices invoice-amounts]} :data}] - (cond - (->> invoice-amounts - vals - (map :amount) - (filter nil?) - seq) - false - - (seq (filter - (fn [{:keys [id outstanding-balance]}] - (does-amount-exceed-outstanding? (get-in invoice-amounts [id :amount]) outstanding-balance )) - invoices)) - false - - :else - true))) + [malli.error :as me] + [re-frame.core :as re-frame])) (def advanced-print-schema (m/schema - [:map - [:bank-account-id schema/not-empty-string]])) + [:and + [:map + [:bank-account-id schema/not-empty-string] + [:invoice-amounts [:map-of + :string + [:map + [:amount schema/money]]]]] + [:fn (fn [{:keys [invoices invoice-amounts] :as z}] + (println "HERE" z) + (when (seq (filter + (fn [{:keys [id outstanding-balance]}] + (does-amount-exceed-outstanding? (get-in invoice-amounts [id :amount]) outstanding-balance )) + invoices)) + (throw (ex-info "Invalid" {:type ::too-much-invoice}))))]])) (defn form [] (let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts]) {:keys [data]} @(re-frame/subscribe [::forms/form ::form])] + (println "TEST?") [form-builder/builder {:submit-event [::try-save] - :can-submit [::can-submit] :id ::form :schema advanced-print-schema} - [:div.field - [:label.label "Pay using"] - [:div.control - [:span.select - [form-builder/raw-field-v2 {:field :bank-account-id} - [com/select-field {:options (for [{:keys [id name]} real-bank-accounts] + [form-builder/field-v2 {:field :bank-account-id} + "Pay using" + [com/select-field {:options (for [{:keys [id name]} real-bank-accounts] [id name]) - :allow-nil? true}]]]]] + :allow-nil? true}]] [:table.table.is-fullwidth [:thead @@ -64,14 +53,14 @@ [:th {:style {"width" "10em"}} "Payment"]]] [:tbody (doall - (for [{:keys [vendor invoice-number id] :as i} (:invoices data)] + (for [{:keys [vendor invoice-number id]} (:invoices data)] ^{:key id} [:tr [:td (:name vendor)] [:td invoice-number] [:td - [form-builder/raw-field-v2 {:field [:invoice-amounts :id :amount]} + [form-builder/raw-field-v2 {:field [:invoice-amounts id :amount]} [money-field]]]]))]]])) (re-frame/reg-event-fx @@ -83,14 +72,13 @@ :status-from [::status/single ::form] :class "is-primary" :on-click (dispatch-event [::try-save]) - :can-submit [::can-submit] :close-event [::status/completed ::form]}}] :db (-> db (forms/start-form ::form {:invoices invoices :invoice-amounts (into {} (map (fn [i] [(:id i) - {:amount (:outstanding-balance i)}]) + {:amount (coerce-float (:outstanding-balance i))}]) invoices))}))})) @@ -115,7 +103,7 @@ first :type) :check) - {:keys [date invoices invoice-amounts check-number bank-account-id client]} (:data db)] + {:keys [invoices invoice-amounts bank-account-id]} (:data db)] {:graphql {:token user :owns-state {:single ::form} @@ -139,6 +127,6 @@ (re-frame/reg-event-fx ::checks-printed - (fn [{:keys [db]} [_ data]] + (fn [{:keys [_]} [_ _]] {:dispatch [::modal/modal-closed]})) diff --git a/src/cljs/auto_ap/views/pages/invoices/form.cljs b/src/cljs/auto_ap/views/pages/invoices/form.cljs index 8f7d9b68..99cd372a 100644 --- a/src/cljs/auto_ap/views/pages/invoices/form.cljs +++ b/src/cljs/auto_ap/views/pages/invoices/form.cljs @@ -33,7 +33,8 @@ [reagent.core :as r] [malli.core :as m] [vimsical.re-frame.cofx.inject :as inject] - [vimsical.re-frame.fx.track :as track])) + [vimsical.re-frame.fx.track :as track] + [auto-ap.views.components :as com])) (def schema (m/schema @@ -392,12 +393,10 @@ [date-picker {:output :cljs-date}]] [form-builder/raw-error-v2 {:field :scheduled-payment}]] [:div.control - [form-builder/raw-field + [form-builder/raw-field-v2 {:field :schedule-when-due} - [switch-field {:id "schedule-when-due" - :field [:schedule-when-due] - :label "Same as due date" - :type "checkbox"}]]]]] + [com/switch-input {:id "schedule-when-due" + :label "Same as due date"}]]]]] [form-builder/field-v2 {:required? true :field :invoice-number} "Invoice #" diff --git a/src/cljs/auto_ap/views/pages/invoices/handwritten_checks.cljs b/src/cljs/auto_ap/views/pages/invoices/handwritten_checks.cljs index 3fafacfe..7bec532f 100644 --- a/src/cljs/auto_ap/views/pages/invoices/handwritten_checks.cljs +++ b/src/cljs/auto_ap/views/pages/invoices/handwritten_checks.cljs @@ -11,32 +11,40 @@ [auto-ap.views.utils :refer [date-picker dispatch-event with-user]] [clojure.string :as str] - [re-frame.core :as re-frame])) + [re-frame.core :as re-frame] + [auto-ap.views.components :as com] + [malli.core :as m] + [auto-ap.schema :as schema])) + +(def handwritten-check-schema + (m/schema + [:map + [:bank-account-id schema/not-empty-string] + [:date schema/date] + [:check-number [:int {:min 1000 :max 99999}]] + ])) (defn form [] (let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts]) {:keys [data]} @(re-frame/subscribe [::forms/form ::form])] [form-builder/builder {:submit-event [::save] :can-submit [::can-submit] - :id ::form} - [form-builder/vertical-control + :id ::form + :schema handwritten-check-schema} + [form-builder/field-v2 {:field :bank-account-id} "Pay using" - [:div.control - [:span.select - [form-builder/raw-field - [:select {:type "select" - :field :bank-account-id} - (for [{:keys [id name]} real-bank-accounts] - ^{:key id} [:option {:value id} name])]]]]] - [form-builder/field + [com/select-field {:options (for [{:keys [id name]} real-bank-accounts] + [id name]) + :allow-nil? true}]] + + [form-builder/field-v2 {:field :date} "Date" [date-picker {:type "date" - :output :cljs-date - :field [:date]}]] - [form-builder/field + :output :cljs-date}]] + + [form-builder/field-v2 {:field :check-number} "Check number" - [:input.input {:type "number" - :field [:check-number]}]] + [com/number-input {:style {:width "8em"}}]] [:table.table.is-fullwidth [:thead [:tr @@ -49,11 +57,8 @@ [:tr [:td invoice-number] [:td - [form-builder/raw-field - [money-field {:type "money" - :field [:invoice-amounts id :amount] - :style {:max-width "8em"} - }]]]]))]] + [form-builder/raw-field-v2 {:field [:invoice-amounts id :amount]} + [money-field {:style {:max-width "9em"}}]]]]))]] [form-builder/hidden-submit-button]])) (re-frame/reg-sub @@ -83,7 +88,7 @@ :close-event [::status/completed ::form]}}] :db (-> db (forms/start-form ::form - {:bank-account-id (:id (first @(re-frame/subscribe [::subs/real-bank-accounts]))) + {:bank-account-id nil :invoices invoices :invoice-amounts (into {} (map (fn [i] [(:id i) diff --git a/src/cljs/auto_ap/views/pages/ledger/balance_sheet.cljs b/src/cljs/auto_ap/views/pages/ledger/balance_sheet.cljs index 7aa28851..c167d3c5 100644 --- a/src/cljs/auto_ap/views/pages/ledger/balance_sheet.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/balance_sheet.cljs @@ -24,7 +24,8 @@ [vimsical.re-frame.fx.track :as track] [vimsical.re-frame.cofx.inject :as inject] [auto-ap.views.pages.ledger.report-table :as rtable] - [auto-ap.forms.builder :as form-builder])) + [auto-ap.forms.builder :as form-builder] + [auto-ap.views.components :as com])) (defn data-params->query-params [params] (when params @@ -190,26 +191,20 @@ NOTE: Please review the transactions we may have question for you here: https:// [:div.level-left [:div.level-item [:div.control - [form-builder/field + [form-builder/field-v2 {:field :date} "Date" - [date-picker {:output :cljs-date - :type "date" - :field [:date]}]]]] + [date-picker {:output :cljs-date}]]]] [:div.level-item - [form-builder/field + [form-builder/field-v2 {:field :include-comparison} [:div.mt-5] - [switch-field {:id "include-comparison" - :field [:include-comparison] - :label "Include compariison" - :type "checkbox"}]]] + [com/switch-input {:id "include-comparison" + :label "Include compariison"}]]] [:div.level-item (when (boolean (:include-comparison data)) - [form-builder/field + [form-builder/field-v2 {:field :comparison-date} "Comparison Date" - [date-picker {:output :cljs-date - :type "date" - :field [:comparison-date]}]])]] + [date-picker {:output :cljs-date}]])]] [:div.level-right [:div.buttons diff --git a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs index 76728d5e..1c9b627f 100644 --- a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs @@ -32,7 +32,8 @@ [reagent.core :as reagent] [vimsical.re-frame.cofx.inject :as inject] [vimsical.re-frame.fx.track :as track] - [auto-ap.forms.builder :as form-builder])) + [auto-ap.forms.builder :as form-builder] + [auto-ap.views.components :as com])) @@ -73,7 +74,7 @@ (cond-> {:graphql {:token user :owns-state {:single ::page} :query-obj {:venia/queries [[:profit-and-loss - {:client-ids (map :id (:clients (:data db))) + {:client-ids (map (comp :id :client) (:clients (:data db))) :periods (mapv #(select-keys % #{:start :end} ) (:periods (:data db))) :include-deltas (:include-deltas (:data db)) :column-per-location (:column-per-location (:data db))} @@ -82,7 +83,7 @@ :set-uri-params {:periods (mapv encode-period (:periods (:data db))) - :clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) } + :clients (mapv #(select-keys (:client %) [:name :id]) (:clients (:data db))) } :db (-> db (dissoc :report) (update-in [:data :clients] #(into [] (filter seq %))))}))) @@ -127,14 +128,14 @@ NOTE: Please review the transactions we may have question for you here: https:// (cond-> {:graphql {:token user :owns-state {:single ::page} :query-obj {:venia/queries [[:profit-and-loss-pdf - {:client-ids (map :id (:clients (:data db))) + {:client-ids (map (:comp :id :client) (:clients (:data db))) :include-deltas (:include-deltas (:data db)) :column-per-location (:column-per-location (:data db)) :periods (mapv #(select-keys % #{:start :end}) (:periods (:data db)))} [:url :name]]]} :on-success [::received-pdf]} :set-uri-params {:periods (mapv encode-period (:periods (:data db))) - :clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) } + :clients (mapv #(select-keys (:client %) [:name :id]) (:clients (:data db))) } :db (dissoc db :report)}))) @@ -228,7 +229,6 @@ NOTE: Please review the transactions we may have question for you here: https:// (defn report-control-detail [{:keys [active box which]} children] (when (and @box (= which @active)) - (println @box) (react-dom/createPortal (reagent/as-element [:div.notification.is-light [:a.delete {:on-click (fn [] (reset! active nil))}] @@ -268,17 +268,17 @@ NOTE: Please review the transactions we may have question for you here: https:// [buttons/dropdown {:on-click (fn [] (reset! active :clients))} [:span (str "Companies" (when-let [clients (:clients data)] - (str " (" (str/join ", " (map :name clients)) ")")))]] + (str " (" (str/join ", " (map (comp :name :client) clients)) ")")))]] [report-control-detail {:active active :box !box :which :clients} [:div {:style {:width "20em"}} [:h4.subtitle "Companies"] - [form-builder/raw-field - [multi-field {:type "multi-field" - :field [:clients] - :template [[typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients]) - :style {:width "18em"} - :entity->text :name - :type "typeahead-v3"}]]}]]]]] + [form-builder/raw-field-v2 {:field :clients} + [com/multi-field-v2 {:new-text "Add another company" + :template [[form-builder/raw-field-v2 {:field :client} + [com/entity-typeahead {:entities @(re-frame/subscribe [::subs/clients]) + :style {:width "18em"} + :entity->text :name}]]] + :key-fn :id}]]]]] [:div.level-item [buttons/dropdown {:on-click (fn [] (reset! active :range))} [:span (str "Range" @@ -291,11 +291,9 @@ NOTE: Please review the transactions we may have question for you here: https:// [:div.control [:div.field.has-addons [:div.control - [form-builder/raw-field + [form-builder/raw-field-v2 {:field :thirteen-periods-end} [date-picker {:placeholder "End date" - :type "date" - :output :cljs-date - :field [:thirteen-periods-end]}]]] + :output :cljs-date}]]] [period-preset-button {:title "13 periods" :periods (let [today (or (some-> (:thirteen-periods-end data)) (local-today))] @@ -312,11 +310,9 @@ NOTE: Please review the transactions we may have question for you here: https:// [:div.control [:div.field.has-addons [:div.control - [form-builder/raw-field + [form-builder/raw-field-v2 {:field :twelve-periods-end} [date-picker {:placeholder "End date" - :output :cljs-date - :type "date" - :field [:twelve-periods-end]}]]] + :output :cljs-date}]]] [period-preset-button {:title "12 months" :periods (let [end-date (or (some-> (:twelve-periods-end data)) (local-today)) @@ -378,22 +374,15 @@ NOTE: Please review the transactions we may have question for you here: https:// :end (local-today)}) :title "Full year"}]] [:div - [:div.field - [:label.checkbox - [form-builder/raw-field - [:input {:type "checkbox" - :field [:show-advanced?]}]] - " Show Advanced"]]] + [form-builder/raw-field-v2 {:field :show-advanced?} + [com/checkbox {:label "Show Advanced"}] + ]] (when (:show-advanced? data) - [form-builder/raw-field - [multi-field {:type "multi-field" - :field [:periods] - :template [[date-picker {:type "date" - :output :cljs-date - :field [:start]}] - [date-picker {:type "date" - :output :cljs-date - :field [:end]}]]}]])]]] + [form-builder/raw-field-v2 {:field :periods} + [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :start} + [date-picker {:output :cljs-date}]] + [form-builder/raw-field-v2 {:field :end} + [date-picker {:output :cljs-date}]]]}]])]]] [:div.level-item [:div @@ -446,7 +435,7 @@ NOTE: Please review the transactions we may have question for you here: https:// report (l-reports/summarize-pnl pnl-data) table (rtable/concat-tables (concat (:summaries report) (:details report)))] [:div - [:h1.title "Profit and Loss - " (str/join ", " (map :name (:clients args)))] + [:h1.title "Profit and Loss - " (str/join ", " (map (comp :name :client) (:clients args)))] (when (:warning report) [:div.notification.is-warning.is-light (:warning report)]) @@ -487,8 +476,9 @@ NOTE: Please review the transactions we may have question for you here: https:// (mapv (fn [period] {:start (str->date (:start period) standard) :end (str->date (:end period) standard)}))) - :clients (or (:clients qp) - [(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]))]) + :clients (mapv (fn [c] {:client c :id (random-uuid)}) + (or (:clients qp) + [(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]) )])) :include-deltas false}) ::track/register {:id ::ledger-params :subscription [::data-page/params ::ledger] diff --git a/src/cljs/auto_ap/views/pages/pos/form.cljs b/src/cljs/auto_ap/views/pages/pos/form.cljs index 3ae576e9..b1b5f71c 100644 --- a/src/cljs/auto_ap/views/pages/pos/form.cljs +++ b/src/cljs/auto_ap/views/pages/pos/form.cljs @@ -4,17 +4,12 @@ [auto-ap.subs :as subs] [auto-ap.views.components.layouts :as layouts] [auto-ap.views.components.money-field :refer [money-field]] - [auto-ap.views.components.typeahead :refer [typeahead-v3]] [auto-ap.views.utils :refer [date->str date-picker dispatch-event standard]] [re-frame.core :as re-frame] - [auto-ap.forms.builder :as form-builder])) + [auto-ap.forms.builder :as form-builder] + [auto-ap.views.components :as com])) -(re-frame/reg-sub - ::can-submit - :<- [::forms/form ::form] - (fn [{:keys [data status]} _] - false)) (re-frame/reg-event-db ::editing @@ -26,63 +21,52 @@ (defn form [] [layouts/side-bar {:on-close (dispatch-event [::forms/form-closing ::form ])} (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])] - [form-builder/builder {:can-submit [::can-submit] - :submit-event [::saving ] + [form-builder/builder {:submit-event [::saving ] :id ::form} [form-builder/section {:title "Sales Order"} (when-not @(re-frame/subscribe [::subs/client]) - [form-builder/field + [form-builder/field-v2 {:field :client} "Client" - [typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients]) - :entity->text :name - :type "typeahead-v3" - :field [:client] - :disabled true}]]) + [com/entity-typeahead {:entities @(re-frame/subscribe [::subs/clients]) + :entity->text :name + :disabled true}]]) - [form-builder/field "Date" - [date-picker {:type "date" - :output :cljs-date - :disabled true - :field [:date]}]] - [form-builder/field + [form-builder/field-v2 {:field :date} + "Date" + [date-picker {:output :cljs-date + :disabled true}]] + [form-builder/field-v2 {:field :total} "Total" - [money-field {:type "money" - :field [:total] - :disabled true}]] - [form-builder/field "Tax" - [money-field {:type "money" - :field [:tax] - :disabled true}] - [form-builder/field + [money-field {:disabled true}]] + [form-builder/field-v2 {:field :tax} + "Tax" + [money-field {:disabled true}] + [form-builder/field-v2 {:field :discount} "Discount" - [money-field {:type "money" - :field [:discount] - :disabled true}]]] + [money-field {:disabled true}]]] - [form-builder/field "Returns" - [money-field {:type "money" - :field [:returns] - :disabled true}]] + [form-builder/field-v2 {:field :returns} + "Returns" + [money-field {:disabled true}]] - [form-builder/field "Service Charge" - [money-field {:type "money" - :field [:service-charge] - :disabled true}]] + [form-builder/field-v2 {:field :service-charge} + "Service Charge" + [money-field {:disabled true}]] - [form-builder/field + [form-builder/field-v2 {:field :tip} "Tip" - [money-field {:type "money" - :field [:tip] - :disabled true}]] + [money-field {:disabled true}]] [form-builder/section {:title "Charges"} [:ul (for [charge (:charges data)] + ^{:key (:id charge)} [:li (:type-name charge) ": " (:total charge)])]] [form-builder/section {:title "Line Items"} [:ul (for [line-item (:line-items data)] + ^{:key (:item-name line-item)} [:li (:item-name line-item) ": " (:total line-item) [:span.tag (:category line-item)]])]]]])]) diff --git a/src/cljs/auto_ap/views/pages/transactions.cljs b/src/cljs/auto_ap/views/pages/transactions.cljs index ee13f25b..3a05b037 100644 --- a/src/cljs/auto_ap/views/pages/transactions.cljs +++ b/src/cljs/auto_ap/views/pages/transactions.cljs @@ -112,7 +112,6 @@ {:id ::manual-import :events #{::manual/import-completed} :event-fn (fn [[_ result]] - (println result) [::status/info ::manual-import (str "Successfully " (str/join ", " diff --git a/src/cljs/auto_ap/views/pages/transactions/bulk_updates.cljs b/src/cljs/auto_ap/views/pages/transactions/bulk_updates.cljs index e63b1a5c..7e61fe1b 100644 --- a/src/cljs/auto_ap/views/pages/transactions/bulk_updates.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/bulk_updates.cljs @@ -3,13 +3,10 @@ [auto-ap.forms :as forms] [auto-ap.status :as status] [auto-ap.subs :as subs] - [auto-ap.views.components.button-radio :refer [button-radio]] [auto-ap.views.components.expense-accounts-field :as expense-accounts-field - :refer [expense-accounts-field]] + :refer [expense-accounts-field-v2]] [auto-ap.views.components.modal :as modal] - [auto-ap.views.components.typeahead.vendor - :refer [search-backed-typeahead]] [auto-ap.views.pages.data-page :as data-page] [auto-ap.views.pages.transactions.common :refer [data-params->query-params]] @@ -20,7 +17,10 @@ [vimsical.re-frame.fx.track :as track] [auto-ap.events :as events] [vimsical.re-frame.cofx.inject :as inject] - [auto-ap.forms.builder :as form-builder])) + [auto-ap.forms.builder :as form-builder] + [malli.core :as m] + [auto-ap.schema :as schema] + [auto-ap.views.components :as com])) (re-frame/reg-sub ::can-submit @@ -106,6 +106,11 @@ (fn [] {::track/dispose {:id ::vendor-change}})) + +(def bulk-update-schema + (m/schema + [:map + [:vendor schema/reference]])) (defn form-content [_] (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])] [form-builder/builder {:submit-event [::code-selected] @@ -114,33 +119,28 @@ :id ::form} - [form-builder/field "Vendor" - [search-backed-typeahead {:search-query (fn [i] - [:search_vendor - {:query i} - [:name :id]]) - :type "typeahead-v3" - :auto-focus true - :field [:vendor]}]] + [form-builder/field-v2 {:field :vendor} + "Vendor" + [com/search-backed-typeahead {:search-query (fn [i] + [:search_vendor + {:query i} + [:name :id]]) + :auto-focus true}]] - [form-builder/field + [form-builder/field-v2 {:field [:transaction-approval-status]} "Approval Status" - [button-radio - {:type "button-radio" - :field [:transaction-approval-status] - :options [[:unapproved "Unapproved"] + [com/button-radio-input + {:options [[:unapproved "Unapproved"] [:requires-feedback "Client Review"] [:approved "Approved"] [:excluded "Excluded from Ledger"]]}]] - [form-builder/raw-field - [expense-accounts-field {:type "expense-accounts" - :descriptor "account asssignment" - :percentage-only? true - :client (:client data) - :locations (into ["Shared"] @(re-frame/subscribe [::subs/locations-for-client (:id (:client data))])) - :max 100 - :field [:accounts]}]]])) + [form-builder/raw-field-v2 {:field :accounts} + [expense-accounts-field-v2 {:descriptor "account asssignment" + :percentage-only? true + :client (:client data) + :locations (into ["Shared"] @(re-frame/subscribe [::subs/locations-for-client (:id (:client data))])) + :max 100}]]])) (defn form [_] (r/create-class {:display-name "transaction-bulk-update-form" diff --git a/src/cljs/auto_ap/views/pages/transactions/form.cljs b/src/cljs/auto_ap/views/pages/transactions/form.cljs index 293ada3b..4c5ed719 100644 --- a/src/cljs/auto_ap/views/pages/transactions/form.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/form.cljs @@ -1,26 +1,31 @@ (ns auto-ap.views.pages.transactions.form (:require + [auto-ap.events :as events] [auto-ap.forms :as forms] + [auto-ap.forms.builder :as form-builder] + [auto-ap.schema :as schema] [auto-ap.status :as status] [auto-ap.subs :as subs] - [auto-ap.views.components.button-radio :refer [button-radio]] + [auto-ap.views.components :as com] [auto-ap.views.components.expense-accounts-field :as expense-accounts-field - :refer [expense-accounts-field]] + :refer [expense-accounts-field-v2]] [auto-ap.views.components.layouts :as layouts] - [auto-ap.views.components.typeahead :refer [typeahead-v3]] - [auto-ap.views.components.typeahead.vendor - :refer [search-backed-typeahead]] [auto-ap.views.pages.transactions.common :refer [transaction-read]] [auto-ap.views.utils :refer [->$ date->str date-picker dispatch-event pretty with-user]] [clojure.string :as str] + [malli.core :as m] [re-frame.core :as re-frame] [react :as react] [reagent.core :as r] - [vimsical.re-frame.fx.track :as track] - [auto-ap.events :as events] - [auto-ap.forms.builder :as form-builder])) + [vimsical.re-frame.fx.track :as track])) + +(def schema + (m/schema [:map + [:vendor schema/reference] + [:accounts expense-accounts-field/schema] + [:approval-status schema/approval-status]])) ;; SUBS (re-frame/reg-sub @@ -45,13 +50,6 @@ accounts)}} transaction-read]}]})) -(re-frame/reg-sub - ::can-submit - :<- [::forms/form ::form] - (fn [{:keys [status]} _] - (not= :loading status))) - - ;; EVENTS (re-frame/reg-event-db @@ -300,7 +298,6 @@ (defonce ^js/React.Context current-tab-context ( react/createContext "default")) (def ^js/React.Provider CurrentTabProvider (. current-tab-context -Provider)) -#_(println "Provider is" Provider) (def ^js/React.Consumer CurrentTabConsumer (. current-tab-context -Consumer)) (defn tabs [props & _] @@ -343,33 +340,30 @@ should-disable-for-client? (and (not (or is-admin? is-power-user?)) (not= :requires-feedback (:original-status data))) is-already-matched? (:payment data)] - [form-builder/builder {:can-submit [::can-submit] - :change-event [::changed] + [form-builder/builder {:change-event [::changed] :submit-event [::saving ] - :id ::form} + :id ::form + :schema schema} [form-builder/section {:title "Transaction"} [:<> (when is-admin? - [form-builder/field + [form-builder/field-v2 {:field [:matched-rule :note] } "Matched Rule" - [:input.input {:type "text" - :field [:matched-rule :note] - :disabled "disabled"}]]) - [form-builder/field "Amount" + [:input.input {:type "text" :disabled "disabled"}]]) + [form-builder/field-v2 {:field :amount} + "Amount" [:input.input {:type "text" - :field [:amount] :disabled "disabled"}]] - [form-builder/field + [form-builder/field-v2 {:field [:description-original]} "Description" [:input.input {:type "text" - :field [:description-original] :disabled "disabled"}]] - [form-builder/field "Date" - [date-picker {:type "date" - :field [:date] + [form-builder/field-v2 {:field [:date]} + "Date" + [date-picker { :disabled "disabled"}]] @@ -407,43 +401,36 @@ [tab {:title "Details" :key :details} [:div - [form-builder/field + [form-builder/field-v2 {:field :vendor} "Vendor" - [search-backed-typeahead {:search-query (fn [i] - [:search_vendor - {:query i} - [:name :id]]) - :type "typeahead-v3" - :auto-focus true - :field [:vendor] - :disabled (or (boolean (:payment data)) - should-disable-for-client?)}]] - [form-builder/raw-field [expense-accounts-field - {:type "expense-accounts" - :field [:accounts] - :max (Math/abs (js/parseFloat (:amount data))) - :descriptor "credit account" - :client (:client data) - :disabled (or (boolean (:payment data)) - should-disable-for-client?) - :locations locations}]] - [form-builder/field + [com/search-backed-typeahead {:search-query (fn [i] + [:search_vendor + {:query i} + [:name :id]]) + :auto-focus true + :disabled (or (boolean (:payment data)) + should-disable-for-client?)}]] + [form-builder/raw-field-v2 {:field :accounts} + [expense-accounts-field-v2 + {:max (Math/abs (js/parseFloat (:amount data))) + :descriptor "credit account" + :client (:client data) + :disabled (or (boolean (:payment data)) + should-disable-for-client?) + :locations locations}]] + [form-builder/field-v2 {:field :approval-status} "Approval Status" - [button-radio - {:type "button-radio" - :field [:approval-status] - :options [[:unapproved "Unapproved"] + [com/button-radio-input + {:options [[:unapproved "Unapproved"] [:requires-feedback "Client Review"] [:approved "Approved"] [:excluded "Excluded from Ledger"]] :disabled should-disable-for-client?}]] - [form-builder/field + [form-builder/field-v2 {:field [:forecast-match]} "Forecasted-transaction" - [typeahead-v3 {:entities @(re-frame/subscribe [::subs/forecasted-transactions-for-client (:id (:client data))]) - :entity->text :identifier - :type "typeahead-v3" - :field [:forecast-match]}]] + [com/entity-typeahead {:entities @(re-frame/subscribe [::subs/forecasted-transactions-for-client (:id (:client data))]) + :entity->text :identifier}]] [form-builder/error-notification] (when-not should-disable-for-client? [form-builder/submit-button "Save"])]]]]]])]) diff --git a/src/cljs/auto_ap/views/pages/transactions/manual.cljs b/src/cljs/auto_ap/views/pages/transactions/manual.cljs index 15efbaff..06198a34 100644 --- a/src/cljs/auto_ap/views/pages/transactions/manual.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/manual.cljs @@ -6,7 +6,9 @@ [auto-ap.views.components.modal :as modal] [auto-ap.views.utils :refer [dispatch-event with-user]] [re-frame.core :as re-frame] - [auto-ap.forms.builder :as form-builder])) + [auto-ap.forms.builder :as form-builder] + [auto-ap.schema :as schema] + [malli.core :as m])) (re-frame/reg-sub ::can-submit @@ -14,15 +16,18 @@ (fn [{ {:keys [data]} :data}] (not-empty data))) -(defn form [] - [form-builder/builder {:submit-event [::save] - :can-submit [::can-submit] - :id ::form} +(def schema + (m/schema [:map [:data schema/not-empty-string]])) - [form-builder/field {:required? true} +(defn form [] + [form-builder/builder {:submit-event [::try-save] + :id ::form + :schema schema} + + [form-builder/field-v2 {:required? true + :field :data} "Yodlee manual import table" - [:div.control - [:textarea.textarea {:field [:data]}]]] + [:textarea.textarea ]] [form-builder/hidden-submit-button]]) (re-frame/reg-event-fx @@ -33,8 +38,7 @@ :confirm {:value "Import" :status-from [::status/single ::form] :class "is-primary" - :on-click (dispatch-event [::save]) - :can-submit [::can-submit] + :on-click (dispatch-event [::try-save]) :close-event [::status/completed ::form]}}] :db (-> db (forms/start-form ::form @@ -59,6 +63,15 @@ :uri (str "/api/transactions/batch-upload") :on-success [::import-completed]}}))) +(re-frame/reg-event-fx + ::try-save + [(forms/in-form ::form)] + (fn [{:keys [db]}] + (if (not (m/validate schema (:data db))) + {:dispatch-n [[::status/error ::form [{:message "Please correct any errors and try again"}]] + [::forms/attempted-submit ::form]]} + {:dispatch [::save]}))) + diff --git a/src/cljs/auto_ap/views/pages/transactions/table.cljs b/src/cljs/auto_ap/views/pages/transactions/table.cljs index 201a716b..8df9ac91 100644 --- a/src/cljs/auto_ap/views/pages/transactions/table.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/table.cljs @@ -1,32 +1,35 @@ (ns auto-ap.views.pages.transactions.table - (:require [auto-ap.events :as events] - [auto-ap.subs :as subs] - [auto-ap.views.components.dropdown - :refer - [drop-down drop-down-contents]] - [auto-ap.views.components.grid :as grid] - [auto-ap.views.pages.transactions.form :as edit] - [auto-ap.views.utils - :refer - [action-cell-width date->str dispatch-event dispatch-event-with-propagation nf pretty with-role]] - [goog.string :as gstring] - [re-frame.core :as re-frame] - [auto-ap.views.components.buttons :as buttons] - [auto-ap.status :as status] - [auto-ap.views.pages.data-page :as data-page] - [bidi.bidi :as bidi] - [cemerick.url :as url] - [auto-ap.routes :as routes])) + (:require + [auto-ap.events :as events] + [auto-ap.routes :as routes] + [auto-ap.status :as status] + [auto-ap.subs :as subs] + [auto-ap.views.components.buttons :as buttons] + [auto-ap.views.components.dropdown + :refer [drop-down drop-down-contents]] + [auto-ap.views.components.grid :as grid] + [auto-ap.views.pages.data-page :as data-page] + [auto-ap.views.pages.transactions.form :as edit] + [auto-ap.views.utils + :refer [action-cell-width + date->str + dispatch-event-with-propagation + nf + pretty + with-role]] + [bidi.bidi :as bidi] + [cemerick.url :as url] + [re-frame.core :as re-frame])) (re-frame/reg-event-fx ::editing-matches-found - (fn [{:keys [db]} [_ which matches]] + (fn [_ [_ which matches]] {:dispatch [::edit/editing which (:potential-payment-matches matches) (:potential-autopay-invoices-matches matches) (:potential-unpaid-invoices-matches matches) (:potential-transaction-rule-matches matches)]})) (re-frame/reg-event-fx ::editing-matches-failed - (fn [{:keys [db]} [_ which payment-matches]] + (fn [_ [_ which payment-matches]] {:dispatch [::edit/editing which payment-matches]})) @@ -71,12 +74,10 @@ (fn [{table-params :db} [_ params :as z]] {:db (merge table-params params)})) -(defn table [{:keys [id data-page check-boxes?]}] +(defn table [{:keys [data-page check-boxes?]}] (let [selected-client @(re-frame/subscribe [::subs/client]) - {:keys [data status params]} @(re-frame/subscribe [::data-page/page data-page]) - states @(re-frame/subscribe [::status/multi ::edits]) - is-power-user? @(re-frame/subscribe [::subs/is-power-user?]) - is-admin? @(re-frame/subscribe [::subs/is-admin?])] + {:keys [data params]} @(re-frame/subscribe [::data-page/page data-page]) + states @(re-frame/subscribe [::status/multi ::edits])] [grid/grid {:data-page data-page :column-count (if selected-client 6 7) :check-boxes? check-boxes?} @@ -94,7 +95,7 @@ [grid/sortable-header-cell {:sort-key "status" :sort-name "Status" :style {:width "7em"}} "Status"] [grid/header-cell {:style {:width (action-cell-width 3)}}]]] [grid/body - (for [{:keys [client account vendor approval-status payment expected-deposit status bank-account description-original date amount id yodlee-merchant ] :as i} (:data data)] + (for [{:keys [client vendor payment expected-deposit status bank-account description-original date amount id yodlee-merchant ] :as i} (:data data)] ^{:key id} [grid/row {:class (:class i) :id id :entity i} (when-not selected-client