From bbc5ba323d015a0005686e40401f37dc832de914 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Mon, 9 Aug 2021 17:53:46 +0200
Subject: [PATCH] Add pagination to featured events

Closes #811

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 js/src/graphql/event.ts | 30 +++++++++++++++--------
 js/src/views/Search.vue | 53 ++++++++++++++++++++++++++++++++---------
 2 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/js/src/graphql/event.ts b/js/src/graphql/event.ts
index 600ea4db2..4f1e82769 100644
--- a/js/src/graphql/event.ts
+++ b/js/src/graphql/event.ts
@@ -209,8 +209,18 @@ export const FETCH_EVENT_BASIC = gql`
 `;
 
 export const FETCH_EVENTS = gql`
-  query FetchEvents($orderBy: EventOrderBy, $direction: SortDirection) {
-    events(orderBy: $orderBy, direction: $direction) {
+  query FetchEvents(
+    $orderBy: EventOrderBy
+    $direction: SortDirection
+    $page: Int
+    $limit: Int
+  ) {
+    events(
+      orderBy: $orderBy
+      direction: $direction
+      page: $page
+      limit: $limit
+    ) {
       total
       elements {
         id
@@ -246,14 +256,14 @@ export const FETCH_EVENTS = gql`
           domain
           name
         }
-        #      attributedTo {
-        #        avatar {
-        #          id
-        #          url
-        #        },
-        #        preferredUsername,
-        #        name,
-        #      },
+        attributedTo {
+          avatar {
+            id
+            url
+          }
+          preferredUsername
+          name
+        }
         category
         tags {
           ...TagFragment
diff --git a/js/src/views/Search.vue b/js/src/views/Search.vue
index 8866d4256..5dda05424 100644
--- a/js/src/views/Search.vue
+++ b/js/src/views/Search.vue
@@ -69,13 +69,27 @@
     >
       <b-loading :active.sync="$apollo.loading"></b-loading>
       <h2 class="title">{{ $t("Featured events") }}</h2>
-      <div v-if="events.elements.length > 0" class="columns is-multiline">
-        <div
-          class="column is-one-third-desktop"
-          v-for="event in events.elements"
-          :key="event.uuid"
-        >
-          <EventCard :event="event" />
+      <div v-if="events.elements.length > 0">
+        <div class="columns is-multiline">
+          <div
+            class="column is-one-third-desktop"
+            v-for="event in events.elements"
+            :key="event.uuid"
+          >
+            <EventCard :event="event" />
+          </div>
+        </div>
+        <div class="pagination" v-if="events.total > EVENT_PAGE_LIMIT">
+          <b-pagination
+            :total="events.total"
+            v-model="eventPage"
+            :per-page="EVENT_PAGE_LIMIT"
+            :aria-next-label="$t('Next page')"
+            :aria-previous-label="$t('Previous page')"
+            :aria-page-label="$t('Page')"
+            :aria-current-label="$t('Current page')"
+          >
+          </b-pagination>
         </div>
       </div>
       <b-message
@@ -104,7 +118,7 @@
               <EventCard :event="event" />
             </div>
           </div>
-          <div class="pagination">
+          <div class="pagination" v-if="searchEvents.total > EVENT_PAGE_LIMIT">
             <b-pagination
               :total="searchEvents.total"
               v-model="eventPage"
@@ -218,7 +232,15 @@ const THROTTLE = 2000; // minimum interval in ms between two requests
   },
   apollo: {
     config: CONFIG,
-    events: FETCH_EVENTS,
+    events: {
+      query: FETCH_EVENTS,
+      variables() {
+        return {
+          page: this.eventPage,
+          limit: EVENT_PAGE_LIMIT,
+        };
+      },
+    },
     searchEvents: {
       query: SEARCH_EVENTS,
       fetchPolicy: "cache-and-network",
@@ -279,8 +301,6 @@ export default class Search extends Vue {
 
   searchGroups: Paginate<IGroup> = { total: 0, elements: [] };
 
-  eventPage = 1;
-
   groupPage = 1;
 
   location: IAddress = new Address();
@@ -355,6 +375,17 @@ export default class Search extends Vue {
     this.$apollo.queries.searchEvents.refetch();
   }
 
+  get eventPage(): number {
+    return parseInt(this.$route.query.eventPage as string, 10) || 1;
+  }
+
+  set eventPage(page: number) {
+    this.$router.push({
+      name: RouteName.SEARCH,
+      query: { ...this.$route.query, eventPage: page.toString() },
+    });
+  }
+
   get search(): string | undefined {
     return this.$route.query.term as string;
   }