(ns auto-ap.views.pages.transactions (:require [auto-ap.effects.forward :as forward] [auto-ap.forms :as forms] [auto-ap.subs :as subs] [auto-ap.views.components.modal :as modal] [auto-ap.views.components.layouts :refer [appearing-side-bar side-bar-layout]] [auto-ap.views.pages.data-page :as data-page] [auto-ap.views.pages.transactions.common :refer [transaction-read data-params->query-params]] [auto-ap.views.pages.transactions.form :as edit] [auto-ap.views.pages.transactions.manual :as manual] [auto-ap.views.pages.transactions.bulk-updates :as bulk] [auto-ap.views.pages.transactions.side-bar :as side-bar] [auto-ap.views.pages.transactions.table :as table] [auto-ap.views.utils :refer [dispatch-event with-user date->str standard]] [cljs-time.core :as time] [re-frame.core :as re-frame] [reagent.core :as reagent] [vimsical.re-frame.fx.track :as track] [auto-ap.status :as status] [clojure.string :as str])) (re-frame/reg-event-fx ::params-change [with-user] (fn [{:keys [user db]} [_ params]] (try {:graphql {:token user :owns-state {:single [::data-page/page ::page]} :query-obj {:venia/queries [{:query/data [:transaction_page {:filters (data-params->query-params params)} [[:data transaction-read] :total :start :end]] :query/alias :result}]} :on-success (fn [result] [::data-page/received ::page (:result result)])} :db (-> db (forms/stop-form ::edit/form))} (catch js/Error e ;; this catches an error where you choose a parameter, change to invoices page, then change to voided invoices (println "Error!" e))))) (re-frame/reg-event-fx ::delete-selected (fn [cofx [_ params suppress]] (let [checked @(re-frame/subscribe [::data-page/checked ::page]) checked-params (get checked "header") specific-transactions (map :id (vals (dissoc checked "header")))] {:db (-> (:db cofx) (assoc-in [:status :loading] true)) :graphql {:token (-> cofx :db :user) :owns-state {:single ::delete-selected} :query-obj {:venia/operation {:operation/type :mutation :operation/name "DeleteTransactions"} :venia/queries [{:query/data [:delete-transactions {:filters (some-> checked-params data-params->query-params) :ids specific-transactions :suppress suppress} [:message]]}]} :on-success (fn [_] [::params-change params])} :dispatch-n [[::data-page/reset-checked ::page] [::modal/modal-closed]]}))) (re-frame/reg-event-fx ::delete-selected-requested (fn [_ [_ params suppress]] (let [checked @(re-frame/subscribe [::data-page/checked ::page]) to-delete (if (get checked "header") "all visible transactions" (str (count checked) " transactions"))] {:dispatch [::modal/modal-requested {:title "Confirmation" :body [:div (str "Are you sure you want to delete " to-delete "?")] :cancel? true :confirm {:value "Delete" :class "is-danger" :status-from [::status/single ::delete-selected] :on-click (dispatch-event [::delete-selected params suppress] )} :close-event [::status/completed ::delete-selected]}]}))) (re-frame/reg-event-fx ::unmounted (fn [{:keys []} _] {:dispatch-n [[::data-page/dispose ::page] [::status/dispose-single ::manual-import]] ::track/dispose {:id ::params} ::forward/dispose [{:id ::updated} {:id ::manual-import}]})) (re-frame/reg-event-fx ::mounted (fn [{:keys [db]} _] {:db (assoc-in db [::data-page/settled-filters ::page :date-range] {:start (date->str (time/plus (time/now) (time/months -1)) standard)}) ::track/register {:id ::params :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])} {:id ::manual-import :events #{::manual/import-completed} :event-fn (fn [[_ result]] [::status/info ::manual-import (str "Successfully " (str/join ", " [(when-let [imported (:import-batch/imported result)] (str "imported " imported)) (when-let [extant (:import-batch/extant result)] (str "extant " extant)) (when-let [suppressed (:import-batch/suppressed result)] (str "suppressed " suppressed)) (when-let [not-ready (:import-batch/not-ready result)] (str "too early " not-ready)) (when-let [error (:validation-error result)] (str "errored " error))]) " transactions." (when (:sample-error result) (str " Sample error: " (:info (:sample-error result)))))])}]})) (defn action-buttons [] (let [is-admin? @(re-frame/subscribe [::subs/is-admin?]) params @(re-frame/subscribe [::data-page/params ::page]) checked @(re-frame/subscribe [::data-page/checked ::page])] (when is-admin? [:<> [:div.level-item [:div.tags (map (fn [[z {:keys [id]}]] (if (= "header" z) ^{:key "header"} [:span.tag.is-medium {:on-click (dispatch-event [::data-page/remove-check ::page "header"])} "All visible transactions"] ^{:key id} [:span.tag.is-medium id [:button.delete.is-small {:on-click (dispatch-event [::data-page/remove-check ::page id])}]])) checked)]] [:div.level-item [:div.buttons [:button.button.is-outlined.is-primary {:on-click (dispatch-event [::manual/opening])} "Manual Yodlee Import"] (when (:client-id params) [:button.button.is-warning {:on-click (dispatch-event [::bulk/code-requested checked params]) :disabled (not (seq checked))} "Code"]) [:button.button.is-danger {:on-click (dispatch-event [::delete-selected-requested params false]) :disabled (not (seq checked))} "Delete"] [:button.button.is-danger {:on-click (dispatch-event [::delete-selected-requested params true]) :disabled (not (seq checked))} "Suppress"]]]]))) (defn content [] (let [is-admin? @(re-frame/subscribe [::subs/is-admin?])] [:div [:h1.title "Transactions"] [status/status-notification {:statuses [[::status/single ::delete-selected] [::status/single ::manual-import]]}] [table/table {:id :transactions :check-boxes? is-admin? :data-page ::page :action-buttons [action-buttons]}]])) (defn transactions-page [{:keys [approval-status]}] (reagent/create-class {:display-name "transaction-page" :component-will-unmount #(re-frame/dispatch [::unmounted]) :component-did-mount #(re-frame/dispatch [::mounted]) :reagent-render (fn [] (let [{transaction-bar-active? :active?} @(re-frame/subscribe [::forms/form ::edit/form])] [side-bar-layout {:side-bar [side-bar/side-bar {:data-page ::page}] :main [:div ^{:key approval-status} [content]] :right-side-bar [appearing-side-bar {:visible? transaction-bar-active?} [edit/form]]}]))}))