From edeb1b1f2ee25bbaaef12b58d3d750b89073f9a2 Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Fri, 29 Oct 2021 14:47:27 -0700 Subject: [PATCH] added ability to reload the bank balances automatically. --- resources/public/css/main.css | 3 + src/cljs/auto_ap/effects.cljs | 16 ++ src/cljs/auto_ap/events.cljs | 41 +++-- .../views/components/invoice_table.cljs | 4 +- .../auto_ap/views/components/layouts.cljs | 165 +++++++++--------- 5 files changed, 135 insertions(+), 94 deletions(-) diff --git a/resources/public/css/main.css b/resources/public/css/main.css index e797a2c9..a0bf81f8 100644 --- a/resources/public/css/main.css +++ b/resources/public/css/main.css @@ -163,6 +163,9 @@ nav.navbar .navbar-item.is-active { display:block; background-color: #F9F9F9; border-right: 1px solid #DEDEDE; + @include until(1280px) { + + } } .aside .subtitle { diff --git a/src/cljs/auto_ap/effects.cljs b/src/cljs/auto_ap/effects.cljs index 42ae337d..09d3a2cf 100644 --- a/src/cljs/auto_ap/effects.cljs +++ b/src/cljs/auto_ap/effects.cljs @@ -259,3 +259,19 @@ (dates->date-times) (on-success) (re-frame/dispatch)))))))) + +(defonce interval-handler + (let [live-intervals (atom {})] + (fn handler [{:keys [action id frequency event]}] + (condp = action + :clean (doall + (map #(handler {:action :end :id %1}) (keys @live-intervals))) + :start (swap! live-intervals assoc id (js/setInterval #(re-frame/dispatch event) frequency)) + :end (do (js/clearInterval (get @live-intervals id)) + (swap! live-intervals dissoc id)))))) +(interval-handler {:action :clean}) +(re-frame.core/reg-fx ;; the re-frame API for registering effect handlers + :interval ;; the effect id + interval-handler) + + diff --git a/src/cljs/auto_ap/events.cljs b/src/cljs/auto_ap/events.cljs index 0524f4e1..9ac9cda5 100644 --- a/src/cljs/auto_ap/events.cljs +++ b/src/cljs/auto_ap/events.cljs @@ -104,20 +104,37 @@ :user (assoc user :token token) :is-initial-loading? true)})) -(re-frame/reg-event-db +(re-frame/reg-event-fx ::received-initial - (fn [db [_ {accounts :accounts clients :client vendors :vendor :as x}]] + (fn [{:keys [db]} [_ {accounts :accounts clients :client vendors :vendor :as x}]] - (-> db - (assoc :clients (by :id clients) ) - (assoc :vendors (by :id vendors) ) - (assoc :is-initial-loading? false) - (assoc :accounts accounts ) - (assoc :client (or (when (= 1 (count clients)) (->> clients first :id )) - (->> clients - (map :id) - (filter #(= % (:last-client-id db))) - first)))))) + {:db (-> db + (assoc :clients (by :id clients) ) + (assoc :vendors (by :id vendors) ) + (assoc :is-initial-loading? false) + (assoc :accounts accounts ) + (assoc :client (or (when (= 1 (count clients)) (->> clients first :id )) + (->> clients + (map :id) + (filter #(= % (:last-client-id db))) + first)))) + :interval {:action :start + :id :refresh-clients + :frequency 600000 + :event [::refresh-clients]}})) + +(re-frame/reg-event-fx + ::refresh-clients + (fn [{:keys [db]}] + (let [token (-> db :user)] + {:graphql {:token token + :query-obj {:venia/queries [[:client (client-query token)]]} + :on-success [::received-refreshed-clients]}}))) + +(re-frame/reg-event-fx + ::received-refreshed-clients + (fn [{:keys [db]} [_ {clients :client}]] + {:db (assoc db :clients (by :id clients))})) (re-frame/reg-event-db ::failed-initial diff --git a/src/cljs/auto_ap/views/components/invoice_table.cljs b/src/cljs/auto_ap/views/components/invoice_table.cljs index c979fec4..55f92962 100644 --- a/src/cljs/auto_ap/views/components/invoice_table.cljs +++ b/src/cljs/auto_ap/views/components/invoice_table.cljs @@ -125,7 +125,7 @@ (:name client))]) [grid/cell {} (:name vendor)] [grid/cell {} invoice-number] - [grid/cell {} (date->str date) ] + [grid/cell {:class "is-hidden-mobile"} (date->str date) ] [grid/cell {} (when due (if (#{":paid" :paid ":voided" :voided} status) @@ -257,7 +257,7 @@ [grid/sortable-header-cell {:sort-key "invoice-number" :sort-name "Invoice Number"} "Invoice #"] [grid/sortable-header-cell {:sort-key "date" :sort-name "Date" :style {:width "8em"}} "Date"] - [grid/sortable-header-cell {:sort-key "due" :sort-name "Due" :style {:width "8em"}} "Due"] + [grid/sortable-header-cell {:sort-key "due" :sort-name "Due" :style {:width "8em"} :class "is-hidden-mobile"} "Due"] [grid/sortable-header-cell {:sort-key "location" :sort-name "Location" :style {:width "5em"}} "Loc"] [grid/sortable-header-cell {:sort-key "total" :sort-name "Total" :style {:width "8em"} :class "has-text-right"} "Total"] diff --git a/src/cljs/auto_ap/views/components/layouts.cljs b/src/cljs/auto_ap/views/components/layouts.cljs index ae89f6f5..b03fd1f3 100644 --- a/src/cljs/auto_ap/views/components/layouts.cljs +++ b/src/cljs/auto_ap/views/components/layouts.cljs @@ -84,88 +84,93 @@ (assoc-in client-search path value))) (defn navbar [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]) - is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])] - [:nav {:class "navbar has-shadow is-fixed-top is-grey"} - - [:div {:class "container"} - [:div {:class "navbar-brand"} - [:a {:class "navbar-item", :href "../"} - [:img {:src "/img/logo.png"}]]] - [:div.navbar-menu - (when-not is-initial-loading - [:div.navbar-start - [:a.navbar-item {:class [(active-when ap = :index)] - :href (bidi/path-for routes/routes :index)} - "Home" ] - [:a.navbar-item {:class [(active-when ap #{:unpaid-invoices :paid-invoices})] - :href (bidi/path-for routes/routes :unpaid-invoices)} - "Invoices" ] - [:a.navbar-item {:class [(active-when ap = :payments)] - :href (bidi/path-for routes/routes :payments)} - "Payments" ] - (when (= "admin" (:user/role @user)) - [:a.navbar-item {:class [(active-when ap = :sales-orders)] - :href (bidi/path-for routes/routes :sales-orders)} - "POS" ]) - [:a.navbar-item {:class [(active-when ap = :transactions)] - :href (bidi/path-for routes/routes :transactions)} - "Transactions" ] - - (when (not= "manager" (:user/role @user)) - [:a.navbar-item {:class [(active-when ap = :ledger)] - :href (bidi/path-for routes/routes :ledger)} - "Ledger" ])]) - [:div {:class "navbar-burger burger", :data-target "navMenu"} - [:span] - [:span] - [:span]] - (when-not is-initial-loading - [:div.navbar-end - [:div.navbar-item - [buttons/new-button {:event [::vendor-dialog/started {}] - :name "Vendor" - :class "is-primary"}]] + (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]) + is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])] + [:nav {:class "navbar has-shadow is-fixed-top is-grey"} + + [:div {:class "container"} + [:div {:class "navbar-brand"} + [:a {:class "navbar-item", :href "../"} + [:img {:src "/img/logo.png"}]] + [:div {:class "navbar-burger burger", :data-target "navMenu" :on-click (fn [] (swap! navbar-menu-shown? #(not %)))} + [:span] + [:span] + [:span]]] + [:div.navbar-menu {:id "navMenu" :class (if @navbar-menu-shown? + "is-active" + "")} + (when-not is-initial-loading + [:div.navbar-start + [:a.navbar-item {:class [(active-when ap = :index)] + :href (bidi/path-for routes/routes :index)} + "Home" ] + [:a.navbar-item {:class [(active-when ap #{:unpaid-invoices :paid-invoices})] + :href (bidi/path-for routes/routes :unpaid-invoices)} + "Invoices" ] + [:a.navbar-item {:class [(active-when ap = :payments)] + :href (bidi/path-for routes/routes :payments)} + "Payments" ] + (when (= "admin" (:user/role @user)) + [:a.navbar-item {:class [(active-when ap = :sales-orders)] + :href (bidi/path-for routes/routes :sales-orders)} + "POS" ]) + [:a.navbar-item {:class [(active-when ap = :transactions)] + :href (bidi/path-for routes/routes :transactions)} + "Transactions" ] + + (when (not= "manager" (:user/role @user)) + [:a.navbar-item {:class [(active-when ap = :ledger)] + :href (bidi/path-for routes/routes :ledger)} + "Ledger" ])]) + (when-not is-initial-loading + [:div.navbar-end + [:div.navbar-item + [buttons/new-button {:event [::vendor-dialog/started {}] + :name "Vendor" + :class "is-primary"}]] + - (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])]])])] - (when-not is-initial-loading - [login-dropdown])] - - - ])) + (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])]])])] + (when-not is-initial-loading + [login-dropdown])] + + + ])))) (defn footer []