From 85ccb643fe6fe89505364da4025ec86025eb7bf3 Mon Sep 17 00:00:00 2001 From: DarlanPrado Date: Fri, 24 Jul 2026 17:25:08 -0300 Subject: [PATCH 1/3] feat(module): enhance ModuleItem component with sortKey prop and update date handling; refactor module loading logic in index page --- app/components/module/ModuleItem.vue | 13 +++++---- app/composables/useModuleHealth.ts | 6 +++- app/pages/modules/index.vue | 41 ++++++++++++++-------------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/app/components/module/ModuleItem.vue b/app/components/module/ModuleItem.vue index d2535b59e..618fffa86 100644 --- a/app/components/module/ModuleItem.vue +++ b/app/components/module/ModuleItem.vue @@ -12,26 +12,27 @@ const props = withDefaults( showBadge?: boolean isAdded: boolean showAddButton?: boolean + sortKey?: string }>(), { showBadge: true, - showAddButton: true + showAddButton: true, + sortKey: 'downloads' } ) const { copy } = useClipboard() -const { selectedSort } = useModules() const { track } = useAnalytics() const publishedAgo = useTimeAgo(() => props.module.stats.publishedAt) const createdAgo = useTimeAgo(() => props.module.stats.createdAt) const relativeDate = computed(() => - selectedSort.value.key === 'publishedAt' ? publishedAgo.value : createdAgo.value + props.sortKey === 'publishedAt' ? publishedAgo.value : createdAgo.value ) const staticModuleDate = computed(() => - selectedSort.value.key === 'publishedAt' + props.sortKey === 'publishedAt' ? formatDateByLocale('en', props.module.stats.publishedAt) : formatDateByLocale('en', props.module.stats.createdAt) ) @@ -181,7 +182,7 @@ const items = computed(() => [ - + [ - + { key: 'modules-health', server: false, lazy: true, - default: () => ({}) + dedupe: 'defer', + default: () => ({}), + getCachedData(key, nuxtApp) { + return nuxtApp.payload.data[key] ?? nuxtApp.static.data[key] + } }) return { health } diff --git a/app/pages/modules/index.vue b/app/pages/modules/index.vue index c31fcaabf..b78adc2a7 100644 --- a/app/pages/modules/index.vue +++ b/app/pages/modules/index.vue @@ -56,35 +56,30 @@ defineShortcuts({ }) const ITEMS_PER_PAGE = 9 +const INITIAL_VISIBLE = ITEMS_PER_PAGE * 2 const SCROLL_THRESHOLD = 450 -const displayedModules = ref([]) +const visibleCount = ref(INITIAL_VISIBLE) const isLoading = ref(false) +const displayedModules = computed(() => + filteredModules.value.slice(0, visibleCount.value) +) + const { y: scrollY } = useWindowScroll() const { copy } = useClipboard() const loadMoreModules = () => { if (isLoading.value) return - - const currentLength = displayedModules.value.length - if (currentLength >= filteredModules.value.length) return + if (visibleCount.value >= filteredModules.value.length) return isLoading.value = true setTimeout(() => { - const nextItems = filteredModules.value.slice( - currentLength, - currentLength + ITEMS_PER_PAGE - ) - displayedModules.value.push(...nextItems) + visibleCount.value += ITEMS_PER_PAGE isLoading.value = false }, 300) } -const initializeModules = () => { - displayedModules.value = filteredModules.value.slice(0, ITEMS_PER_PAGE * 2) -} - const debouncedLoadMore = useDebounceFn(loadMoreModules, 50) watch(scrollY, (y) => { @@ -93,11 +88,18 @@ watch(scrollY, (y) => { } }) -watch(filteredModules, () => { - isLoading.value = false - displayedModules.value = [] - initializeModules() -}) +watch( + () => [ + q.value, + selectedCategory.value?.key, + selectedSort.value?.key, + selectedOrder.value?.key + ], + () => { + isLoading.value = false + visibleCount.value = INITIAL_VISIBLE + } +) const copyAllInstallCommands = () => { const moduleNames = modulesToAdd.value.map(module => module.name).join(' ') @@ -137,8 +139,6 @@ Steps: const clearAllModules = () => { modulesToAdd.value = [] } - -initializeModules()