added ability to reload the bank balances automatically.
This commit is contained in:
@@ -163,6 +163,9 @@ nav.navbar .navbar-item.is-active {
|
|||||||
display:block;
|
display:block;
|
||||||
background-color: #F9F9F9;
|
background-color: #F9F9F9;
|
||||||
border-right: 1px solid #DEDEDE;
|
border-right: 1px solid #DEDEDE;
|
||||||
|
@include until(1280px) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.aside .subtitle {
|
.aside .subtitle {
|
||||||
|
|||||||
@@ -259,3 +259,19 @@
|
|||||||
(dates->date-times)
|
(dates->date-times)
|
||||||
(on-success)
|
(on-success)
|
||||||
(re-frame/dispatch))))))))
|
(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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -104,20 +104,37 @@
|
|||||||
:user (assoc user :token token)
|
:user (assoc user :token token)
|
||||||
:is-initial-loading? true)}))
|
:is-initial-loading? true)}))
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-fx
|
||||||
::received-initial
|
::received-initial
|
||||||
(fn [db [_ {accounts :accounts clients :client vendors :vendor :as x}]]
|
(fn [{:keys [db]} [_ {accounts :accounts clients :client vendors :vendor :as x}]]
|
||||||
|
|
||||||
(-> db
|
{:db (-> db
|
||||||
(assoc :clients (by :id clients) )
|
(assoc :clients (by :id clients) )
|
||||||
(assoc :vendors (by :id vendors) )
|
(assoc :vendors (by :id vendors) )
|
||||||
(assoc :is-initial-loading? false)
|
(assoc :is-initial-loading? false)
|
||||||
(assoc :accounts accounts )
|
(assoc :accounts accounts )
|
||||||
(assoc :client (or (when (= 1 (count clients)) (->> clients first :id ))
|
(assoc :client (or (when (= 1 (count clients)) (->> clients first :id ))
|
||||||
(->> clients
|
(->> clients
|
||||||
(map :id)
|
(map :id)
|
||||||
(filter #(= % (:last-client-id db)))
|
(filter #(= % (:last-client-id db)))
|
||||||
first))))))
|
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
|
(re-frame/reg-event-db
|
||||||
::failed-initial
|
::failed-initial
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
(:name client))])
|
(:name client))])
|
||||||
[grid/cell {} (:name vendor)]
|
[grid/cell {} (:name vendor)]
|
||||||
[grid/cell {} invoice-number]
|
[grid/cell {} invoice-number]
|
||||||
[grid/cell {} (date->str date) ]
|
[grid/cell {:class "is-hidden-mobile"} (date->str date) ]
|
||||||
[grid/cell {}
|
[grid/cell {}
|
||||||
(when due
|
(when due
|
||||||
(if (#{":paid" :paid ":voided" :voided} status)
|
(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 "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 "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 "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"]
|
[grid/sortable-header-cell {:sort-key "total" :sort-name "Total" :style {:width "8em"} :class "has-text-right"} "Total"]
|
||||||
|
|
||||||
|
|||||||
@@ -84,88 +84,93 @@
|
|||||||
(assoc-in client-search path value)))
|
(assoc-in client-search path value)))
|
||||||
|
|
||||||
(defn navbar [ap]
|
(defn navbar [ap]
|
||||||
(let [user (re-frame/subscribe [::subs/user])
|
(let [navbar-menu-shown? (r/atom false)]
|
||||||
client (re-frame/subscribe [::subs/client])
|
(fn [ap]
|
||||||
clients (re-frame/subscribe [::subs/clients])
|
(let [user (re-frame/subscribe [::subs/user])
|
||||||
matching-clients @(re-frame/subscribe [::matching-clients])
|
client (re-frame/subscribe [::subs/client])
|
||||||
menu (re-frame/subscribe [::subs/menu])
|
clients (re-frame/subscribe [::subs/clients])
|
||||||
client-search @(re-frame/subscribe [::client-search])
|
matching-clients @(re-frame/subscribe [::matching-clients])
|
||||||
is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])]
|
menu (re-frame/subscribe [::subs/menu])
|
||||||
[:nav {:class "navbar has-shadow is-fixed-top is-grey"}
|
client-search @(re-frame/subscribe [::client-search])
|
||||||
|
is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])]
|
||||||
[:div {:class "container"}
|
[:nav {:class "navbar has-shadow is-fixed-top is-grey"}
|
||||||
[:div {:class "navbar-brand"}
|
|
||||||
[:a {:class "navbar-item", :href "../"}
|
[:div {:class "container"}
|
||||||
[:img {:src "/img/logo.png"}]]]
|
[:div {:class "navbar-brand"}
|
||||||
[:div.navbar-menu
|
[:a {:class "navbar-item", :href "../"}
|
||||||
(when-not is-initial-loading
|
[:img {:src "/img/logo.png"}]]
|
||||||
[:div.navbar-start
|
[:div {:class "navbar-burger burger", :data-target "navMenu" :on-click (fn [] (swap! navbar-menu-shown? #(not %)))}
|
||||||
[:a.navbar-item {:class [(active-when ap = :index)]
|
[:span]
|
||||||
:href (bidi/path-for routes/routes :index)}
|
[:span]
|
||||||
"Home" ]
|
[:span]]]
|
||||||
[:a.navbar-item {:class [(active-when ap #{:unpaid-invoices :paid-invoices})]
|
[:div.navbar-menu {:id "navMenu" :class (if @navbar-menu-shown?
|
||||||
:href (bidi/path-for routes/routes :unpaid-invoices)}
|
"is-active"
|
||||||
"Invoices" ]
|
"")}
|
||||||
[:a.navbar-item {:class [(active-when ap = :payments)]
|
(when-not is-initial-loading
|
||||||
:href (bidi/path-for routes/routes :payments)}
|
[:div.navbar-start
|
||||||
"Payments" ]
|
[:a.navbar-item {:class [(active-when ap = :index)]
|
||||||
(when (= "admin" (:user/role @user))
|
:href (bidi/path-for routes/routes :index)}
|
||||||
[:a.navbar-item {:class [(active-when ap = :sales-orders)]
|
"Home" ]
|
||||||
:href (bidi/path-for routes/routes :sales-orders)}
|
[:a.navbar-item {:class [(active-when ap #{:unpaid-invoices :paid-invoices})]
|
||||||
"POS" ])
|
:href (bidi/path-for routes/routes :unpaid-invoices)}
|
||||||
[:a.navbar-item {:class [(active-when ap = :transactions)]
|
"Invoices" ]
|
||||||
:href (bidi/path-for routes/routes :transactions)}
|
[:a.navbar-item {:class [(active-when ap = :payments)]
|
||||||
"Transactions" ]
|
:href (bidi/path-for routes/routes :payments)}
|
||||||
|
"Payments" ]
|
||||||
(when (not= "manager" (:user/role @user))
|
(when (= "admin" (:user/role @user))
|
||||||
[:a.navbar-item {:class [(active-when ap = :ledger)]
|
[:a.navbar-item {:class [(active-when ap = :sales-orders)]
|
||||||
:href (bidi/path-for routes/routes :ledger)}
|
:href (bidi/path-for routes/routes :sales-orders)}
|
||||||
"Ledger" ])])
|
"POS" ])
|
||||||
[:div {:class "navbar-burger burger", :data-target "navMenu"}
|
[:a.navbar-item {:class [(active-when ap = :transactions)]
|
||||||
[:span]
|
:href (bidi/path-for routes/routes :transactions)}
|
||||||
[:span]
|
"Transactions" ]
|
||||||
[:span]]
|
|
||||||
(when-not is-initial-loading
|
(when (not= "manager" (:user/role @user))
|
||||||
[:div.navbar-end
|
[:a.navbar-item {:class [(active-when ap = :ledger)]
|
||||||
[:div.navbar-item
|
:href (bidi/path-for routes/routes :ledger)}
|
||||||
[buttons/new-button {:event [::vendor-dialog/started {}]
|
"Ledger" ])])
|
||||||
:name "Vendor"
|
|
||||||
:class "is-primary"}]]
|
|
||||||
|
|
||||||
|
(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)
|
(when (> (count @clients) 1)
|
||||||
[navbar-drop-down {:header (str "Company: " (if @client (:name @client)
|
[navbar-drop-down {:header (str "Company: " (if @client (:name @client)
|
||||||
"All"))
|
"All"))
|
||||||
:id ::select-client}
|
:id ::select-client}
|
||||||
[:div
|
[:div
|
||||||
[:a {:class "navbar-item"
|
[:a {:class "navbar-item"
|
||||||
:on-click (fn []
|
:on-click (fn []
|
||||||
(re-frame/dispatch [::events/swap-client nil]))} "All" ]
|
(re-frame/dispatch [::events/swap-client nil]))} "All" ]
|
||||||
[:hr {:class "navbar-divider"}]
|
[:hr {:class "navbar-divider"}]
|
||||||
[bind-field
|
[bind-field
|
||||||
[:input.input.navbar-item {:placeholder "Company name"
|
[:input.input.navbar-item {:placeholder "Company name"
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
:field [:value]
|
:field [:value]
|
||||||
:on-key-up (fn [k]
|
:on-key-up (fn [k]
|
||||||
(when (= 13 (.-which k))
|
(when (= 13 (.-which k))
|
||||||
(do
|
(do
|
||||||
(re-frame/dispatch [::events/swap-client (first matching-clients)])
|
(re-frame/dispatch [::events/swap-client (first matching-clients)])
|
||||||
(re-frame/dispatch [::events/toggle-menu ::select-client])
|
(re-frame/dispatch [::events/toggle-menu ::select-client])
|
||||||
(re-frame/dispatch [::client-search-changed [:value] nil])))
|
(re-frame/dispatch [::client-search-changed [:value] nil])))
|
||||||
)
|
)
|
||||||
:event [::client-search-changed]
|
:event [::client-search-changed]
|
||||||
:subscription client-search}]]
|
:subscription client-search}]]
|
||||||
(for [{:keys [name id] :as client} matching-clients]
|
(for [{:keys [name id] :as client} matching-clients]
|
||||||
^{:key id }
|
^{:key id }
|
||||||
[:a {:class "navbar-item"
|
[:a {:class "navbar-item"
|
||||||
:on-click (fn []
|
:on-click (fn []
|
||||||
(re-frame/dispatch [::events/swap-client client]))
|
(re-frame/dispatch [::events/swap-client client]))
|
||||||
} name])]])])]
|
} name])]])])]
|
||||||
(when-not is-initial-loading
|
(when-not is-initial-loading
|
||||||
[login-dropdown])]
|
[login-dropdown])]
|
||||||
|
|
||||||
|
|
||||||
]))
|
]))))
|
||||||
|
|
||||||
|
|
||||||
(defn footer []
|
(defn footer []
|
||||||
|
|||||||
Reference in New Issue
Block a user