pagination and sorting for reminders.

This commit is contained in:
Bryce Covert
2018-04-13 22:03:02 -07:00
parent 5e14ecd005
commit b6b7b1932a
8 changed files with 204 additions and 121 deletions

View File

@@ -35,15 +35,10 @@
(and (string? node)
(re-matches is-8601 node))
(do
(println node)
(format/parse (format/formatters :date-time) node))
(format/parse (format/formatters :date-time) node)
(instance? js/Date node)
(do
(println node)
(time/to-default-time-zone (c/from-date node)))
(time/to-default-time-zone (c/from-date node))
:else
node))

View File

@@ -4,22 +4,4 @@
[auto-ap.routes :as routes]
[auto-ap.effects :as effects]))
(re-frame/reg-event-fx
::mounted
(fn [{:keys [db]} _]
{:graphql {:token (:user db)
:query-obj {:venia/queries [[:reminder_page
[[: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 :reminders (:reminders (first (:reminder-page reminders))))))

View File

@@ -24,11 +24,6 @@
(fn [db]
(:user db)))
(re-frame/reg-sub
::reminders
(fn [db]
(:reminders db)))
(re-frame/reg-sub
::vendors
(fn [db]

View File

@@ -2,29 +2,15 @@
(:require [re-frame.core :as re-frame]
[auto-ap.subs :as subs]
[auto-ap.views.utils :refer [date->str]]
[auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sorter :refer [sorted-column]]
[reagent.core :as reagent]
[clojure.string :as str]
[cljs-time.format :as format]))
(defn toggle-sort-by [params key]
(-> params
(assoc :sort-by key)
(update :asc not)))
(defn sort-icon [which sort-by asc]
(cond
(and (= sort-by which) asc)
[:span.icon
[:i.fa.fa-sort-up]]
(and (= sort-by which) (not asc))
[:span.icon
[:i.fa.fa-sort-down]]
:else
[:span.icon
[:i.fa.fa-sort]]))
(defn query [params]
{:venia/queries [[:invoice_page
@@ -35,72 +21,55 @@
:start
:end]]]})
(defn bound [x y z]
(cond
(< z x)
x
(< y x)
x
(> y z)
z
:else
y))
(defn buttons-for [start end count total on-params-change state]
(let [per-page 20
max-buttons 5
buttons-before (Math/floor (/ max-buttons 2))
total-pages (Math/ceil (/ total per-page))
current-page (Math/floor (/ start per-page))
first-page-button (bound 0 (- current-page buttons-before) (- total-pages max-buttons))
all-buttons (into [] (for [x (range total-pages)]
^{:key x} [:button.button {:class (str/join " " [(when (= current-page x)
"is-active")])
:on-click (fn [e] (on-params-change (swap! state assoc :start (* x per-page))))} (inc x)]))
last-page-button (Math/min total-pages (+ max-buttons first-page-button))
extended-last-page-button (when (not= last-page-button total-pages)
[:span "..." [:button.button {:on-click (fn [e] (on-params-change (swap! state assoc :start (* (dec total-pages) per-page))))} total-pages]])
extended-first-page-button (when (not= first-page-button 0)
[:span [:button.button {:on-click (fn [e] (on-params-change (swap! state assoc :start 0)))} 1] "..."])
]
[:div.is-pulled-right
[:div
extended-first-page-button
(apply list (subvec all-buttons first-page-button last-page-button))
extended-last-page-button]]
))
(defn invoice-table [{:keys [id invoice-page status on-params-change vendors params]}]
(let [state (reagent/atom (or @params {}))]
(let [state (reagent/atom (or @params {}))
opc (fn [p]
(swap! state merge p)
(on-params-change p))]
(fn [{:keys [id invoice-page status on-params-change vendors]}]
(let [{:keys [sort-by asc]} @state
{:keys [invoices start end count total]} @invoice-page]
[:div
[buttons-for start end count total on-params-change state]
[paginator {:start start :end end :count count :total total
:on-change (fn [p ]
(on-params-change (swap! state merge p)))}]
"Showing " (inc start) "-" end "/" total
[:table.table.is-fullwidth
[:thead
[:tr
[:th {:on-click (fn [e]
(on-params-change (swap! state toggle-sort-by "vendor"))) :style {:width "25%" :cursor "pointer"}} "Vendor"
(sort-icon "vendor" sort-by asc)]
[:th {:on-click (fn [e] (on-params-change (swap! state toggle-sort-by "company"))) :style {:width "25%" :cursor "pointer"}} "Company"
(sort-icon "company" sort-by asc)]
[:th {:on-click (fn [e] (on-params-change (swap! state toggle-sort-by "invoice-number"))) :style {:width "18%" :cursor "pointer"}} "Invoice #"
(sort-icon "invoice-number" sort-by asc)]
[:th {:on-click (fn [e] (on-params-change (swap! state toggle-sort-by "date"))) :style {:width "16%" :cursor "pointer"}} "Date"
(sort-icon "date" sort-by asc)]
[:th {:on-click (fn [e] (on-params-change (swap! state toggle-sort-by "total"))) :style {:width "16%" :cursor "pointer"}} "Amount"
(sort-icon "total" sort-by asc)]]]
[sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"}
:sort-key "vendor"
:sort-by sort-by
:asc asc}
"Vendor"]
[sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"}
:sort-key "company"
:sort-by sort-by
:asc asc}
"Company"]
[sorted-column {:on-sort opc
:style {:width "18%" :cursor "pointer"}
:sort-key "invoice-number"
:sort-by sort-by
:asc asc}
"Invoice #"]
[sorted-column {:on-sort opc
:style {:width "16%" :cursor "pointer"}
:sort-key "date"
:sort-by sort-by
:asc asc}
"Date"]
[sorted-column {:on-sort opc
:style {:width "16%" :cursor "pointer"}
:sort-key "total"
:sort-by sort-by
:asc asc}
"Amount"]]]
[:tbody
(if (:loading @status)
[:tr

View File

@@ -0,0 +1,54 @@
(ns auto-ap.views.components.paginator
(:require [re-frame.core :as re-frame]
[auto-ap.subs :as subs]
[auto-ap.views.utils :refer [date->str]]
[reagent.core :as reagent]
[clojure.string :as str]
[cljs-time.format :as format]))
(defn bound [x y z]
(cond
(< z x)
x
(< y x)
x
(> y z)
z
:else
y))
(defn paginator [{:keys [start end count total on-change]}]
(let [per-page 20
max-buttons 5
buttons-before (Math/floor (/ max-buttons 2))
total-pages (Math/ceil (/ total per-page))
current-page (Math/floor (/ start per-page))
first-page-button (bound 0 (- current-page buttons-before) (- total-pages max-buttons))
all-buttons (into [] (for [x (range total-pages)]
^{:key x}
[:li
[:a.pagination-link {:class (when (= current-page x)
"is-current")
:on-click (fn [e] (on-change {:start (* x per-page)}))}
(inc x)]]))
last-page-button (Math/min total-pages (+ max-buttons first-page-button))
extended-last-page-button (when (not= last-page-button total-pages)
(list
[:li [:span.pagination-ellipsis "…"]]
(last all-buttons)))
extended-first-page-button (when (not= first-page-button 0)
(list
(first all-buttons)
[:li [:span.pagination-ellipsis "…"]]))]
[:nav.pagination {:role "pagination"}
[:ul.pagination-list
extended-first-page-button
(apply list (subvec all-buttons first-page-button last-page-button))
extended-last-page-button]]))

View File

@@ -0,0 +1,33 @@
(ns auto-ap.views.components.sorter
(:require [re-frame.core :as re-frame]
[auto-ap.subs :as subs]
[auto-ap.views.utils :refer [date->str]]
[reagent.core :as reagent]
[clojure.string :as str]
[cljs-time.format :as format]))
(defn toggle-sort-by [params key]
(-> params
(assoc :sort-by key)
(update :asc not)))
(defn sort-icon [which sort-by asc]
(cond
(and (= sort-by which) asc)
[:span.icon
[:i.fa.fa-sort-up]]
(and (= sort-by which) (not asc))
[:span.icon
[:i.fa.fa-sort-down]]
:else
[:span.icon
[:i.fa.fa-sort]]))
(defn sorted-column [{:keys [on-sort sort-key sort-by asc style]} & rest]
[:th {:on-click (fn [e] (on-sort (toggle-sort-by {:asc asc} sort-key)))
:style style}
rest
(sort-icon sort-key sort-by asc)])

View File

@@ -1,6 +1,8 @@
(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]]
[reagent.core :as reagent]
[auto-ap.subs :as subs]
[auto-ap.events.admin.reminders :as events]
@@ -10,24 +12,78 @@
[auto-ap.routes :as routes]
[bidi.bidi :as bidi]))
(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-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
::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 reminders-table []
(let [reminders (or @(re-frame/subscribe [::subs/reminders]) [])]
[:table {:class "table", :style {:width "100%"}}
[:thead
[:tr
[:th "Vendor"]
[:th "Scheduled Date"]
[:th "Status"]
[:th "Email"]]]
[:tbody (for [{:keys [id vendor scheduled sent email ]} reminders]
^{:key id}
[:tr
[:td (:name vendor)]
[:td (date->str scheduled)]
[:td (when sent
[:span [:span.icon [:i.fa.fa-check]] "Sent " (date-time->str sent)]) ]
[:td email]])]]))
(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 ]} reminders]
^{:key id}
[:tr
[:td (:name vendor)]
[:td (date->str scheduled)]
[:td (when sent
[:span [:span.icon [:i.fa.fa-check]] "Sent " (date-time->str sent)]) ]
[:td email]])]]]))
(defn admin-reminders-page []
@@ -37,4 +93,4 @@
[:h1.title "Reminders"]
[reminders-table]])
{:component-did-mount (fn []
(re-frame/dispatch [::events/mounted]))})])
(re-frame/dispatch [::mounted]))})])

View File

@@ -18,8 +18,9 @@
(defn dispatch-event [event]
(fn [e]
(.stopPropagation e)
(.preventDefault e)
(when (.-stopPropagation e)
(.stopPropagation e)
(.preventDefault e))
(re-frame/dispatch event)))
(def pretty-long (format/formatter "MM/dd/yyyy HH:mm:ss"))
@@ -33,8 +34,6 @@
(when d
(format/unparse pretty-long d)))
(defmulti do-bind (fn [_ {:keys [type]}]
type))