Files
order_site/apps/frontend/src/composables/useAdminListPage.ts
T

63 lines
1.5 KiB
TypeScript

import { ref } from 'vue'
import type { ApiEnvelope } from '@/lib/http'
import type { AdminPagination } from '@/types/admin'
export interface AdminListPageData<TItem> {
items: TItem[]
pagination: AdminPagination
}
export interface UseAdminListPageOptions<TItem> {
defaultErrorMessage: string
pageSize?: number
fetchPage: (page: number, pageSize: number) => Promise<ApiEnvelope<AdminListPageData<TItem>>>
}
export function useAdminListPage<TItem>(options: UseAdminListPageOptions<TItem>) {
const loading = ref(true)
const errorMessage = ref('')
const items = ref<TItem[]>([])
const pagination = ref<AdminPagination>({
page: 1,
pageSize: options.pageSize ?? 20,
total: 0,
})
let latestRequestId = 0
async function loadPage(page = pagination.value.page) {
const requestId = ++latestRequestId
loading.value = true
errorMessage.value = ''
try {
const response = await options.fetchPage(page, pagination.value.pageSize)
if (requestId !== latestRequestId) {
return
}
items.value = response.data.items
pagination.value = response.data.pagination
} catch (error) {
if (requestId !== latestRequestId) {
return
}
errorMessage.value = error instanceof Error ? error.message : options.defaultErrorMessage
} finally {
if (requestId === latestRequestId) {
loading.value = false
}
}
}
return {
loading,
errorMessage,
items,
pagination,
loadPage,
}
}