Skip to content

Commit d92953e

Browse files
committed
Refactor ListOfItems template with infiniteScroll composable
1 parent 9cb6535 commit d92953e

File tree

2 files changed

+52
-44
lines changed

2 files changed

+52
-44
lines changed

components/ListOfItemsCollection.vue

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@ import { computed, ref } from 'vue'
44
import { useCollectionAggregator } from '../composables/useCollectionAggregator'
55
import config from '~/utils/searchConfig'
66
import normalizeTitleForAlphabeticalBrowse from '~/utils/normalizeTitleForAlphabeticalBrowseBy'
7+
import useMobileOnlyInfiniteScroll from '@/composables/useMobileOnlyInfiniteScroll'
78
89
const attrs = useAttrs() as { page?: { title: string, ftvaFilters: string[], ftvaHomepageDescription: string, titleBrowse: string, groupName: string } }
910
1011
const route = useRoute()
1112
const router = useRouter()
13+
1214
defineOptions({
1315
inheritAttrs: false
1416
})
17+
1518
interface AggregationBucket {
1619
key: string
1720
doc_count: number
1821
}
22+
1923
interface Aggregations {
2024
[key: string]: { buckets: AggregationBucket[] }
2125
}
@@ -37,20 +41,51 @@ if (attrs.page && import.meta.prerender) {
3741
}
3842
3943
// "STATE"
40-
const currentPage = ref(1)
4144
const documentsPerPage = 15 // show 15 search results at a time
42-
const totalPages = ref(0)
4345
const totalResults = ref(0)
4446
const noResultsFound = ref(false)
45-
const isLoading = ref<boolean>(false)
46-
const isMobile = ref(false)
47-
const hasMore = ref(true) // Flag to control infinite scroll
4847
49-
const collectionResults = ref([])
48+
// "STATE"
49+
const collectionFetchFunction = async () => {
50+
const { paginatedCollectionSearchFilters } = useListSearchFilter() // composable
51+
52+
const currpage = currentPage.value
53+
const size = documentsPerPage
54+
let results: any = {}
55+
56+
results = await paginatedCollectionSearchFilters(currpage, size, 'ftvaItemInCollection', titleForSearch.value, selectedFilters.value, selectedSortFilters.value.sortField)
57+
58+
return results
59+
}
60+
61+
const onResults = (results) => {
62+
if (results && results.hits && results?.hits?.hits?.length > 0) {
63+
const newCollectionResults = results.hits.hits || []
64+
totalResults.value = results.hits.total.value
65+
66+
if (isMobile.value) {
67+
totalPages.value = 0
68+
mobileItemList.value.push(...newCollectionResults)
69+
hasMore.value = currentPage.value < Math.ceil(results.hits.total.value / documentsPerPage)
70+
} else {
71+
desktopItemList.value = newCollectionResults
72+
totalPages.value = Math.ceil(results.hits.total.value / documentsPerPage)
73+
}
74+
noResultsFound.value = false
75+
} else {
76+
noResultsFound.value = true
77+
totalPages.value = 0
78+
hasMore.value = false
79+
}
80+
}
81+
82+
// INFINITE SCROLL
83+
const { isLoading, isMobile, hasMore, desktopPage, desktopItemList, mobileItemList, totalPages, currentPage, currentList, scrollElem, reset, searchES } = useMobileOnlyInfiniteScroll(collectionFetchFunction, onResults)
84+
5085
// format search results for SectionTeaserCard
5186
const parsedCollectionResults = computed(() => {
52-
if (collectionResults.value.length === 0) return []
53-
return collectionResults.value.map((obj) => {
87+
if (currentList.value.length === 0) return []
88+
return currentList.value.map((obj) => {
5489
const objImage = obj._source.ftvaImage.length ? obj._source.ftvaImage[0] : null
5590
return {
5691
...obj._source,
@@ -78,7 +113,9 @@ const sortDropdownData = {
78113
label: 'Sort by',
79114
fieldName: 'sortField'
80115
}
116+
81117
const selectedSortFilters = ref({ sortField: 'asc' })
118+
82119
function updateSort(newSort) {
83120
router.push({
84121
path: route.path,
@@ -102,7 +139,9 @@ function parseESConfigFilters(configFilters, ftvaFiltersArg) {
102139
}
103140
return parsedfilters
104141
}
142+
105143
const searchFilters = ref([])
144+
106145
function parseAggRes(response: Aggregations) {
107146
// console.log('parseAggRes response', response)
108147
const filters = (Object.entries(response) || []).map(([key, value]) => ({
@@ -128,6 +167,7 @@ function parseAggRes(response: Aggregations) {
128167
129168
return filters
130169
}
170+
131171
// fetch filters for the page from ES after page loads in Onmounted hook on the client side
132172
async function setFilters() {
133173
const parsedESConfigFiltersRes = parseESConfigFilters(config.collection.filters, ftvaFilters.value)
@@ -142,12 +182,14 @@ async function setFilters() {
142182
searchAggsResponse
143183
)
144184
}
185+
145186
const selectedFilters = ref({}) // initialise with empty filter
146187
// Object w key filter label and value ESFieldName for selected filter lookup
147188
const fieldNamefromLabel = {
148189
'Filter by Topic': 'ftvaCollectionGroup.title.keyword',
149190
'Filter by Season': 'episodeSeason.keyword'
150191
}
192+
151193
function updateFilters(newFilter) {
152194
const newFilterValue = Object.values(newFilter)[0]
153195
if (newFilterValue === '(none selected)') {
@@ -169,6 +211,7 @@ function updateFilters(newFilter) {
169211
})
170212
}
171213
}
214+
172215
const titleForSearch = computed(() => {
173216
// TODO: get the title from ES for the slug `in-the-life or la-rebellion`
174217
if (route.path.endsWith('filmography')) {
@@ -180,41 +223,6 @@ const titleForSearch = computed(() => {
180223
}
181224
})
182225
183-
// ELASTIC SEARCH FUNCTION
184-
async function searchES() {
185-
if (isLoading.value || !hasMore.value) return
186-
187-
isLoading.value = true
188-
189-
try {
190-
const currpage = currentPage.value
191-
const size = documentsPerPage
192-
let results: any = {}
193-
194-
const { paginatedCollectionSearchFilters } = useListSearchFilter()
195-
196-
results = await paginatedCollectionSearchFilters(currpage, size, 'ftvaItemInCollection', titleForSearch.value, selectedFilters.value, selectedSortFilters.value.sortField)
197-
if (results && results.hits && results.hits.hits.length > 0) {
198-
const newCollectionResults = results.hits.hits || []
199-
200-
collectionResults.value = newCollectionResults
201-
totalResults.value = results.hits.total.value
202-
totalPages.value = Math.ceil(results.hits.total.value / documentsPerPage)
203-
204-
noResultsFound.value = false
205-
} else {
206-
noResultsFound.value = true
207-
hasMore.value = false
208-
}
209-
} catch (error) {
210-
// eslint-disable-next-line no-console
211-
console.error('Error fetching data:', error)
212-
hasMore.value = false
213-
} finally {
214-
isLoading.value = false
215-
}
216-
}
217-
218226
// WATCHERS
219227
// This watcher is called when router pushes updates the query params
220228
watch(

pages/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// HELPERS
33
import _get from 'lodash/get'
44
import { useWindowSize } from '@vueuse/core'
5-
import { format } from 'date-fns/format'
5+
import { format } from 'date-fns'
66
77
// GQL
88
import FTVAHomepage from '../gql/queries/FTVAHomepage.gql'

0 commit comments

Comments
 (0)