Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5eef451
remove page-ident
myguidingstar Mar 20, 2019
b1ee49e
update keys in Page
myguidingstar Mar 20, 2019
188c7ad
add list-ident and page-ident
myguidingstar Mar 20, 2019
cc939d9
add has-previous|next-page?
myguidingstar Mar 20, 2019
4d41c49
update Page's initial-state
myguidingstar Mar 20, 2019
20829e9
update Page's query
myguidingstar Mar 20, 2019
5b1ad39
update Page's renderer
myguidingstar Mar 20, 2019
7218e53
add List
myguidingstar Mar 20, 2019
65ea615
update Page's keyword in PageRouter
myguidingstar Mar 20, 2019
b68f41c
update has-prious|next-page?
myguidingstar Mar 20, 2019
148f717
move pagination part from Page to List
myguidingstar Mar 20, 2019
faa5b69
fix wrong keyword: articles/on-feed
myguidingstar Mar 20, 2019
56ef7a0
exclude clojure List
myguidingstar Mar 21, 2019
5ff49e7
fix keyword typo
myguidingstar Mar 21, 2019
1f71580
standardize pagination keywords
myguidingstar Mar 21, 2019
130297a
fix wrong if with if-not
myguidingstar Mar 21, 2019
ad2a43b
add next/prev helper functions
myguidingstar Mar 21, 2019
d64e9fb
update FeedSelector with article-list
myguidingstar Mar 21, 2019
60e6266
update pagination keyword
myguidingstar Mar 21, 2019
f861fd4
update FeedScreen with article-list
myguidingstar Mar 21, 2019
ffddbd3
update TagScreen with article-list
myguidingstar Mar 21, 2019
01c002e
replace load-feed and load-tag with load-list
myguidingstar Mar 21, 2019
2c75e24
use the new load-list
myguidingstar Mar 21, 2019
c662d26
update config for walkable
myguidingstar Mar 21, 2019
631d58b
update article-list-resolver
myguidingstar Mar 21, 2019
9993704
update Profile with List
myguidingstar Mar 21, 2019
eb23098
implement whoami-resolver
myguidingstar Mar 21, 2019
56c514c
move list-ident to conduit.util
myguidingstar Mar 21, 2019
b8dcb43
fix has-next|previous-page?
myguidingstar Mar 21, 2019
6c45dc6
extract page-ident-value from page-ident
myguidingstar Mar 30, 2019
9a6f132
remove stub functions
myguidingstar Mar 30, 2019
1a2abd2
implement client next-page & previous-page
myguidingstar Mar 30, 2019
9b6ff39
use new next/prev mutations in ui
myguidingstar Mar 30, 2019
df2d6bb
implement server side next-page mutation
myguidingstar Mar 30, 2019
a9aa352
make page-filters aware of direction and operation
myguidingstar Mar 30, 2019
ddc1a6a
make article-list-resolver aware of direction and operation
myguidingstar Mar 30, 2019
afcbb89
order-by should be aware of operation, too
myguidingstar Mar 30, 2019
5dd2a80
implement server side previous-page mutation
myguidingstar Mar 30, 2019
25d7a38
update duct
myguidingstar Apr 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[duct/module.logging "0.4.0"]
[duct/module.web "0.7.0"]
[duct/module.ataraxy "0.3.0"]
[duct/module.cljs "0.4.0" :exclusions [org.clojure/clojurescript]]
[duct/module.cljs "0.4.1" :exclusions [org.clojure/clojurescript]]
[duct/module.sql "0.5.0"]

[duct/middleware.buddy "0.1.0"]
Expand All @@ -27,7 +27,7 @@
[org.clojure/core.async "0.4.490"]
[org.postgresql/postgresql "42.2.5"]]
:middleware [lein-duct.plugin/middleware]
:plugins [[duct/lein-duct "0.11.2"]]
:plugins [[duct/lein-duct "0.12.0"]]
:main ^:skip-aot conduit.main
:resource-paths ["resources" "target/resources"]
:prep-tasks ["javac" "compile" ["run" ":duct/compiler"]]
Expand All @@ -43,7 +43,7 @@
:resource-paths ["dev/resources"]
:dependencies [ ;; cljs
[cider/piggieback "0.4.0"]
[walkable/duct.server.figwheel "0.4.0-SNAPSHOT" :exclusions [org.clojure/clojurescript]]
[duct/server.figwheel "0.3.1" :exclusions [org.clojure/clojurescript]]
[org.clojure/test.check "0.10.0-alpha3"]
[devcards "0.2.6" :exclusions [org.clojure/clojurescript]]

Expand Down
18 changes: 11 additions & 7 deletions resources/conduit/config.edn
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@
:user/whoami
"user"

[:feed.global/articles :feed.global/next-id
:feed.personal/articles :feed.personal/next-id]
[:feed.global/articles :feed.personal/articles]
"article"

:tags/all
Expand All @@ -74,14 +73,19 @@

:comment/author [:comment/author-id :user/id]}

