Skip to content

Commit

Permalink
Basic working Pagination for donations
Browse files Browse the repository at this point in the history
Related to Issue #42
  • Loading branch information
BobChao87 committed Mar 5, 2022
1 parent 00387b0 commit 716e3e4
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
30 changes: 24 additions & 6 deletions components/element/table/Paginator.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
<template>
<!-- XXX @click.native will stop working in Vue v3+ (Vue Router v4+), but @click should start working -->
<nav class="element-table-paginator pagination is-centered" role="navigation" aria-label="pagination">
<ElementLink class="pagination-previous">
<ElementLink class="button pagination-previous" @click.native="emitClick(pageData.number - 1)">
<FontAwesomeIcon :icon="[ 'fas', 'caret-left' ]" />
</ElementLink>
<ul class="pagination-list">
<template v-for="pageMeta in pagesMeta">
<li v-if="!pageMeta.spacer" :key="`link-${pageMeta.pageIndex}`">
<ElementLink class="pagination-link" :class="isCurrent(pageMeta.pageIndex)">
{{ $n(pageMeta.pageIndex + 1) }}
<ElementLink class="button pagination-link" :class="isCurrent(pageMeta.pageIndex)" :to="linkTo(pageMeta.pageIndex)" @click.native="emitClick(pageMeta.pageIndex)">
{{ $n(pageMeta.pageIndex + 1) }}
</ElementLink>
</li>
<li v-else :key="`ellipsis-${pageMeta.pageIndex}`">
<FontAwesomeIcon :icon="[ 'fas', 'ellipsis-h' ]" />
</li>
</template>
</ul>
<ElementLink class="pagination-next">
<ElementLink class="button pagination-next" @click.native="emitClick(pageData.number + 1)">
<FontAwesomeIcon :icon="[ 'fas', 'caret-right' ]" />
</ElementLink>
</nav>
</template>

<script lang="ts">
import Vue from 'vue';
import { Location } from 'vue-router';
import { OengusPagination } from '~/types/api/oengus-api';
interface PaginatorMeta {
Expand All @@ -36,13 +38,19 @@ export default Vue.extend({
type: Object as () => OengusPagination<any>,
default: undefined,
},
/** Pass this to have paginator handle pagination via the given URL pattern, e.g. 'page/{}' makes ./page/1 */
pageChangePathTemplate: {
type: String,
default: undefined,
},
},
computed: {
pagesMeta(): Array<PaginatorMeta> {
let pages = new Set([ this.pageData.number - 1, this.pageData.number, this.pageData.number + 1, this.pageData.totalPages - 1 ]);
const pages = new Set([ this.pageData.number - 1, this.pageData.number, this.pageData.number + 1, this.pageData.totalPages - 1 ]);
return [ ...pages.values() ]
.filter(a => a > 0)
// Exclude 0 because we always include 0 manually later
.filter(a => a > 0 && a < this.pageData.totalPages)
.sort((a, b) => a - b)
.reduce((pagesMeta, pageIndex) => {
if (pagesMeta[pagesMeta.length - 1].pageIndex + 1 < pageIndex) {
Expand All @@ -60,6 +68,16 @@ export default Vue.extend({
'is-current': pageIndex === this.pageData.number,
};
},
linkTo(pageNumber: number): undefined|Location {
// Computers use 0-indexed, but humans like 1-indexed, so these all use 1-indexed
pageNumber++;
if (this.pageChangePathTemplate) {
return { path: this.pageChangePathTemplate.replaceAll('{}', pageNumber.toString()) };
}
},
emitClick(pageNumber: number) {
this.$emit('pageChanged', pageNumber);
},
},
});
</script>
Expand Down
33 changes: 28 additions & 5 deletions components/marathon/donation/List.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
</ElementTableCell>

<MarathonDonationRow v-for="(donation, index) of donations" :key="donation.id" :class="getRowParity(index)" :donation="donation" :donation-currency="donationCurrency" />

<template #pagination>
<ElementTablePaginator :page-data="donationsPage" page-change-path-template="?donations-page={}" />
</template>
</ElementTable>
</div>
</template>
Expand Down Expand Up @@ -75,13 +79,34 @@ export default Vue.extend({
},
},
watch: {
$route(): void {
this.updatePage();
},
page(newPage, oldPage): void {
if (newPage !== oldPage) {
this.$fetch();
}
},
},
mounted(): void {
this.updatePage();
},
methods: {
getRowParity(index: number): { 'is-even': boolean, 'is-odd': boolean } {
return {
'is-even': index % 2 === 0,
'is-odd': index % 2 === 1,
};
},
updatePage(): void {
if (typeof this.$route.query['donations-page'] === 'string') {
// Convert from 1-indexed to 0-indexed
this.page = Number.parseInt(this.$route.query['donations-page']) - 1;
}
},
...mapActions({
getDonations: 'api/donation/get',
getMarathon: 'api/marathon/get',
Expand All @@ -99,11 +124,9 @@ export default Vue.extend({
500px null (1fr auto 2fr),
));
@media (max-width: 500px) {
& ::v-deep .name,
& ::v-deep .comment {
overflow-x: auto;
}
& ::v-deep .name,
& ::v-deep .comment {
overflow-x: auto;
}
}
</style>

0 comments on commit 716e3e4

Please sign in to comment.