From ffa0cfa3bb58e14db4fe7d0e48c4bd0796c633ab Mon Sep 17 00:00:00 2001 From: pablodip Date: Tue, 16 Jan 2018 06:55:45 +0100 Subject: [PATCH 01/29] some filter and sort markup --- src/cljs/commiteth/bounties.cljs | 58 +++++++++++++++++---------- src/cljs/commiteth/db.cljs | 3 +- src/cljs/commiteth/subscriptions.cljs | 5 +++ src/less/style.less | 47 ++++++++++++++++++++++ 4 files changed, 90 insertions(+), 23 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index f7ba984..69bef6a 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -5,19 +5,19 @@ (defn bounty-item [bounty] - (let [{avatar-url :repo_owner_avatar_url - owner :repo-owner - repo-name :repo-name - issue-title :issue-title + (let [{avatar-url :repo_owner_avatar_url + owner :repo-owner + repo-name :repo-name + issue-title :issue-title issue-number :issue-number - updated :updated - tokens :tokens - balance-eth :balance-eth - value-usd :value-usd - claim-count :claim-count} bounty - full-repo (str owner "/" repo-name) - repo-url (str "https://github.com/" full-repo) - repo-link [:a {:href repo-url} full-repo] + updated :updated + tokens :tokens + balance-eth :balance-eth + value-usd :value-usd + claim-count :claim-count} bounty + full-repo (str owner "/" repo-name) + repo-url (str "https://github.com/" full-repo) + repo-link [:a {:href repo-url} full-repo] issue-link [:a {:href (issue-url owner repo-name issue-number)} issue-title]] @@ -37,24 +37,38 @@ [:span.usd-value-label "Value "] [:span.usd-balance-label (str "$" value-usd)] (when (> claim-count 0) [:span.open-claims-label (str claim-count " open claim" - (when (> claim-count 1) "s"))]) ]] + (when (> claim-count 1) "s"))])]] [:div.open-bounty-item-icon [:div.ui.tiny.circular.image [:img {:src avatar-url}]]]])) (defn bounties-list [open-bounties] - [:div.ui.container.open-bounties-container - [:div.open-bounties-header "Bounties"] - (if (empty? open-bounties) - [:div.view-no-data-container - [:p "No recent activity yet"]] - (into [:div.ui.items] - (for [bounty open-bounties] - [bounty-item bounty])))]) + (let [order (rf/subscribe [:bounties-order])] + [:div.ui.container.open-bounties-container + [:div.open-bounties-header "Bounties"] + [:div.open-bounties-filter-and-sort + [:div.open-bounties-filter + [:a.open-bounties-filter-element {:href "javascript:;"} "Value"] + [:div.open-bounties-filter-tooltip "Lalala"] + [:a.open-bounties-filter-element {:href "javascript:;"} "Type"] + [:a.open-bounties-filter-element {:href "javascript:;"} "Language"] + [:a.open-bounties-filter-element {:href "javascript:;"} "Date"] + [:a.open-bounties-filter-element {:href "javascript:;"} "More"]] + [:div.open-bounties-sort + "Most Recent" + [:div.icon-forward-white-box + [:img + {:src "icon-forward-white.svg"}]]]] + (if (empty? open-bounties) + [:div.view-no-data-container + [:p "No recent activity yet"]] + (into [:div.ui.items] + (for [bounty open-bounties] + [bounty-item bounty])))])) (defn bounties-page [] - (let [open-bounties (rf/subscribe [:open-bounties]) + (let [open-bounties (rf/subscribe [:open-bounties]) open-bounties-loading? (rf/subscribe [:get-in [:open-bounties-loading?]])] (fn [] (if @open-bounties-loading? diff --git a/src/cljs/commiteth/db.cljs b/src/cljs/commiteth/db.cljs index 2ee532f..4a51dbf 100644 --- a/src/cljs/commiteth/db.cljs +++ b/src/cljs/commiteth/db.cljs @@ -10,4 +10,5 @@ :open-bounties [] :owner-bounties {} :top-hunters [] - :activity-feed []}) + :activity-feed [] + :bounties-order ::bounties-order|most-recent}) diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index 6e18eb1..9228ddc 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -80,3 +80,8 @@ :user-dropdown-open? (fn [db _] (:user-dropdown-open? db))) + +(reg-sub + :bounties-order + (fn [db _] + (:bounties-order db))) diff --git a/src/less/style.less b/src/less/style.less index 2c0c2e4..f9e4a0c 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -413,6 +413,53 @@ font-weight: 500; color: #42505c; } + + .open-bounties-filter-and-sort { + margin-top: 24px; + display: flex; + justify-content: space-between; + } + + .open-bounties-filter { + display: flex; + } + + .open-bounties-filter-element { + position: relative; + font-size: 15px; + font-weight: 500; + line-height: 1.0; + color: #8d99a4; + padding: 8px 12px; + border-radius: 8px; + border: solid 1px rgba(151, 151, 151, 0.2); + margin-right: 10px; + } + + .open-bounties-filter-element:focus { + background-color: #57a7ed; + } + + .open-bounties-filter-tooltip { + position: absolute; + } + + .open-bounties-sort { + font-size: 15px; + font-weight: 500; + line-height: 1.0; + color: #8d99a4; + display: flex; + align-items: center; + } + + .icon-forward-white-box { + width: 24px; + height: 24px; + display: flex; + justify-content: center; + align-content: center; + } } .open-bounty-item { From 26c740517bd657d823fc5638e3fbbb17aa0d0506 Mon Sep 17 00:00:00 2001 From: pablodip Date: Tue, 16 Jan 2018 13:05:41 +0100 Subject: [PATCH 02/29] some more sort and filter markup and interface behaviour --- src/cljs/commiteth/bounties.cljs | 55 ++++++++++++++++++++++++-------- src/less/style.less | 49 ++++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 16 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 69bef6a..6c6c91e 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -1,5 +1,6 @@ (ns commiteth.bounties - (:require [re-frame.core :as rf] + (:require [reagent.core :as r] + [re-frame.core :as rf] [commiteth.common :refer [moment-timestamp issue-url]])) @@ -42,23 +43,51 @@ [:div.ui.tiny.circular.image [:img {:src avatar-url}]]]])) +(defn bounties-filter [name] + (let [open? (r/atom false)] + (fn [name] + [:div.open-bounties-filter-element-container + {:tab-index 0 + :on-blur #(reset! open? false)} + [:div.open-bounties-filter-element + {:on-click #(swap! open? not) + :class (when @open? "open-bounties-filter-element-active")} + name] + (when @open? + [:div.open-bounties-filter-element-tooltip + "TOOLTIP"])]))) + +(defn bounties-filters [] + [:div.open-bounties-filter + [bounties-filter "Value"] + [bounties-filter "Type"] + [bounties-filter "Language"] + [bounties-filter "Date"] + [bounties-filter "More"]]) + +(defn bounties-sort [] + (let [open? (r/atom false)] + (fn [] + [:div.open-bounties-sort + {:tab-index 0 + :on-blur #(reset! open? false)} + [:div.open-bounties-sort-element + {:on-click #(swap! open? not)} + "Most Recent" + [:div.icon-forward-white-box + [:img + {:src "icon-forward-white.svg"}]]] + (when @open? + [:div.open-bounties-sort-element-tooltip + "TOOLTIP"])]))) + (defn bounties-list [open-bounties] (let [order (rf/subscribe [:bounties-order])] [:div.ui.container.open-bounties-container [:div.open-bounties-header "Bounties"] [:div.open-bounties-filter-and-sort - [:div.open-bounties-filter - [:a.open-bounties-filter-element {:href "javascript:;"} "Value"] - [:div.open-bounties-filter-tooltip "Lalala"] - [:a.open-bounties-filter-element {:href "javascript:;"} "Type"] - [:a.open-bounties-filter-element {:href "javascript:;"} "Language"] - [:a.open-bounties-filter-element {:href "javascript:;"} "Date"] - [:a.open-bounties-filter-element {:href "javascript:;"} "More"]] - [:div.open-bounties-sort - "Most Recent" - [:div.icon-forward-white-box - [:img - {:src "icon-forward-white.svg"}]]]] + [bounties-filters] + [bounties-sort]] (if (empty? open-bounties) [:div.view-no-data-container [:p "No recent activity yet"]] diff --git a/src/less/style.less b/src/less/style.less index f9e4a0c..1c9eeef 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -425,7 +425,6 @@ } .open-bounties-filter-element { - position: relative; font-size: 15px; font-weight: 500; line-height: 1.0; @@ -434,25 +433,69 @@ border-radius: 8px; border: solid 1px rgba(151, 151, 151, 0.2); margin-right: 10px; + position: relative; } - .open-bounties-filter-element:focus { + .open-bounties-filter-element:hover { + cursor: pointer; + } + + .open-bounties-filter-element-active { background-color: #57a7ed; + color: #ffffff; } - .open-bounties-filter-tooltip { + .open-bounties-filter-element-container:focus { + outline: none; + } + + .open-bounties-filter-element-tooltip { position: absolute; + margin-top: 12px; + padding: 16px 24px; + border-radius: 10px; + background-color: #ffffff; + box-shadow: 0 15px 12px 0 rgba(161, 174, 182, 0.53), 0 0 38px 0 rgba(0, 0, 0, 0.05); } .open-bounties-sort { + position: relative; + } + + .open-bounties-sort:focus { + outline: none; + } + + .open-bounties-sort-element { + display: flex; font-size: 15px; font-weight: 500; line-height: 1.0; color: #8d99a4; + padding: 8px 12px; display: flex; align-items: center; } + .open-bounties-sort-element:hover { + cursor: pointer; + } + + .open-bounties-sort-element-tooltip { + position: absolute; + right: 0; + //margin-top: 12px; + padding: 16px 24px; + min-width: 200px; + border-radius: 8px; + background-color: #1e3751; + font-family: "PostGrotesk-Medium"; + font-size: 15px; + line-height: 1.0; + text-align: left; + color: #ffffff; + } + .icon-forward-white-box { width: 24px; height: 24px; From bdbdc2e2d23dee4f4fc54ba37591992fd8ec333b Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 18 Jan 2018 05:45:42 +0100 Subject: [PATCH 03/29] add some bounty sorting --- src/cljs/commiteth/bounties.cljs | 62 +++++++++++++++------------ src/cljs/commiteth/db.cljs | 23 ++++++---- src/cljs/commiteth/handlers.cljs | 5 +++ src/cljs/commiteth/subscriptions.cljs | 7 +-- src/less/style.less | 12 +++++- 5 files changed, 67 insertions(+), 42 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 6c6c91e..7da81fa 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -2,7 +2,9 @@ (:require [reagent.core :as r] [re-frame.core :as rf] [commiteth.common :refer [moment-timestamp - issue-url]])) + issue-url]] + [commiteth.handlers :as handlers] + [commiteth.db :as db])) (defn bounty-item [bounty] @@ -60,40 +62,44 @@ (defn bounties-filters [] [:div.open-bounties-filter [bounties-filter "Value"] - [bounties-filter "Type"] - [bounties-filter "Language"] + [bounties-filter "Currency"] [bounties-filter "Date"] - [bounties-filter "More"]]) + [bounties-filter "Owner"]]) (defn bounties-sort [] (let [open? (r/atom false)] (fn [] - [:div.open-bounties-sort - {:tab-index 0 - :on-blur #(reset! open? false)} - [:div.open-bounties-sort-element - {:on-click #(swap! open? not)} - "Most Recent" - [:div.icon-forward-white-box - [:img - {:src "icon-forward-white.svg"}]]] - (when @open? - [:div.open-bounties-sort-element-tooltip - "TOOLTIP"])]))) + (let [current-sorting (rf/subscribe [::db/bounty-sorting-type])] + [:div.open-bounties-sort + {:tab-index 0 + :on-blur #(reset! open? false)} + [:div.open-bounties-sort-element + {:on-click #(swap! open? not)} + (db/bounty-sorting-types @current-sorting) + [:div.icon-forward-white-box + [:img + {:src "icon-forward-white.svg"}]]] + (when @open? + [:div.open-bounties-sort-element-tooltip + (for [[sorting-type sorting-name] db/bounty-sorting-types] + [:div.open-bounties-sort-type + {:on-click #(do + (reset! open? false) + (rf/dispatch [::handlers/set-bounty-sorting-type sorting-type]))} + sorting-name])])])))) (defn bounties-list [open-bounties] - (let [order (rf/subscribe [:bounties-order])] - [:div.ui.container.open-bounties-container - [:div.open-bounties-header "Bounties"] - [:div.open-bounties-filter-and-sort - [bounties-filters] - [bounties-sort]] - (if (empty? open-bounties) - [:div.view-no-data-container - [:p "No recent activity yet"]] - (into [:div.ui.items] - (for [bounty open-bounties] - [bounty-item bounty])))])) + [:div.ui.container.open-bounties-container + [:div.open-bounties-header "Bounties"] + [:div.open-bounties-filter-and-sort + [bounties-filters] + [bounties-sort]] + (if (empty? open-bounties) + [:div.view-no-data-container + [:p "No recent activity yet"]] + (into [:div.ui.items] + (for [bounty open-bounties] + [bounty-item bounty])))]) (defn bounties-page [] diff --git a/src/cljs/commiteth/db.cljs b/src/cljs/commiteth/db.cljs index 4a51dbf..e54bcd1 100644 --- a/src/cljs/commiteth/db.cljs +++ b/src/cljs/commiteth/db.cljs @@ -1,14 +1,19 @@ (ns commiteth.db) +(def bounty-sorting-types {::bounty-sorting-type|most-recent "Most recent" + ::bounty-sorting-type|lowest-value "Lowest value" + ::bounty-sorting-type|highest-value "Highest value" + ::bounty-sorting-type|owner "Owner"}) + (def default-db - {:page :bounties - :user nil - :repos-loading? false - :repos {} + {:page :bounties + :user nil + :repos-loading? false + :repos {} :activity-feed-loading? false :open-bounties-loading? false - :open-bounties [] - :owner-bounties {} - :top-hunters [] - :activity-feed [] - :bounties-order ::bounties-order|most-recent}) + :open-bounties [] + :owner-bounties {} + :top-hunters [] + :activity-feed [] + ::bounty-sorting-type ::bounty-sorting-type|most-recent}) diff --git a/src/cljs/commiteth/handlers.cljs b/src/cljs/commiteth/handlers.cljs index 528c116..b69f1ca 100644 --- a/src/cljs/commiteth/handlers.cljs +++ b/src/cljs/commiteth/handlers.cljs @@ -453,3 +453,8 @@ (fn [db [_]] (.removeEventListener js/window "click" close-dropdown) (assoc db :user-dropdown-open? false))) + +(reg-event-db + ::set-bounty-sorting-type + (fn [db [_ sorting-type]] + (assoc db ::db/bounty-sorting-type sorting-type))) diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index 9228ddc..c6d4340 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -1,5 +1,6 @@ (ns commiteth.subscriptions - (:require [re-frame.core :refer [reg-sub]])) + (:require [re-frame.core :refer [reg-sub]] + [commiteth.db :as db])) (reg-sub :db @@ -82,6 +83,6 @@ (:user-dropdown-open? db))) (reg-sub - :bounties-order + ::db/bounty-sorting-type (fn [db _] - (:bounties-order db))) + (::db/bounty-sorting-type db))) diff --git a/src/less/style.less b/src/less/style.less index 1c9eeef..e52f7fa 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -484,8 +484,7 @@ .open-bounties-sort-element-tooltip { position: absolute; right: 0; - //margin-top: 12px; - padding: 16px 24px; + //padding: 16px 0; min-width: 200px; border-radius: 8px; background-color: #1e3751; @@ -496,6 +495,15 @@ color: #ffffff; } + .open-bounties-sort-type { + padding: 19px 24px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + } + + .open-bounties-sort-type:hover { + cursor: pointer; + } + .icon-forward-white-box { width: 24px; height: 24px; From 11e4a00ac6c9ed9d7fe66e2f9cf06f0c55a7fb63 Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 18 Jan 2018 09:08:37 +0100 Subject: [PATCH 04/29] some filter markup and behaviour --- src/cljs/commiteth/bounties.cljs | 94 ++++++++++++----- src/less/style.less | 169 ++++++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 28 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 7da81fa..e64e11f 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -45,48 +45,90 @@ [:div.ui.tiny.circular.image [:img {:src avatar-url}]]]])) -(defn bounties-filter [name] +(defn bounties-filter-tooltip [& content] + [:div.open-bounties-filter-element-tooltip + content]) + +(defn bounties-filter-tooltip-value-input [label tooltip-open?] + [:div.open-bounties-filter-element-tooltip-value-input-container + [:div.:input.open-bounties-filter-element-tooltip-value-input-label + label] + [:input.open-bounties-filter-element-tooltip-value-input + {:type "range" + :min 0 + :max 1000 + :step 10 + :on-focus #(reset! tooltip-open? true)}]]) + +(defn bounties-filter-tooltip-value [tooltip-open?] + [bounties-filter-tooltip + "$0 - $1000+" + [bounties-filter-tooltip-value-input "Min" tooltip-open?] + [bounties-filter-tooltip-value-input "Max" tooltip-open?]]) + +(defn bounties-filter-tooltip-currency [] + [bounties-filter-tooltip "CURRENCY"]) + +(defn bounties-filter-tooltip-date [] + [bounties-filter-tooltip + [:div.open-bounties-filter-list + (for [t ["Last week" "Last month" "Last 3 months"]] + [:div.open-bounties-filter-list-option + t])]]) + +(defn bounties-filter-tooltip-owner [tooltip-open?] + [bounties-filter-tooltip + [:div.open-bounties-filter-list + (for [t ["status-im" "aragon"]] + [:div.open-bounties-filter-list-option-checkbox + [:label + [:input + {:type "checkbox" + :on-focus #(reset! tooltip-open? true)}] + [:div.text t]]])]]) + +(defn bounties-filter [name tooltip] (let [open? (r/atom false)] - (fn [name] + (fn [name tooltip] [:div.open-bounties-filter-element-container {:tab-index 0 + :on-focus #(reset! open? true) :on-blur #(reset! open? false)} [:div.open-bounties-filter-element - {:on-click #(swap! open? not) - :class (when @open? "open-bounties-filter-element-active")} + {:on-mouse-down #(swap! open? not) + :class (when @open? "open-bounties-filter-element-active")} name] (when @open? - [:div.open-bounties-filter-element-tooltip - "TOOLTIP"])]))) + [tooltip open?])]))) (defn bounties-filters [] [:div.open-bounties-filter - [bounties-filter "Value"] - [bounties-filter "Currency"] - [bounties-filter "Date"] - [bounties-filter "Owner"]]) + [bounties-filter "Value" bounties-filter-tooltip-value] + [bounties-filter "Currency" bounties-filter-tooltip-currency] + [bounties-filter "Date" bounties-filter-tooltip-date] + [bounties-filter "Owner" bounties-filter-tooltip-owner]]) (defn bounties-sort [] (let [open? (r/atom false)] (fn [] (let [current-sorting (rf/subscribe [::db/bounty-sorting-type])] [:div.open-bounties-sort - {:tab-index 0 - :on-blur #(reset! open? false)} - [:div.open-bounties-sort-element - {:on-click #(swap! open? not)} - (db/bounty-sorting-types @current-sorting) - [:div.icon-forward-white-box - [:img - {:src "icon-forward-white.svg"}]]] - (when @open? - [:div.open-bounties-sort-element-tooltip - (for [[sorting-type sorting-name] db/bounty-sorting-types] - [:div.open-bounties-sort-type - {:on-click #(do - (reset! open? false) - (rf/dispatch [::handlers/set-bounty-sorting-type sorting-type]))} - sorting-name])])])))) + {:tab-index 0 + :on-blur #(reset! open? false)} + [:div.open-bounties-sort-element + {:on-click #(swap! open? not)} + (db/bounty-sorting-types @current-sorting) + [:div.icon-forward-white-box + [:img + {:src "icon-forward-white.svg"}]]] + (when @open? + [:div.open-bounties-sort-element-tooltip + (for [[sorting-type sorting-name] db/bounty-sorting-types] + [:div.open-bounties-sort-type + {:on-click #(do + (reset! open? false) + (rf/dispatch [::handlers/set-bounty-sorting-type sorting-type]))} + sorting-name])])])))) (defn bounties-list [open-bounties] [:div.ui.container.open-bounties-container diff --git a/src/less/style.less b/src/less/style.less index e52f7fa..4e4b05e 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -425,6 +425,7 @@ } .open-bounties-filter-element { + font-family: "PostGrotesk-Book"; font-size: 15px; font-weight: 500; line-height: 1.0; @@ -451,11 +452,175 @@ .open-bounties-filter-element-tooltip { position: absolute; + min-width: 227px; margin-top: 12px; - padding: 16px 24px; + padding: 24px 16px; border-radius: 10px; background-color: #ffffff; box-shadow: 0 15px 12px 0 rgba(161, 174, 182, 0.53), 0 0 38px 0 rgba(0, 0, 0, 0.05); + font-family: "PostGrotesk-Book"; + font-size: 16px; + line-height: 1.5; + + .open-bounties-filter-element-tooltip-value-input-container { + display: flex; + margin-top: 10px; + } + + .open-bounties-filter-element-tooltip-value-input-label { + width: 60px; + } + + .open-bounties-filter-element-tooltip-value-input { + margin-top: 24px; + width: 288.5px; + height: 4px; + background-color: #55a5ea; + } + + // generated with http://danielstern.ca/range.css/#/ + input[type=range] { + -webkit-appearance: none; + //width: 100%; + margin: 14.5px 0; + } + input[type=range]:focus { + outline: none; + } + input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 4px; + cursor: pointer; + box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; + background: #55a5ea; + border-radius: 0px; + border: 0px solid #010101; + } + input[type=range]::-webkit-slider-thumb { + box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; + border: 0px solid #000000; + height: 33px; + width: 33px; + border-radius: 50px; + background: #55a5ea; + cursor: pointer; + -webkit-appearance: none; + margin-top: -14.5px; + } + input[type=range]:focus::-webkit-slider-runnable-track { + background: #5aa7eb; + } + input[type=range]::-moz-range-track { + width: 100%; + height: 4px; + cursor: pointer; + box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; + background: #55a5ea; + border-radius: 0px; + border: 0px solid #010101; + } + input[type=range]::-moz-range-thumb { + box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; + border: 0px solid #000000; + height: 33px; + width: 33px; + border-radius: 50px; + background: #55a5ea; + cursor: pointer; + } + input[type=range]::-ms-track { + width: 100%; + height: 4px; + cursor: pointer; + background: transparent; + border-color: transparent; + color: transparent; + } + input[type=range]::-ms-fill-lower { + background: #50a3e9; + border: 0px solid #010101; + border-radius: 0px; + box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; + } + input[type=range]::-ms-fill-upper { + background: #55a5ea; + border: 0px solid #010101; + border-radius: 0px; + box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; + } + input[type=range]::-ms-thumb { + box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; + border: 0px solid #000000; + height: 33px; + width: 33px; + border-radius: 50px; + background: #55a5ea; + cursor: pointer; + height: 4px; + } + input[type=range]:focus::-ms-fill-lower { + background: #55a5ea; + } + input[type=range]:focus::-ms-fill-upper { + background: #5aa7eb; + } + + .open-bounties-filter-list { + display: flex; + flex-direction: column; + align-items: flex-start; + } + + .open-bounties-filter-list-option { + font-family: "PostGrotesk-Book"; + font-size: 15px; + font-weight: 500; + line-height: 1.0; + color: #42505c; + padding: 8px 12px; + border-radius: 8px; + border: solid 1px rgba(151, 151, 151, 0.2); + } + + .open-bounties-filter-list-option:not(:first-child) { + margin-top: 8px; + } + + .open-bounties-filter-list-option:hover { + cursor: pointer; + background-color: #57a7ed; + color: #ffffff; + } + + .open-bounties-filter-list-option-checkbox { + label { + display: flex; + } + + label:hover { + cursor: pointer; + } + + input { + background: green; + transform: scale(1.3); + } + + input:hover { + cursor: pointer; + } + + .text { + font-size: 15px; + font-weight: 500; + line-height: 1.0; + margin-left: 12px; + } + } + + .open-bounties-filter-list-option-checkbox:not(:first-child) { + margin-top: 12px; + } } .open-bounties-sort { @@ -488,7 +653,7 @@ min-width: 200px; border-radius: 8px; background-color: #1e3751; - font-family: "PostGrotesk-Medium"; + font-family: "PostGrotesk-Book"; font-size: 15px; line-height: 1.0; text-align: left; From 646ad8a03843e06611064197c24b43cd77c4873c Mon Sep 17 00:00:00 2001 From: pablodip Date: Fri, 19 Jan 2018 07:51:50 +0100 Subject: [PATCH 05/29] some more filter markup --- src/cljs/commiteth/bounties.cljs | 46 ++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index e64e11f..173d7e5 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -61,35 +61,40 @@ :on-focus #(reset! tooltip-open? true)}]]) (defn bounties-filter-tooltip-value [tooltip-open?] - [bounties-filter-tooltip + [:div "$0 - $1000+" [bounties-filter-tooltip-value-input "Min" tooltip-open?] [bounties-filter-tooltip-value-input "Max" tooltip-open?]]) -(defn bounties-filter-tooltip-currency [] - [bounties-filter-tooltip "CURRENCY"]) +(defn bounties-filter-tooltip-currency [tooltip-open?] + [:div.open-bounties-filter-list + (for [t ["ETH" "SNT"]] + [:div.open-bounties-filter-list-option-checkbox + [:label + [:input + {:type "checkbox" + :on-focus #(reset! tooltip-open? true)}] + [:div.text t]]])]) (defn bounties-filter-tooltip-date [] - [bounties-filter-tooltip - [:div.open-bounties-filter-list - (for [t ["Last week" "Last month" "Last 3 months"]] - [:div.open-bounties-filter-list-option - t])]]) + [:div.open-bounties-filter-list + (for [t ["Last week" "Last month" "Last 3 months"]] + [:div.open-bounties-filter-list-option + t])]) (defn bounties-filter-tooltip-owner [tooltip-open?] - [bounties-filter-tooltip - [:div.open-bounties-filter-list - (for [t ["status-im" "aragon"]] - [:div.open-bounties-filter-list-option-checkbox - [:label - [:input - {:type "checkbox" - :on-focus #(reset! tooltip-open? true)}] - [:div.text t]]])]]) + [:div.open-bounties-filter-list + (for [t ["status-im" "aragon"]] + [:div.open-bounties-filter-list-option-checkbox + [:label + [:input + {:type "checkbox" + :on-focus #(reset! tooltip-open? true)}] + [:div.text t]]])]) -(defn bounties-filter [name tooltip] +(defn bounties-filter [name tooltip-content] (let [open? (r/atom false)] - (fn [name tooltip] + (fn [name tooltip-content] [:div.open-bounties-filter-element-container {:tab-index 0 :on-focus #(reset! open? true) @@ -99,7 +104,8 @@ :class (when @open? "open-bounties-filter-element-active")} name] (when @open? - [tooltip open?])]))) + [bounties-filter-tooltip + [tooltip-content open?]])]))) (defn bounties-filters [] [:div.open-bounties-filter From 366148f250c9fda2dad726e35431057331d8c580 Mon Sep 17 00:00:00 2001 From: pablodip Date: Sat, 20 Jan 2018 08:21:59 +0100 Subject: [PATCH 06/29] some behaviour in bounty filters --- src/cljs/commiteth/bounties.cljs | 164 ++++++++++++++++++-------- src/cljs/commiteth/db.cljs | 34 +++--- src/cljs/commiteth/handlers.cljs | 9 +- src/cljs/commiteth/subscriptions.cljs | 9 +- src/cljs/commiteth/ui_model.cljs | 44 +++++++ src/less/style.less | 20 +++- 6 files changed, 211 insertions(+), 69 deletions(-) create mode 100644 src/cljs/commiteth/ui_model.cljs diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 173d7e5..83aa4f3 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -4,7 +4,9 @@ [commiteth.common :refer [moment-timestamp issue-url]] [commiteth.handlers :as handlers] - [commiteth.db :as db])) + [commiteth.db :as db] + [commiteth.ui-model :as ui-model] + [commiteth.subscriptions :as subs])) (defn bounty-item [bounty] @@ -45,102 +47,172 @@ [:div.ui.tiny.circular.image [:img {:src avatar-url}]]]])) -(defn bounties-filter-tooltip [& content] +(defn bounties-filter-tooltip [content] [:div.open-bounties-filter-element-tooltip content]) -(defn bounties-filter-tooltip-value-input [label tooltip-open?] +(defn bounties-filter-tooltip-value-input [label tooltip-open? opts] [:div.open-bounties-filter-element-tooltip-value-input-container [:div.:input.open-bounties-filter-element-tooltip-value-input-label label] [:input.open-bounties-filter-element-tooltip-value-input - {:type "range" - :min 0 - :max 1000 - :step 10 - :on-focus #(reset! tooltip-open? true)}]]) + {:type "range" + :min (:min opts) + :max (:max opts) + :step (:step opts) + :value (:current-val opts) + :on-change (when-let [f (:on-change-val opts)] + #(-> % .-target .-value int f)) + :on-focus #(reset! tooltip-open? true)}]]) -(defn bounties-filter-tooltip-value [tooltip-open?] - [:div - "$0 - $1000+" - [bounties-filter-tooltip-value-input "Min" tooltip-open?] - [bounties-filter-tooltip-value-input "Max" tooltip-open?]]) +(defn bounties-filter-tooltip-value [current-filter-value tooltip-open?] + (let [default-min 0 + default-max 1000 + common-range-opts {:min default-min :max default-max} + current-min (or (first current-filter-value) default-min) + current-max (or (second current-filter-value) default-max) + on-change-fn (fn [min-val max-val] + (rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|value + [(min min-val (dec default-max)) + (max max-val (inc default-min))]])) + on-min-change-fn (fn [new-min] + (let [new-max (max current-max (inc new-min))] + (on-change-fn new-min new-max))) + on-max-change-fn (fn [new-max] + (let [new-min (min current-min (dec new-max))] + (on-change-fn new-min new-max)))] + [:div + "$0 - $1000+" + [bounties-filter-tooltip-value-input "Min" tooltip-open? (merge common-range-opts + {:current-val current-min + :on-change-val on-min-change-fn})] + [bounties-filter-tooltip-value-input "Max" tooltip-open? (merge common-range-opts + {:current-val current-max + :on-change-val on-max-change-fn})]])) -(defn bounties-filter-tooltip-currency [tooltip-open?] +(defn bounties-filter-tooltip-currency [current-filter-value tooltip-open?] [:div.open-bounties-filter-list (for [t ["ETH" "SNT"]] - [:div.open-bounties-filter-list-option-checkbox - [:label - [:input - {:type "checkbox" - :on-focus #(reset! tooltip-open? true)}] - [:div.text t]]])]) + (let [active? (and current-filter-value (current-filter-value t))] + [:div.open-bounties-filter-list-option-checkbox + [:label + {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|currency + (cond + (and active? (= #{t} current-filter-value)) nil + active? (disj current-filter-value t) + :else (into #{t} current-filter-value))])} + [:input + {:type "checkbox" + :on-focus #(reset! tooltip-open? true)}] + [:div.text t]]]))]) -(defn bounties-filter-tooltip-date [] +(defn bounties-filter-tooltip-date [current-filter-value tooltip-open?] [:div.open-bounties-filter-list - (for [t ["Last week" "Last month" "Last 3 months"]] + (for [[option-type option-text] ui-model/bounty-filter-type-date-options-def] + ^{:key (str option-type)} [:div.open-bounties-filter-list-option - t])]) + (merge {:on-click #(do (rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|date + option-type]) + (reset! tooltip-open? false))} + (when (= option-type current-filter-value) + {:class "active"})) + option-text])]) -(defn bounties-filter-tooltip-owner [tooltip-open?] +(defn bounties-filter-tooltip-owner [current-filter-value tooltip-open?] [:div.open-bounties-filter-list (for [t ["status-im" "aragon"]] - [:div.open-bounties-filter-list-option-checkbox - [:label - [:input - {:type "checkbox" - :on-focus #(reset! tooltip-open? true)}] - [:div.text t]]])]) + (let [active? (and current-filter-value (current-filter-value t))] + [:div.open-bounties-filter-list-option-checkbox + [:label + {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|owner + (cond + (and active? (= #{t} current-filter-value)) nil + active? (disj current-filter-value t) + :else (into #{t} current-filter-value))])} + [:input + {:type "checkbox" + :on-focus #(reset! tooltip-open? true) + :checked (when active? "checked")}] + [:div.text t]]]))]) -(defn bounties-filter [name tooltip-content] +(defn- tooltip-view-for-filter-type [filter-type] + (condp = filter-type + ::ui-model/bounty-filter-type|value bounties-filter-tooltip-value + ::ui-model/bounty-filter-type|currency bounties-filter-tooltip-currency + ::ui-model/bounty-filter-type|date bounties-filter-tooltip-date + ::ui-model/bounty-filter-type|owner bounties-filter-tooltip-owner)) + +(defn bounty-filter-view [filter-type current-filter-value] (let [open? (r/atom false)] - (fn [name tooltip-content] + (fn [filter-type current-filter-value] [:div.open-bounties-filter-element-container {:tab-index 0 :on-focus #(reset! open? true) :on-blur #(reset! open? false)} [:div.open-bounties-filter-element {:on-mouse-down #(swap! open? not) - :class (when @open? "open-bounties-filter-element-active")} - name] + :class (when (or current-filter-value @open?) + "open-bounties-filter-element-active")} + [:div.text + (if current-filter-value + (ui-model/bounty-filter-value->short-text filter-type current-filter-value) + (ui-model/bounty-filter-type->name filter-type))] + (when current-filter-value + [:img.remove + {:src "bounty-filter-remove.svg" + :tab-index 0 + :on-focus #(.stopPropagation %) + :on-mouse-down (fn [e] + (.stopPropagation e) + (rf/dispatch [::handlers/set-open-bounty-filter-type filter-type nil]) + (reset! open? false))}])] (when @open? [bounties-filter-tooltip - [tooltip-content open?]])]))) + [(tooltip-view-for-filter-type filter-type) current-filter-value open?]])]))) -(defn bounties-filters [] - [:div.open-bounties-filter - [bounties-filter "Value" bounties-filter-tooltip-value] - [bounties-filter "Currency" bounties-filter-tooltip-currency] - [bounties-filter "Date" bounties-filter-tooltip-date] - [bounties-filter "Owner" bounties-filter-tooltip-owner]]) +(defn bounty-filters-view [] + (let [current-filters (rf/subscribe [::subs/open-bounties-filters])] + [:div.open-bounties-filter + ; doall because derefs are not supported in lazy seqs: https://github.com/reagent-project/reagent/issues/18 + (doall + (for [filter-type ui-model/bounty-filter-types] + ^{:key (str filter-type)} + [bounty-filter-view + filter-type + (get @current-filters filter-type)]))])) (defn bounties-sort [] (let [open? (r/atom false)] (fn [] - (let [current-sorting (rf/subscribe [::db/bounty-sorting-type])] + (let [current-sorting (rf/subscribe [::subs/open-bounties-sorting-type])] [:div.open-bounties-sort {:tab-index 0 :on-blur #(reset! open? false)} [:div.open-bounties-sort-element {:on-click #(swap! open? not)} - (db/bounty-sorting-types @current-sorting) + (ui-model/bounty-sorting-types-def @current-sorting) [:div.icon-forward-white-box [:img {:src "icon-forward-white.svg"}]]] (when @open? [:div.open-bounties-sort-element-tooltip - (for [[sorting-type sorting-name] db/bounty-sorting-types] + (for [[sorting-type sorting-name] ui-model/bounty-sorting-types-def] + ^{:key (str sorting-type)} [:div.open-bounties-sort-type {:on-click #(do (reset! open? false) - (rf/dispatch [::handlers/set-bounty-sorting-type sorting-type]))} + (rf/dispatch [::handlers/set-open-bounties-sorting-type sorting-type]))} sorting-name])])])))) (defn bounties-list [open-bounties] [:div.ui.container.open-bounties-container [:div.open-bounties-header "Bounties"] [:div.open-bounties-filter-and-sort - [bounties-filters] + [bounty-filters-view] [bounties-sort]] (if (empty? open-bounties) [:div.view-no-data-container diff --git a/src/cljs/commiteth/db.cljs b/src/cljs/commiteth/db.cljs index e54bcd1..39e8f11 100644 --- a/src/cljs/commiteth/db.cljs +++ b/src/cljs/commiteth/db.cljs @@ -1,19 +1,19 @@ -(ns commiteth.db) - -(def bounty-sorting-types {::bounty-sorting-type|most-recent "Most recent" - ::bounty-sorting-type|lowest-value "Lowest value" - ::bounty-sorting-type|highest-value "Highest value" - ::bounty-sorting-type|owner "Owner"}) +(ns commiteth.db + (:require [commiteth.ui-model :as ui-model])) (def default-db - {:page :bounties - :user nil - :repos-loading? false - :repos {} - :activity-feed-loading? false - :open-bounties-loading? false - :open-bounties [] - :owner-bounties {} - :top-hunters [] - :activity-feed [] - ::bounty-sorting-type ::bounty-sorting-type|most-recent}) + {:page :bounties + :user nil + :repos-loading? false + :repos {} + :activity-feed-loading? false + :open-bounties-loading? false + :open-bounties [] + ::open-bounties-sorting-type ::ui-model/bounty-sorting-type|most-recent + ::open-bounties-filters {::ui-model/bounty-filter-type|value nil + ::ui-model/bounty-filter-type|currency nil + ::ui-model/bounty-filter-type|date nil + ::ui-model/bounty-filter-type|owner nil} + :owner-bounties {} + :top-hunters [] + :activity-feed []}) diff --git a/src/cljs/commiteth/handlers.cljs b/src/cljs/commiteth/handlers.cljs index b69f1ca..ef183be 100644 --- a/src/cljs/commiteth/handlers.cljs +++ b/src/cljs/commiteth/handlers.cljs @@ -455,6 +455,11 @@ (assoc db :user-dropdown-open? false))) (reg-event-db - ::set-bounty-sorting-type + ::set-open-bounties-sorting-type (fn [db [_ sorting-type]] - (assoc db ::db/bounty-sorting-type sorting-type))) + (assoc db ::db/open-bounties-sorting-type sorting-type))) + +(reg-event-db + ::set-open-bounty-filter-type + (fn [db [_ filter-type filter-value]] + (assoc-in db [::db/open-bounties-filters filter-type] filter-value))) diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index c6d4340..f9ef6b5 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -83,6 +83,11 @@ (:user-dropdown-open? db))) (reg-sub - ::db/bounty-sorting-type + ::open-bounties-sorting-type (fn [db _] - (::db/bounty-sorting-type db))) + (::db/open-bounties-sorting-type db))) + +(reg-sub + ::open-bounties-filters + (fn [db _] + (::db/open-bounties-filters db))) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs new file mode 100644 index 0000000..e274297 --- /dev/null +++ b/src/cljs/commiteth/ui_model.cljs @@ -0,0 +1,44 @@ +(ns commiteth.ui-model) + +;;;; bounty sorting types + +(def bounty-sorting-types-def {::bounty-sorting-type|most-recent "Most recent" + ::bounty-sorting-type|lowest-value "Lowest value" + ::bounty-sorting-type|highest-value "Highest value" + ::bounty-sorting-type|owner "Owner"}) + +;;;; bounty filter types + +(def bounty-filter-types-def {::bounty-filter-type|value "Value" + ::bounty-filter-type|currency "Currency" + ::bounty-filter-type|date "Date" + ::bounty-filter-type|owner "Owner"}) + +(def bounty-filter-types (keys bounty-filter-types-def)) + +(defn bounty-filter-type->name [filter-type] + (bounty-filter-types-def filter-type)) + +(def bounty-filter-type-date-options-def {::bounty-filter-type-date-option|last-week "Last week" + ::bounty-filter-type-date-option|last-month "Last month" + ::bounty-filter-type-date-option|last-3-months "Last 3 months"}) + +(def bounty-filter-type-date-options (keys bounty-filter-type-date-options-def)) + +(defn bounty-filter-type-date-option->name [option] + (bounty-filter-type-date-options-def option)) + +(defn bounty-filter-value->short-text [filter-type filter-value] + (cond + (= filter-type ::bounty-filter-type|date) + (bounty-filter-type-date-option->name filter-value) + + (#{::bounty-filter-type|owner + ::bounty-filter-type|currency} filter-type) + (str (bounty-filter-type->name filter-type) " (" (count filter-value) ")") + + (= filter-type ::bounty-filter-type|value) + (str "$" (first filter-value) "-$" (second filter-value)) + + :else + (str filter-type " with val " filter-value))) diff --git a/src/less/style.less b/src/less/style.less index 4e4b05e..669db74 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -430,18 +430,29 @@ font-weight: 500; line-height: 1.0; color: #8d99a4; - padding: 8px 12px; + //padding: 8px 12px; border-radius: 8px; border: solid 1px rgba(151, 151, 151, 0.2); margin-right: 10px; position: relative; + display: flex; + + .text { + margin: 8px 12px; + } + + .remove { + margin-left: -6px; + margin-right: 5px; + } } .open-bounties-filter-element:hover { cursor: pointer; } - .open-bounties-filter-element-active { + .open-bounties-filter-element-active + { background-color: #57a7ed; color: #ffffff; } @@ -582,6 +593,11 @@ border: solid 1px rgba(151, 151, 151, 0.2); } + .open-bounties-filter-list-option.active { + background-color: #57a7ed; + color: #ffffff; + } + .open-bounties-filter-list-option:not(:first-child) { margin-top: 8px; } From 4563781192856026ba284f94334d06ee704c727d Mon Sep 17 00:00:00 2001 From: pablodip Date: Sat, 20 Jan 2018 10:49:07 +0100 Subject: [PATCH 07/29] take some filter options from open bounties --- src/cljs/commiteth/bounties.cljs | 64 ++++++++++++++------------- src/cljs/commiteth/subscriptions.cljs | 19 ++++++++ src/less/style.less | 1 + 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 83aa4f3..ffd3162 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -92,21 +92,22 @@ :on-change-val on-max-change-fn})]])) (defn bounties-filter-tooltip-currency [current-filter-value tooltip-open?] - [:div.open-bounties-filter-list - (for [t ["ETH" "SNT"]] - (let [active? (and current-filter-value (current-filter-value t))] - [:div.open-bounties-filter-list-option-checkbox - [:label - {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|currency - (cond - (and active? (= #{t} current-filter-value)) nil - active? (disj current-filter-value t) - :else (into #{t} current-filter-value))])} - [:input - {:type "checkbox" - :on-focus #(reset! tooltip-open? true)}] - [:div.text t]]]))]) + (let [currencies (rf/subscribe [::subs/open-bounties-currencies])] + [:div.open-bounties-filter-list + (for [currency @currencies] + (let [active? (and current-filter-value (current-filter-value currency))] + [:div.open-bounties-filter-list-option-checkbox + [:label + {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|currency + (cond + (and active? (= #{currency} current-filter-value)) nil + active? (disj current-filter-value currency) + :else (into #{currency} current-filter-value))])} + [:input + {:type "checkbox" + :on-focus #(reset! tooltip-open? true)}] + [:div.text currency]]]))])) (defn bounties-filter-tooltip-date [current-filter-value tooltip-open?] [:div.open-bounties-filter-list @@ -122,22 +123,23 @@ option-text])]) (defn bounties-filter-tooltip-owner [current-filter-value tooltip-open?] - [:div.open-bounties-filter-list - (for [t ["status-im" "aragon"]] - (let [active? (and current-filter-value (current-filter-value t))] - [:div.open-bounties-filter-list-option-checkbox - [:label - {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|owner - (cond - (and active? (= #{t} current-filter-value)) nil - active? (disj current-filter-value t) - :else (into #{t} current-filter-value))])} - [:input - {:type "checkbox" - :on-focus #(reset! tooltip-open? true) - :checked (when active? "checked")}] - [:div.text t]]]))]) + (let [owners (rf/subscribe [::subs/open-bounties-owners])] + [:div.open-bounties-filter-list + (for [owner @owners] + (let [active? (and current-filter-value (current-filter-value owner))] + [:div.open-bounties-filter-list-option-checkbox + [:label + {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|owner + (cond + (and active? (= #{owner} current-filter-value)) nil + active? (disj current-filter-value owner) + :else (into #{owner} current-filter-value))])} + [:input + {:type "checkbox" + :on-focus #(reset! tooltip-open? true) + :checked (when active? "checked")}] + [:div.text owner]]]))])) (defn- tooltip-view-for-filter-type [filter-type] (condp = filter-type diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index f9ef6b5..7ad64f9 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -91,3 +91,22 @@ ::open-bounties-filters (fn [db _] (::db/open-bounties-filters db))) + +(reg-sub + ::open-bounties-owners + :<- [:open-bounties] + (fn [open-bounties _] + (->> open-bounties + (map :repo-owner) + set))) + +(reg-sub + ::open-bounties-currencies + :<- [:open-bounties] + (fn [open-bounties _] + (let [token-ids (->> open-bounties + (map :tokens) + (map keys) + (filter identity) + set)] + (into #{"ETH"} token-ids)))) diff --git a/src/less/style.less b/src/less/style.less index 669db74..20de0c3 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -472,6 +472,7 @@ font-family: "PostGrotesk-Book"; font-size: 16px; line-height: 1.5; + z-index: 999; .open-bounties-filter-element-tooltip-value-input-container { display: flex; From d470b3aea34cf3e53d8c90512fccbf1b67a8a339 Mon Sep 17 00:00:00 2001 From: pablodip Date: Sun, 21 Jan 2018 08:06:09 +0100 Subject: [PATCH 08/29] zindex --- src/less/style.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/less/style.less b/src/less/style.less index 20de0c3..7ef8658 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -675,6 +675,7 @@ line-height: 1.0; text-align: left; color: #ffffff; + z-index: 999; } .open-bounties-sort-type { From 09cd84a89b527809a78f1938bbd6796c06be5109 Mon Sep 17 00:00:00 2001 From: pablodip Date: Sun, 21 Jan 2018 10:27:32 +0100 Subject: [PATCH 09/29] sorting behaviour --- src/clj/commiteth/routes/services.clj | 3 ++- src/cljs/commiteth/bounties.cljs | 8 +++---- src/cljs/commiteth/subscriptions.cljs | 31 +++++++++++++++++-------- src/cljs/commiteth/ui_model.cljs | 33 +++++++++++++++++++++++---- 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/clj/commiteth/routes/services.clj b/src/clj/commiteth/routes/services.clj index 82c5633..6a60fec 100644 --- a/src/clj/commiteth/routes/services.clj +++ b/src/clj/commiteth/routes/services.clj @@ -155,7 +155,8 @@ :value_usd :value-usd :claim_count :claim-count :balance_eth :balance-eth - :user_has_address :user-has-address}] + :user_has_address :user-has-address + :created_at :created-at}] (map #(-> % (rename-keys renames) (update :value-usd usd-decimal->str) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index ffd3162..5169598 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -196,19 +196,19 @@ :on-blur #(reset! open? false)} [:div.open-bounties-sort-element {:on-click #(swap! open? not)} - (ui-model/bounty-sorting-types-def @current-sorting) + (ui-model/bounty-sorting-type->name @current-sorting) [:div.icon-forward-white-box [:img {:src "icon-forward-white.svg"}]]] (when @open? [:div.open-bounties-sort-element-tooltip - (for [[sorting-type sorting-name] ui-model/bounty-sorting-types-def] + (for [sorting-type (keys ui-model/bounty-sorting-types-def)] ^{:key (str sorting-type)} [:div.open-bounties-sort-type {:on-click #(do (reset! open? false) (rf/dispatch [::handlers/set-open-bounties-sorting-type sorting-type]))} - sorting-name])])])))) + (ui-model/bounty-sorting-type->name sorting-type)])])])))) (defn bounties-list [open-bounties] [:div.ui.container.open-bounties-container @@ -225,7 +225,7 @@ (defn bounties-page [] - (let [open-bounties (rf/subscribe [:open-bounties]) + (let [open-bounties (rf/subscribe [::subs/filtered-and-sorted-open-bounties]) open-bounties-loading? (rf/subscribe [:get-in [:open-bounties-loading?]])] (fn [] (if @open-bounties-loading? diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index 7ad64f9..d91f770 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -1,10 +1,11 @@ (ns commiteth.subscriptions (:require [re-frame.core :refer [reg-sub]] - [commiteth.db :as db])) + [commiteth.db :as db] + [commiteth.ui-model :as ui-model])) (reg-sub - :db - (fn [db _] db)) + :db + (fn [db _] db)) (reg-sub :page @@ -68,17 +69,17 @@ (get-in db path))) (reg-sub - :usage-metrics - (fn [db _] - (:usage-metrics db))) + :usage-metrics + (fn [db _] + (:usage-metrics db))) (reg-sub - :metrics-loading? - (fn [db _] - (:metrics-loading? db))) + :metrics-loading? + (fn [db _] + (:metrics-loading? db))) (reg-sub - :user-dropdown-open? + :user-dropdown-open? (fn [db _] (:user-dropdown-open? db))) @@ -110,3 +111,13 @@ (filter identity) set)] (into #{"ETH"} token-ids)))) + +(reg-sub + ::filtered-and-sorted-open-bounties + :<- [:open-bounties] + :<- [::open-bounties-sorting-type] + (fn [[open-bounties sorting-type] _] + (println "RAW" open-bounties) + (cond->> open-bounties + sorting-type (ui-model/sort-bounties-by-sorting-type sorting-type) + ))) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index e274297..39dc764 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -2,10 +2,35 @@ ;;;; bounty sorting types -(def bounty-sorting-types-def {::bounty-sorting-type|most-recent "Most recent" - ::bounty-sorting-type|lowest-value "Lowest value" - ::bounty-sorting-type|highest-value "Highest value" - ::bounty-sorting-type|owner "Owner"}) +(def bounty-sorting-types-def + {::bounty-sorting-type|most-recent {::bounty-sorting-type.name "Most recent" + ::bounty-sorting-type.sort-key-fn (fn [bounty] + (:created-at bounty)) + ::bounty-sorting-type.sort-comparator-fn compare} + ::bounty-sorting-type|lowest-value {::bounty-sorting-type.name "Lowest value" + ::bounty-sorting-type.sort-key-fn (fn [bounty] + (:value-usd bounty)) + ::bounty-sorting-type.sort-comparator-fn compare} + ::bounty-sorting-type|highest-value {::bounty-sorting-type.name "Highest value" + ::bounty-sorting-type.sort-key-fn (fn [bounty] + (:value-usd bounty)) + ::bounty-sorting-type.sort-comparator-fn (comp - compare)} + ::bounty-sorting-type|owner {::bounty-sorting-type.name "Owner" + ::bounty-sorting-type.sort-key-fn (fn [bounty] + (:repo-owner bounty)) + ::bounty-sorting-type.sort-comparator-fn compare}}) + +(defn bounty-sorting-type->name [sorting-type] + (-> bounty-sorting-types-def (get sorting-type) ::bounty-sorting-type.name)) + +(defn sort-bounties-by-sorting-type [sorting-type bounties] + (let [keyfn (-> bounty-sorting-types-def + sorting-type + ::bounty-sorting-type.sort-key-fn) + comparator (-> bounty-sorting-types-def + sorting-type + ::bounty-sorting-type.sort-comparator-fn)] + (sort-by keyfn comparator bounties))) ;;;; bounty filter types From d937bf361daff7bc534ab6c69c9cab2643f5eb43 Mon Sep 17 00:00:00 2001 From: pablodip Date: Mon, 22 Jan 2018 12:21:04 +0100 Subject: [PATCH 10/29] fix ui checkbox checked and start filtering --- src/cljs/commiteth/bounties.cljs | 11 ++++--- src/cljs/commiteth/subscriptions.cljs | 10 +++---- src/cljs/commiteth/ui_model.cljs | 42 +++++++++++++++++++++------ 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 5169598..cfb5f57 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -95,7 +95,8 @@ (let [currencies (rf/subscribe [::subs/open-bounties-currencies])] [:div.open-bounties-filter-list (for [currency @currencies] - (let [active? (and current-filter-value (current-filter-value currency))] + (let [active? (boolean (and current-filter-value (current-filter-value currency)))] + ^{:key (str currency)} [:div.open-bounties-filter-list-option-checkbox [:label {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type @@ -106,6 +107,7 @@ :else (into #{currency} current-filter-value))])} [:input {:type "checkbox" + :checked active? :on-focus #(reset! tooltip-open? true)}] [:div.text currency]]]))])) @@ -126,7 +128,8 @@ (let [owners (rf/subscribe [::subs/open-bounties-owners])] [:div.open-bounties-filter-list (for [owner @owners] - (let [active? (and current-filter-value (current-filter-value owner))] + (let [active? (boolean (and current-filter-value (current-filter-value owner)))] + ^{:key (str owner)} [:div.open-bounties-filter-list-option-checkbox [:label {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type @@ -137,8 +140,8 @@ :else (into #{owner} current-filter-value))])} [:input {:type "checkbox" - :on-focus #(reset! tooltip-open? true) - :checked (when active? "checked")}] + :checked active? + :on-focus #(reset! tooltip-open? true)}] [:div.text owner]]]))])) (defn- tooltip-view-for-filter-type [filter-type] diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index d91f770..eadb318 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -107,7 +107,7 @@ (fn [open-bounties _] (let [token-ids (->> open-bounties (map :tokens) - (map keys) + (mapcat keys) (filter identity) set)] (into #{"ETH"} token-ids)))) @@ -115,9 +115,9 @@ (reg-sub ::filtered-and-sorted-open-bounties :<- [:open-bounties] + :<- [::open-bounties-filters] :<- [::open-bounties-sorting-type] - (fn [[open-bounties sorting-type] _] - (println "RAW" open-bounties) + (fn [[open-bounties filters sorting-type] _] (cond->> open-bounties - sorting-type (ui-model/sort-bounties-by-sorting-type sorting-type) - ))) + filters (ui-model/filter-bounties filters) + sorting-type (ui-model/sort-bounties-by-sorting-type sorting-type)))) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index 39dc764..75f1c6f 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -1,4 +1,5 @@ -(ns commiteth.ui-model) +(ns commiteth.ui-model + (:require [clojure.set :as set])) ;;;; bounty sorting types @@ -24,9 +25,9 @@ (-> bounty-sorting-types-def (get sorting-type) ::bounty-sorting-type.name)) (defn sort-bounties-by-sorting-type [sorting-type bounties] - (let [keyfn (-> bounty-sorting-types-def - sorting-type - ::bounty-sorting-type.sort-key-fn) + (let [keyfn (-> bounty-sorting-types-def + sorting-type + ::bounty-sorting-type.sort-key-fn) comparator (-> bounty-sorting-types-def sorting-type ::bounty-sorting-type.sort-comparator-fn)] @@ -34,15 +35,27 @@ ;;;; bounty filter types -(def bounty-filter-types-def {::bounty-filter-type|value "Value" - ::bounty-filter-type|currency "Currency" - ::bounty-filter-type|date "Date" - ::bounty-filter-type|owner "Owner"}) +(def bounty-filter-types-def + {::bounty-filter-type|value {::bounty-filter-type.name "Value" + ::bounty-filter-type.predicate (fn [filter-value bounty] + true)} + ::bounty-filter-type|currency {::bounty-filter-type.name "Currency" + ::bounty-filter-type.predicate (fn [filter-value bounty] + (and (or (not-any? #{"ETH"} filter-value) + (< 0 (:balance-eth bounty))) + (set/subset? (->> filter-value (remove #{"ETH"}) set) + (-> bounty :tokens keys set))))} + ::bounty-filter-type|date {::bounty-filter-type.name "Date" + ::bounty-filter-type.predicate (fn [filter-value bounty] + true)} + ::bounty-filter-type|owner {::bounty-filter-type.name "Owner" + ::bounty-filter-type.predicate (fn [filter-value bounty] + true)}}) (def bounty-filter-types (keys bounty-filter-types-def)) (defn bounty-filter-type->name [filter-type] - (bounty-filter-types-def filter-type)) + (-> bounty-filter-types-def (get filter-type) ::bounty-filter-type.name)) (def bounty-filter-type-date-options-def {::bounty-filter-type-date-option|last-week "Last week" ::bounty-filter-type-date-option|last-month "Last month" @@ -67,3 +80,14 @@ :else (str filter-type " with val " filter-value))) + +(defn filter-bounties [filters-by-type bounties] + (let [filter-preds (->> filters-by-type + (remove #(nil? (val %))) + (map (fn [[filter-type filter-value]] + (let [pred (-> bounty-filter-types-def (get filter-type) ::bounty-filter-type.predicate)] + (partial pred filter-value))))) + filters-pred (fn [bounty] + (every? #(% bounty) filter-preds))] + (->> bounties + (filter filters-pred)))) From 12edb1abc60226b05beb8030d0a7ac2436c2ebd0 Mon Sep 17 00:00:00 2001 From: pablodip Date: Tue, 23 Jan 2018 17:48:45 +0100 Subject: [PATCH 11/29] some fixes and behaviours of sort and filter --- src/cljs/commiteth/bounties.cljs | 8 ++++---- src/cljs/commiteth/ui_model.cljs | 26 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index cfb5f57..b4bb03c 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -74,13 +74,13 @@ on-change-fn (fn [min-val max-val] (rf/dispatch [::handlers/set-open-bounty-filter-type ::ui-model/bounty-filter-type|value - [(min min-val (dec default-max)) - (max max-val (inc default-min))]])) + [(min min-val default-max) + (max max-val default-min)]])) on-min-change-fn (fn [new-min] - (let [new-max (max current-max (inc new-min))] + (let [new-max (max current-max (min default-max new-min))] (on-change-fn new-min new-max))) on-max-change-fn (fn [new-max] - (let [new-min (min current-min (dec new-max))] + (let [new-min (min current-min (max default-min new-max))] (on-change-fn new-min new-max)))] [:div "$0 - $1000+" diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index 75f1c6f..75e9c3c 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -1,5 +1,8 @@ (ns commiteth.ui-model - (:require [clojure.set :as set])) + (:require [clojure.set :as set] + [cljs-time.core :as t] + [cljs-time.coerce :as t-coerce] + [cljs-time.format :as t-format])) ;;;; bounty sorting types @@ -10,11 +13,11 @@ ::bounty-sorting-type.sort-comparator-fn compare} ::bounty-sorting-type|lowest-value {::bounty-sorting-type.name "Lowest value" ::bounty-sorting-type.sort-key-fn (fn [bounty] - (:value-usd bounty)) + (js/parseFloat (:value-usd bounty))) ::bounty-sorting-type.sort-comparator-fn compare} ::bounty-sorting-type|highest-value {::bounty-sorting-type.name "Highest value" ::bounty-sorting-type.sort-key-fn (fn [bounty] - (:value-usd bounty)) + (js/parseFloat (:value-usd bounty))) ::bounty-sorting-type.sort-comparator-fn (comp - compare)} ::bounty-sorting-type|owner {::bounty-sorting-type.name "Owner" ::bounty-sorting-type.sort-key-fn (fn [bounty] @@ -38,7 +41,9 @@ (def bounty-filter-types-def {::bounty-filter-type|value {::bounty-filter-type.name "Value" ::bounty-filter-type.predicate (fn [filter-value bounty] - true)} + (let [min-val (first filter-value) + max-val (second filter-value)] + (<= min-val (:value-usd bounty) max-val)))} ::bounty-filter-type|currency {::bounty-filter-type.name "Currency" ::bounty-filter-type.predicate (fn [filter-value bounty] (and (or (not-any? #{"ETH"} filter-value) @@ -47,10 +52,19 @@ (-> bounty :tokens keys set))))} ::bounty-filter-type|date {::bounty-filter-type.name "Date" ::bounty-filter-type.predicate (fn [filter-value bounty] - true)} + (when-let [created-at-inst (:created-at bounty)] + (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long) + filter-from (condp = filter-value + ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) + ::bounty-filter-type-date-option|last-month (t/minus (t/now) (t/months 1)) + ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3))) + interval (t/interval filter-from (t/now))] + (t/within? interval created-at-date))))} ::bounty-filter-type|owner {::bounty-filter-type.name "Owner" ::bounty-filter-type.predicate (fn [filter-value bounty] - true)}}) + (->> filter-value + (some #{(:repo-owner bounty)}) + boolean))}}) (def bounty-filter-types (keys bounty-filter-types-def)) From 27442937cf94f4a50825264978ff5e89b013da6a Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 24 Jan 2018 09:46:51 +0100 Subject: [PATCH 12/29] fix firefox behaviour when removing filters and with checkbox filters --- src/cljs/commiteth/bounties.cljs | 38 ++++++++++++++++++-------------- src/less/style.less | 8 +++++++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index b4bb03c..c07576d 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -99,12 +99,15 @@ ^{:key (str currency)} [:div.open-bounties-filter-list-option-checkbox [:label - {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|currency - (cond - (and active? (= #{currency} current-filter-value)) nil - active? (disj current-filter-value currency) - :else (into #{currency} current-filter-value))])} + {:on-click #(do (println "label on-click") + (rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|currency + (cond + (and active? (= #{currency} current-filter-value)) nil + active? (disj current-filter-value currency) + :else (into #{currency} current-filter-value))])) + :tab-index 0 + :on-focus #(do (.stopPropagation %) (reset! tooltip-open? true))} [:input {:type "checkbox" :checked active? @@ -137,7 +140,9 @@ (cond (and active? (= #{owner} current-filter-value)) nil active? (disj current-filter-value owner) - :else (into #{owner} current-filter-value))])} + :else (into #{owner} current-filter-value))]) + :tab-index 0 + :on-focus #(do (.stopPropagation %) (reset! tooltip-open? true))} [:input {:type "checkbox" :checked active? @@ -159,7 +164,7 @@ :on-focus #(reset! open? true) :on-blur #(reset! open? false)} [:div.open-bounties-filter-element - {:on-mouse-down #(swap! open? not) + {:on-mouse-down #(do (println "element on-mouse-down") (swap! open? not)) :class (when (or current-filter-value @open?) "open-bounties-filter-element-active")} [:div.text @@ -167,14 +172,15 @@ (ui-model/bounty-filter-value->short-text filter-type current-filter-value) (ui-model/bounty-filter-type->name filter-type))] (when current-filter-value - [:img.remove - {:src "bounty-filter-remove.svg" - :tab-index 0 - :on-focus #(.stopPropagation %) - :on-mouse-down (fn [e] - (.stopPropagation e) - (rf/dispatch [::handlers/set-open-bounty-filter-type filter-type nil]) - (reset! open? false))}])] + [:div.remove-container + {:tab-index 0 + :on-focus #(.stopPropagation %)} + [:img.remove + {:src "bounty-filter-remove.svg" + :on-mouse-down (fn [e] + (.stopPropagation e) + (rf/dispatch [::handlers/set-open-bounty-filter-type filter-type nil]) + (reset! open? false))}]])] (when @open? [bounties-filter-tooltip [(tooltip-view-for-filter-type filter-type) current-filter-value open?]])]))) diff --git a/src/less/style.less b/src/less/style.less index 7ef8658..68ed6f5 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -441,6 +441,10 @@ margin: 8px 12px; } + .remove-container { + display: flex; + } + .remove { margin-left: -6px; margin-right: 5px; @@ -618,6 +622,10 @@ cursor: pointer; } + label:focus { + outline: none; + } + input { background: green; transform: scale(1.3); From 561232d6e2b90431f1088a8fd4d4ce882e1aa2ba Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 24 Jan 2018 09:49:21 +0100 Subject: [PATCH 13/29] remove printlns and fix chrome remove filter style --- src/cljs/commiteth/bounties.cljs | 15 +++++++-------- src/less/style.less | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index c07576d..a701762 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -99,13 +99,12 @@ ^{:key (str currency)} [:div.open-bounties-filter-list-option-checkbox [:label - {:on-click #(do (println "label on-click") - (rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|currency - (cond - (and active? (= #{currency} current-filter-value)) nil - active? (disj current-filter-value currency) - :else (into #{currency} current-filter-value))])) + {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type + ::ui-model/bounty-filter-type|currency + (cond + (and active? (= #{currency} current-filter-value)) nil + active? (disj current-filter-value currency) + :else (into #{currency} current-filter-value))]) :tab-index 0 :on-focus #(do (.stopPropagation %) (reset! tooltip-open? true))} [:input @@ -164,7 +163,7 @@ :on-focus #(reset! open? true) :on-blur #(reset! open? false)} [:div.open-bounties-filter-element - {:on-mouse-down #(do (println "element on-mouse-down") (swap! open? not)) + {:on-mouse-down #(swap! open? not) :class (when (or current-filter-value @open?) "open-bounties-filter-element-active")} [:div.text diff --git a/src/less/style.less b/src/less/style.less index 68ed6f5..5977c85 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -616,6 +616,7 @@ .open-bounties-filter-list-option-checkbox { label { display: flex; + align-items: baseline; } label:hover { From fdec3ad56bc4430d7dbc62f8a28314f9ecff930e Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 08:28:48 +0100 Subject: [PATCH 14/29] abstracting filter type category --- src/cljs/commiteth/bounties.cljs | 103 +++++++++++++------------------ src/cljs/commiteth/ui_model.cljs | 43 ++++++++----- 2 files changed, 70 insertions(+), 76 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index a701762..b034495 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -47,10 +47,6 @@ [:div.ui.tiny.circular.image [:img {:src avatar-url}]]]])) -(defn bounties-filter-tooltip [content] - [:div.open-bounties-filter-element-tooltip - content]) - (defn bounties-filter-tooltip-value-input [label tooltip-open? opts] [:div.open-bounties-filter-element-tooltip-value-input-container [:div.:input.open-bounties-filter-element-tooltip-value-input-label @@ -65,15 +61,15 @@ #(-> % .-target .-value int f)) :on-focus #(reset! tooltip-open? true)}]]) -(defn bounties-filter-tooltip-value [current-filter-value tooltip-open?] - (let [default-min 0 - default-max 1000 +(defn bounties-filter-tooltip-category-range [filter-type filter-type-def current-filter-value tooltip-open?] + (let [default-min (::ui-model/bounty-filter-type.min-val filter-type-def) + default-max (::ui-model/bounty-filter-type.max-val filter-type-def) common-range-opts {:min default-min :max default-max} current-min (or (first current-filter-value) default-min) current-max (or (second current-filter-value) default-max) on-change-fn (fn [min-val max-val] (rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|value + filter-type [(min min-val default-max) (max max-val default-min)]])) on-min-change-fn (fn [new-min] @@ -91,80 +87,66 @@ {:current-val current-max :on-change-val on-max-change-fn})]])) -(defn bounties-filter-tooltip-currency [current-filter-value tooltip-open?] - (let [currencies (rf/subscribe [::subs/open-bounties-currencies])] - [:div.open-bounties-filter-list - (for [currency @currencies] - (let [active? (boolean (and current-filter-value (current-filter-value currency)))] - ^{:key (str currency)} - [:div.open-bounties-filter-list-option-checkbox - [:label - {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|currency - (cond - (and active? (= #{currency} current-filter-value)) nil - active? (disj current-filter-value currency) - :else (into #{currency} current-filter-value))]) - :tab-index 0 - :on-focus #(do (.stopPropagation %) (reset! tooltip-open? true))} - [:input - {:type "checkbox" - :checked active? - :on-focus #(reset! tooltip-open? true)}] - [:div.text currency]]]))])) - -(defn bounties-filter-tooltip-date [current-filter-value tooltip-open?] +(defn bounties-filter-tooltip-category-single-static-option + [filter-type filter-type-def current-filter-value tooltip-open?] [:div.open-bounties-filter-list - (for [[option-type option-text] ui-model/bounty-filter-type-date-options-def] + (for [[option-type option-text] (::ui-model/bounty-filter-type.options filter-type-def)] ^{:key (str option-type)} [:div.open-bounties-filter-list-option (merge {:on-click #(do (rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|date + filter-type option-type]) (reset! tooltip-open? false))} (when (= option-type current-filter-value) {:class "active"})) option-text])]) -(defn bounties-filter-tooltip-owner [current-filter-value tooltip-open?] - (let [owners (rf/subscribe [::subs/open-bounties-owners])] +(defn bounties-filter-tooltip-category-multiple-dynamic-options + [filter-type filter-type-def current-filter-value tooltip-open?] + (let [options (rf/subscribe [(::ui-model/bounty-filter-type.re-frame-subscription-key-for-options filter-type-def)])] [:div.open-bounties-filter-list - (for [owner @owners] - (let [active? (boolean (and current-filter-value (current-filter-value owner)))] - ^{:key (str owner)} + (for [option @options] + (let [active? (boolean (and current-filter-value (current-filter-value option)))] + ^{:key (str option)} [:div.open-bounties-filter-list-option-checkbox [:label - {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type - ::ui-model/bounty-filter-type|owner - (cond - (and active? (= #{owner} current-filter-value)) nil - active? (disj current-filter-value owner) - :else (into #{owner} current-filter-value))]) + {:on-click #(rf/dispatch [::handlers/set-open-bounty-filter-type + filter-type + (cond + (and active? (= #{option} current-filter-value)) nil + active? (disj current-filter-value option) + :else (into #{option} current-filter-value))]) :tab-index 0 :on-focus #(do (.stopPropagation %) (reset! tooltip-open? true))} [:input {:type "checkbox" :checked active? :on-focus #(reset! tooltip-open? true)}] - [:div.text owner]]]))])) + [:div.text option]]]))])) -(defn- tooltip-view-for-filter-type [filter-type] - (condp = filter-type - ::ui-model/bounty-filter-type|value bounties-filter-tooltip-value - ::ui-model/bounty-filter-type|currency bounties-filter-tooltip-currency - ::ui-model/bounty-filter-type|date bounties-filter-tooltip-date - ::ui-model/bounty-filter-type|owner bounties-filter-tooltip-owner)) +(defn bounties-filter-tooltip [filter-type filter-type-def current-filter-val tooltip-open?] + [:div.open-bounties-filter-element-tooltip + (let [compo (condp = (::ui-model/bounty-filter-type.category filter-type-def) + ::ui-model/bounty-filter-type-category|single-static-option + bounties-filter-tooltip-category-single-static-option + + ::ui-model/bounty-filter-type-category|multiple-dynamic-options + bounties-filter-tooltip-category-multiple-dynamic-options + + ::ui-model/bounty-filter-type-category|range + bounties-filter-tooltip-category-range)] + (compo filter-type filter-type-def current-filter-val tooltip-open?))]) (defn bounty-filter-view [filter-type current-filter-value] - (let [open? (r/atom false)] + (let [tooltip-open? (r/atom false)] (fn [filter-type current-filter-value] [:div.open-bounties-filter-element-container {:tab-index 0 - :on-focus #(reset! open? true) - :on-blur #(reset! open? false)} + :on-focus #(reset! tooltip-open? true) + :on-blur #(reset! tooltip-open? false)} [:div.open-bounties-filter-element - {:on-mouse-down #(swap! open? not) - :class (when (or current-filter-value @open?) + {:on-mouse-down #(swap! tooltip-open? not) + :class (when (or current-filter-value @tooltip-open?) "open-bounties-filter-element-active")} [:div.text (if current-filter-value @@ -179,10 +161,13 @@ :on-mouse-down (fn [e] (.stopPropagation e) (rf/dispatch [::handlers/set-open-bounty-filter-type filter-type nil]) - (reset! open? false))}]])] - (when @open? + (reset! tooltip-open? false))}]])] + (when @tooltip-open? [bounties-filter-tooltip - [(tooltip-view-for-filter-type filter-type) current-filter-value open?]])]))) + filter-type + (ui-model/bounty-filter-types-def filter-type) + current-filter-value + tooltip-open?])]))) (defn bounty-filters-view [] (let [current-filters (rf/subscribe [::subs/open-bounties-filters])] diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index 75e9c3c..e85e925 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -38,19 +38,32 @@ ;;;; bounty filter types +(def bounty-filter-type-date-options-def {::bounty-filter-type-date-option|last-week "Last week" + ::bounty-filter-type-date-option|last-month "Last month" + ::bounty-filter-type-date-option|last-3-months "Last 3 months"}) + +(def bounty-filter-type-date-options (keys bounty-filter-type-date-options-def)) + (def bounty-filter-types-def {::bounty-filter-type|value {::bounty-filter-type.name "Value" + ::bounty-filter-type.category ::bounty-filter-type-category|range + ::bounty-filter-type.min-val 0 + ::bounty-filter-type.max-val 1000 ::bounty-filter-type.predicate (fn [filter-value bounty] (let [min-val (first filter-value) max-val (second filter-value)] (<= min-val (:value-usd bounty) max-val)))} - ::bounty-filter-type|currency {::bounty-filter-type.name "Currency" - ::bounty-filter-type.predicate (fn [filter-value bounty] - (and (or (not-any? #{"ETH"} filter-value) - (< 0 (:balance-eth bounty))) - (set/subset? (->> filter-value (remove #{"ETH"}) set) - (-> bounty :tokens keys set))))} + ::bounty-filter-type|currency {::bounty-filter-type.name "Currency" + ::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options + ::bounty-filter-type.re-frame-subscription-key-for-options :commiteth.subscriptions/open-bounties-currencies + ::bounty-filter-type.predicate (fn [filter-value bounty] + (and (or (not-any? #{"ETH"} filter-value) + (< 0 (:balance-eth bounty))) + (set/subset? (->> filter-value (remove #{"ETH"}) set) + (-> bounty :tokens keys set))))} ::bounty-filter-type|date {::bounty-filter-type.name "Date" + ::bounty-filter-type.category ::bounty-filter-type-category|single-static-option + ::bounty-filter-type.options bounty-filter-type-date-options-def ::bounty-filter-type.predicate (fn [filter-value bounty] (when-let [created-at-inst (:created-at bounty)] (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long) @@ -60,23 +73,19 @@ ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3))) interval (t/interval filter-from (t/now))] (t/within? interval created-at-date))))} - ::bounty-filter-type|owner {::bounty-filter-type.name "Owner" - ::bounty-filter-type.predicate (fn [filter-value bounty] - (->> filter-value - (some #{(:repo-owner bounty)}) - boolean))}}) + ::bounty-filter-type|owner {::bounty-filter-type.name "Owner" + ::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options + ::bounty-filter-type.re-frame-subscription-key-for-options :commiteth.subscriptions/open-bounties-owners + ::bounty-filter-type.predicate (fn [filter-value bounty] + (->> filter-value + (some #{(:repo-owner bounty)}) + boolean))}}) (def bounty-filter-types (keys bounty-filter-types-def)) (defn bounty-filter-type->name [filter-type] (-> bounty-filter-types-def (get filter-type) ::bounty-filter-type.name)) -(def bounty-filter-type-date-options-def {::bounty-filter-type-date-option|last-week "Last week" - ::bounty-filter-type-date-option|last-month "Last month" - ::bounty-filter-type-date-option|last-3-months "Last 3 months"}) - -(def bounty-filter-type-date-options (keys bounty-filter-type-date-options-def)) - (defn bounty-filter-type-date-option->name [option] (bounty-filter-type-date-options-def option)) From 834f82609221420296bb98e206b057250c6fae4c Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 08:33:18 +0100 Subject: [PATCH 15/29] disable filter and sort in mobile for now --- src/less/style.less | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/less/style.less b/src/less/style.less index 5977c85..18d9c5b 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -420,6 +420,12 @@ justify-content: space-between; } + @media (max-width: 767px) { + .open-bounties-filter-and-sort { + display: none; + } + } + .open-bounties-filter { display: flex; } From 4bb81f976bf07d70bf0b8b9229be6407ea631d77 Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 09:33:05 +0100 Subject: [PATCH 16/29] pre-predicate-value-processor --- src/cljs/commiteth/ui_model.cljs | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index e85e925..fa25f0c 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -61,18 +61,19 @@ (< 0 (:balance-eth bounty))) (set/subset? (->> filter-value (remove #{"ETH"}) set) (-> bounty :tokens keys set))))} - ::bounty-filter-type|date {::bounty-filter-type.name "Date" - ::bounty-filter-type.category ::bounty-filter-type-category|single-static-option - ::bounty-filter-type.options bounty-filter-type-date-options-def - ::bounty-filter-type.predicate (fn [filter-value bounty] - (when-let [created-at-inst (:created-at bounty)] - (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long) - filter-from (condp = filter-value - ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) - ::bounty-filter-type-date-option|last-month (t/minus (t/now) (t/months 1)) - ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3))) - interval (t/interval filter-from (t/now))] - (t/within? interval created-at-date))))} + ::bounty-filter-type|date {::bounty-filter-type.name "Date" + ::bounty-filter-type.category ::bounty-filter-type-category|single-static-option + ::bounty-filter-type.options bounty-filter-type-date-options-def + ::bounty-filter-type.pre-predicate-value-processor (fn [filter-value] + (let [filter-from (condp = filter-value + ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) + ::bounty-filter-type-date-option|last-month (t/minus (t/now) (t/months 1)) + ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3)))] + (t/interval filter-from (t/now)))) + ::bounty-filter-type.predicate (fn [filter-value-interval bounty] + (when-let [created-at-inst (:created-at bounty)] + (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long)] + (t/within? filter-value-interval created-at-date))))} ::bounty-filter-type|owner {::bounty-filter-type.name "Owner" ::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options ::bounty-filter-type.re-frame-subscription-key-for-options :commiteth.subscriptions/open-bounties-owners @@ -108,7 +109,11 @@ (let [filter-preds (->> filters-by-type (remove #(nil? (val %))) (map (fn [[filter-type filter-value]] - (let [pred (-> bounty-filter-types-def (get filter-type) ::bounty-filter-type.predicate)] + (let [filter-type-def (bounty-filter-types-def filter-type) + pred (::bounty-filter-type.predicate filter-type-def) + pre-pred-processor (::bounty-filter-type.pre-predicate-value-processor filter-type-def) + filter-value (cond-> filter-value + pre-pred-processor (pre-pred-processor filter-value))] (partial pred filter-value))))) filters-pred (fn [bounty] (every? #(% bounty) filter-preds))] From b3b3e47acda14f8cea14a5cb45eb630d3b14ace0 Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 09:48:12 +0100 Subject: [PATCH 17/29] change no open bounties message --- src/cljs/commiteth/bounties.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index b034495..b79960b 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -211,7 +211,7 @@ [bounties-sort]] (if (empty? open-bounties) [:div.view-no-data-container - [:p "No recent activity yet"]] + [:p "No matching bounties found."]] (into [:div.ui.items] (for [bounty open-bounties] [bounty-item bounty])))]) From cc1cedbbbd85c88c596b6515e5101e7ed3a97ca8 Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 10:06:53 +0100 Subject: [PATCH 18/29] set bounty page 1 when filters or sorting change --- src/cljs/commiteth/handlers.cljs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cljs/commiteth/handlers.cljs b/src/cljs/commiteth/handlers.cljs index 1345ade..4367c9a 100644 --- a/src/cljs/commiteth/handlers.cljs +++ b/src/cljs/commiteth/handlers.cljs @@ -467,9 +467,12 @@ (reg-event-db ::set-open-bounties-sorting-type (fn [db [_ sorting-type]] - (assoc db ::db/open-bounties-sorting-type sorting-type))) + (merge db {::db/open-bounties-sorting-type sorting-type + :bounty-page-number 1}))) (reg-event-db ::set-open-bounty-filter-type (fn [db [_ filter-type filter-value]] - (assoc-in db [::db/open-bounties-filters filter-type] filter-value))) + (-> db + (assoc-in [::db/open-bounties-filters filter-type] filter-value) + (assoc :bounty-page-number 1)))) From fc994102e85203dff573ddea17864e1df37cf8c5 Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 10:08:36 +0100 Subject: [PATCH 19/29] add -view suffix and remove old code --- src/cljs/commiteth/bounties.cljs | 67 +++++++------------------------- 1 file changed, 13 insertions(+), 54 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 7d50292..27e9e9e 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -63,7 +63,7 @@ #(-> % .-target .-value int f)) :on-focus #(reset! tooltip-open? true)}]]) -(defn bounties-filter-tooltip-category-range [filter-type filter-type-def current-filter-value tooltip-open?] +(defn bounties-filter-tooltip-category-range-view [filter-type filter-type-def current-filter-value tooltip-open?] (let [default-min (::ui-model/bounty-filter-type.min-val filter-type-def) default-max (::ui-model/bounty-filter-type.max-val filter-type-def) common-range-opts {:min default-min :max default-max} @@ -89,7 +89,7 @@ {:current-val current-max :on-change-val on-max-change-fn})]])) -(defn bounties-filter-tooltip-category-single-static-option +(defn bounties-filter-tooltip-category-single-static-option-view [filter-type filter-type-def current-filter-value tooltip-open?] [:div.open-bounties-filter-list (for [[option-type option-text] (::ui-model/bounty-filter-type.options filter-type-def)] @@ -103,7 +103,7 @@ {:class "active"})) option-text])]) -(defn bounties-filter-tooltip-category-multiple-dynamic-options +(defn bounties-filter-tooltip-category-multiple-dynamic-options-view [filter-type filter-type-def current-filter-value tooltip-open?] (let [options (rf/subscribe [(::ui-model/bounty-filter-type.re-frame-subscription-key-for-options filter-type-def)])] [:div.open-bounties-filter-list @@ -126,17 +126,17 @@ :on-focus #(reset! tooltip-open? true)}] [:div.text option]]]))])) -(defn bounties-filter-tooltip [filter-type filter-type-def current-filter-val tooltip-open?] +(defn bounties-filter-tooltip-view [filter-type filter-type-def current-filter-val tooltip-open?] [:div.open-bounties-filter-element-tooltip (let [compo (condp = (::ui-model/bounty-filter-type.category filter-type-def) ::ui-model/bounty-filter-type-category|single-static-option - bounties-filter-tooltip-category-single-static-option + bounties-filter-tooltip-category-single-static-option-view ::ui-model/bounty-filter-type-category|multiple-dynamic-options - bounties-filter-tooltip-category-multiple-dynamic-options + bounties-filter-tooltip-category-multiple-dynamic-options-view ::ui-model/bounty-filter-type-category|range - bounties-filter-tooltip-category-range)] + bounties-filter-tooltip-category-range-view)] (compo filter-type filter-type-def current-filter-val tooltip-open?))]) (defn bounty-filter-view [filter-type current-filter-value] @@ -165,7 +165,7 @@ (rf/dispatch [::handlers/set-open-bounty-filter-type filter-type nil]) (reset! tooltip-open? false))}]])] (when @tooltip-open? - [bounties-filter-tooltip + [bounties-filter-tooltip-view filter-type (ui-model/bounty-filter-types-def filter-type) current-filter-value @@ -182,7 +182,7 @@ filter-type (get @current-filters filter-type)]))])) -(defn bounties-sort [] +(defn bounties-sort-view [] (let [open? (r/atom false)] (fn [] (let [current-sorting (rf/subscribe [::subs/open-bounties-sorting-type])] @@ -205,38 +205,25 @@ (rf/dispatch [::handlers/set-open-bounties-sorting-type sorting-type]))} (ui-model/bounty-sorting-type->name sorting-type)])])])))) -;(defn bounties-list [open-bounties] -; [:div.ui.container.open-bounties-container -; [:div.open-bounties-header "Bounties"] -; [:div.open-bounties-filter-and-sort -; [bounty-filters-view] -; [bounties-sort]] -; (if (empty? open-bounties) -; [:div.view-no-data-container -; [:p "No matching bounties found."]] -; (into [:div.ui.items] -; (for [bounty open-bounties] -; [bounty-item bounty])))]) - (defn bounties-list [{:keys [items item-count page-number total-count] - :as bounty-page-data}] + :as bounty-page-data}] [:div.ui.container.open-bounties-container [:div.open-bounties-header "Bounties"] [:div.open-bounties-filter-and-sort [bounty-filters-view] - [bounties-sort]] + [bounties-sort-view]] (if (empty? items) [:div.view-no-data-container [:p "No matching bounties found."]] [:div - (let [left (inc (* (dec page-number) items-per-page)) + (let [left (inc (* (dec page-number) items-per-page)) right (dec (+ left item-count))] [:div.item-counts-label [:span (str "Showing " left "-" right " of " total-count)]]) (display-data-page bounty-page-data bounty-item :set-bounty-page-number)])]) (defn bounties-page [] - (let [bounty-page-data (rf/subscribe [:open-bounties-page]) + (let [bounty-page-data (rf/subscribe [:open-bounties-page]) open-bounties-loading? (rf/subscribe [:get-in [:open-bounties-loading?]])] (fn [] (if @open-bounties-loading? @@ -244,31 +231,3 @@ [:div.ui.active.inverted.dimmer [:div.ui.text.loader.view-loading-label "Loading"]]] [bounties-list @bounty-page-data])))) -; -;(defn bounties-page [] -; (let [open-bounties (rf/subscribe [::subs/filtered-and-sorted-open-bounties]) -;======= -;(defn bounties-list [{:keys [items item-count page-number total-count] -; :as bounty-page-data}] -; [:div.ui.container.open-bounties-container -; [:div.open-bounties-header "Bounties"] -; (if (empty? items) -; [:div.view-no-data-container -; [:p "No recent activity yet"]] -; [:div -; (let [left (inc (* (dec page-number) items-per-page)) -; right (dec (+ left item-count))] -; [:div.item-counts-label -; [:span (str "Showing " left "-" right " of " total-count)]]) -; (display-data-page bounty-page-data bounty-item :set-bounty-page-number)])]) -; -;(defn bounties-page [] -; (let [bounty-page-data (rf/subscribe [:open-bounties-page]) -;>>>>>>> status/develop -; 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 @bounty-page-data])))) From aabdff10fda655c13574fc97aea18eae7ac5cbb4 Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 10:34:32 +0100 Subject: [PATCH 20/29] use multimethod in bounties-filter-tooltip-view --- src/cljs/commiteth/bounties.cljs | 47 +++++++++++++------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 27e9e9e..3964f04 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -49,7 +49,7 @@ [:div.ui.tiny.circular.image [:img {:src avatar-url}]]]])) -(defn bounties-filter-tooltip-value-input [label tooltip-open? opts] +(defn bounties-filter-tooltip-value-input-view [label tooltip-open? opts] [:div.open-bounties-filter-element-tooltip-value-input-container [:div.:input.open-bounties-filter-element-tooltip-value-input-label label] @@ -63,7 +63,10 @@ #(-> % .-target .-value int f)) :on-focus #(reset! tooltip-open? true)}]]) -(defn bounties-filter-tooltip-category-range-view [filter-type filter-type-def current-filter-value tooltip-open?] +(defmulti bounties-filter-tooltip-view #(-> %2 ::ui-model/bounty-filter-type.category)) + +(defmethod bounties-filter-tooltip-view ::ui-model/bounty-filter-type-category|range + [filter-type filter-type-def current-filter-value tooltip-open?] (let [default-min (::ui-model/bounty-filter-type.min-val filter-type-def) default-max (::ui-model/bounty-filter-type.max-val filter-type-def) common-range-opts {:min default-min :max default-max} @@ -82,14 +85,14 @@ (on-change-fn new-min new-max)))] [:div "$0 - $1000+" - [bounties-filter-tooltip-value-input "Min" tooltip-open? (merge common-range-opts - {:current-val current-min - :on-change-val on-min-change-fn})] - [bounties-filter-tooltip-value-input "Max" tooltip-open? (merge common-range-opts - {:current-val current-max - :on-change-val on-max-change-fn})]])) + [bounties-filter-tooltip-value-input-view "Min" tooltip-open? (merge common-range-opts + {:current-val current-min + :on-change-val on-min-change-fn})] + [bounties-filter-tooltip-value-input-view "Max" tooltip-open? (merge common-range-opts + {:current-val current-max + :on-change-val on-max-change-fn})]])) -(defn bounties-filter-tooltip-category-single-static-option-view +(defmethod bounties-filter-tooltip-view ::ui-model/bounty-filter-type-category|single-static-option [filter-type filter-type-def current-filter-value tooltip-open?] [:div.open-bounties-filter-list (for [[option-type option-text] (::ui-model/bounty-filter-type.options filter-type-def)] @@ -103,7 +106,7 @@ {:class "active"})) option-text])]) -(defn bounties-filter-tooltip-category-multiple-dynamic-options-view +(defmethod bounties-filter-tooltip-view ::ui-model/bounty-filter-type-category|multiple-dynamic-options [filter-type filter-type-def current-filter-value tooltip-open?] (let [options (rf/subscribe [(::ui-model/bounty-filter-type.re-frame-subscription-key-for-options filter-type-def)])] [:div.open-bounties-filter-list @@ -126,19 +129,6 @@ :on-focus #(reset! tooltip-open? true)}] [:div.text option]]]))])) -(defn bounties-filter-tooltip-view [filter-type filter-type-def current-filter-val tooltip-open?] - [:div.open-bounties-filter-element-tooltip - (let [compo (condp = (::ui-model/bounty-filter-type.category filter-type-def) - ::ui-model/bounty-filter-type-category|single-static-option - bounties-filter-tooltip-category-single-static-option-view - - ::ui-model/bounty-filter-type-category|multiple-dynamic-options - bounties-filter-tooltip-category-multiple-dynamic-options-view - - ::ui-model/bounty-filter-type-category|range - bounties-filter-tooltip-category-range-view)] - (compo filter-type filter-type-def current-filter-val tooltip-open?))]) - (defn bounty-filter-view [filter-type current-filter-value] (let [tooltip-open? (r/atom false)] (fn [filter-type current-filter-value] @@ -165,11 +155,12 @@ (rf/dispatch [::handlers/set-open-bounty-filter-type filter-type nil]) (reset! tooltip-open? false))}]])] (when @tooltip-open? - [bounties-filter-tooltip-view - filter-type - (ui-model/bounty-filter-types-def filter-type) - current-filter-value - tooltip-open?])]))) + [:div.open-bounties-filter-element-tooltip + [bounties-filter-tooltip-view + filter-type + (ui-model/bounty-filter-types-def filter-type) + current-filter-value + tooltip-open?]])]))) (defn bounty-filters-view [] (let [current-filters (rf/subscribe [::subs/open-bounties-filters])] From 6786411299e94e2c23f0067402ac19c4a3e99ac0 Mon Sep 17 00:00:00 2001 From: pablodip Date: Thu, 25 Jan 2018 11:08:50 +0100 Subject: [PATCH 21/29] add created_at to queries --- resources/sql/queries.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index e8a3115..1fa529c 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -422,6 +422,7 @@ SELECT i.payout_hash AS payout_hash, i.payout_receipt AS payout_receipt, i.updated AS updated, + i.created_at AS created_at, r.owner AS repo_owner, r.owner_avatar_url AS repo_owner_avatar_url, r.repo AS repo_name, From 9b40abc1a1b88728b257f62a053920fb7b19944f Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 11:43:39 +0100 Subject: [PATCH 22/29] added missing svgs --- resources/public/bounty-filter-remove.svg | 6 ++++++ resources/public/icon-forward-white.svg | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 resources/public/bounty-filter-remove.svg create mode 100644 resources/public/icon-forward-white.svg diff --git a/resources/public/bounty-filter-remove.svg b/resources/public/bounty-filter-remove.svg new file mode 100644 index 0000000..b4e091f --- /dev/null +++ b/resources/public/bounty-filter-remove.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/resources/public/icon-forward-white.svg b/resources/public/icon-forward-white.svg new file mode 100644 index 0000000..9842677 --- /dev/null +++ b/resources/public/icon-forward-white.svg @@ -0,0 +1,3 @@ + + + From fa5bdef66ae23813875ea3dab291b1958bf0c1d4 Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 11:51:55 +0100 Subject: [PATCH 23/29] a few improvements and comments in filter-bounties --- src/cljs/commiteth/subscriptions.cljs | 4 ++-- src/cljs/commiteth/ui_model.cljs | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index 03be998..d7a1818 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -162,6 +162,6 @@ :<- [::open-bounties-sorting-type] (fn [[open-bounties filters sorting-type] _] (cond->> open-bounties - filters (ui-model/filter-bounties filters) + true (ui-model/filter-bounties filters) sorting-type (ui-model/sort-bounties-by-sorting-type sorting-type) - filter vec))) + true vec))) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index fa25f0c..cfa0210 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -107,15 +107,16 @@ (defn filter-bounties [filters-by-type bounties] (let [filter-preds (->> filters-by-type + ; used `nil?` because a valid filter value can be `false` (remove #(nil? (val %))) (map (fn [[filter-type filter-value]] (let [filter-type-def (bounty-filter-types-def filter-type) pred (::bounty-filter-type.predicate filter-type-def) pre-pred-processor (::bounty-filter-type.pre-predicate-value-processor filter-type-def) filter-value (cond-> filter-value - pre-pred-processor (pre-pred-processor filter-value))] + pre-pred-processor pre-pred-processor)] (partial pred filter-value))))) filters-pred (fn [bounty] (every? #(% bounty) filter-preds))] - (->> bounties - (filter filters-pred)))) + (cond->> bounties + (not-empty filter-preds) (filter filters-pred)))) From 65cea5d521eb86bf2f95e442dd62e322a3d0d692 Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 12:01:24 +0100 Subject: [PATCH 24/29] reformat bounty-filter-types-def --- src/cljs/commiteth/bounties.cljs | 2 +- src/cljs/commiteth/ui_model.cljs | 79 +++++++++++++++++--------------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 3964f04..645958a 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -108,7 +108,7 @@ (defmethod bounties-filter-tooltip-view ::ui-model/bounty-filter-type-category|multiple-dynamic-options [filter-type filter-type-def current-filter-value tooltip-open?] - (let [options (rf/subscribe [(::ui-model/bounty-filter-type.re-frame-subscription-key-for-options filter-type-def)])] + (let [options (rf/subscribe [(::ui-model/bounty-filter-type.re-frame-subs-key-for-options filter-type-def)])] [:div.open-bounties-filter-list (for [option @options] (let [active? (boolean (and current-filter-value (current-filter-value option)))] diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index cfa0210..039920d 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -45,42 +45,49 @@ (def bounty-filter-type-date-options (keys bounty-filter-type-date-options-def)) (def bounty-filter-types-def - {::bounty-filter-type|value {::bounty-filter-type.name "Value" - ::bounty-filter-type.category ::bounty-filter-type-category|range - ::bounty-filter-type.min-val 0 - ::bounty-filter-type.max-val 1000 - ::bounty-filter-type.predicate (fn [filter-value bounty] - (let [min-val (first filter-value) - max-val (second filter-value)] - (<= min-val (:value-usd bounty) max-val)))} - ::bounty-filter-type|currency {::bounty-filter-type.name "Currency" - ::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options - ::bounty-filter-type.re-frame-subscription-key-for-options :commiteth.subscriptions/open-bounties-currencies - ::bounty-filter-type.predicate (fn [filter-value bounty] - (and (or (not-any? #{"ETH"} filter-value) - (< 0 (:balance-eth bounty))) - (set/subset? (->> filter-value (remove #{"ETH"}) set) - (-> bounty :tokens keys set))))} - ::bounty-filter-type|date {::bounty-filter-type.name "Date" - ::bounty-filter-type.category ::bounty-filter-type-category|single-static-option - ::bounty-filter-type.options bounty-filter-type-date-options-def - ::bounty-filter-type.pre-predicate-value-processor (fn [filter-value] - (let [filter-from (condp = filter-value - ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) - ::bounty-filter-type-date-option|last-month (t/minus (t/now) (t/months 1)) - ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3)))] - (t/interval filter-from (t/now)))) - ::bounty-filter-type.predicate (fn [filter-value-interval bounty] - (when-let [created-at-inst (:created-at bounty)] - (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long)] - (t/within? filter-value-interval created-at-date))))} - ::bounty-filter-type|owner {::bounty-filter-type.name "Owner" - ::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options - ::bounty-filter-type.re-frame-subscription-key-for-options :commiteth.subscriptions/open-bounties-owners - ::bounty-filter-type.predicate (fn [filter-value bounty] - (->> filter-value - (some #{(:repo-owner bounty)}) - boolean))}}) + {::bounty-filter-type|value + {::bounty-filter-type.name "Value" + ::bounty-filter-type.category ::bounty-filter-type-category|range + ::bounty-filter-type.min-val 0 + ::bounty-filter-type.max-val 1000 + ::bounty-filter-type.predicate (fn [filter-value bounty] + (let [min-val (first filter-value) + max-val (second filter-value)] + (<= min-val (:value-usd bounty) max-val)))} + + ::bounty-filter-type|currency + {::bounty-filter-type.name "Currency" + ::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options + ::bounty-filter-type.re-frame-subs-key-for-options :commiteth.subscriptions/open-bounties-currencies + ::bounty-filter-type.predicate (fn [filter-value bounty] + (and (or (not-any? #{"ETH"} filter-value) + (< 0 (:balance-eth bounty))) + (set/subset? (->> filter-value (remove #{"ETH"}) set) + (-> bounty :tokens keys set))))} + + ::bounty-filter-type|date + {::bounty-filter-type.name "Date" + ::bounty-filter-type.category ::bounty-filter-type-category|single-static-option + ::bounty-filter-type.options bounty-filter-type-date-options-def + ::bounty-filter-type.pre-predicate-value-processor (fn [filter-value] + (let [filter-from (condp = filter-value + ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) + ::bounty-filter-type-date-option|last-month (t/minus (t/now) (t/months 1)) + ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3)))] + (t/interval filter-from (t/now)))) + ::bounty-filter-type.predicate (fn [filter-value-interval bounty] + (when-let [created-at-inst (:created-at bounty)] + (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long)] + (t/within? filter-value-interval created-at-date))))} + + ::bounty-filter-type|owner + {::bounty-filter-type.name "Owner" + ::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options + ::bounty-filter-type.re-frame-subs-key-for-options :commiteth.subscriptions/open-bounties-owners + ::bounty-filter-type.predicate (fn [filter-value bounty] + (->> filter-value + (some #{(:repo-owner bounty)}) + boolean))}}) (def bounty-filter-types (keys bounty-filter-types-def)) From 15768318cf7f5ef53bbcc57d5db1b34004adbf9f Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 12:04:33 +0100 Subject: [PATCH 25/29] reset sorting and filters when navigating page --- src/cljs/commiteth/handlers.cljs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cljs/commiteth/handlers.cljs b/src/cljs/commiteth/handlers.cljs index 4367c9a..554e6d6 100644 --- a/src/cljs/commiteth/handlers.cljs +++ b/src/cljs/commiteth/handlers.cljs @@ -11,7 +11,8 @@ [cljs-web3.eth :as web3-eth] [akiroz.re-frame.storage :as rf-storage - :refer [reg-co-fx!]])) + :refer [reg-co-fx!]] + [commiteth.ui-model :as ui-model])) (rf-storage/reg-co-fx! :commiteth-sob {:fx :store @@ -66,7 +67,9 @@ (reg-event-db :set-active-page (fn [db [_ page]] - (assoc db :page page))) + (assoc db :page page + ::db/open-bounties-filters {} + ::db/open-bounties-sorting-type ::ui-model/bounty-sorting-type|most-recent))) (reg-event-db :set-bounty-page-number From faff5327978b32cbbe4e7e1fe63a37943e16ceba Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 12:45:40 +0100 Subject: [PATCH 26/29] making some lines shorter --- src/cljs/commiteth/ui_model.cljs | 48 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index 039920d..9fab8c8 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -44,6 +44,19 @@ (def bounty-filter-type-date-options (keys bounty-filter-type-date-options-def)) +(def bounty-filter-type-date-pre-predicate-value-processor + (fn [filter-value] + (let [filter-from (condp = filter-value + ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) + ::bounty-filter-type-date-option|last-month (t/minus (t/now) (t/months 1)) + ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3)))] + (t/interval filter-from (t/now))))) +(def bounty-filter-type-date-predicate + (fn [filter-value-interval bounty] + (when-let [created-at-inst (:created-at bounty)] + (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long)] + (t/within? filter-value-interval created-at-date))))) + (def bounty-filter-types-def {::bounty-filter-type|value {::bounty-filter-type.name "Value" @@ -69,16 +82,8 @@ {::bounty-filter-type.name "Date" ::bounty-filter-type.category ::bounty-filter-type-category|single-static-option ::bounty-filter-type.options bounty-filter-type-date-options-def - ::bounty-filter-type.pre-predicate-value-processor (fn [filter-value] - (let [filter-from (condp = filter-value - ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) - ::bounty-filter-type-date-option|last-month (t/minus (t/now) (t/months 1)) - ::bounty-filter-type-date-option|last-3-months (t/minus (t/now) (t/months 3)))] - (t/interval filter-from (t/now)))) - ::bounty-filter-type.predicate (fn [filter-value-interval bounty] - (when-let [created-at-inst (:created-at bounty)] - (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long)] - (t/within? filter-value-interval created-at-date))))} + ::bounty-filter-type.pre-predicate-value-processor bounty-filter-type-date-pre-predicate-value-processor + ::bounty-filter-type.predicate bounty-filter-type-date-predicate} ::bounty-filter-type|owner {::bounty-filter-type.name "Owner" @@ -112,17 +117,20 @@ :else (str filter-type " with val " filter-value))) +(defn- bounty-filter-values-by-type->predicates [filters-by-type] + (->> filters-by-type + ; used `nil?` because a valid filter value can be `false` + (remove #(nil? (val %))) + (map (fn [[filter-type filter-value]] + (let [filter-type-def (bounty-filter-types-def filter-type) + pred (::bounty-filter-type.predicate filter-type-def) + pre-pred-processor (::bounty-filter-type.pre-predicate-value-processor filter-type-def) + filter-value (cond-> filter-value + pre-pred-processor pre-pred-processor)] + (partial pred filter-value)))))) + (defn filter-bounties [filters-by-type bounties] - (let [filter-preds (->> filters-by-type - ; used `nil?` because a valid filter value can be `false` - (remove #(nil? (val %))) - (map (fn [[filter-type filter-value]] - (let [filter-type-def (bounty-filter-types-def filter-type) - pred (::bounty-filter-type.predicate filter-type-def) - pre-pred-processor (::bounty-filter-type.pre-predicate-value-processor filter-type-def) - filter-value (cond-> filter-value - pre-pred-processor pre-pred-processor)] - (partial pred filter-value))))) + (let [filter-preds (bounty-filter-values-by-type->predicates filters-by-type) filters-pred (fn [bounty] (every? #(% bounty) filter-preds))] (cond->> bounties From 35ad4e48d07e9fc7b7eaadedd45df9e5a5848c6b Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 15:21:34 +0100 Subject: [PATCH 27/29] add filter for claims --- src/cljs/commiteth/ui_model.cljs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index 9fab8c8..0a99444 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -44,6 +44,9 @@ (def bounty-filter-type-date-options (keys bounty-filter-type-date-options-def)) +(defn bounty-filter-type-date-option->name [option] + (bounty-filter-type-date-options-def option)) + (def bounty-filter-type-date-pre-predicate-value-processor (fn [filter-value] (let [filter-from (condp = filter-value @@ -57,6 +60,13 @@ (let [created-at-date (-> created-at-inst inst-ms t-coerce/from-long)] (t/within? filter-value-interval created-at-date))))) +(def bounty-filter-type-claims-options-def {::bounty-filter-type-claims-option|no-claims "With no claims"}) + +(def bounty-filter-type-claims-options (keys bounty-filter-type-claims-options-def)) + +(defn bounty-filter-type-claims-option->name [option] + (bounty-filter-type-claims-options-def option)) + (def bounty-filter-types-def {::bounty-filter-type|value {::bounty-filter-type.name "Value" @@ -92,16 +102,22 @@ ::bounty-filter-type.predicate (fn [filter-value bounty] (->> filter-value (some #{(:repo-owner bounty)}) - boolean))}}) + boolean))} + + ::bounty-filter-type|claims + {::bounty-filter-type.name "Claims" + ::bounty-filter-type.category ::bounty-filter-type-category|single-static-option + ::bounty-filter-type.options bounty-filter-type-claims-options-def + ::bounty-filter-type.predicate (fn [filter-value bounty] + (condp = filter-value + ::bounty-filter-type-claims-option|no-claims + (<= 0 (:claim-count bounty))))}}) (def bounty-filter-types (keys bounty-filter-types-def)) (defn bounty-filter-type->name [filter-type] (-> bounty-filter-types-def (get filter-type) ::bounty-filter-type.name)) -(defn bounty-filter-type-date-option->name [option] - (bounty-filter-type-date-options-def option)) - (defn bounty-filter-value->short-text [filter-type filter-value] (cond (= filter-type ::bounty-filter-type|date) @@ -114,6 +130,9 @@ (= filter-type ::bounty-filter-type|value) (str "$" (first filter-value) "-$" (second filter-value)) + (= filter-type ::bounty-filter-type|claims) + (bounty-filter-type-claims-option->name filter-value) + :else (str filter-type " with val " filter-value))) From eef57a3046547a457cfcd3adbc0abab7859eab43 Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 16:06:01 +0100 Subject: [PATCH 28/29] add some docstrings --- src/cljs/commiteth/ui_model.cljs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index 0a99444..2efba9c 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -48,6 +48,9 @@ (bounty-filter-type-date-options-def option)) (def bounty-filter-type-date-pre-predicate-value-processor + "It converts an option of the filter type date to a cljs-time interval in which + that option is valid, so that you can check `cljs-time.core.within?` against that + interval and know if a `cljs-time` date is valid for that filter type date option." (fn [filter-value] (let [filter-from (condp = filter-value ::bounty-filter-type-date-option|last-week (t/minus (t/now) (t/weeks 1)) @@ -137,6 +140,11 @@ (str filter-type " with val " filter-value))) (defn- bounty-filter-values-by-type->predicates [filters-by-type] + "It receives a map with filter types as keys and filter values as values and + returns a lazy seq of predicates, one for each pair of filter type and value. + Those predicate can receive a bounty and tell whether that bounty passes + the filter type with that filter value. It removes filter types with a `nil` + filter value." (->> filters-by-type ; used `nil?` because a valid filter value can be `false` (remove #(nil? (val %))) From 489260aaf4e67c6ceb4d5a41da648aeeba375938 Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 31 Jan 2018 18:51:44 +0100 Subject: [PATCH 29/29] change <= for < --- src/cljs/commiteth/ui_model.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cljs/commiteth/ui_model.cljs b/src/cljs/commiteth/ui_model.cljs index 2efba9c..db3234d 100644 --- a/src/cljs/commiteth/ui_model.cljs +++ b/src/cljs/commiteth/ui_model.cljs @@ -114,7 +114,7 @@ ::bounty-filter-type.predicate (fn [filter-value bounty] (condp = filter-value ::bounty-filter-type-claims-option|no-claims - (<= 0 (:claim-count bounty))))}}) + (= 0 (:claim-count bounty))))}}) (def bounty-filter-types (keys bounty-filter-types-def))