Merge pull request #1677 from gradido/503-Transaction-List-Pagination-Pages-clickable

503 transaction list pagination pages clickable
This commit is contained in:
Alexander Friedland 2022-04-05 14:49:37 +02:00 committed by GitHub
commit c54ec6cf6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 99 additions and 178 deletions

View File

@ -23,6 +23,8 @@ describe('GddTransactionList', () => {
return mount(GddTransactionList, { localVue, mocks })
}
const decayStartBlock = new Date(2001, 8, 9)
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
@ -84,7 +86,6 @@ describe('GddTransactionList', () => {
describe('with transactions', () => {
beforeEach(async () => {
const decayStartBlock = new Date(2001, 8, 9)
await wrapper.setProps({
transactions: [
{
@ -406,78 +407,58 @@ describe('GddTransactionList', () => {
})
describe('pagination buttons', () => {
const transactions = Array.from({ length: 42 }, (_, idx) => {
return {
amount: '3.14',
balanceDate: '2021-04-29T17:26:40+00:00',
decay: {},
memo: 'Kreiszahl PI',
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
id: idx + 1,
typeId: 'RECEIVE',
balance: '33.33',
}
})
let paginationButtons
beforeEach(async () => {
await wrapper.setProps({
transactions,
transactions: Array.from({ length: 42 }, (_, idx) => {
return {
amount: '3.14',
balanceDate: '2021-04-29T17:26:40+00:00',
decay: {},
memo: 'Kreiszahl PI',
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
__typename: 'User',
},
id: idx + 1,
typeId: 'RECEIVE',
balance: '33.33',
}
}),
transactionCount: 42,
decayStartBlock,
pageSize: 25,
showPagination: true,
decayStartBlock: new Date(),
})
paginationButtons = wrapper.find('div.pagination-buttons')
})
it('shows the pagination buttons', () => {
expect(paginationButtons.exists()).toBeTruthy()
describe('next page button clicked', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.findComponent({ name: 'BPagination' }).vm.$emit('input', 2)
})
it('emits update transactions', () => {
expect(wrapper.emitted('update-transactions')).toEqual(
expect.arrayContaining([[{ currentPage: 2, pageSize: 25 }]]),
)
})
})
})
describe('show no pagination', () => {
beforeEach(async () => {
await wrapper.setProps({
transactions: [],
transactionCount: 2,
decayStartBlock,
pageSize: 25,
showPagination: false,
})
})
it('has the previous button disabled', () => {
expect(paginationButtons.find('button.previous-page').attributes('disabled')).toBe(
'disabled',
)
})
it('shows the text "1 / 2"', () => {
expect(paginationButtons.find('p.text-center').text()).toBe('1 math.div 2')
})
it('emits update-transactions when next button is clicked', async () => {
await paginationButtons.find('button.next-page').trigger('click')
expect(wrapper.emitted('update-transactions')[1]).toEqual([
{ currentPage: 2, pageSize: 25 },
])
})
it('shows text "2 / 2" when next button is clicked', async () => {
await paginationButtons.find('button.next-page').trigger('click')
expect(paginationButtons.find('p.text-center').text()).toBe('2 math.div 2')
})
it('has next-button disabled when next button is clicked', async () => {
await paginationButtons.find('button.next-page').trigger('click')
expect(paginationButtons.find('button.next-page').attributes('disabled')).toBe('disabled')
})
it('scrolls to top after loading next page', async () => {
await paginationButtons.find('button.next-page').trigger('click')
expect(scrollToMock).toBeCalled()
})
it('emits update-transactions when preivous button is clicked after next buton', async () => {
await paginationButtons.find('button.next-page').trigger('click')
await paginationButtons.find('button.previous-page').trigger('click')
expect(wrapper.emitted('update-transactions')[2]).toEqual([
{ currentPage: 1, pageSize: 25 },
])
expect(scrollToMock).toBeCalled()
it('shows no pagination buttons', () => {
expect(wrapper.find('ul.pagination').exists()).toBe(false)
})
})
})

View File

@ -63,12 +63,17 @@
</transaction-list-item>
</div>
</div>
<pagination-buttons
<b-pagination
v-if="showPagination"
class="mt-3"
pills
size="lg"
v-model="currentPage"
:per-page="pageSize"
:total-rows="transactionCount"
></pagination-buttons>
align="center"
></b-pagination>
<div v-if="transactionCount <= 0" class="mt-4 text-center">
<b-icon v-if="pending" icon="three-dots" animation="cylon"></b-icon>
<div v-else>{{ $t('transaction.nullTransactions') }}</div>
@ -78,7 +83,6 @@
<script>
import TransactionListItem from '@/components/TransactionListItem'
import PaginationButtons from '@/components/PaginationButtons'
import TransactionDecay from '@/components/Transactions/TransactionDecay'
import TransactionSend from '@/components/Transactions/TransactionSend'
import TransactionReceive from '@/components/Transactions/TransactionReceive'
@ -89,7 +93,6 @@ export default {
name: 'gdd-transaction-list',
components: {
TransactionListItem,
PaginationButtons,
TransactionDecay,
TransactionSend,
TransactionReceive,

View File

@ -155,8 +155,8 @@ describe('GdtTransactionList ', () => {
describe('change of currentPage', () => {
it('calls the API after currentPage changes', async () => {
jest.clearAllMocks()
wrapper.setData({ currentPage: 2 })
await wrapper.vm.$nextTick()
await wrapper.setData({ transactionGdtCount: 42 })
await wrapper.findComponent({ name: 'BPagination' }).vm.$emit('input', 2)
expect(apolloMock).toBeCalledWith(
expect.objectContaining({
variables: {
@ -166,6 +166,44 @@ describe('GdtTransactionList ', () => {
}),
)
})
describe('pagination buttons', () => {
describe('with transactionCount > pageSize', () => {
beforeEach(async () => {
apolloMock.mockResolvedValue({
data: {
listGDTEntries: {
count: 42,
gdtEntries: [],
},
},
})
wrapper = Wrapper()
})
it('shows the pagination buttons', () => {
expect(wrapper.find('ul.pagination').exists()).toBe(true)
})
})
describe('with transactionCount < pageSize', () => {
beforeEach(async () => {
apolloMock.mockResolvedValue({
data: {
listGDTEntries: {
count: 2,
gdtEntries: [],
},
},
})
wrapper = Wrapper()
})
it('shows no pagination buttons', () => {
expect(wrapper.find('ul.pagination').exists()).toBe(false)
})
})
})
})
})
})

View File

@ -27,23 +27,26 @@
></transaction>
</div>
</div>
<pagination-buttons
<b-pagination
v-if="transactionGdtCount > pageSize"
class="mt-3"
pills
size="lg"
v-model="currentPage"
:per-page="pageSize"
:total-rows="transactionGdtCount"
></pagination-buttons>
align="center"
></b-pagination>
</div>
</template>
<script>
import { listGDTEntriesQuery } from '@/graphql/queries'
import PaginationButtons from '@/components/PaginationButtons'
import Transaction from '@/components/Transaction.vue'
export default {
name: 'gdt-transaction-list',
components: {
PaginationButtons,
Transaction,
},
data() {

View File

@ -1,49 +0,0 @@
import { mount } from '@vue/test-utils'
import PaginationButtons from './PaginationButtons'
const localVue = global.localVue
const propsData = {
totalRows: 42,
perPage: 12,
value: 1,
}
describe('PaginationButtons', () => {
let wrapper
const mocks = {
$t: jest.fn((t) => t),
}
const Wrapper = () => {
return mount(PaginationButtons, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component', () => {
expect(wrapper.find('div.pagination-buttons').exists()).toBeTruthy()
})
describe('with active buttons', () => {
it('emits input next page button is clicked', async () => {
wrapper.find('button.next-page').trigger('click')
await wrapper.vm.$nextTick()
expect(wrapper.emitted().input[0]).toEqual([2])
})
it('emits input when previous page button is clicked', async () => {
wrapper.setProps({ value: 2 })
wrapper.setData({ currentValue: 2 })
await wrapper.vm.$nextTick()
wrapper.find('button.previous-page').trigger('click')
await wrapper.vm.$nextTick()
expect(wrapper.emitted().input[0]).toEqual([1])
})
})
})
})

View File

@ -1,53 +0,0 @@
<template>
<div class="pagination-buttons" v-if="totalRows > perPage">
<b-row class="m-4">
<b-col class="text-right">
<b-button class="previous-page" :disabled="!hasPrevious" @click="currentValue--">
<b-icon icon="chevron-left" variant="primary"></b-icon>
</b-button>
</b-col>
<b-col cols="3">
<p class="text-center pt-2">{{ value }} {{ $t('math.div') }} {{ totalPages }}</p>
</b-col>
<b-col>
<b-button class="next-page" :disabled="!hasNext" @click="currentValue++">
<b-icon icon="chevron-right" variant="primary"></b-icon>
</b-button>
</b-col>
</b-row>
</div>
</template>
<script>
export default {
name: 'PaginationButtons',
props: {
totalRows: { required: true },
perPage: { type: Number, required: true },
value: { type: Number, required: true },
},
data() {
return {
currentValue: { type: Number, default: 1 },
}
},
computed: {
hasNext() {
return this.value * this.perPage < this.totalRows
},
hasPrevious() {
return this.value > 1
},
totalPages() {
return Math.ceil(this.totalRows / this.perPage)
},
},
created() {
this.currentValue = this.value
},
watch: {
currentValue() {
if (this.currentValue !== this.value) this.$emit('input', this.currentValue)
},
},
}
</script>

View File

@ -143,7 +143,6 @@
"login": "Anmeldung",
"math": {
"aprox": "~",
"div": "/",
"equal": "=",
"exclaim": "!",
"pipe": "|"

View File

@ -143,7 +143,6 @@
"login": "Login",
"math": {
"aprox": "~",
"div": "/",
"equal": "=",
"exclaim": "!",
"pipe": "|"