mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-07 00:20:07 +00:00
* knip: Don't ignore exports that are only used within a given file * knip: More pruning after rebase * knip: Vite plugin config fix * knip: vitest plugin config * knip: Playwright config, remove unnecessary ignores. * knip: Simplify project file enumeration. * knip: simplify the config file patterns ?(.optional_segment) * knip: tailwind v4 fix * knip: A little more, explain some of the deps. Should be good for this PR. * knip: remove unused disabling of classMembers. It's opt-in, which we should probably do. * knip: floating comments We should probably delete _one_ of these parallell trees, right? * knip: Add additional entrypoints * knip: Restore UserData that's exposed via the types for now. * knip: Add as an entry file even though knip says it's not necessary. * knip: re-export functions used by nodes (h/t @christian-byrne)
108 lines
2.7 KiB
TypeScript
108 lines
2.7 KiB
TypeScript
import { type Ref, computed, ref, shallowRef, watch } from 'vue'
|
|
|
|
interface LazyPaginationOptions {
|
|
itemsPerPage?: number
|
|
initialPage?: number
|
|
}
|
|
|
|
export function useLazyPagination<T>(
|
|
items: Ref<T[]> | T[],
|
|
options: LazyPaginationOptions = {}
|
|
) {
|
|
const { itemsPerPage = 12, initialPage = 1 } = options
|
|
|
|
const currentPage = ref(initialPage)
|
|
const isLoading = ref(false)
|
|
const loadedPages = shallowRef(new Set<number>([]))
|
|
|
|
// Get reactive items array
|
|
const itemsArray = computed(() => {
|
|
const itemData = 'value' in items ? items.value : items
|
|
return Array.isArray(itemData) ? itemData : []
|
|
})
|
|
|
|
// Simulate pagination by slicing the items
|
|
const paginatedItems = computed(() => {
|
|
const itemData = itemsArray.value
|
|
if (itemData.length === 0) {
|
|
return []
|
|
}
|
|
|
|
const loadedPageNumbers = Array.from(loadedPages.value).sort(
|
|
(a, b) => a - b
|
|
)
|
|
const maxLoadedPage = Math.max(...loadedPageNumbers, 0)
|
|
const endIndex = maxLoadedPage * itemsPerPage
|
|
return itemData.slice(0, endIndex)
|
|
})
|
|
|
|
const hasMoreItems = computed(() => {
|
|
const itemData = itemsArray.value
|
|
if (itemData.length === 0) {
|
|
return false
|
|
}
|
|
|
|
const loadedPagesArray = Array.from(loadedPages.value)
|
|
const maxLoadedPage = Math.max(...loadedPagesArray, 0)
|
|
return maxLoadedPage * itemsPerPage < itemData.length
|
|
})
|
|
|
|
const totalPages = computed(() => {
|
|
const itemData = itemsArray.value
|
|
if (itemData.length === 0) {
|
|
return 0
|
|
}
|
|
return Math.ceil(itemData.length / itemsPerPage)
|
|
})
|
|
|
|
const loadNextPage = async () => {
|
|
if (isLoading.value || !hasMoreItems.value) return
|
|
|
|
isLoading.value = true
|
|
const loadedPagesArray = Array.from(loadedPages.value)
|
|
const nextPage = Math.max(...loadedPagesArray, 0) + 1
|
|
|
|
// Simulate network delay
|
|
// await new Promise((resolve) => setTimeout(resolve, 5000))
|
|
|
|
const newLoadedPages = new Set(loadedPages.value)
|
|
newLoadedPages.add(nextPage)
|
|
loadedPages.value = newLoadedPages
|
|
currentPage.value = nextPage
|
|
isLoading.value = false
|
|
}
|
|
|
|
// Initialize with first page
|
|
watch(
|
|
() => itemsArray.value.length,
|
|
(length) => {
|
|
if (length > 0 && loadedPages.value.size === 0) {
|
|
loadedPages.value = new Set([1])
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
const reset = () => {
|
|
currentPage.value = initialPage
|
|
loadedPages.value = new Set([])
|
|
isLoading.value = false
|
|
|
|
// Immediately load first page if we have items
|
|
const itemData = itemsArray.value
|
|
if (itemData.length > 0) {
|
|
loadedPages.value = new Set([1])
|
|
}
|
|
}
|
|
|
|
return {
|
|
paginatedItems,
|
|
isLoading,
|
|
hasMoreItems,
|
|
currentPage,
|
|
totalPages,
|
|
loadNextPage,
|
|
reset
|
|
}
|
|
}
|