From e8301b071daa86dc4206fe0db766d1f144f5ba4e Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Fri, 21 Aug 2020 08:21:47 -0700 Subject: [PATCH] Transactions are converted! --- src/cljs/auto_ap/effects.cljs | 62 +++++++++---- src/cljs/auto_ap/status.cljs | 44 +++++++--- src/cljs/auto_ap/views/pages/ledger.cljs | 3 +- .../auto_ap/views/pages/transactions.cljs | 38 +++----- .../views/pages/transactions/manual.cljs | 88 +++++++++++-------- 5 files changed, 145 insertions(+), 90 deletions(-) diff --git a/src/cljs/auto_ap/effects.cljs b/src/cljs/auto_ap/effects.cljs index 124296cd..42ae337d 100644 --- a/src/cljs/auto_ap/effects.cljs +++ b/src/cljs/auto_ap/effects.cljs @@ -80,8 +80,14 @@ (re-frame/reg-fx :http - (fn [{:keys [method uri on-success on-error body headers token]}] + (fn [{:keys [method uri on-success on-error body headers owns-state token]}] + (go + (when (:multi owns-state) + (re-frame/dispatch-sync [::status/loading-multi (:multi owns-state) (:which owns-state)])) + + (when (:single owns-state) + (re-frame/dispatch-sync [::status/loading (:single owns-state)])) (let [headers (if token (assoc headers "Authorization" (str "Token " token)) headers) @@ -90,23 +96,37 @@ :headers headers :url uri}))] (if (>= (:status response) 400) - (when on-error + (do + (when (:multi owns-state) + (re-frame/dispatch [::status/error-multi (:multi owns-state) (:which owns-state) [(:body response)]])) + (when (:single owns-state) + (re-frame/dispatch [::status/error (:single owns-state) [(:body response)]])) + (when on-error + (->> response + :body + (dates->date-times) + (conj on-error) + (re-frame/dispatch)))) + (do + (when (:multi owns-state) + (re-frame/dispatch [::status/completed-multi (:multi owns-state) (:which owns-state)])) + (when (:single owns-state) + (re-frame/dispatch [::status/completed (:single owns-state)])) (->> response - :body - (dates->date-times) - (conj on-error) - (re-frame/dispatch))) - (->> response - :body - (dates->date-times) - (conj on-success) - (re-frame/dispatch))))))) + :body + (dates->date-times) + (conj on-success) + (re-frame/dispatch)))))))) (re-frame/reg-fx :https - (fn [{:keys [requests on-success on-failure]}] + (fn [{:keys [requests on-success on-failure owns-state]}] (go - + (when (:multi owns-state) + (re-frame/dispatch-sync [::status/loading-multi (:multi owns-state) (:which owns-state)])) + + (when (:single owns-state) + (re-frame/dispatch-sync [::status/loading (:single owns-state)])) (let [results (->> (for [{:keys [method body headers uri token]} requests] (go @@ -123,9 +143,21 @@ (async/merge) (async/reduce conj []) (async/snake [s] (str/replace s #"-" "_")) diff --git a/src/cljs/auto_ap/status.cljs b/src/cljs/auto_ap/status.cljs index c4b31405..f12ffcdf 100644 --- a/src/cljs/auto_ap/status.cljs +++ b/src/cljs/auto_ap/status.cljs @@ -89,6 +89,12 @@ (assoc db single {:state :loading :error nil}))) +(re-frame/reg-event-db + ::dispose-single + [(re-frame/path [::status]) ] + (fn [db [_ single]] + (dissoc db single ))) + (re-frame/reg-event-db ::completed [(re-frame/path [::status]) ] @@ -101,17 +107,33 @@ [(re-frame/path [::status]) ] (fn [db [_ single error]] (assoc db single {:state :error + :info nil :error error}))) +(re-frame/reg-event-db + ::info + [(re-frame/path [::status]) ] + (fn [db [_ single info]] + (assoc db single {:info info}))) + (defn status-notification [{:keys [statuses]}] - (let [states - (->> statuses - (mapv #(deref (re-frame/subscribe %))) - (filter #(= :error (:state %))))] - (when (seq states) - [:div.notification.is-warning - (for [state states - state (:error state)] - (do - ^{:key (:message state)} - [:p (:message state)]))]))) + (let [states (mapv #(deref (re-frame/subscribe %)) statuses) + error-states + (->> states + (filter #(= :error (:state %)))) + info-states + (->> states (filter #(:info %)))] + [:<> + (if (seq error-states) + [:div.notification.is-warning + (for [state states + state (:error state)] + (do + ^{:key (:message state)} + [:p (:message state)]))]) + (if (seq info-states) + [:div.notification + (for [state states] + (do + ^{:key (:info state)} + [:p (:info state)]))])])) diff --git a/src/cljs/auto_ap/views/pages/ledger.cljs b/src/cljs/auto_ap/views/pages/ledger.cljs index e4676d76..780d0a1e 100644 --- a/src/cljs/auto_ap/views/pages/ledger.cljs +++ b/src/cljs/auto_ap/views/pages/ledger.cljs @@ -94,8 +94,7 @@ [:h1.title "Ledger"] [table/table {:id :ledger :ledger-page @(re-frame/subscribe [::ledger-page]) - :status @(re-frame/subscribe [::status/single ::page])}] - [manual/modal {:import-completed [::manual-import-completed ]}]])) + :status @(re-frame/subscribe [::status/single ::page])}]])) (defn ledger-page [] diff --git a/src/cljs/auto_ap/views/pages/transactions.cljs b/src/cljs/auto_ap/views/pages/transactions.cljs index 34e4f958..414f195c 100644 --- a/src/cljs/auto_ap/views/pages/transactions.cljs +++ b/src/cljs/auto_ap/views/pages/transactions.cljs @@ -20,14 +20,6 @@ [auto-ap.status :as status])) -(re-frame/reg-event-fx - ::manual-import-completed - (fn [{:keys [db]} [_ {:keys [imported errors]}]] - {:dispatch [::params-change @(re-frame/subscribe [::data-page/params ::page])] - :db (-> db - (assoc-in [::notification :message] (str "Successfully imported " imported " transactions")) - (assoc-in [::notification :errors] errors))})) - (defn data-params->query-params [params] {:start (:start params 0) @@ -87,9 +79,11 @@ (re-frame/reg-event-fx ::unmounted (fn [{:keys [db]} _] - {:dispatch [::data-page/dispose ::page] + {:dispatch-n [[::data-page/dispose ::page] + [::status/dispose-single ::manual-import]] ::track/dispose {:id ::params} - ::forward/dispose {:id ::updated}})) + ::forward/dispose [{:id ::updated} + {:id ::manual-import}]})) (re-frame/reg-event-fx ::mounted @@ -98,26 +92,24 @@ :subscription [::data-page/params ::page] :event-fn (fn [params] [::params-change params])} - ::forward/register {:id ::updated - :events #{::edit/edited} - :event-fn (fn [[_ edited-transaction]] - [::data-page/updated-entity ::page edited-transaction])}})) + ::forward/register [{:id ::updated + :events #{::edit/edited} + :event-fn (fn [[_ edited-transaction]] + [::data-page/updated-entity ::page edited-transaction])} + {:id ::manual-import + :events #{::manual/import-completed} + :event-fn (fn [[_ {:keys [imported errors] :as result}]] + [::status/info ::manual-import (str "Successfully imported " imported " transactions")])}]})) - - -(re-frame/reg-sub - ::notification - (fn [db] - (-> db ::notification))) - (defn content [] (let [notification (re-frame/subscribe [::notification]) user @(re-frame/subscribe [::subs/user]) params @(re-frame/subscribe [::data-page/params ::page])] [:div [:h1.title "Transactions"] - [status/status-notification {:statuses [[::status/single ::unapprove-all]]}] + [status/status-notification {:statuses [[::status/single ::unapprove-all] + [::status/single ::manual-import]]}] (when (= "admin" (:user/role user)) [:div (when (:message @notification) @@ -155,8 +147,6 @@ {:side-bar [side-bar/side-bar {:data-page ::page}] :main [:div ^{:key approval-status} [content]] - :bottom [:div - [manual/modal {:import-completed [::manual-import-completed ]}]] :right-side-bar [appearing-side-bar {:visible? transaction-bar-active?} [edit/form]]}]))})) diff --git a/src/cljs/auto_ap/views/pages/transactions/manual.cljs b/src/cljs/auto_ap/views/pages/transactions/manual.cljs index 08ffe5b9..89b4b143 100644 --- a/src/cljs/auto_ap/views/pages/transactions/manual.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/manual.cljs @@ -1,59 +1,71 @@ (ns auto-ap.views.pages.transactions.manual (:require [auto-ap.events :as events] + [auto-ap.forms :as forms] + [auto-ap.status :as status] [auto-ap.subs :as subs] - [auto-ap.views.components.modal :refer [action-modal]] - [auto-ap.views.utils :refer [bind-field]] + [auto-ap.views.components.modal :as modal] + [auto-ap.views.utils :refer [dispatch-event with-user]] [re-frame.core :as re-frame])) +(re-frame/reg-sub + ::can-submit + :<- [::forms/form ::form] + (fn [{ {:keys [data]} :data}] + (not-empty data))) + +(def import-form (forms/vertical-form {:submit-event [::save] + :change-event [::forms/change ::form] + :can-submit [::can-submit] + :id ::form})) + +(defn form [{import-completed-event :import-completed}] + (let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::form]) + {:keys [form-inline horizontal-field field raw-field error-notification submit-button]} import-form] + + (form-inline {} + [:div.field + [:label.label + "Yodlee manual import table"] + [:div.control + [raw-field + [:textarea.textarea {:field [:data]}]]]]))) + (re-frame/reg-event-fx ::opening (fn [{:keys [db]} _] - {:dispatch [::events/modal-status ::import {:visible? true}] - :db (assoc-in db [::import] {:client-id (:id @(re-frame/subscribe [::subs/client])) - :data ""})})) + {:dispatch [::modal/modal-requested {:title "Import Transactions" + :body [form] + :confirm {:value "Import" + :status-from [::status/single ::form] + :class "is-primary" + :on-click (dispatch-event [::save]) + :can-submit [::can-submit] + :close-event [::status/completed ::form]}}] + :db (-> db + (forms/start-form ::form + {:client-id (:id @(re-frame/subscribe [::subs/client])) + :data ""}))})) + -(re-frame/reg-sub - ::import - (fn [db] - (-> db ::import))) (re-frame/reg-event-fx ::import-completed - (fn [{:keys [db]} [_ import-completed-event {:keys [imported errors] :as result}]] - {:dispatch-n [[::events/modal-completed ::import] - (conj import-completed-event result)]})) + (fn [{:keys [db]} [_ {:keys [imported errors] :as result}]] + {:dispatch [::modal/modal-closed ]})) (re-frame/reg-event-fx - ::import-error - (fn [{:keys [db]} [_ result]] - {:dispatch [::events/modal-failed ::import "Import failed"]})) - -(re-frame/reg-event-fx - ::import-started - (fn [{:keys [db]} [_ import-completed-event]] - (let [import (::import db)] - {:http {:token (:user db) + ::save + [with-user (forms/in-form ::form) ] + (fn [{:keys [db user]}] + (let [import (:data db)] + {:http {:token user + :owns-state {:single ::form} :method :post :body (pr-str import) :headers {"Content-Type" "application/edn"} :uri (str "/api/transactions/batch-upload") - :on-success [::import-completed import-completed-event] - :on-error [::import-error]}}))) + :on-success [::import-completed]}}))) + -(defn modal [{import-completed-event :import-completed}] - (let [data @(re-frame/subscribe [::import]) - change-event [::events/change-form [::import]]] - [action-modal {:id ::import - :title "Manual Yodlee Import" - :action-text "Import" - :save-event [::import-started import-completed-event]} - [:div.field - [:label.label - "Yodlee manual import table"] - [:div.control - [bind-field - [:textarea.textarea {:field [:data] - :event change-event - :subscription data}]]]]]))