mirror of
https://github.com/status-im/open-bounty.git
synced 2025-02-22 22:28:07 +00:00
[FIX #156] Add pagination to Bounties and Activities views
This commit is contained in:
parent
cd3bbbdda0
commit
fea0db845a
3
resources/public/icon-forward-gray.svg
Normal file
3
resources/public/icon-forward-gray.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#57A7ED" fill-rule="evenodd" d="M7.223 11.293l7.068-7.067a.999.999 0 1 1 1.414 1.414l-6.377 6.377 6.377 6.376a.999.999 0 1 1-1.414 1.415L7.223 12.74a1.001 1.001 0 0 1-.288-.827 1 1 0 0 1 .288-.62z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 307 B |
@ -2,6 +2,7 @@
|
||||
(:require [re-frame.core :as rf]
|
||||
[reagent.core :as r]
|
||||
[commiteth.common :refer [moment-timestamp
|
||||
display-data-page
|
||||
issue-url]]))
|
||||
|
||||
|
||||
@ -56,21 +57,19 @@
|
||||
|
||||
|
||||
|
||||
(defn activity-list [activity-items]
|
||||
(defn activity-list [activity-page-data]
|
||||
[:div.ui.container.activity-container
|
||||
(if (empty? activity-items)
|
||||
(if (empty? (:items activity-page-data))
|
||||
[:div.view-no-data-container
|
||||
[:p "No recent activity yet"]]
|
||||
(into [:div.ui.items]
|
||||
(for [item activity-items]
|
||||
^{:key item} [activity-item item])))] )
|
||||
(display-data-page activity-page-data activity-item :set-activity-page-number))])
|
||||
|
||||
(defn activity-page []
|
||||
(let [activity-items (rf/subscribe [:activity-feed])
|
||||
(let [activity-page-data (rf/subscribe [:activities-page])
|
||||
activity-feed-loading? (rf/subscribe [:get-in [:activity-feed-loading?]])]
|
||||
(fn []
|
||||
(if @activity-feed-loading?
|
||||
[:div.view-loading-container
|
||||
[:div.ui.active.inverted.dimmer
|
||||
[:div.ui.text.loader.view-loading-label "Loading"]]]
|
||||
[activity-list @activity-items]))))
|
||||
[activity-list @activity-page-data]))))
|
||||
|
@ -1,6 +1,7 @@
|
||||
(ns commiteth.bounties
|
||||
(:require [re-frame.core :as rf]
|
||||
[commiteth.common :refer [moment-timestamp
|
||||
display-data-page
|
||||
issue-url]]))
|
||||
|
||||
|
||||
@ -42,23 +43,22 @@
|
||||
[:div.ui.tiny.circular.image
|
||||
[:img {:src avatar-url}]]]]))
|
||||
|
||||
(defn bounties-list [open-bounties]
|
||||
(defn bounties-list [{:keys [items item-count total-count] :as bounty-page-data}]
|
||||
[:div.ui.container.open-bounties-container
|
||||
[:div.open-bounties-header "Bounties"]
|
||||
(if (empty? open-bounties)
|
||||
(if (empty? items)
|
||||
[:div.view-no-data-container
|
||||
[:p "No recent activity yet"]]
|
||||
(into [:div.ui.items]
|
||||
(for [bounty open-bounties]
|
||||
[bounty-item bounty])))])
|
||||
|
||||
[:div [:div.item-counts-label
|
||||
[:span (str "Showing " item-count " of " total-count)]]
|
||||
(display-data-page bounty-page-data bounty-item :set-bounty-page-number)])])
|
||||
|
||||
(defn bounties-page []
|
||||
(let [open-bounties (rf/subscribe [:open-bounties])
|
||||
(let [bounty-page-data (rf/subscribe [:open-bounties-page])
|
||||
open-bounties-loading? (rf/subscribe [:get-in [:open-bounties-loading?]])]
|
||||
(fn []
|
||||
(if @open-bounties-loading?
|
||||
[:div.view-loading-container
|
||||
[:div.ui.active.inverted.dimmer
|
||||
[:div.ui.text.loader.view-loading-label "Loading"]]]
|
||||
[bounties-list @open-bounties]))))
|
||||
[bounties-list @bounty-page-data]))))
|
||||
|
@ -29,3 +29,87 @@
|
||||
|
||||
(defn issue-url [owner repo number]
|
||||
(str "https://github.com/" owner "/" repo "/issues/" number))
|
||||
|
||||
(def items-per-page 20)
|
||||
|
||||
(defn draw-page-numbers [page-number page-count set-page-kw]
|
||||
"Draw page numbers for the pagination component.
|
||||
Inserts ellipsis when list is too long, by default
|
||||
max 6 items are allowed"
|
||||
(let [draw-page-num-fn (fn [current? i]
|
||||
^{:key i}
|
||||
[:div.rectangle-rounded
|
||||
(cond-> {}
|
||||
(not current?)
|
||||
(assoc :class "grayed-out"
|
||||
:on-click #(rf/dispatch [set-page-kw i])))
|
||||
i])
|
||||
max-page-nums 6]
|
||||
[:div.page-nums-container
|
||||
(cond (<= page-count max-page-nums)
|
||||
(for [i (map inc (range page-count))]
|
||||
(draw-page-num-fn (= i page-number) i))
|
||||
(<= page-number (- max-page-nums 3))
|
||||
(concat
|
||||
(for [i (map inc (range (- max-page-nums 2)))]
|
||||
(draw-page-num-fn (= i page-number) i))
|
||||
[^{:key (dec max-page-nums)}
|
||||
[:div.page-nav-text [:span "..."]]]
|
||||
[(draw-page-num-fn false page-count)])
|
||||
(>= page-number (- page-count (- max-page-nums 4)))
|
||||
(concat
|
||||
[(draw-page-num-fn false 1)
|
||||
^{:key 2}
|
||||
[:div.page-nav-text [:span "..."]]]
|
||||
(for [i (map inc (range (- page-count 4) page-count))]
|
||||
(draw-page-num-fn (= i page-number) i))
|
||||
)
|
||||
:else
|
||||
(concat
|
||||
[(draw-page-num-fn false 1)
|
||||
^{:key 2} [:div.page-nav-text [:span "..."]]]
|
||||
(for [i [(dec page-number) page-number (inc page-number)]]
|
||||
(draw-page-num-fn (= i page-number) i))
|
||||
[^{:key (dec page-count)} [:div.page-nav-text [:span "..."]]
|
||||
(draw-page-num-fn false page-count)]))]))
|
||||
|
||||
(defn display-data-page [{:keys [items
|
||||
item-count
|
||||
total-count
|
||||
page-number
|
||||
page-count]}
|
||||
draw-item-fn
|
||||
set-page-kw]
|
||||
"Draw data items along with pagination controls"
|
||||
(let [draw-items (fn []
|
||||
(into [:div.ui.items]
|
||||
(for [item items]
|
||||
^{:key item} [draw-item-fn item])))
|
||||
on-direction-click (fn [forward?]
|
||||
#(when (or (and (< page-number page-count)
|
||||
forward?)
|
||||
(and (< 1 page-number)
|
||||
(not forward?)))
|
||||
(rf/dispatch [set-page-kw
|
||||
(if forward?
|
||||
(inc page-number)
|
||||
(dec page-number))])))
|
||||
draw-rect (fn [direction]
|
||||
(let [forward? (= direction :forward)]
|
||||
[:div.rectangle-rounded
|
||||
{:on-click (on-direction-click forward?)}
|
||||
[:img.icon-forward-gray
|
||||
(cond-> {:src "icon-forward-gray.svg"}
|
||||
forward? (assoc :class "flip-horizontal"))]]))]
|
||||
(cond (<= total-count items-per-page)
|
||||
[draw-items]
|
||||
:else
|
||||
[:div
|
||||
[draw-items]
|
||||
[:div.page-nav-container
|
||||
[draw-rect :backward]
|
||||
[draw-rect :forward]
|
||||
[:div.page-nav-text [:span (str "Page " page-number " of " page-count)]]
|
||||
[draw-page-numbers page-number page-count set-page-kw]]])))
|
||||
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
:activity-feed-loading? false
|
||||
:open-bounties-loading? false
|
||||
:open-bounties []
|
||||
:bounty-page-number 1
|
||||
:activity-page-number 1
|
||||
:owner-bounties {}
|
||||
:top-hunters []
|
||||
:activity-feed []})
|
||||
|
@ -68,6 +68,16 @@
|
||||
(fn [db [_ page]]
|
||||
(assoc db :page page)))
|
||||
|
||||
(reg-event-db
|
||||
:set-bounty-page-number
|
||||
(fn [db [_ page]]
|
||||
(assoc db :bounty-page-number page)))
|
||||
|
||||
(reg-event-db
|
||||
:set-activity-page-number
|
||||
(fn [db [_ page]]
|
||||
(assoc db :activity-page-number page)))
|
||||
|
||||
(reg-event-fx
|
||||
:set-flash-message
|
||||
(fn [{:keys [db]} [_ type text]]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(ns commiteth.subscriptions
|
||||
(:require [re-frame.core :refer [reg-sub]]))
|
||||
(:require [re-frame.core :refer [reg-sub]]
|
||||
[commiteth.common :refer [items-per-page]]))
|
||||
|
||||
(reg-sub
|
||||
:db
|
||||
@ -33,7 +34,28 @@
|
||||
(reg-sub
|
||||
:open-bounties
|
||||
(fn [db _]
|
||||
(:open-bounties db)))
|
||||
(vec (:open-bounties db))))
|
||||
|
||||
(reg-sub
|
||||
:bounty-page-number
|
||||
(fn [db _]
|
||||
(:bounty-page-number db)))
|
||||
|
||||
(reg-sub
|
||||
:open-bounties-page
|
||||
:<- [:open-bounties]
|
||||
:<- [:bounty-page-number]
|
||||
(fn [[open-bounties page-number] _]
|
||||
(let [total-count (count open-bounties)
|
||||
start (* (dec page-number) items-per-page)
|
||||
end (min total-count (+ items-per-page start))
|
||||
items (subvec open-bounties start end)]
|
||||
{:items items
|
||||
:item-count (count items)
|
||||
:total-count total-count
|
||||
:page-number page-number
|
||||
:page-count (Math/ceil (/ total-count items-per-page))})))
|
||||
|
||||
|
||||
(reg-sub
|
||||
:owner-bounties
|
||||
@ -53,7 +75,28 @@
|
||||
(reg-sub
|
||||
:activity-feed
|
||||
(fn [db _]
|
||||
(:activity-feed db)))
|
||||
(vec (:activity-feed db))))
|
||||
|
||||
(reg-sub
|
||||
:activity-page-number
|
||||
(fn [db _]
|
||||
(:activity-page-number db)))
|
||||
|
||||
(reg-sub
|
||||
:activities-page
|
||||
:<- [:activity-feed]
|
||||
:<- [:activity-page-number]
|
||||
(fn [[activities page-number] _]
|
||||
(let [total-count (count activities)
|
||||
start (* (dec page-number) items-per-page)
|
||||
end (min total-count (+ items-per-page start))
|
||||
items (subvec activities start end)]
|
||||
{:items items
|
||||
:item-count (count items)
|
||||
:total-count total-count
|
||||
:page-number page-number
|
||||
:page-count (Math/ceil (/ total-count items-per-page))})))
|
||||
|
||||
|
||||
(reg-sub
|
||||
:gh-admin-token
|
||||
|
@ -870,3 +870,85 @@ body {
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.rectangle-rounded {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
color: #57a7ed;
|
||||
/*opacity: 0.2;*/
|
||||
border-radius: 22.5px;
|
||||
/*background-color: #57a7ed;*/
|
||||
background-color: rgba(87,167,237,.2);
|
||||
font-family: "PostGrotesk-Medium";
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
margin: 0 6px;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.grayed-out {
|
||||
color: #8d99a4;
|
||||
background-color: #f2f5f8;
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.flip-horizontal {
|
||||
-moz-transform: scaleX(-1);
|
||||
-webkit-transform: scaleX(-1);
|
||||
-o-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
-ms-filter: fliph; /*IE*/
|
||||
filter: fliph;
|
||||
}
|
||||
|
||||
.pagination-text {
|
||||
width: 83px;
|
||||
height: 15px;
|
||||
font-family: PostGrotesk;
|
||||
font-size: 15px;
|
||||
text-align: center;
|
||||
color: #8d99a4;
|
||||
}
|
||||
|
||||
.icon-forward-gray {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.page-nav-container {
|
||||
display: flex;
|
||||
margin: 0 -6px;
|
||||
}
|
||||
|
||||
.page-nums-container {
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.page-nav-text {
|
||||
font-family: PostGrotesk-Book;
|
||||
font-size: 15px;
|
||||
color: #8d99a4;
|
||||
|
||||
display: flex;
|
||||
margin: 0 6px;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.item-counts-label {
|
||||
margin: auto;
|
||||
font-family: "PostGrotesk-Book";
|
||||
font-size: 15px;
|
||||
color: #8d99a4;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user