diff --git a/src/cljc/auto_ap/client_routes.cljc b/src/cljc/auto_ap/client_routes.cljc index 5af3beab..e54bb53b 100644 --- a/src/cljc/auto_ap/client_routes.cljc +++ b/src/cljc/auto_ap/client_routes.cljc @@ -14,7 +14,6 @@ "rules" :admin-rules "accounts" :admin-accounts "import-batches" :admin-import-batches - "reminders" :admin-reminders "vendors" :admin-vendors "excel-import" :admin-excel-import "yodlee2" :admin-yodlee2} diff --git a/src/cljs/auto_ap/events.cljs b/src/cljs/auto_ap/events.cljs index 44cd4ae1..ff28338c 100644 --- a/src/cljs/auto_ap/events.cljs +++ b/src/cljs/auto_ap/events.cljs @@ -2,7 +2,6 @@ (:require [auto-ap.db :as db] [auto-ap.routes :as routes] - [auto-ap.subs :as subs] [auto-ap.utils :refer [by]] [auto-ap.views.utils :refer [with-user parse-jwt]] [bidi.bidi :as bidi] @@ -143,12 +142,12 @@ (re-frame/reg-event-fx ::set-active-route (fn [{:keys [db]} [_ handler params route-params]] - (println (:user/role (parse-jwt (:user db)))) (cond (and (not= :login handler) (not (:user db))) {:redirect (bidi/path-for routes/routes :login) :db (assoc db :active-route :login :active-page :login + :menu nil :page-failure nil)} (and (not= "admin" (:user/role (parse-jwt (:user db)))) @@ -156,11 +155,13 @@ {:redirect (bidi/path-for routes/routes :index) :db (assoc db :active-route :index :active-page :index + :menu nil :page-failure nil)} :else {:db (-> db (assoc :active-route handler :page-failure nil + :menu nil :query-params params :route-params route-params) (auto-ap.views.pages.data-page/dispose-all))}))) diff --git a/src/cljs/auto_ap/events/admin/reminders.cljs b/src/cljs/auto_ap/events/admin/reminders.cljs deleted file mode 100644 index 33bdefee..00000000 --- a/src/cljs/auto_ap/events/admin/reminders.cljs +++ /dev/null @@ -1,7 +0,0 @@ -(ns auto-ap.events.admin.reminders - (:require [re-frame.core :as re-frame] - [auto-ap.db :as db] - [auto-ap.routes :as routes] - [auto-ap.effects :as effects])) - - diff --git a/src/cljs/auto_ap/forms.cljs b/src/cljs/auto_ap/forms.cljs index de4f6b71..638333e1 100644 --- a/src/cljs/auto_ap/forms.cljs +++ b/src/cljs/auto_ap/forms.cljs @@ -2,7 +2,7 @@ (:require [re-frame.core :as re-frame] [re-frame.interceptor :as i] [auto-ap.status :as status] - [auto-ap.views.utils :refer [dispatch-event bind-field]] + [auto-ap.views.utils :refer [dispatch-event]] [malli.core :as m])) diff --git a/src/cljs/auto_ap/forms/builder.cljs b/src/cljs/auto_ap/forms/builder.cljs index 3c6a3093..3263bc25 100644 --- a/src/cljs/auto_ap/forms/builder.cljs +++ b/src/cljs/auto_ap/forms/builder.cljs @@ -1,14 +1,12 @@ (ns auto-ap.forms.builder (:require - [auto-ap.views.utils :refer [bind-field]] [re-frame.core :as re-frame] [react :as react] [reagent.core :as r] [auto-ap.forms :as forms] [auto-ap.status :as status] [malli.core :as m] - [malli.error :as me] - [clojure.string :as str])) + [malli.error :as me])) (defonce ^js/React.Context form-context (react/createContext "default")) (def ^js/React.Provider Provider (. form-context -Provider)) @@ -119,28 +117,6 @@ (into [:<>] (r/children (r/current-component))))))))) -(defn raw-field [] - (let [[child] (r/children (r/current-component))] - [:> Consumer {} - (fn [consume-form] - (r/as-element - [:> FormScopeConsumer {} - (fn [form-scope] - (r/as-element - [bind-field (-> child - (update-in [1 :field] (fn [f] - (cond - (sequential? f) - (into form-scope f) - - f - (conj form-scope f) - - :else - nil))) - - (assoc-in [1 :subscription] (aget consume-form "data")) - (assoc-in [1 :event] (aget consume-form "change-event")))]))]))])) (defn change-handler [path re-frame-change-event event-or-value] (re-frame/dispatch (-> re-frame-change-event diff --git a/src/cljs/auto_ap/views/components/address.cljs b/src/cljs/auto_ap/views/components/address.cljs index ffe0980b..fa92e600 100644 --- a/src/cljs/auto_ap/views/components/address.cljs +++ b/src/cljs/auto_ap/views/components/address.cljs @@ -1,8 +1,8 @@ (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.views.components.level :as level])) + (:require + [auto-ap.entities.address :as address] + [auto-ap.forms.builder :as form-builder] + [auto-ap.views.components.level :as level])) (defn address2-field [{:keys [value on-change]}] [form-builder/virtual-builder {:value (or value {}) diff --git a/src/cljs/auto_ap/views/components/admin/side_bar.cljs b/src/cljs/auto_ap/views/components/admin/side_bar.cljs index a53f490e..e239dbef 100644 --- a/src/cljs/auto_ap/views/components/admin/side_bar.cljs +++ b/src/cljs/auto_ap/views/components/admin/side_bar.cljs @@ -1,15 +1,11 @@ (ns auto-ap.views.components.admin.side-bar - (:require [re-frame.core :as re-frame] - [reagent.core :as r] - [clojure.string :as str] - [clojure.spec.alpha :as s] - [cljs-time.core :as c] - [goog.string :as gstring] - [bidi.bidi :as bidi] - [auto-ap.routes :as routes] - [auto-ap.views.utils :refer [active-when dispatch-event bind-field horizontal-field date->str str->date pretty standard]] - [auto-ap.subs :as subs] - [auto-ap.events :as events])) + (:require + [auto-ap.routes :as routes] + [auto-ap.subs :as subs] + [auto-ap.views.utils :refer [active-when]] + [bidi.bidi :as bidi] + [re-frame.core :as re-frame] + [reagent.core :as r])) (defn admin-side-bar [params ] (let [ap @(re-frame/subscribe [::subs/active-page])] @@ -59,14 +55,6 @@ [:ul ]] - [:p.menu-label "History"] - [:ul.menu-list - [:li.menu-item - [:a {:href (bidi/path-for routes/routes :admin-reminders) , :class (str "item" (active-when ap = :admin-reminders))} - [:span {:class "icon"} - [:i {:class "fa fa-star-o"}]] - - [:span {:class "name"} "Reminders"]]]] [:p.menu-label "Import"] [:ul.menu-list [:li.menu-item 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 bfe1c2af..f18c4427 100644 --- a/src/cljs/auto_ap/views/components/expense_accounts_field.cljs +++ b/src/cljs/auto_ap/views/components/expense_accounts_field.cljs @@ -10,11 +10,9 @@ [auto-ap.views.components.percentage-field :refer [percentage-field]] [auto-ap.views.components.typeahead.vendor :refer [search-backed-typeahead]] - [auto-ap.views.utils :refer [->$ bind-field dispatch-event appearing-group]] - [clojure.string :as str] + [auto-ap.views.utils :refer [->$ appearing-group]] [goog.string :as gstring] - [malli.core :as m] - [re-frame.core :as re-frame])) + [malli.core :as m])) (defn can-replace-with-default? [accounts] (and (or (not (seq accounts)) @@ -56,27 +54,6 @@ ;; EVENTS -(re-frame/reg-event-fx - ::add-expense-account - (fn [_ [_ event expense-accounts locations]] - {:dispatch (conj event (conj expense-accounts - {:amount 0 :id (str "new-" (random-uuid)) - :amount-mode "%" - :amount-percentage 0 - :location (if (= 1 (count locations)) - (first locations) - nil)}))})) - -(re-frame/reg-event-fx - ::remove-expense-account - (fn [_ [_ event expense-accounts id]] - {:dispatch (conj event (transduce (filter - (fn [ea] - (not= (:id ea) id)) ) - conj - [] - expense-accounts))})) - (defn recalculate-amounts [expense-accounts total] (mapv (fn [ea] @@ -86,146 +63,8 @@ (* (/ (js/parseFloat (:amount-percentage ea)) 100.0) total))))) expense-accounts)) -(re-frame/reg-event-fx - ::spread-evenly - (fn [_ [_ event expense-accounts max-value]] - {:dispatch (into event [(recalculate-amounts (mapv - (fn [ea] - (assoc ea :amount-percentage (js/parseFloat - (goog.string/format "%.2f" - (* 100 (/ 1 (count expense-accounts))))))) - expense-accounts) - max-value)])})) -(re-frame/reg-event-fx - ::expense-account-changed - (fn [_ [_ event expense-accounts max-value field value]] - (let [updated-accounts (cond-> expense-accounts - true (assoc-in field value) - (= (list :account) (drop 1 field)) (assoc-in [(first field) :location] nil) - - (= (list :amount-percentage) (drop 1 field)) (assoc-in [(first field) :amount] - (js/parseFloat - (goog.string/format "%.2f" - (* (/ (cond-> value - (not (float? value)) (js/parseFloat )) 100.0) - (cond-> max-value - (not (float? max-value)) (js/parseFloat))))))) - updated-accounts (if-let [location (get-in updated-accounts [(first field) :account :location])] - (assoc-in updated-accounts [(first field) :location] location) - updated-accounts)] - {:dispatch (into event [updated-accounts])}))) - - ;; VIEWS -(defn expense-accounts-field [{expense-accounts :value client :client max-value :max locations :locations event :event descriptor :descriptor disabled :disabled percentage-only? :percentage-only? :or {percentage-only? false}}] - [:div - [:div.columns - [:div.column - [:h1.subtitle.is-4.is-inline (str/capitalize descriptor) "s"] - (when-not percentage-only? - [:p.help "Remaining" (->$ (- max-value (reduce + 0 (map (comp js/parseFloat :amount) expense-accounts))))])] - [:div.column.is-narrow - (when-not disabled - [:p.buttons - [:a.button {:on-click (dispatch-event [::spread-evenly event expense-accounts max-value])} "Spread evenly"] - [:a.button {:on-click (dispatch-event [::add-expense-account event expense-accounts locations])} "Add"]])]] - (for [[index {:keys [account id location amount amount-percentage amount-mode] :as expense-account}] (map vector (range) expense-accounts)] - ^{:key id} - [:div.box - [:div.columns - [:div.column - [:h1.subtitle.is-6 (cond (and account (not percentage-only?)) - (str (:name account) " - " - location ": " - (gstring/format "$%.2f" (or amount 0) )) - - account - (str (:name account) " - " - location ": %" - amount-percentage) - - :else - [:i "New " descriptor])]] - [:div.column.is-narrow - (when-not disabled - [:a.delete {:on-click (dispatch-event [::remove-expense-account event expense-accounts id])}])]] - - [:div.field - [:div.columns - [:div.column - [:p.help "Account"] - [:div.control.is-fullwidth - [bind-field - ^{:key (:id client)} - [search-backed-typeahead {:search-query (fn [i] - [:search_account - {:query i - :client-id (:id client)} - [:name :id :location]]) - :type "typeahead-v3" - :field [index :account] - - :disabled disabled - :event [::expense-account-changed event expense-accounts max-value] - :subscription expense-accounts}]]]] - [:div.column.is-narrow - [:p.help "Location"] - [:div.control - (if-let [forced-location (:location account)] - [:div.select - [:select {:disabled "disabled" :style {:width "5em"} :value forced-location} [:option {:value forced-location} forced-location]]] - [:div.select - [bind-field - [:select {:type "select" - :disabled (boolean (or (:location account) - disabled)) - :style {:width "5em"} - :field [index :location] - :allow-nil? true - :spec (set locations) - :event [::expense-account-changed event expense-accounts max-value] - :subscription expense-accounts} - (map (fn [l] ^{:key l} [:option {:value l} l]) locations)]]])]]]] - - [:div.field - [:p.help "Amount"] - [:div.control - [:div.field.has-addons.is-extended - [:p.control [:span.select - [bind-field - [:select {:type "select" - :disabled (or disabled percentage-only?) - :field [index :amount-mode] - :allow-nil? false - :event [::expense-account-changed event expense-accounts max-value] - :subscription expense-accounts} - [:option "$"] - [:option "%"]]]]] - [:p.control - (if (= "$" amount-mode) - [bind-field - [:input.input {:type "number" - :field [index :amount] - :style {:text-align "right" :width "7em"} - :event [::expense-account-changed event expense-accounts max-value] - :disabled disabled - :subscription expense-accounts - :precision 2 - :value (get-in expense-account [:amount]) - :max max-value - :step "0.01"}]] - [bind-field - [:input.input {:type "number" - :field [index :amount-percentage] - :style {:text-align "right" :width "7em"} - :disabled disabled - :event [::expense-account-changed event expense-accounts max-value] - :precision 2 - :subscription expense-accounts - :value (get-in expense-account [:amount-percentage]) - :max "100" - :step "0.01"}]])]]]]])]) (def schema (m/schema [:sequential [:map [:id :string] diff --git a/src/cljs/auto_ap/views/components/layouts.cljs b/src/cljs/auto_ap/views/components/layouts.cljs index 367307de..0ab3265e 100644 --- a/src/cljs/auto_ap/views/components/layouts.cljs +++ b/src/cljs/auto_ap/views/components/layouts.cljs @@ -3,44 +3,53 @@ [auto-ap.events :as events] [auto-ap.routes :as routes] [auto-ap.subs :as subs] - [auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]] [auto-ap.views.components.modal :as modal] [auto-ap.views.components.vendor-dialog :as vendor-dialog] [auto-ap.views.utils - :refer [active-when appearing bind-field dispatch-event dispatch-event-with-propagation login-url]] + :refer [active-when + appearing + dispatch-event-with-propagation + login-url]] [bidi.bidi :as bidi] [clojure.string :as str] [re-frame.core :as re-frame] - [reagent.core :as r])) + [reagent.core :as r] + [auto-ap.forms.builder :as form-builder] + [vimsical.re-frame.cofx.inject :as inject] + [auto-ap.forms :as forms])) -(defn navbar-drop-down-contents [{:keys [id]} children ] - (let [toggle-fn (fn [] (re-frame/dispatch [::events/toggle-menu id]))] - (r/create-class {:component-did-mount (fn [] (.addEventListener js/document "click" toggle-fn)) - :component-will-unmount (fn [] (.removeEventListener js/document "click" toggle-fn)) - :reagent-render - (fn [children] - children)}))) - -(defn navbar-drop-down [{:keys [ header id class]} child] - (r/create-class - {:reagent-render (fn [{:keys [header id]} child] - (let [menu-active? @(re-frame/subscribe [::subs/menu-active? id])] - [:div { :class (str "navbar-item has-dropdown " (when menu-active? "is-active " ) " " class)} - [:a {:class "navbar-link login" :on-click (fn [e] - (.preventDefault e) - (.stopPropagation e) - (re-frame/dispatch [::events/toggle-menu id]) - true)} header] - [appearing {:visible? menu-active? :enter-class "appear" :exit-class "disappear" :timeout 200} - [:div {:class "navbar-dropdown"} - [navbar-drop-down-contents {:id id} - [:div child]]]]]))})) +(defn navbar-drop-down [{:keys [ class]} _] + (let [!child (r/atom nil)] + (r/create-class + {:reagent-render (fn [{:keys [header id]} child] + (let [menu-active? @(re-frame/subscribe [::subs/menu-active? id])] + [:div { :class (str "navbar-item has-dropdown " (when menu-active? "is-active " ) " " class) + :ref (fn [n] + (reset! !child n)) + :tab-index 0 + :onBlur (fn [e] + (js/setTimeout (fn [] + (println @!child) + (println (.-activeElement js/document)) + (when-not (.contains @!child (.-activeElement js/document)) + (re-frame/dispatch [::events/toggle-menu id]))) + 2)) + } + [:a {:class "navbar-link login" :on-click (fn [e] + (.preventDefault e) + (.stopPropagation e) + (re-frame/dispatch [::events/toggle-menu id]) + true)} header] + [appearing {:visible? menu-active? :enter-class "appear" :exit-class "disappear" :timeout 200} + [:div {:class "navbar-dropdown"} + [:div child]]]]))}))) (defn login-dropdown [] (let [user (re-frame/subscribe [::subs/user])] (if @user [navbar-drop-down {:header [:span [:span.icon [:i.fa.fa-user] ] - [:span (:user/name @user)]] :id ::account} + [:span (:user/name @user)]] + :id ::account} [:div [:a {:class "navbar-item" :href (bidi/path-for routes/routes :reports)} "My company"] @@ -60,8 +69,8 @@ (re-frame/reg-sub ::matching-clients :<- [::subs/clients] - :<- [::client-search] - (fn [[clients {client-search :value}]] + :<- [::forms/form ::client-search] + (fn [[clients {{client-search :value} :data}]] (if (empty? client-search) clients (if-let [exact-match (first (filter @@ -76,21 +85,46 @@ (str/includes? (str/lower-case (:name client)) (str/lower-case client-search)))) clients))))) -(re-frame/reg-event-db - ::client-search-changed - [(re-frame/path [::client-search])] - (fn [client-search [_ path value]] - (assoc-in client-search path value))) + +(re-frame/reg-event-fx + ::client-searched + [(re-frame/inject-cofx ::inject/sub [::matching-clients])] + (fn [{::keys [matching-clients]}] + {:dispatch-n [[::events/swap-client (first matching-clients)] + [::events/toggle-menu ::select-client]]})) + +(defn client-dropdown [] + (let [client (re-frame/subscribe [::subs/client]) + matching-clients @(re-frame/subscribe [::matching-clients])] + + [navbar-drop-down {:header (str "Company: " (if @client (:name @client) + "All")) + :id ::select-client} + [:div + [:a {:class "navbar-item" + :on-click (fn [] + (re-frame/dispatch [::events/toggle-menu ::select-client]) + (re-frame/dispatch [::forms/form-closing ::client-search]) + (re-frame/dispatch [::events/swap-client nil]))} "All" ] + [:hr {:class "navbar-divider"}] + [form-builder/builder {:id ::client-search + :submit-event [::client-searched]} + [form-builder/raw-field-v2 {:field :value} + [:input.input.navbar-item {:placeholder "Company name" + :auto-focus true}]]] + (for [{:keys [name id] :as client} (take 8 matching-clients)] + ^{:key id } + [:a {:class "navbar-item" + :on-click (fn [] + (re-frame/dispatch [::events/toggle-menu ::select-client]) + (re-frame/dispatch [::events/swap-client client])) + } name])]])) (defn navbar [ap] (let [navbar-menu-shown? (r/atom false)] (fn [ap] - (let [user (re-frame/subscribe [::subs/user]) - client (re-frame/subscribe [::subs/client]) - clients (re-frame/subscribe [::subs/clients]) - matching-clients @(re-frame/subscribe [::matching-clients]) - menu (re-frame/subscribe [::subs/menu]) - client-search @(re-frame/subscribe [::client-search]) + (let [user (re-frame/subscribe [::subs/user]) + clients (re-frame/subscribe [::subs/clients]) is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])] [:nav {:class "navbar has-shadow is-fixed-top is-grey"} @@ -133,33 +167,8 @@ [:div.navbar-end (when (> (count @clients) 1) - [navbar-drop-down {:header (str "Company: " (if @client (:name @client) - "All")) - :id ::select-client} - [:div - [:a {:class "navbar-item" - :on-click (fn [] - (re-frame/dispatch [::events/swap-client nil]))} "All" ] - [:hr {:class "navbar-divider"}] - [bind-field - [:input.input.navbar-item {:placeholder "Company name" - :auto-focus true - :field [:value] - :on-key-up (fn [k] - (when (= 13 (.-which k)) - (do - (re-frame/dispatch [::events/swap-client (first matching-clients)]) - (re-frame/dispatch [::events/toggle-menu ::select-client]) - (re-frame/dispatch [::client-search-changed [:value] nil]))) - ) - :event [::client-search-changed] - :subscription client-search}]] - (for [{:keys [name id] :as client} matching-clients] - ^{:key id } - [:a {:class "navbar-item" - :on-click (fn [] - (re-frame/dispatch [::events/swap-client client])) - } name])]])])] + [client-dropdown] + )])] (when-not is-initial-loading [login-dropdown])] @@ -167,11 +176,7 @@ ])))) -(defn footer [] - [:footer {:style {:padding "1em"}} - [:div {:class "content has-text-centered"} - [:p - [:strong "Integreat"] ]]]) + (defn appearing-side-bar [{:keys [visible?]} ] [appearing {:visible? visible? :enter-class "slide-in-right" :exit-class "slide-out-right" :timeout 500} @@ -179,7 +184,7 @@ (into [:div.sub-main {} ] (r/children (r/current-component)))]]) -(defn side-bar-layout [{:keys [side-bar main ap bottom right-side-bar]}] +(defn side-bar-layout [{:keys [side-bar main bottom right-side-bar]}] (let [ap @(re-frame/subscribe [::subs/active-page]) client @(re-frame/subscribe [::subs/client])] [:div @@ -200,7 +205,6 @@ (when right-side-bar right-side-bar) ] - #_[footer] [:div bottom] [:div#dz-hidden]])) diff --git a/src/cljs/auto_ap/views/components/multi.cljs b/src/cljs/auto_ap/views/components/multi.cljs index 1c57ff05..6d45ba95 100644 --- a/src/cljs/auto_ap/views/components/multi.cljs +++ b/src/cljs/auto_ap/views/components/multi.cljs @@ -12,7 +12,7 @@ ;; 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 + (vec prop-value) [])] [form-builder/virtual-builder {:value prop-value :schema schema @@ -21,21 +21,18 @@ [:div {:style {:margin-bottom "0.25em"}} (into [(if key-fn appearing-group - [:<>])] + :<>)] (for [[i override] (map vector (range) prop-value) :let [extant? (if key-fn (boolean (key-fn override)) true) is-disabled? (boolean (and (= false allow-change?) - extant?))]] - - ^{:key (or (when key-fn (key-fn override)) - (::key override) - i)} + extant?)) + key (or (when key-fn (key-fn override)) + (::key override) + i)]] + ^{:key key} [form-builder/with-scope {:scope [i]} - ^{: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? @@ -44,9 +41,9 @@ (template override) template)] [:fieldset.level-left {:disabled is-disabled? - :style {:padding "0.5em 1em"} - :class (when-not extant? - "has-background-info-light")} + :style {:padding "0.5em 1em"} + :class (when-not extant? + "has-background-info-light")} (for [[idx template] (map vector (range ) template)] ^{:key idx} [:div.level-item @@ -67,6 +64,7 @@ [:button.button.is-outline {:type "button" :on-click (fn [e] + (println "ADDING" prop-value) (on-change (conj prop-value {::key (random-uuid)})) (.stopPropagation e) (.preventDefault e))} diff --git a/src/cljs/auto_ap/views/pages/admin/reminders.cljs b/src/cljs/auto_ap/views/pages/admin/reminders.cljs deleted file mode 100644 index abbfd966..00000000 --- a/src/cljs/auto_ap/views/pages/admin/reminders.cljs +++ /dev/null @@ -1,193 +0,0 @@ -(ns auto-ap.views.pages.admin.reminders - (:require-macros [cljs.core.async.macros :refer [go]]) - (:require [re-frame.core :as re-frame] - [auto-ap.views.components.paginator :refer [paginator]] - [auto-ap.views.components.sorter :refer [sorted-column]] - [auto-ap.entities.vendors :as entity] - [reagent.core :as reagent] - [auto-ap.subs :as subs] - [auto-ap.views.utils :refer [login-url dispatch-value-change dispatch-event date-time->str date->str horizontal-field bind-field]] - [cljs.reader :as edn] - - [auto-ap.routes :as routes] - [bidi.bidi :as bidi])) -(re-frame/reg-sub - ::editing-reminder - (fn [db] - (::editing-reminder db))) - -(re-frame/reg-sub - ::reminder-page - (fn [db] - (::reminder-page db))) - -(re-frame/reg-sub - ::reminder-params - (fn [db] - (::reminder-params db))) - -(re-frame/reg-event-db - ::edit - (fn [db [_ which]] - (assoc db ::editing-reminder which))) - -(re-frame/reg-event-db - ::change - (fn [db [_ field v]] - (assoc-in db (into [::editing-reminder] field) v))) - -(re-frame/reg-event-fx - ::mounted - (fn [{:keys [db]} _] - {:db (assoc db ::reminder-params {:start 0}) - :dispatch [::invalidated]})) - -(re-frame/reg-event-fx - ::params-changed - (fn [{:keys [db]} [_ params]] - {:db (update db ::reminder-params merge params) - :dispatch [::invalidated]})) - -(re-frame/reg-event-fx - ::save - (fn [{:keys [db]}] - (let [edited-reminder (::editing-reminder db)] - (println edited-reminder) - {:http {:token (:user db) - :method :put - :body (pr-str (dissoc edited-reminder :sent :scheduled)) - :headers {"Content-Type" "application/edn"} - :uri (str "/api/reminders/" (:id edited-reminder)) - :on-success [::save-complete] - :on-error [::save-error]}}))) - -(re-frame/reg-event-fx - ::save-complete - (fn [{:keys [db]}] - {:dispatch [::edit nil]})) - -(re-frame/reg-event-fx - ::save-error - (fn [{:keys [db]}] - {:dispatch [::change [:error] true]})) - -(re-frame/reg-event-fx - ::invalidated - (fn [{:keys [db]}] - {:graphql {:token (:user db) - :query-obj {:venia/queries [[:reminder_page - (::reminder-params db) - - [[:reminders [:id :email :sent :scheduled :subject :body [:vendor [:name :id]] ]] - :total - :start - :end]]]} - - :on-success [::received]}})) - - -(re-frame/reg-event-db - ::received - (fn [db [_ reminders]] - (assoc db ::reminder-page (first (:reminder-page reminders))))) - -(defn edit-dialog [] - (let [editing-reminder @(re-frame/subscribe [::editing-reminder])] - [:div.modal.is-active - [:div.modal-background {:on-click (fn [] (re-frame/dispatch [::edit nil]))}] - - [:div.modal-card - [:header.modal-card-head - [:p.modal-card-title - (str "Reminder for " (:name (:vendor editing-reminder)))] - (when (:error editing-reminder) - [:span.icon.has-text-danger - [:i.fa.fa-exclamation-triangle]]) - [:button.delete {:on-click (fn [] (re-frame/dispatch [::edit nil]))}]] - [:section.modal-card-body - [horizontal-field - [:label.label "Email"] - [:div.control - [bind-field - [:input.input {:type "text" - :field :email - :event ::change - :subscription editing-reminder}]]]] - [horizontal-field - [:label.label "Subject"] - [:div.control - [bind-field - [:input.input {:type "text" - :field :subject - :event ::change - :subscription editing-reminder}]]]] - - [horizontal-field - [:label.label "Body"] - [:div.control - - [bind-field - [:textarea.textarea.is-expanded {:type "text" - :field :body - :event ::change - :subscription editing-reminder}]]]] - - (when (:saving? editing-reminder) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])] - - [:footer.modal-card-foot - [:button.button.is-primary {:on-click (fn [] (re-frame/dispatch [::save])) - #_#_:disabled (when (not (s/valid? ::entity/vendor editing-reminder )) - "disabled")} - [:span "Save"] - (when (:saving? editing-reminder) - [:span.icon - [:i.fa.fa-spin.fa-spinner]])]]]])) - -(defn reminders-table [] - (let [{:keys [reminders start end total count]} @(re-frame/subscribe [::reminder-page]) - {:keys [sort-by asc]} @(re-frame/subscribe [::reminder-params]) - reminders (or reminders [])] - [:div - [:div.is-pulled-right - [paginator {:start start - :end end - :total total - :count count - :on-change (fn [params] - (re-frame/dispatch [::params-changed params]))}]] - [:table {:class "table", :style {:width "100%"}} - [:thead - [:tr - (for [[sort-key name] [["vendor" "Vendor"] - ["scheduled" "Scheduled Date"] - ["sent" "Status"] - ["email" "Email"]]] - ^{:key name} - [sorted-column {:on-sort (fn [params] (re-frame/dispatch [::params-changed params])) - :style {:width "20%" :cursor "pointer"} - :sort-key sort-key - :sort-by sort-by - :asc asc} - name])]] - [:tbody (for [{:keys [id vendor scheduled sent email ] :as r} reminders] - ^{:key id} - [:tr (when-not sent - {:on-click (fn [] (re-frame/dispatch [::edit r])) :style {:cursor "pointer"}}) - [:td (:name vendor)] - [:td (date->str scheduled)] - [:td (when sent - [:span [:span.icon [:i.fa.fa-check]] "Sent " (date-time->str sent)]) ] - [:td email]])]] - - (when @(re-frame/subscribe [::editing-reminder]) - [edit-dialog])])) - - -(defn admin-reminders-page [] - [(with-meta - (fn [] - [:div - [:h1.title "Reminders"] - [reminders-table]]) - {:component-did-mount (fn [] - (re-frame/dispatch [::mounted]))})]) 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 99c6cb79..31fa9fd6 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 @@ -24,18 +24,17 @@ [:map [:amount schema/money]]]]] [:fn (fn [{:keys [invoices invoice-amounts] :as z}] - (println "HERE" z) - (when (seq (filter + (if (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}))))]])) + (throw (ex-info "Invalid" {:type ::too-much-invoice})) + true))]])) (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] :id ::form :schema advanced-print-schema} @@ -87,6 +86,7 @@ ::try-save [(forms/in-form ::form)] (fn [{:keys [db]}] + #_(println (m/explain advanced-print-schema (:data db))) (if (not (m/validate advanced-print-schema (:data db))) {:dispatch-n [[::status/error ::form [{:message "Please correct any errors and try again"}]] [::forms/attempted-submit ::form]]} 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 1c9b627f..dc529d84 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 @@ -375,8 +375,7 @@ NOTE: Please review the transactions we may have question for you here: https:// :title "Full year"}]] [:div [form-builder/raw-field-v2 {:field :show-advanced?} - [com/checkbox {:label "Show Advanced"}] - ]] + [com/checkbox {:label "Show Advanced"}]]] (when (:show-advanced? data) [form-builder/raw-field-v2 {:field :periods} [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :start} @@ -479,7 +478,8 @@ NOTE: Please review the transactions we may have question for you here: https:// :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}) + :include-deltas false + :show-advanced? false}) ::track/register {:id ::ledger-params :subscription [::data-page/params ::ledger] :event-fn (fn [params] [::ledger-params-change params])}}))) diff --git a/src/cljs/auto_ap/views/pages/ledger/report_table.cljs b/src/cljs/auto_ap/views/pages/ledger/report_table.cljs index f33bbacd..c5c3e629 100644 --- a/src/cljs/auto_ap/views/pages/ledger/report_table.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/report_table.cljs @@ -30,7 +30,7 @@ [(keyword (str "border-" (name b))) "1px solid black"]) ) (into s)))) - (:colspan c) (assoc :colspan (:colspan c)) + (:colspan c) (assoc :col-span (:colspan c)) (:align c) (assoc :align (:align c)) (= :dollar (:format c)) (assoc :align :right) (= :percent (:format c)) (assoc :align :right)