From 6a8bb77e9591a7d2fa1521c405a6953c5aee2915 Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Mon, 17 Aug 2020 19:43:31 -0700 Subject: [PATCH] Made all interactions much better --- src/cljs/auto_ap/effects.cljs | 1 + src/cljs/auto_ap/status.cljs | 2 +- src/cljs/auto_ap/views/components/grid.cljs | 47 ++++-- .../views/components/invoice_table.cljs | 57 +++---- .../views/components/invoices/side_bar.cljs | 108 ++----------- .../auto_ap/views/components/typeahead.cljs | 10 +- src/cljs/auto_ap/views/main.cljs | 13 +- src/cljs/auto_ap/views/pages/data_page.cljs | 93 ++++++++++- .../auto_ap/views/pages/import_invoices.cljs | 150 ++++++------------ .../auto_ap/views/pages/unpaid_invoices.cljs | 37 +---- 10 files changed, 234 insertions(+), 284 deletions(-) diff --git a/src/cljs/auto_ap/effects.cljs b/src/cljs/auto_ap/effects.cljs index da79df69..3b035cc8 100644 --- a/src/cljs/auto_ap/effects.cljs +++ b/src/cljs/auto_ap/effects.cljs @@ -21,6 +21,7 @@ (re-frame/reg-fx :set-uri-params (fn [uri-params] + (println "HERE?") (pushy/set-token! p/history (str (.-protocol (.-location js/window)) "//" (.-host (.-location js/window)) (.-pathname (.-location js/window)) "?" diff --git a/src/cljs/auto_ap/status.cljs b/src/cljs/auto_ap/status.cljs index 911877ed..c4b31405 100644 --- a/src/cljs/auto_ap/status.cljs +++ b/src/cljs/auto_ap/status.cljs @@ -109,7 +109,7 @@ (mapv #(deref (re-frame/subscribe %))) (filter #(= :error (:state %))))] (when (seq states) - [:div.notification + [:div.notification.is-warning (for [state states state (:error state)] (do diff --git a/src/cljs/auto_ap/views/components/grid.cljs b/src/cljs/auto_ap/views/components/grid.cljs index 399864b5..15c62952 100644 --- a/src/cljs/auto_ap/views/components/grid.cljs +++ b/src/cljs/auto_ap/views/components/grid.cljs @@ -1,7 +1,9 @@ (ns auto-ap.views.components.grid (:require [reagent.core :as r] [auto-ap.views.utils :refer [appearing]] - [react :as react])) + [react :as react] + [re-frame.core :as re-frame] + [auto-ap.views.pages.data-page :as data-page])) (defonce grid-context (react/createContext "default")) (def Provider (.-Provider grid-context)) @@ -105,6 +107,7 @@ [:> Consumer {} (fn [consume] (let [{:strs [on-params-change params] :as consume} (js->clj consume)] + (println "PARAMS" params) (r/as-element (into [:div {:style {:margin-bottom "1rem"}} [:div.level @@ -215,19 +218,35 @@ children) (sort-icon sort-key (:sort params))))))])) -(defn grid [{:keys [on-params-change on-check-changed checked params status column-count check-boxes?]}] - (r/create-element Provider - #js {:value #js {:on-params-change on-params-change - :on-check-changed on-check-changed - :check-boxes? check-boxes? - :checked checked - :params params - :status status - :column-count column-count}} - (r/as-element - (into - [:<> ] - (r/children (r/current-component)))))) +(defn grid [{:keys [on-params-change on-check-changed checked params status column-count check-boxes? data-page]}] + (if data-page + (let [page @(re-frame/subscribe [::data-page/page data-page])] + (r/create-element Provider + #js {:value #js {:on-params-change (fn [p] + (re-frame/dispatch [::data-page/table-params-changed data-page p])) + :on-check-changed (fn [new] + (re-frame/dispatch [::data-page/toggle-check data-page new])) + :check-boxes? check-boxes? + :checked (:checked page) + :params (:params page) + :status (:status page) + :column-count column-count}} + (r/as-element + (into + [:<> ] + (r/children (r/current-component)))))) + (r/create-element Provider + #js {:value #js {:on-params-change on-params-change + :on-check-changed on-check-changed + :check-boxes? check-boxes? + :checked checked + :params params + :status status + :column-count column-count}} + (r/as-element + (into + [:<> ] + (r/children (r/current-component))))))) (defn virtual-paginate [start xs ] (take 100 (drop (or start 0) xs))) diff --git a/src/cljs/auto_ap/views/components/invoice_table.cljs b/src/cljs/auto_ap/views/components/invoice_table.cljs index 989d8ce6..7cb5668b 100644 --- a/src/cljs/auto_ap/views/components/invoice_table.cljs +++ b/src/cljs/auto_ap/views/components/invoice_table.cljs @@ -16,13 +16,29 @@ [clojure.string :as str] [goog.string :as gstring] [re-frame.core :as re-frame] - [auto-ap.views.components.expense-accounts-dialog :as expense-accounts-dialog])) + [auto-ap.views.components.expense-accounts-dialog :as expense-accounts-dialog] + [auto-ap.views.pages.data-page :as data-page])) (defn query [params] {:venia/queries [[:invoice_page - (-> params - (assoc - :client-id (:id @(re-frame/subscribe [::subs/client])))) + { + :start (:start params 0) + :sort (:sort params) + + :vendor-id (:id (:vendor params)) + :date-range (:date-range params) + :due-range (:due-range params) + :amount-gte (:amount-gte (:amount-range params)) + :amount-lte (:amount-lte (:amount-range params)) + :invoice-number-like (:invoice-number-like params) + :client-id (:id @(re-frame/subscribe [::subs/client])) + :import-status (:import-status params) + :status (condp = @(re-frame/subscribe [::subs/active-page]) + :invoices nil + :import-invoices nil + :unpaid-invoices :unpaid + :paid-invoices :paid + :voided-invoices :voided)} [[:invoices [:id :total :outstanding-balance :invoice-number :date :due :status :client-identifier :automatically-paid-when-due [:vendor [:name :id]] [:expense_accounts [:amount :id :location @@ -35,24 +51,7 @@ :start :end]]]}) -(re-frame/reg-sub - ::specific-table-params - (fn [db] - (::table-params db))) -(re-frame/reg-sub - ::table-params - :<- [::specific-table-params] - :<- [::subs/query-params] - (fn [[specific-table-params query-params]] - (update (merge (select-keys query-params #{:start :sort}) specific-table-params ) - :sort seq))) - -(re-frame/reg-event-fx - ::params-changed - [(re-frame/path [::table-params])] - (fn [{table-params :db} [_ params :as z]] - {:db (merge table-params params)})) (re-frame/reg-event-fx ::void-invoice @@ -92,7 +91,7 @@ (fn [{:keys [db]} [_ invoice]] {:db db})) -(defn row [{:keys [invoice check-boxes checked selected-client overrides expense-event actions]}] +(defn row [{:keys [invoice check-boxes selected-client overrides expense-event actions]}] (let [{:keys [client payments expense-accounts invoice-number date due total outstanding-balance id vendor checkable?] :as i} invoice accounts-by-id @(re-frame/subscribe [::subs/accounts-by-id client]) account->name #(:name (accounts-by-id (:id %)))] @@ -180,12 +179,13 @@ [buttons/fa-icon {:icon "fa-undo" :event [::unvoid-invoice i]}])]]])) -(defn invoice-table [{:keys [id data checked status check-boxes on-check-changed overrides actions]}] +(defn invoice-table [{:keys [id check-boxes overrides actions data-page]}] (let [selected-client @(re-frame/subscribe [::subs/client]) - {:keys [sort]} @(re-frame/subscribe [::table-params]) + {:keys [data status table-params]} @(re-frame/subscribe [::data-page/page data-page]) + selected-client @(re-frame/subscribe [::subs/client]) is-loading? (= :loading (:state status)) - is-sorted-by-vendor? (and (= "vendor" (:sort-key (first sort))) + is-sorted-by-vendor? (and (= "vendor" (:sort-key (first (:sort table-params)))) (not is-loading?) (or (apply <= (map (comp :name :vendor) (:data data))) (apply >= (map (comp :name :vendor) (:data data))))) @@ -202,12 +202,7 @@ [[] nil] (:data data)) [[(:data data)]])] - [grid/grid {:on-params-change (fn [p] - (re-frame/dispatch [::params-changed p])) - :on-check-changed on-check-changed - :params @(re-frame/subscribe [::table-params]) - :checked checked - :status status + [grid/grid {:data-page data-page :check-boxes? check-boxes :column-count (if selected-client 8 9)} [grid/controls data diff --git a/src/cljs/auto_ap/views/components/invoices/side_bar.cljs b/src/cljs/auto_ap/views/components/invoices/side_bar.cljs index d4eec58c..24463f12 100644 --- a/src/cljs/auto_ap/views/components/invoices/side_bar.cljs +++ b/src/cljs/auto_ap/views/components/invoices/side_bar.cljs @@ -13,93 +13,16 @@ [auto-ap.views.components.typeahead :refer [typeahead-entity]] [auto-ap.views.utils :refer [active-when dispatch-event bind-field horizontal-field date->str str->date pretty standard query-params dispatch-value-change]] [auto-ap.subs :as subs] - [auto-ap.events :as events])) + [auto-ap.events :as events] + [auto-ap.views.pages.data-page :as data-page])) -(re-frame/reg-sub - ::specific-filters - (fn [db ] - (::filters db nil))) - -(re-frame/reg-sub - ::filters - :<- [::specific-filters] - :<- [::subs/vendors-by-id] - :<- [::subs/query-params] - (fn [[specific-filters vendors-by-id query-params] ] - (let [url-filters (-> query-params - (select-keys #{:vendor-id - :date-range - :due-range - :invoice-number-like - :amount-gte - :amount-lte - :status})) - url-filters {:vendor (when-let [vendor-id (:vendor-id url-filters)] - {:id (str vendor-id) - :name (get-in vendors-by-id [(str vendor-id) :name] "Loading...")}) - :date-range (:date-range url-filters) - :due-range (:due-range url-filters) - :amount-range {:amount-gte (:amount-gte url-filters) - :amount-lte (:amount-lte url-filters)} - :invoice-number-like (str (:invoice-number-like url-filters))}] - - (deep-merge url-filters (or specific-filters {}) )))) - -(re-frame/reg-sub - ::filter - :<- [::filters] - (fn [filters [_ which]] - (get filters which))) - -(re-frame/reg-sub - ::settled-filters - (fn [db ] - (::settled-filters db))) - -(re-frame/reg-sub - ::filter-params - :<- [::settled-filters] - :<- [::filters] - :<- [::subs/active-page] - (fn [[settled-filters filters ap ]] - (let [filters (or settled-filters filters)] - {:vendor-id (:id (:vendor filters)) - :date-range (:date-range filters) - :due-range (:due-range filters) - :amount-gte (:amount-gte (:amount-range filters)) - :amount-lte (:amount-lte (:amount-range filters)) - :invoice-number-like (:invoice-number-like filters) - :status (condp = ap - :invoices nil - :unpaid-invoices :unpaid - :paid-invoices :paid - :voided-invoices :voided)}))) - -(re-frame/reg-event-fx - ::filters-settled - (fn [{:keys [db]} [_ & params]] - {:db (assoc db ::settled-filters @(re-frame/subscribe [::filters]))})) - -(re-frame/reg-event-fx - ::filter-changed - (fn [{:keys [db]} [_ & params]] - (let [[a b c] params - [which val] (if (= 3 (count params)) - [(into [a] b) c] - [[a] b])] - {:db (assoc-in db (into [::filters] which) val) - :dispatch-debounce - {:event [::filters-settled] - :time 800 - :key ::filters}}))) - -(defn invoice-number-filter [] +(defn invoice-number-filter [{:keys [data-page]}] [:div.field [:div.control [:input.input {:placeholder "AP-123" - :value @(re-frame/subscribe [::filter :invoice-number-like]) - :on-change (dispatch-value-change [::filter-changed :invoice-number-like ])} ]]]) + :value @(re-frame/subscribe [::data-page/filter data-page :invoice-number-like]) + :on-change (dispatch-value-change [::data-page/filter-changed data-page :invoice-number-like ])} ]]]) -(defn invoices-side-bar [params] +(defn invoices-side-bar [{:keys [data-page] :as params}] (let [ap @(re-frame/subscribe [::subs/active-page]) user @(re-frame/subscribe [::subs/user])] [:div @@ -142,28 +65,29 @@ [:p.menu-label "Vendor"] [:div [typeahead-entity {:matches @(re-frame/subscribe [::subs/vendors]) - :on-change #(re-frame/dispatch [::filter-changed :vendor %]) + :on-change #(re-frame/dispatch [::data-page/filter-changed data-page :vendor %]) :match->text :name :type "typeahead-entity" - :value @(re-frame/subscribe [::filter :vendor])}]] + :value @(re-frame/subscribe [::data-page/filter data-page :vendor]) + :include-keys [:name :id]}]] [:p.menu-label "Date Range"] [:div [date-range-filter - {:on-change-event [::filter-changed :date-range] - :value @(re-frame/subscribe [::filter :date-range])}]] + {:on-change-event [::data-page/filter-changed data-page :date-range] + :value @(re-frame/subscribe [::data-page/filter data-page :date-range])}]] [:p.menu-label "Due Range"] [:div [date-range-filter - {:on-change-event [::filter-changed :due-range] - :value @(re-frame/subscribe [::filter :due-range])}]] + {:on-change-event [::data-page/filter-changed data-page :due-range] + :value @(re-frame/subscribe [::data-page/filter data-page :due-range])}]] [:p.menu-label "Amount"] [:div [number-filter - {:on-change-event [::filter-changed :amount-range] - :value @(re-frame/subscribe [::filter :amount-range])}]] + {:on-change-event [::data-page/filter-changed data-page :amount-range] + :value @(re-frame/subscribe [::data-page/filter data-page :amount-range])}]] [:p.menu-label "Invoice #"] [:div - [invoice-number-filter]]])])) + [invoice-number-filter params]]])])) diff --git a/src/cljs/auto_ap/views/components/typeahead.cljs b/src/cljs/auto_ap/views/components/typeahead.cljs index c36fcb74..be501231 100644 --- a/src/cljs/auto_ap/views/components/typeahead.cljs +++ b/src/cljs/auto_ap/views/components/typeahead.cljs @@ -1,7 +1,8 @@ (ns auto-ap.views.components.typeahead (:require [reagent.core :as r] [reagent.ratom :as ra] - [clojure.string :as str])) + [clojure.string :as str] + [clojure.set :as set])) (defn get-valid-matches [matches not-found-description not-found-value text] (let [valid-matches (take 15 (for [[[id t :as match] i] (map vector matches (range)) @@ -124,17 +125,18 @@ valid-matches)] valid-matches)) (defn typeahead-entity [{:keys [matches on-change field value class not-found-description - disabled not-found-value auto-focus name]}] + disabled not-found-value auto-focus name include-keys]}] (let [text (r/atom (or (second (first (filter #(= (first %) value) matches))) "")) highlighted (r/atom nil) ] (r/create-class - {:reagent-render (fn [{:keys [matches on-change disabled match->text field value class not-found-description]}] + {:reagent-render (fn [{:keys [matches on-change disabled match->text field value class not-found-description include-keys]}] (let [select (fn [entity] (when on-change (if (= :not-found entity) (on-change nil) - (on-change entity)))) + (on-change (cond-> entity + (and include-keys entity) (select-keys include-keys)))))) text-atom text text (or (when value (match->text value)) @text) valid-matches (get-valid-entity-matches matches not-found-description not-found-value text match->text)] diff --git a/src/cljs/auto_ap/views/main.cljs b/src/cljs/auto_ap/views/main.cljs index 41b1c71c..35c47b99 100644 --- a/src/cljs/auto_ap/views/main.cljs +++ b/src/cljs/auto_ap/views/main.cljs @@ -31,20 +31,25 @@ (defmulti page (fn [active-page] active-page)) (defmethod page :unpaid-invoices [_] - (unpaid-invoices-page {:status "unpaid"})) + ^{:key :voided} + [unpaid-invoices-page {:status :unpaid}]) (defmethod page :import-invoices [_] (import-invoices-page )) (defmethod page :paid-invoices [_] - (unpaid-invoices-page {:status "paid"})) + ^{:key :voided} + [unpaid-invoices-page {:status :paid}] + ) (defmethod page :voided-invoices [_] - (unpaid-invoices-page {:status "voided"})) + ^{:key :voided} + [unpaid-invoices-page {:status :voided}]) (defmethod page :invoices [_] - (unpaid-invoices-page {})) + ^{:key :all} + [unpaid-invoices-page {}]) (defmethod page :payments [_] [payments-page]) diff --git a/src/cljs/auto_ap/views/pages/data_page.cljs b/src/cljs/auto_ap/views/pages/data_page.cljs index 25fbc6ad..4cbd2ece 100644 --- a/src/cljs/auto_ap/views/pages/data_page.cljs +++ b/src/cljs/auto_ap/views/pages/data_page.cljs @@ -1,6 +1,7 @@ (ns auto-ap.views.pages.data-page (:require [auto-ap.status :as status] - [auto-ap.utils :refer [by merge-by replace-by]] + [auto-ap.subs :as subs] + [auto-ap.utils :refer [deep-merge replace-by]] [re-frame.core :as re-frame])) (re-frame/reg-sub @@ -35,10 +36,30 @@ [::data id :data] replace-by :id (update entity :class #(or % "live-added"))))) -(re-frame/reg-event-db +(re-frame/reg-sub + ::table-params + (fn [db [_ which]] + (get-in db [::table-params which]))) + +(re-frame/reg-sub + ::params + (fn [[_ id]] + [(re-frame/subscribe [::subs/client]) + (re-frame/subscribe [::settled-filters id]) + (re-frame/subscribe [::table-params id]) + (re-frame/subscribe [::subs/query-params])]) + (fn [[client filters table-params query-params]] + (cond-> {} + client (assoc :client-id (:id client)) + (seq query-params) (merge query-params) + (seq filters) (merge filters) + (seq table-params) (merge table-params)))) + +(re-frame/reg-event-fx ::received - (fn [db [_ id data]] - (assoc-in db [::data id] data))) + (fn [{:keys [db]} [_ id data]] + {:db (assoc-in db [::data id] data) + :set-uri-params (dissoc @(re-frame/subscribe [::params id]) :client-id)})) (re-frame/reg-event-db ::dispose @@ -46,7 +67,9 @@ (-> db (update ::data dissoc id) (update ::checked dissoc id) - (update ::params dissoc id)))) + (update ::table-params dissoc id) + (update ::filters dissoc id) + (update ::settled-filters dissoc id)))) (re-frame/reg-sub ::data @@ -58,13 +81,67 @@ (fn [[_ id]] [(re-frame/subscribe [::data id]) (re-frame/subscribe [::status/single [::page id]]) - (re-frame/subscribe [::checked id])]) - (fn [[data status checked] [_ id]] + (re-frame/subscribe [::checked id]) + (re-frame/subscribe [::params id]) + (re-frame/subscribe [::table-params id]) + (re-frame/subscribe [::filters id])]) + (fn [[data status checked params table-params filters] [_ id]] {:id id :data data :status status - :checked checked})) + :checked checked + :params params + :filters filters + :table-params table-params})) (defn in-page-entities [which] (re-frame/path [::data which :data ] )) +(re-frame/reg-event-fx + ::table-params-changed + (fn [{:keys [db]} [_ which params :as z]] + {:db (update-in db [::table-params which] merge params)})) + +(re-frame/reg-sub + ::specific-filters + (fn [db [_ id]] + (get-in db [::filters id]))) + +(re-frame/reg-sub + ::filters + (fn [[_ id]] + [(re-frame/subscribe [::specific-filters id]) + (re-frame/subscribe [::subs/query-params])]) + (fn [[specific-filters query-params] ] + (deep-merge query-params (or specific-filters {}) ))) + +(re-frame/reg-sub + ::filter + (fn [[_ id]] + [(re-frame/subscribe [::filters id])]) + (fn [[filters] [_ id which]] + (get filters which))) + + +(re-frame/reg-event-fx + ::filters-settled + (fn [{:keys [db]} [_ id]] + {:db (assoc-in db [::settled-filters id] @(re-frame/subscribe [::filters id]))})) + +(re-frame/reg-sub + ::settled-filters + (fn [db [_ id]] + (get-in db [::settled-filters id]))) + +(re-frame/reg-event-fx + ::filter-changed + (fn [{:keys [db]} [_ id & params]] + (let [[a b c] params + [which val] (if (= 3 (count params)) + [(into [a] b) c] + [[a] b])] + {:db (assoc-in db (into [::filters id] which) val) + :dispatch-debounce + {:event [::filters-settled id] + :time 800 + :key [::filters id]}}))) diff --git a/src/cljs/auto_ap/views/pages/import_invoices.cljs b/src/cljs/auto_ap/views/pages/import_invoices.cljs index 96f62658..12c36491 100644 --- a/src/cljs/auto_ap/views/pages/import_invoices.cljs +++ b/src/cljs/auto_ap/views/pages/import_invoices.cljs @@ -17,7 +17,11 @@ [clojure.string :as str] [vimsical.re-frame.cofx.inject :as inject] [auto-ap.status :as status] - [vimsical.re-frame.fx.track :as track])) + [vimsical.re-frame.fx.track :as track] + [auto-ap.views.pages.data-page :as data-page] + [clojure.set :as set] + [auto-ap.effects.forward :as forward])) + (defn dropzone [] (let [client (re-frame/subscribe [::subs/client]) token (re-frame/subscribe [::subs/token]) @@ -30,7 +34,7 @@ (.on (js-this) "success" (fn [_ files] (re-frame/dispatch [::invalidated]))) (.on (js-this) "error" (fn [_ error] - (re-frame/dispatch [::errored error])))) + (re-frame/dispatch [::status/error ::import [(edn/read-string error)]])))) :paramName "file" :headers {"Authorization" (str "Token " @token)} :url (str "/api/invoices/upload" @@ -59,7 +63,6 @@ :value @vendor}]] ] [:div.tile.notification - [:div.has-text-centered {:style {:padding "80px 0px" :width "100%"}} [:span [:span {:class "icon"} @@ -68,15 +71,6 @@ )) -(re-frame/reg-sub - ::invoice-page - (fn [db] - (-> db ::invoice-page))) - -(re-frame/reg-sub - ::error - (fn [db] - (-> db ::error))) (re-frame/reg-sub @@ -86,65 +80,49 @@ (re-frame/reg-event-fx ::invalidated - (fn [cofx [_ params]] - {:dispatch [::params-change @(re-frame/subscribe [::params])]})) + (fn [{:keys [db]} [_ params]] + {:dispatch-n [[::params-change @(re-frame/subscribe [::data-page/params :import-invoices])] + [::data-page/reset-checked :import-invoices]/] + :db (update db ::batch inc)} + )) (re-frame/reg-event-fx ::mounted (fn [cofx [_ params]] - {::track/register {:id ::params - :subscription [::params] - :event-fn (fn [params] - [::params-change params])}})) + {::track/register [{:id ::params + :subscription [::data-page/params :import-invoices] + :event-fn (fn [params] + [::params-change params])} + ] + ::forward/register [{:id ::received + :events #{::data-page/received} + :event-fn (fn [[_ _ {:keys [data]}]] + [::received data])}] + :dispatch [::data-page/dispose :import-invoices]})) (re-frame/reg-event-fx ::unmounted (fn [cofx [_ params]] {::track/dispose {:id ::params}})) -(re-frame/reg-event-fx - ::completed - (fn [cofx [_ params]] - (println (::batch (:db cofx))) - {:dispatch [::invalidated] - :db (-> (:db cofx) - (update ::batch inc))})) - - -(re-frame/reg-sub - ::params - :<- [::subs/client] - :<- [::invoice-table/table-params] - (fn [[client table-params]] - (cond-> {:import-status "pending"} - client (assoc :client-id (:id client)) - (seq table-params) (merge table-params)))) (re-frame/reg-event-fx ::params-change - [with-user (re-frame/inject-cofx ::inject/sub [::params])] - (fn [{:keys [db user] ::keys [params]} [_]] - {:db (-> db - (dissoc ::error)) - :graphql {:token user - :owns-state {:single ::page} - :query-obj (invoice-table/query params) - :on-success [::received]}})) + [with-user] + (fn [{:keys [user] } [_ params]] + {:graphql {:token user + :owns-state {:single [::data-page/page :import-invoices]} + :query-obj (invoice-table/query (assoc params :import-status "pending")) + :on-success (fn [result] + (let [result (set/rename-keys (first (:invoice-page result)) + {:invoices :data})] -(re-frame/reg-event-db + [::data-page/received :import-invoices result]))}})) + +(re-frame/reg-event-fx ::received - (fn [db [_ data]] - (-> db - (assoc ::invoice-page (first (:invoice-page data))) - (update-in [::invoice-page] (fn [ip] - (assoc ip :checked (set (map :id (:invoices ip)))))) - (assoc-in [:status :loading] false)))) - -(re-frame/reg-event-db - ::errored - (fn [db [_ error]] - (assoc db ::error (or (:message (edn/read-string error)) - "An unknown error has occured.")))) + (fn [_ [_ data]] + {:dispatch [::data-page/toggle-check :import-invoices (set (map :id data))]})) (re-frame/reg-event-fx ::reject-invoices-clicked @@ -154,12 +132,10 @@ :owns-state {:single ::reject} :query-obj {:venia/operation {:operation/type :mutation :operation/name "RejectInvoices"} - :venia/queries [[:reject-invoices {:invoices (vec invoices)} - []]]} - :on-success [::completed]} - })) + []]]} + :on-success [::invalidated]}})) (re-frame/reg-event-fx ::approve-invoices-clicked @@ -169,12 +145,10 @@ :owns-state {:single ::approve} :query-obj {:venia/operation {:operation/type :mutation :operation/name "ApproveInvoices"} - :venia/queries [[:approve-invoices {:invoices (vec invoices)} - []]]} - :on-success [::completed]} - })) + []]]} + :on-success [::invalidated]}})) (re-frame/reg-event-fx ::approve-invoices @@ -184,17 +158,10 @@ :uri (str "/api/invoices/approve" (when-let [client-id (:id @(re-frame/subscribe [::subs/client]))] (str "?client=" client-id))) - :on-success on-success - }})) - -(re-frame/reg-event-db - ::toggle-check - (fn [db [_ new]] - (-> db (assoc-in [::invoice-page :checked] new)))) + :on-success on-success}})) (defn approve-reject-button [checked] [:div.is-pulled-right - [:button.button.is-success {:on-click (dispatch-event [::approve-invoices-clicked checked]) :class (status/class-for @(re-frame/subscribe [::status/single ::approve])) :disabled (if (seq checked) @@ -205,8 +172,6 @@ (str (count checked) " invoices")) - - [:span " "]] [:button.button.is-danger {:on-click (dispatch-event [::reject-invoices-clicked checked]) :class (status/class-for @(re-frame/subscribe [::status/single ::reject])) @@ -218,47 +183,34 @@ (str (count checked) " invoices")) - - - [:span " "] - ]]) + [:span " "]]]) (def import-invoices-content (with-meta (fn [] - (let [invoice-page (re-frame/subscribe [::invoice-page]) - status (re-frame/subscribe [::subs/status]) - error (re-frame/subscribe [::error]) - batch (re-frame/subscribe [::batch]) - params @(re-frame/subscribe [::params]) + (let [page @(re-frame/subscribe [::data-page/page :import-invoices]) + batch @(re-frame/subscribe [::batch]) client (:id @(re-frame/subscribe [::subs/client]))] - ^{:key (str client "-" @batch)} + ^{:key (str client "-" batch)} [:div [:h1.title "Upload invoices"] - - ^{:key (str @batch)} + [status/status-notification {:statuses [[::status/single ::approve] + [::status/single ::reject] + [::status/single ::import]]}] + ^{:key (str batch)} [dropzone] - - [:div {:class "section"} - (when @error - - [:div.notification.is-warning @error])] [:div {:class "card found-invoices",} [:div {:class "card-header"} [:span {:class "card-header-title"} "Found Invoices"]] [:div {:class "card-content"} - [approve-reject-button (:checked @invoice-page)] - (if (seq (:invoices @invoice-page)) + [approve-reject-button (:checked page)] + (if (seq (:data (:data page))) [invoice-table {:id :approved - :invoice-page @invoice-page + :data-page :import-invoices :overrides {:client (fn [row] [:p (:name (:client row)) [:p [:i.is-size-7 (:client-identifier row)]]])} - :check-boxes true - :checked (:checked @invoice-page) - :on-check-changed (fn [which] - (re-frame/dispatch [::toggle-check which])) - :status @(re-frame/subscribe [::status/single ::page])}] + :check-boxes true}] [:span "No pending invoices"])]]])) {:component-did-mount (fn [] (re-frame/dispatch-sync [::mounted])) diff --git a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs index 3689a139..7b3ce02b 100644 --- a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs +++ b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs @@ -35,22 +35,6 @@ [reagent.core :as r] [vimsical.re-frame.fx.track :as track])) -;; TODO: Sort out approaches for which buttons to show -;; TODO: make it so filters are basically free - -(re-frame/reg-sub - ::params - :<- [::subs/client] - :<- [::side-bar/filter-params] - :<- [::table/table-params] - (fn [[client filter-params table-params]] - (cond-> {:import-status "imported"} - client (assoc :client-id (:id client)) - (seq filter-params) (merge filter-params) - (seq table-params) (merge table-params)))) - - - (re-frame/reg-event-fx ::params-change [with-user] @@ -63,11 +47,7 @@ {:invoices :data})] [::data-page/received :invoices result])) - :on-error [::events/page-failed]} - :set-uri-params (dissoc params - :status - :client-id - :import-status)})) + :on-error [::events/page-failed]}})) (re-frame/reg-event-fx ::unmounted @@ -82,7 +62,7 @@ ::mounted (fn [{:keys [db]} _] {::track/register [{:id ::params - :subscription [::params] + :subscription [::data-page/params :invoices] :event-fn (fn [params] [::params-change params])}] ::forward/register [{:id ::updated @@ -207,7 +187,7 @@ (dispatch-event [::data-page/remove-check :invoices id])}]]) checked-invoices))]])) -(defn unpaid-invoices-content [{:keys [status] :as params}] +(defn unpaid-invoices-content [{:keys [status]}] (let [page @(re-frame/subscribe [::data-page/page :invoices]) current-client @(re-frame/subscribe [::subs/client])] [:div @@ -216,12 +196,8 @@ (when (= status :unpaid) [pay-button]) [table/invoice-table {:id (:id page) - :checked (:checked page) - :data (:data page) - :status (:status page) + :data-page :invoices :check-boxes (= status :unpaid) - :on-check-changed (fn [new] - (re-frame/dispatch [::data-page/toggle-check :invoices new ])) :actions #{:edit :void :expense-accounts}}]])) (defn unpaid-invoices-page [params] @@ -231,8 +207,7 @@ :component-did-mount #(re-frame/dispatch [::mounted]) :reagent-render (fn [] - (let [{invoice-bar-active? :active?} @(re-frame/subscribe [::forms/form ::form/form]) - params @(re-frame/subscribe [::params])] - [side-bar-layout {:side-bar [invoices-side-bar {}] + (let [{invoice-bar-active? :active?} @(re-frame/subscribe [::forms/form ::form/form])] + [side-bar-layout {:side-bar [invoices-side-bar {:data-page :invoices}] :main [unpaid-invoices-content params] :right-side-bar [appearing-side-bar {:visible? invoice-bar-active?} [form/form {}]]}]))}))