From f7d74a78ebe122ef0b623aa6db1bcc61b80153de Mon Sep 17 00:00:00 2001 From: Nimish Gupta Date: Mon, 5 Nov 2018 02:55:11 +0530 Subject: [PATCH] feat: added the pagination for user query (#198) --- client/shared/Utils.re | 8 ++ client/src/Config.re | 2 + client/src/User.re | 93 ++++++++++++-- client/src/components/UI_SketchList.re | 163 ++++++++++++++----------- 4 files changed, 182 insertions(+), 84 deletions(-) diff --git a/client/shared/Utils.re b/client/shared/Utils.re index 569a4260..20048275 100644 --- a/client/shared/Utils.re +++ b/client/shared/Utils.re @@ -132,3 +132,11 @@ let joinWithComma = acc ++ ", " ++ str; } ); + +module Object = { + [@bs.val] + external assign3: (Js.t({..}), Js.t({..}), Js.t({..})) => Js.t({..}) = + "Object.assign"; + let merge = (o1: Js.t({..}), o2: Js.t({..})) => + assign3(Js.Obj.empty(), o1, o2); +}; diff --git a/client/src/Config.re b/client/src/Config.re index 4f04fea0..ed1ba996 100644 --- a/client/src/Config.re +++ b/client/src/Config.re @@ -23,3 +23,5 @@ let graphqlEndpoint = let anonymousUserId = "anonymous"; let cmTheme = "rtop"; + +let sketchListLimit = 30; diff --git a/client/src/User.re b/client/src/User.re index 82c66213..4cfc383c 100644 --- a/client/src/User.re +++ b/client/src/User.re @@ -3,33 +3,74 @@ open Utils; module GetNotes = [%graphql {| - query getNotes($userName: String!) { - note( - where: {owner: {username: {_eq: $userName}}} - order_by: updated_at_desc + query getNotes($userName: String!, $limit: Int, $offset: Int) { + note( + where: {owner: {username: {_eq: $userName}}} + order_by: updated_at_desc + limit: $limit, + offset: $offset ) { id title date: updated_at } } - |} + |} ]; module GetNotesComponent = ReasonApollo.CreateQuery(GetNotes); -let component = ReasonReact.statelessComponent("User"); +let getNotesQuery = (~userName, ~offset=0, ()) => + GetNotes.make(~userName, ~offset, ~limit=Config.sketchListLimit, ()); +external unsafeFromJson: Js.Json.t => GetNotes.t = "%identity"; +external unsafeToJson: GetNotes.t => Js.Json.t = "%identity"; + +let updateQuery = (prev, next) => { + let prev = unsafeFromJson(prev); + let fetchMoreResult = ReasonApolloQuery.fetchMoreResultGet(next); + + ( + switch (fetchMoreResult) { + | None => prev + | Some(moreNotes) => + let moreNotes = unsafeFromJson(moreNotes); + let newNotes = { + "note": Belt.Array.concat(prev##note, moreNotes##note), + }; + Utils.Object.merge(prev, newNotes); + } + ) + |> unsafeToJson; +}; + +let shouldFetchMore = (note, count) => + Array.length(note) >= Config.sketchListLimit * count; + +type state = {count: int}; +type action = + | ChangeCount; + +let initialState = () => {count: 1}; + +let reducer = (action, state) => + switch (action) { + | ChangeCount => ReasonReact.Update({count: 1 + state.count}) + }; + +let component = ReasonReact.reducerComponent("User"); let make = (~userName, _children) => { ...component, - render: _self => { - let notesQuery = GetNotes.make(~userName, ()); + initialState, + reducer, + render: self => { + let notesQuery = getNotesQuery(~userName, ());

{j|$(userName)'s sketches|j}->str

...{ - ({result}) => + ({result, fetchMore}) => switch (result) { | Loading =>
@@ -37,10 +78,36 @@ let make = (~userName, _children) => {
| Error(error) => error##message->str | Data(response) => - } - /> + let notesQuery = + getNotesQuery( + ~userName, + ~offset=Array.length(response##note), + (), + ); + let fetchMore = _e => + Js.Promise.( + fetchMore( + ~variables=notesQuery##variables, + ~updateQuery, + (), + ) + |> then_(_ => { + self.send(ChangeCount); + resolve(); + }) + ) + |> ignore; + + shouldFetchMore(response##note, self.state.count) ? + } + fetchMore + /> : + } + />; } }
diff --git a/client/src/components/UI_SketchList.re b/client/src/components/UI_SketchList.re index a4527b63..35fbdb66 100644 --- a/client/src/components/UI_SketchList.re +++ b/client/src/components/UI_SketchList.re @@ -15,85 +15,106 @@ module DeleteNoteComponent = ReasonApollo.CreateMutation(DeleteNote); let component = ReasonReact.statelessComponent("UI_SketchList"); let make = - (~sketches, ~className=?, ~noSketches="No sketches"->str, _children) => { + ( + ~sketches, + ~className=?, + ~noSketches="No sketches"->str, + ~fetchMore=?, + _children, + ) => { ...component, render: _self => switch (sketches) { | [||] =>
noSketches
| sketches => - + { + switch (fetchMore) { + | None => ReasonReact.null + | Some(fetchMore) => + + } + } + }, }; @@ -162,4 +183,4 @@ module Placeholder = { , }; -}; +}; \ No newline at end of file