From d334f8237f4736c244d8eb8be69e519e8589a762 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 22 Sep 2020 11:45:54 +0200 Subject: [PATCH] Add pagination to search Signed-off-by: Thomas Citharel --- js/src/graphql/search.ts | 8 +++- js/src/types/search.model.ts | 5 ++ js/src/views/Search.vue | 93 +++++++++++++++++++++++++----------- 3 files changed, 77 insertions(+), 29 deletions(-) diff --git a/js/src/graphql/search.ts b/js/src/graphql/search.ts index 9274847f5..bcff6e7e6 100644 --- a/js/src/graphql/search.ts +++ b/js/src/graphql/search.ts @@ -8,6 +8,8 @@ export const SEARCH_EVENTS = gql` $term: String $beginsOn: DateTime $endsOn: DateTime + $page: Int + $limit: Int ) { searchEvents( location: $location @@ -16,6 +18,8 @@ export const SEARCH_EVENTS = gql` term: $term beginsOn: $beginsOn endsOn: $endsOn + page: $page + limit: $limit ) { total elements { @@ -36,8 +40,8 @@ export const SEARCH_EVENTS = gql` `; export const SEARCH_GROUPS = gql` - query SearchGroups($term: String, $location: String, $radius: Float) { - searchGroups(term: $term, location: $location, radius: $radius) { + query SearchGroups($term: String, $location: String, $radius: Float, $page: Int, $limit: Int) { + searchGroups(term: $term, location: $location, radius: $radius, page: $page, limit: $limit) { total elements { avatar { diff --git a/js/src/types/search.model.ts b/js/src/types/search.model.ts index d72be8657..4d4ddaf9c 100644 --- a/js/src/types/search.model.ts +++ b/js/src/types/search.model.ts @@ -15,3 +15,8 @@ export interface SearchPerson { total: number; elements: IPerson[]; } + +export enum SearchTabs { + EVENTS = 0, + GROUPS = 1, +} diff --git a/js/src/views/Search.vue b/js/src/views/Search.vue index 5d9cc5405..205eaeac8 100644 --- a/js/src/views/Search.vue +++ b/js/src/views/Search.vue @@ -71,13 +71,27 @@ {{ searchEvents.total }} -
-
- +
+
+
+ +
+
+
{{ @@ -91,13 +105,27 @@ {{ $t("Groups") }} {{ searchGroups.total }} -
-
- +
+
+
+ +
+
+
@@ -129,10 +157,10 @@ import { FETCH_EVENTS } from "../graphql/event"; import { IEvent } from "../types/event.model"; import RouteName from "../router/name"; import { IAddress, Address } from "../types/address.model"; -import { SearchEvent, SearchGroup } from "../types/search.model"; import AddressAutoComplete from "../components/Event/AddressAutoComplete.vue"; import { SEARCH_EVENTS, SEARCH_GROUPS } from "../graphql/search"; import { Paginate } from "../types/paginate"; +import { SearchTabs } from "../types/search.model"; import { IGroup } from "../types/actor"; import GroupCard from "../components/Group/GroupCard.vue"; import { CONFIG } from "../graphql/config"; @@ -143,16 +171,15 @@ interface ISearchTimeOption { end?: Date | null; } -enum SearchTabs { - EVENTS = 0, - GROUPS = 1, -} - const tabsName: { events: number; groups: number } = { events: SearchTabs.EVENTS, groups: SearchTabs.GROUPS, }; +const EVENT_PAGE_LIMIT = 1; + +const GROUP_PAGE_LIMIT = 10; + @Component({ components: { EventCard, @@ -173,6 +200,8 @@ const tabsName: { events: number; groups: number } = { beginsOn: this.start, endsOn: this.end, radius: this.radius, + page: this.eventPage, + limit: EVENT_PAGE_LIMIT, }; }, debounce: 300, @@ -188,6 +217,8 @@ const tabsName: { events: number; groups: number } = { term: this.search, location: this.geohash, radius: this.radius, + page: this.groupPage, + limit: GROUP_PAGE_LIMIT, }; }, skip() { @@ -213,6 +244,10 @@ export default class Search extends Vue { searchGroups: Paginate = { total: 0, elements: [] }; + eventPage = 1; + + groupPage = 1; + search: string = (this.$route.query.term as string) || ""; activeTab: SearchTabs = tabsName[this.$route.query.searchType as "events" | "groups"] || 0; @@ -268,23 +303,27 @@ export default class Search extends Vue { end: null, }; - radiusString = (radius: number | null) => { + EVENT_PAGE_LIMIT = EVENT_PAGE_LIMIT; + + GROUP_PAGE_LIMIT = GROUP_PAGE_LIMIT; + + radiusString = (radius: number | null): string => { if (radius) { - return this.$tc("{nb} km", radius, { nb: radius }); + return this.$tc("{nb} km", radius, { nb: radius }) as string; } - return this.$t("any distance"); + return this.$t("any distance") as string; }; radiusOptions: (number | null)[] = [1, 5, 10, 25, 50, 100, 150, null]; radius = 50; - submit() { + submit(): void { this.$apollo.queries.searchEvents.refetch(); } @Watch("search") - updateSearchTerm() { + updateSearchTerm(): void { this.$router.push({ name: RouteName.SEARCH, query: { ...this.$route.query, term: this.search }, @@ -292,7 +331,7 @@ export default class Search extends Vue { } @Watch("activeTab") - updateActiveTab() { + updateActiveTab(): void { const searchType = this.activeTab === tabsName.events ? "events" : "groups"; this.$router.push({ name: RouteName.SEARCH, @@ -308,7 +347,7 @@ export default class Search extends Vue { return { start: startOfDay(start), end: endOfDay(end) }; } - get geohash() { + get geohash(): string | undefined { if (this.location && this.location.geom) { const [lon, lat] = this.location.geom.split(";"); return ngeohash.encode(lat, lon, 6);