usePagination.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { computed, reactive, readonly, ref } from 'vue'
  3. import type { QueryHandler } from '#shared/server/apollo/handler/index.ts'
  4. import type {
  5. BaseConnection,
  6. OperationQueryResult,
  7. PaginationVariables,
  8. } from '#shared/types/server/apollo/handler.ts'
  9. import type { OperationVariables } from '@apollo/client/core'
  10. export default function usePagination<
  11. TQueryResult extends OperationQueryResult = OperationQueryResult,
  12. TQueryVariables extends OperationVariables = OperationVariables,
  13. >(
  14. query: QueryHandler<TQueryResult, TQueryVariables>,
  15. resultKey: string,
  16. pageSize: number,
  17. ) {
  18. const pageInfo = computed(() => {
  19. const result: OperationQueryResult = query.result().value || {}
  20. return (result[resultKey] as BaseConnection)?.pageInfo
  21. })
  22. const hasNextPage = computed(() => !!pageInfo.value?.hasNextPage)
  23. const hasPreviousPage = computed(() => !!pageInfo.value?.hasPreviousPage)
  24. const getInitialCurrentPage = (): number => {
  25. const result: OperationQueryResult = query.result().value || {}
  26. const data = result[resultKey] as BaseConnection
  27. if (!data) return 1
  28. const currentLength = data.edges?.length || 0
  29. if (!currentLength) return 1
  30. return Math.ceil(currentLength / pageSize)
  31. }
  32. const loadingNewPage = ref(false)
  33. const currentPage = ref(getInitialCurrentPage())
  34. return reactive({
  35. pageInfo: readonly(pageInfo),
  36. hasNextPage: readonly(hasNextPage),
  37. hasPreviousPage: readonly(hasPreviousPage),
  38. loadingNewPage: readonly(loadingNewPage),
  39. currentPage: readonly(currentPage),
  40. async fetchPreviousPage() {
  41. try {
  42. loadingNewPage.value = true
  43. await query.fetchMore({
  44. variables: {
  45. pageSize,
  46. cursor: pageInfo.value?.startCursor,
  47. } as Partial<TQueryVariables & PaginationVariables>,
  48. })
  49. } finally {
  50. currentPage.value -= 1
  51. loadingNewPage.value = false
  52. }
  53. },
  54. async fetchNextPage() {
  55. try {
  56. loadingNewPage.value = true
  57. await query.fetchMore({
  58. variables: {
  59. pageSize,
  60. cursor: pageInfo.value?.endCursor,
  61. } as Partial<TQueryVariables & PaginationVariables>,
  62. })
  63. } finally {
  64. currentPage.value += 1
  65. loadingNewPage.value = false
  66. }
  67. },
  68. })
  69. }