Switch transactions to server-side pagination
Replace v-data-table with v-data-table-server so page changes fetch from the API instead of being limited to the first 50 results. Filters reset to page 1; page/size changes trigger a new API call with the correct page and pageSize parameters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -37,14 +37,17 @@
|
||||
</v-card>
|
||||
|
||||
<v-card>
|
||||
<v-data-table
|
||||
<v-data-table-server
|
||||
:headers="headers"
|
||||
:items="transactions"
|
||||
:items-length="totalCount"
|
||||
:loading="loading"
|
||||
:items-per-page="50"
|
||||
:items-per-page="itemsPerPage"
|
||||
:page="page"
|
||||
density="compact"
|
||||
show-expand
|
||||
:expand-on-click="false"
|
||||
@update:options="onTableOptions"
|
||||
>
|
||||
<template #item.date="{ item }">{{ formatDate(item.date) }}</template>
|
||||
<template #item.categoryName="{ item }">
|
||||
@@ -87,7 +90,7 @@
|
||||
<v-btn icon size="x-small" variant="text" color="error" @click="deleteTransaction(item.id)"><v-icon size="small">mdi-delete</v-icon></v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-data-table-server>
|
||||
</v-card>
|
||||
|
||||
<!-- Add/Edit Transaction Dialog -->
|
||||
@@ -202,6 +205,9 @@ import type { Transaction, Category, SplitFormItem } from '@/types'
|
||||
const props = defineProps<{ id?: string }>()
|
||||
const accountsStore = useAccountsStore()
|
||||
const transactions = ref<Transaction[]>([])
|
||||
const totalCount = ref(0)
|
||||
const page = ref(1)
|
||||
const itemsPerPage = ref(50)
|
||||
const categories = ref<Category[]>([])
|
||||
const loading = ref(false)
|
||||
const accountName = ref('')
|
||||
@@ -272,34 +278,39 @@ async function loadCategories() {
|
||||
async function loadTransactions() {
|
||||
loading.value = true
|
||||
try {
|
||||
if (props.id) {
|
||||
const { data } = await transactionsApi.getByAccount(props.id)
|
||||
if (props.id && !search.value && !startDate.value && !endDate.value && statusFilter.value === 'All') {
|
||||
const { data } = await transactionsApi.getByAccount(props.id, page.value, itemsPerPage.value)
|
||||
transactions.value = data.items
|
||||
totalCount.value = data.totalCount
|
||||
} else {
|
||||
const { data } = await transactionsApi.search({})
|
||||
transactions.value = data.items
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function doSearch() {
|
||||
loading.value = true
|
||||
try {
|
||||
const { data } = await transactionsApi.search({
|
||||
accountId: props.id || undefined,
|
||||
searchText: search.value || undefined,
|
||||
startDate: startDate.value || undefined,
|
||||
endDate: endDate.value || undefined,
|
||||
status: statusFilter.value === 'All' ? undefined : statusFilter.value,
|
||||
page: page.value,
|
||||
pageSize: itemsPerPage.value,
|
||||
})
|
||||
transactions.value = data.items
|
||||
totalCount.value = data.totalCount
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function doSearch() {
|
||||
page.value = 1
|
||||
loadTransactions()
|
||||
}
|
||||
|
||||
function onTableOptions(options: { page: number; itemsPerPage: number }) {
|
||||
page.value = options.page
|
||||
itemsPerPage.value = options.itemsPerPage
|
||||
loadTransactions()
|
||||
}
|
||||
|
||||
function openAddDialog() {
|
||||
editingTxn.value = false
|
||||
editingTxnId.value = ''
|
||||
|
||||
Reference in New Issue
Block a user