feat(frontend): implement P1 admin list improvements
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user