:pseudo-columns {:pagination/total [:count-*]
:pagination/last-id [:max :article/id]}
:pseudo-columns {}

:aggregators {[:article/liked-by-count :user/followed-by-count :tag/count]
[:count-*]

[:feed.global/next-id :feed.personal/next-id]
:article/id
:app.articles.list/total-items
[:count-*]

:app.articles.list/first-item-id
[:min :article/id]

:app.articles.list/last-item-id
[:max :article/id]

[:user/followed-by-me :article/liked-by-me]
[:< 0 [:count-*]]}
Expand All @@ -91,7 +95,7 @@
:user/articles :article/author}

:extra-conditions
{[:feed.personal/articles :feed.personal/next-id]
{[:feed.personal/articles]
{:article/author {:user/followed-by [:= app/current-user :user/id]}}

:article/liked-by-me
Expand Down
18 changes: 18 additions & 0 deletions src/conduit/handler/mutations.clj
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,21 @@
(if current-user
(article/remove-tag db current-user article-id tag)
{})))

(defmutation conduit.ui.pagination/next-page [page-ident]
(action [{:keys [parser] :app/keys [db current-user] :as env
list-subquery :query}]
(let [next-page-ident-value (assoc page-ident :app.articles.list.page/operation :next)
next-page-ident [:app.articles/list next-page-ident-value]]
(-> env
(parser [{next-page-ident list-subquery}])
(get next-page-ident)))))

(defmutation conduit.ui.pagination/previous-page [page-ident]
(action [{:keys [parser] :app/keys [db current-user] :as env
list-subquery :query}]
(let [next-page-ident-value (assoc page-ident :app.articles.list.page/operation :previous)
next-page-ident [:app.articles/list next-page-ident-value]]
(-> env
(parser [{next-page-ident list-subquery}])
(get next-page-ident)))))
233 changes: 109 additions & 124 deletions src/conduit/handler/walkable.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,154 +11,139 @@
[conduit.handler.mutations :as mutations]
[fulcro.server :as server :refer [server-mutate]]
[com.wsscode.pathom.core :as p]
[conduit.util :as util :refer [list-ident list-ident-value]]
[clojure.spec.alpha :as s]))

