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-card>
|
<v-card>
|
||||||
<v-data-table
|
<v-data-table-server
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:items="transactions"
|
:items="transactions"
|
||||||
|
:items-length="totalCount"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:items-per-page="50"
|
:items-per-page="itemsPerPage"
|
||||||
|
:page="page"
|
||||||
density="compact"
|
density="compact"
|
||||||
show-expand
|
show-expand
|
||||||
:expand-on-click="false"
|
:expand-on-click="false"
|
||||||
|
@update:options="onTableOptions"
|
||||||
>
|
>
|
||||||
<template #item.date="{ item }">{{ formatDate(item.date) }}</template>
|
<template #item.date="{ item }">{{ formatDate(item.date) }}</template>
|
||||||
<template #item.categoryName="{ item }">
|
<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>
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table-server>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<!-- Add/Edit Transaction Dialog -->
|
<!-- Add/Edit Transaction Dialog -->
|
||||||
@@ -202,6 +205,9 @@ import type { Transaction, Category, SplitFormItem } from '@/types'
|
|||||||
const props = defineProps<{ id?: string }>()
|
const props = defineProps<{ id?: string }>()
|
||||||
const accountsStore = useAccountsStore()
|
const accountsStore = useAccountsStore()
|
||||||
const transactions = ref<Transaction[]>([])
|
const transactions = ref<Transaction[]>([])
|
||||||
|
const totalCount = ref(0)
|
||||||
|
const page = ref(1)
|
||||||
|
const itemsPerPage = ref(50)
|
||||||
const categories = ref<Category[]>([])
|
const categories = ref<Category[]>([])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const accountName = ref('')
|
const accountName = ref('')
|
||||||
@@ -272,32 +278,37 @@ async function loadCategories() {
|
|||||||
async function loadTransactions() {
|
async function loadTransactions() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
if (props.id) {
|
if (props.id && !search.value && !startDate.value && !endDate.value && statusFilter.value === 'All') {
|
||||||
const { data } = await transactionsApi.getByAccount(props.id)
|
const { data } = await transactionsApi.getByAccount(props.id, page.value, itemsPerPage.value)
|
||||||
transactions.value = data.items
|
transactions.value = data.items
|
||||||
|
totalCount.value = data.totalCount
|
||||||
} else {
|
} else {
|
||||||
const { data } = await transactionsApi.search({})
|
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
|
transactions.value = data.items
|
||||||
|
totalCount.value = data.totalCount
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doSearch() {
|
function doSearch() {
|
||||||
loading.value = true
|
page.value = 1
|
||||||
try {
|
loadTransactions()
|
||||||
const { data } = await transactionsApi.search({
|
}
|
||||||
accountId: props.id || undefined,
|
|
||||||
searchText: search.value || undefined,
|
function onTableOptions(options: { page: number; itemsPerPage: number }) {
|
||||||
startDate: startDate.value || undefined,
|
page.value = options.page
|
||||||
endDate: endDate.value || undefined,
|
itemsPerPage.value = options.itemsPerPage
|
||||||
status: statusFilter.value === 'All' ? undefined : statusFilter.value,
|
loadTransactions()
|
||||||
})
|
|
||||||
transactions.value = data.items
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function openAddDialog() {
|
function openAddDialog() {
|
||||||
|
|||||||
Reference in New Issue
Block a user