pagination and sorting for reminders.
This commit is contained in:
@@ -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
|
||||
|
||||
54
src/cljs/auto_ap/views/components/paginator.cljs
Normal file
54
src/cljs/auto_ap/views/components/paginator.cljs
Normal 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]]))
|
||||
33
src/cljs/auto_ap/views/components/sorter.cljs
Normal file
33
src/cljs/auto_ap/views/components/sorter.cljs
Normal 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)])
|
||||
Reference in New Issue
Block a user