(defn get-items-subquery [query]
(->> query
(some #(and (map? %) (get % :pagination/items)))))

(defn query-params [env]
(let [{:pagination/keys [size start end] :or {size 10}} (env/params env)]
{:order-by [:article/id (if-not (number? end) :desc :asc)]
:filters (cond
(number? end)
[:<= :article/id end]
(number? start)
[:<= start :article/id])}))

(defn extra-filter [env]
(let [{:pagination/keys [list-type list-id]} (env/params env)]
(case list-type
:liked-articles/by-user-id
{:article/liked-by [:= :user/id list-id]}

:owned-articles/by-user-id
[:= :article/author-id list-id]

:articles/by-tag
{:article/tags [:= :tag/tag list-id]}

;; default
(some #(and (map? %) (get % :app.articles.list/current-page)))
(some #(and (map? %) (get % :app.articles.list.page/items)))))

(defn page-filters [{:app.articles.list/keys [direction]
:app.articles.list.page/keys [operation start end]}]
(if (= :forward direction)
(case operation
:current
[:>= start :article/id end]

:next
[:> end :article/id]

:previous
[:> :article/id start]

;; else
nil)
(case operation
:current
[:<= start :article/id end]

:next
[:< end :article/id]

:previous
[:< :article/id start]

;; else
nil)))

(defn order-by [{:app.articles.list/keys [direction]
:app.articles.list.page/keys [operation]}]
[:article/id (if (and (= direction :forward) (not= operation :previous))
:desc
:asc)])

(defn list-filters [{:app.articles.list/keys [list-type list-id]}]
(case list-type
:app.articles/liked-by-user
{:article/liked-by [:= :user/id list-id]}

:app.articles/owned-by-user
[:= :article/author-id list-id]

:app.articles/with-tag
{:article/tags [:= :tag/tag list-id]}

;; default
nil))

(defn merge-filters [xs]
(let [xs (remove nil? xs)]
(when (seq xs)
(if (= 1 (count xs))
(first xs)
(into [:and] xs)))))

(defn next-id [env]
(let [{:pagination/keys [list-type list-id size start end] :or {size 10}} (env/params env)

{:keys [parser query]} env

query-root
(cond
(= [list-type list-id] [:articles/by-feed :personal])
:feed.personal/next-id

:default
:feed.global/next-id)

params {:order-by [:article/id :desc]
:limit 1
:offset (when-not (number? end) size)
:filters (merge-filters
[(extra-filter env)
(cond
(number? end)
[:< :article/id end]
(number? start)
[:<= :article/id start])])}]
(-> (parser env [(list query-root params)])
(get query-root))))

(defn previous-id [env]
(let [{:pagination/keys [list-type list-id size start end] :or {size 10}} (env/params env)

{:keys [parser query]} env
query-root
(cond
(= [list-type list-id] [:articles/by-feed :personal])
:feed.personal/next-id

:default
:feed.global/next-id)

params {:order-by [:article/id :asc]
:limit 1
:offset (when (number? end) size)
:filters (merge-filters
[(extra-filter env)
(cond
(number? end)
[:<= end :article/id]
(number? start)
[:< start :article/id])])}]
(when (or end start)
(-> (parser env [(list query-root params)])
(get query-root)))))

(defn fetch-items [env]
(let [{:pagination/keys [list-type list-id size start end] :or {size 10}} (env/params env)

{:keys [parser query]} env

query-root
(cond
(= [list-type list-id] [:articles/by-feed :personal])
:feed.personal/articles

:default
:feed.global/articles)

params {:order-by [:article/id (if (number? end) :asc :desc)]
:limit size
:filters (merge-filters
[(extra-filter env)
(cond
(number? end)
[:<= end :article/id]
(number? start)
[:<= :article/id start])])}
items-query [{(list query-root params) (get-items-subquery query)}]]
(defn fetch-items
[query-root params {:keys [parser query] :as env}]
(let [items-query
[{(list query-root params) (get-items-subquery query)}]]
(-> (parser env items-query)
(get query-root))))

(defn paginated-list-resolver [env]
(if (not= :paginated-list/articles (env/dispatch-key env))
(defn query-root
[{:app.articles.list/keys [list-type list-id]}]
(cond
(= [list-type list-id] [:app.articles/on-feed :personal])
:feed.personal/articles

:default
:feed.global/articles))

(defn fetch-list-stats
[query-root list-filters {:keys [parser] :as env}]
(let [query [{(list query-root {:filters list-filters})
[:app.articles.list/first-item-id
:app.articles.list/last-item-id
:app.articles.list/total-items]}]]
(-> (parser env query)
(get query-root)
first)))

(defn article-list-resolver [env]
(if (not= :app.articles/list (env/dispatch-key env))
::p/continue
(let [page (env/ident-value env)
ident-value (list-ident-value page)
direction (:app.articles.list/direction ident-value)
qr (query-root ident-value)
lf (list-filters ident-value)
stats (fetch-list-stats qr lf env)
items (fetch-items qr
{:order-by (order-by ident-value)
:limit (:app.articles.list/size ident-value)
:filters (merge-filters [lf (page-filters page)])}
env)]
(merge ident-value
(clojure.set/rename-keys stats (when (= :forward direction)
{:app.articles.list/first-item-id
:app.articles.list/last-item-id
:app.articles.list/last-item-id
:app.articles.list/first-item-id}))
{:app.articles.list/current-page
(merge ident-value
#:app.articles.list.page {:items items
:start (-> items first :article/id)
:end (-> items last :article/id)})}))))

(defn whoami-resolver [env]
(if (not= :user/whoami (env/dispatch-key env))
::p/continue
(let [{:pagination/keys [list-type list-id size start end] :or {size 10}} (env/params env)

items (fetch-items env)]
(merge
{(if (number? end) :pagination/end :pagination/start)
(or (:article/id (first items)) :no-start)}
#:pagination{:size size
:list-type list-type
:list-id list-id
:next-id (let [n (next-id env)]
(when (number? n)
#:pagination{:list-type list-type
:list-id list-id
:size size
:start n}))
:previous-id (let [p (previous-id env)]
(when (number? p)
#:pagination{:list-type list-type
:list-id list-id
:size size
:end p}))
:items items}))))
(if-let [user-id (:app/current-user env)]
(let [{:keys [parser query]} env
ident [:user/by-id user-id]]
(-> (parser env [{ident query}])
(get ident)))
#:user {:id :guest :email "non@exist"})))

(def pathom-parser
(p/parser
{:mutate server-mutate
::p/plugins
[(p/env-plugin
{::p/reader
[paginated-list-resolver
[article-list-resolver
whoami-resolver
sqb/pull-entities
p/map-reader
p/env-placeholder-reader]})]}))
Expand Down
Loading