Merge pull request #806 from gradido/refactor-pagination-buttons

refactor: Pagination Buttons
This commit is contained in:
Moriz Wahl 2021-09-15 15:08:15 +02:00 committed by GitHub
commit 5c7ddb0ce4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 96 deletions

View File

@ -316,7 +316,7 @@ jobs:
report_name: Coverage Frontend
type: lcov
result_path: ./coverage/lcov.info
min_coverage: 60
min_coverage: 61
token: ${{ github.token }}
##############################################################################

View File

@ -3,11 +3,17 @@ import PaginationButtons from './PaginationButtons'
const localVue = global.localVue
const propsData = {
totalRows: 42,
perPage: 12,
value: 1,
}
describe('PaginationButtons', () => {
let wrapper
const Wrapper = () => {
return mount(PaginationButtons, { localVue })
return mount(PaginationButtons, { localVue, propsData })
}
describe('mount', () => {
@ -19,34 +25,20 @@ describe('PaginationButtons', () => {
expect(wrapper.find('div.pagination-buttons').exists()).toBeTruthy()
})
it('has previous page button disabled by default', () => {
expect(wrapper.find('button.previous-page').attributes('disabled')).toBe('disabled')
})
it('has bext page button disabled by default', () => {
expect(wrapper.find('button.next-page').attributes('disabled')).toBe('disabled')
})
it('shows the text "1 / 1" by default"', () => {
expect(wrapper.find('p.text-center').text()).toBe('1 / 1')
})
describe('with active buttons', () => {
beforeEach(async () => {
await wrapper.setProps({
hasNext: true,
hasPrevious: true,
})
})
it('emits show-previous when previous page button is clicked', () => {
wrapper.find('button.previous-page').trigger('click')
expect(wrapper.emitted('show-previous')).toBeTruthy()
})
it('emits show-next when next page button is clicked', () => {
it('emits input next page button is clicked', async () => {
wrapper.find('button.next-page').trigger('click')
expect(wrapper.emitted('show-next')).toBeTruthy()
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,16 +1,16 @@
<template>
<div class="pagination-buttons">
<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="$emit('show-previous')">
<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">{{ currentPage }} / {{ totalPages }}</p>
<p class="text-center pt-2">{{ value }} / {{ totalPages }}</p>
</b-col>
<b-col>
<b-button class="next-page" :disabled="!hasNext" @click="$emit('show-next')">
<b-button class="next-page" :disabled="!hasNext" @click="currentValue++">
<b-icon icon="chevron-right" variant="primary"></b-icon>
</b-button>
</b-col>
@ -21,10 +21,33 @@
export default {
name: 'PaginationButtons',
props: {
hasNext: { type: Boolean, default: false },
hasPrevious: { type: Boolean, default: false },
totalPages: { type: Number, default: 1 },
currentPage: { type: Number, default: 1 },
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

@ -84,13 +84,10 @@
</div>
</div>
<pagination-buttons
v-if="showPagination && transactionCount > pageSize"
:has-next="hasNext"
:has-previous="hasPrevious"
:total-pages="totalPages"
:current-page="currentPage"
@show-next="showNext"
@show-previous="showPrevious"
v-if="showPagination"
v-model="currentPage"
:per-page="pageSize"
:total-rows="transactionCount"
></pagination-buttons>
<div v-if="transactions.length === 0" class="mt-4 text-center">
<span>{{ $t('transaction.nullTransactions') }}</span>
@ -128,29 +125,13 @@ export default {
transactionCount: { type: Number, default: 0 },
showPagination: { type: Boolean, default: false },
},
watch: {
timestamp: {
immediate: true,
handler: 'updateTransactions',
},
},
computed: {
hasNext() {
return this.currentPage * this.pageSize < this.transactionCount
},
hasPrevious() {
return this.currentPage > 1
},
totalPages() {
return Math.ceil(this.transactionCount / this.pageSize)
},
},
methods: {
updateTransactions() {
this.$emit('update-transactions', {
firstPage: this.currentPage,
items: this.pageSize,
})
window.scrollTo(0, 0)
},
getProperties(givenType) {
const type = iconsByType[givenType]
@ -165,15 +146,14 @@ export default {
throwError(msg) {
throw new Error(msg)
},
showNext() {
this.currentPage++
},
watch: {
currentPage() {
this.updateTransactions()
window.scrollTo(0, 0)
},
showPrevious() {
this.currentPage--
this.updateTransactions()
window.scrollTo(0, 0)
timestamp: {
immediate: true,
handler: 'updateTransactions',
},
},
}

View File

@ -46,6 +46,9 @@ const apolloMock = jest.fn().mockResolvedValue({
})
const toastErrorMock = jest.fn()
const windowScrollToMock = jest.fn()
window.scrollTo = windowScrollToMock
describe('GdtTransactionList', () => {
let wrapper
@ -90,6 +93,10 @@ describe('GdtTransactionList', () => {
}),
)
})
it('scrolls to (0, 0) after API call', () => {
expect(windowScrollToMock).toBeCalledWith(0, 0)
})
})
describe('server returns error', () => {
@ -105,5 +112,21 @@ describe('GdtTransactionList', () => {
expect(toastErrorMock).toBeCalledWith('Ouch!')
})
})
describe('change of currentPage', () => {
it('calls the API after currentPage changes', async () => {
jest.clearAllMocks()
wrapper.setData({ currentPage: 2 })
await wrapper.vm.$nextTick()
expect(apolloMock).toBeCalledWith(
expect.objectContaining({
variables: {
currentPage: 2,
pageSize: 25,
},
}),
)
})
})
})
})

View File

@ -28,13 +28,9 @@
</div>
</div>
<pagination-buttons
v-if="transactionGdtCount > pageSize"
:has-next="hasNext"
:has-previous="hasPrevious"
:total-pages="totalPages"
:current-page="currentPage"
@show-next="showNext"
@show-previous="showPrevious"
v-model="currentPage"
:per-page="pageSize"
:total-rows="transactionGdtCount"
></pagination-buttons>
</div>
</template>
@ -52,23 +48,12 @@ export default {
},
data() {
return {
transactionsGdt: { default: () => [] },
transactionsGdt: [],
transactionGdtCount: { type: Number, default: 0 },
currentPage: 1,
pageSize: 25,
}
},
computed: {
hasNext() {
return this.currentPage * this.pageSize < this.transactionGdtCount
},
hasPrevious() {
return this.currentPage > 1
},
totalPages() {
return Math.ceil(this.transactionGdtCount / this.pageSize)
},
},
methods: {
async updateGdt() {
this.$apollo
@ -85,25 +70,21 @@ export default {
} = result
this.transactionsGdt = listGDTEntries.gdtEntries
this.transactionGdtCount = listGDTEntries.count
window.scrollTo(0, 0)
})
.catch((error) => {
this.$toasted.error(error.message)
})
},
showNext() {
this.currentPage++
this.updateGdt()
window.scrollTo(0, 0)
},
showPrevious() {
this.currentPage--
this.updateGdt()
window.scrollTo(0, 0)
},
},
mounted() {
this.updateGdt()
},
watch: {
currentPage() {
this.updateGdt()
},
},
}
</script>
<style>