From 1447b3fb8a155491ac8d0e1b364c18f424ea8394 Mon Sep 17 00:00:00 2001 From: christianbeeznst Date: Fri, 18 Oct 2024 12:06:13 -0500 Subject: [PATCH 1/2] Course: Implement infinite scroll to load more than 30 courses - refs BT#22105 --- assets/vue/graphql/queries/CourseRelUser.js | 49 ++++++++------ assets/vue/views/user/courses/List.vue | 74 ++++++++++++++++++--- 2 files changed, 93 insertions(+), 30 deletions(-) diff --git a/assets/vue/graphql/queries/CourseRelUser.js b/assets/vue/graphql/queries/CourseRelUser.js index 68429daef6..575a541d26 100644 --- a/assets/vue/graphql/queries/CourseRelUser.js +++ b/assets/vue/graphql/queries/CourseRelUser.js @@ -1,32 +1,37 @@ import gql from 'graphql-tag'; export const GET_COURSE_REL_USER = gql` - query getCourses($user: String!) { - courseRelUsers(user: $user) { - edges { + query getCourses($user: String!, $first: Int!, $after: String) { + courseRelUsers(user: $user, first: $first, after: $after) { + edges { + cursor + node { + course { + _id, + title, + illustrationUrl, + duration, + users(status: 1, first: 4) { + edges { node { - course { - _id, - title, - illustrationUrl, - duration, - users(status: 1, first: 4) { - edges { - node { - id - status - user { - illustrationUrl, - username, - fullName - } - } - } - } - } + id + status + user { + illustrationUrl, + username, + fullName + } } + } } + } } + } + pageInfo { + endCursor + hasNextPage + } } + } `; diff --git a/assets/vue/views/user/courses/List.vue b/assets/vue/views/user/courses/List.vue index f666e05ab3..2d83022f52 100644 --- a/assets/vue/views/user/courses/List.vue +++ b/assets/vue/views/user/courses/List.vue @@ -4,7 +4,7 @@
@@ -23,10 +23,11 @@
+
From 5ae508e94a87224f19195abf43bf9bd7572a2201 Mon Sep 17 00:00:00 2001 From: christianbeeznst Date: Mon, 25 Nov 2024 23:22:07 -0500 Subject: [PATCH 2/2] Internal: Fix: Reset course list to avoid duplication on page reload - refs BT#22105 --- assets/vue/views/user/courses/List.vue | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/assets/vue/views/user/courses/List.vue b/assets/vue/views/user/courses/List.vue index 2d83022f52..d6dd9cbcba 100644 --- a/assets/vue/views/user/courses/List.vue +++ b/assets/vue/views/user/courses/List.vue @@ -97,6 +97,14 @@ const loadMoreCourses = () => { updateQuery: (previousResult, {fetchMoreResult}) => { if (!fetchMoreResult) return previousResult + const newCourses = fetchMoreResult.courseRelUsers.edges.map(({ node }) => node.course) + const filteredCourses = newCourses.filter( + (newCourse) => !courses.value.some((existingCourse) => existingCourse._id === newCourse._id) + ) + courses.value.push(...filteredCourses) + endCursor.value = fetchMoreResult.courseRelUsers.pageInfo.endCursor + hasMore.value = fetchMoreResult.courseRelUsers.pageInfo.hasNextPage + return { ...previousResult, courseRelUsers: { @@ -105,10 +113,12 @@ const loadMoreCourses = () => { }, } }, + }).finally(() => { + isLoading.value = false }) } -const observer = new IntersectionObserver((entries) => { +let observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { loadMoreCourses(); } @@ -117,6 +127,20 @@ const observer = new IntersectionObserver((entries) => { }) onMounted(() => { + courses.value = [] + endCursor.value = null + hasMore.value = true + isLoading.value = false + + if (observer) observer.disconnect() + observer = new IntersectionObserver((entries) => { + if (entries[0].isIntersecting) { + loadMoreCourses() + } + }, { + rootMargin: '300px', + }) + loadMoreCourses() })