Skip to content

Commit c908181

Browse files
committed
Add support for Laravel API Resource responses
1 parent aa0b48a commit c908181

File tree

4 files changed

+154
-61
lines changed

4 files changed

+154
-61
lines changed

src/App.vue

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,51 @@
11
<template>
22
<div class="p-5">
3+
<p>Paginator Response:</p>
34
<pagination :data="laravelData" :limit="2" @pagination-change-page="getResults" />
5+
6+
<p>API Resource Response:</p>
7+
<pagination :data="laravelResourceData" :limit="2" @pagination-change-page="getResourceResults" />
48
</div>
59
</template>
610

711
<script>
812
import '../node_modules/bootstrap/dist/css/bootstrap.css';
913
import LaravelVuePagination from './LaravelVuePagination.vue';
1014
15+
const dummyData = [
16+
{ id: 1 },
17+
{ id: 2 },
18+
{ id: 3 },
19+
{ id: 4 },
20+
{ id: 5 },
21+
{ id: 6 },
22+
{ id: 7 },
23+
{ id: 8 },
24+
{ id: 9 },
25+
{ id: 10 },
26+
{ id: 11 },
27+
{ id: 12 },
28+
{ id: 13 },
29+
{ id: 14 },
30+
{ id: 15 },
31+
{ id: 16 },
32+
{ id: 17 },
33+
{ id: 18 },
34+
{ id: 19 },
35+
{ id: 20 }
36+
];
37+
1138
export default {
1239
data () {
1340
return {
14-
laravelData: {}
41+
laravelData: {},
42+
laravelResourceData: {}
1543
}
1644
},
1745
1846
mounted () {
1947
this.getResults();
48+
this.getResourceResults();
2049
},
2150
2251
methods: {
@@ -25,29 +54,6 @@ export default {
2554
page = 1;
2655
}
2756
28-
var dummyData = [
29-
{ id: 1 },
30-
{ id: 2 },
31-
{ id: 3 },
32-
{ id: 4 },
33-
{ id: 5 },
34-
{ id: 6 },
35-
{ id: 7 },
36-
{ id: 8 },
37-
{ id: 9 },
38-
{ id: 10 },
39-
{ id: 11 },
40-
{ id: 12 },
41-
{ id: 13 },
42-
{ id: 14 },
43-
{ id: 15 },
44-
{ id: 16 },
45-
{ id: 17 },
46-
{ id: 18 },
47-
{ id: 19 },
48-
{ id: 20 }
49-
];
50-
5157
this.laravelData = {
5258
current_page: page,
5359
data: dummyData,
@@ -59,6 +65,30 @@ export default {
5965
to: page + 1,
6066
total: dummyData.length
6167
};
68+
},
69+
getResourceResults (page) {
70+
if (!page) {
71+
page = 1;
72+
}
73+
74+
this.laravelResourceData = {
75+
data: dummyData,
76+
links: {
77+
first: 'http://example.com/page/1',
78+
last: 'http://example.com/page/' + dummyData.length,
79+
prev: page > 1 ? 'http://example.com/page/1' : null,
80+
next: page < dummyData.length ? 'http://example.com/page/2' : null
81+
},
82+
meta: {
83+
current_page: page,
84+
from: page,
85+
last_page: dummyData.length,
86+
path: 'http://example.com/page',
87+
per_page: 1,
88+
to: page + 1,
89+
total: dummyData.length
90+
}
91+
};
6292
}
6393
},
6494

src/LaravelVuePagination.vue

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
<template>
22
<renderless-laravel-vue-pagination :data="data" :limit="limit" v-on:pagination-change-page="onPaginationChangePage">
3-
<ul class="pagination" v-if="data.total > data.per_page" slot-scope="{ data, limit, pageRange, prevButtonEvents, nextButtonEvents, pageButtonEvents }">
4-
<li class="page-item pagination-prev-nav" v-if="data.prev_page_url">
3+
<ul class="pagination" v-if="computed.total > computed.perPage" slot-scope="{ data, limit, computed, prevButtonEvents, nextButtonEvents, pageButtonEvents }">
4+
<li class="page-item pagination-prev-nav" v-if="computed.prevPageUrl">
55
<a class="page-link" href="#" aria-label="Previous" v-on="prevButtonEvents">
66
<slot name="prev-nav">
77
<span aria-hidden="true">&laquo;</span>
88
<span class="sr-only">Previous</span>
99
</slot>
1010
</a>
1111
</li>
12-
<li class="page-item pagination-page-nav" v-for="(page, key) in pageRange" :key="key" :class="{ 'active': page == data.current_page }">
12+
<li class="page-item pagination-page-nav" v-for="(page, key) in computed.pageRange" :key="key" :class="{ 'active': page == computed.currentPage }">
1313
<a class="page-link" href="#" v-on="pageButtonEvents(page)">{{ page }}</a>
1414
</li>
15-
<li class="page-item pagination-next-nav" v-if="data.next_page_url">
15+
<li class="page-item pagination-next-nav" v-if="computed.nextPageUrl">
1616
<a class="page-link" href="#" aria-label="Next" v-on="nextButtonEvents">
1717
<slot name="next-nav">
1818
<span aria-hidden="true">&raquo;</span>
@@ -31,19 +31,7 @@ export default {
3131
props: {
3232
data: {
3333
type: Object,
34-
default: () => {
35-
return {
36-
current_page: 1,
37-
data: [],
38-
from: 1,
39-
last_page: 1,
40-
next_page_url: null,
41-
per_page: 10,
42-
prev_page_url: null,
43-
to: 1,
44-
total: 0
45-
}
46-
}
34+
default: () => {}
4735
},
4836
limit: {
4937
type: Number,

src/RenderlessLaravelVuePagination.vue

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,7 @@ export default {
33
props: {
44
data: {
55
type: Object,
6-
default: () => {
7-
return {
8-
current_page: 1,
9-
data: [],
10-
from: 1,
11-
last_page: 1,
12-
next_page_url: null,
13-
per_page: 10,
14-
prev_page_url: null,
15-
to: 1,
16-
total: 0
17-
}
18-
}
6+
default: () => {}
197
},
208
limit: {
219
type: Number,
@@ -24,17 +12,50 @@ export default {
2412
},
2513
2614
computed: {
15+
isApiResource () {
16+
return !!this.data.meta;
17+
},
18+
currentPage () {
19+
return this.isApiResource ? this.data.meta.current_page : this.data.current_page;
20+
},
21+
firstPageUrl () {
22+
return this.isApiResource ? this.data.links.first : null;
23+
},
24+
from () {
25+
return this.isApiResource ? this.data.meta.from : this.data.from;
26+
},
27+
lastPage () {
28+
return this.isApiResource ? this.data.meta.last_page : this.data.last_page;
29+
},
30+
lastPageUrl () {
31+
return this.isApiResource ? this.data.links.last : null;
32+
},
33+
nextPageUrl () {
34+
return this.isApiResource ? this.data.links.next : this.data.next_page_url;
35+
},
36+
perPage () {
37+
return this.isApiResource ? this.data.meta.per_page : this.data.per_page;
38+
},
39+
prevPageUrl () {
40+
return this.isApiResource ? this.data.links.prev : this.data.prev_page_url;
41+
},
42+
to () {
43+
return this.isApiResource ? this.data.meta.to : this.data.to;
44+
},
45+
total () {
46+
return this.isApiResource ? this.data.meta.total : this.data.total;
47+
},
2748
pageRange () {
2849
if (this.limit === -1) {
2950
return 0;
3051
}
3152
3253
if (this.limit === 0) {
33-
return this.data.last_page;
54+
return this.lastPage;
3455
}
3556
36-
var current = this.data.current_page;
37-
var last = this.data.last_page;
57+
var current = this.currentPage;
58+
var last = this.lastPage;
3859
var delta = this.limit;
3960
var left = current - delta;
4061
var right = current + delta + 1;
@@ -66,10 +87,10 @@ export default {
6687
6788
methods: {
6889
previousPage () {
69-
this.selectPage(--this.data.current_page);
90+
this.selectPage((this.currentPage - 1));
7091
},
7192
nextPage () {
72-
this.selectPage(++this.data.current_page);
93+
this.selectPage((this.currentPage + 1));
7394
},
7495
selectPage (page) {
7596
if (page === '...') {
@@ -84,7 +105,20 @@ export default {
84105
return this.$scopedSlots.default({
85106
data: this.data,
86107
limit: this.limit,
87-
pageRange: this.pageRange,
108+
computed: {
109+
isApiResource: this.isApiResource,
110+
currentPage: this.currentPage,
111+
firstPageUrl: this.firstPageUrl,
112+
from: this.from,
113+
lastPage: this.lastPage,
114+
lastPageUrl: this.lastPageUrl,
115+
nextPageUrl: this.nextPageUrl,
116+
perPage: this.perPage,
117+
prevPageUrl: this.prevPageUrl,
118+
to: this.to,
119+
total: this.total,
120+
pageRange: this.pageRange
121+
},
88122
prevButtonEvents: {
89123
click: (e) => {
90124
e.preventDefault();

tests/unit/LaravelVuePagination.spec.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,41 @@ var exampleData = {
2626
next_page_url: 'http://example.com/page/2',
2727
per_page: 2,
2828
prev_page_url: null,
29-
to: 3,
29+
to: 2,
3030
total: 11,
3131
};
3232

33+
var exampleResourceData = {
34+
data: [
35+
{ id: 1 },
36+
{ id: 2 },
37+
{ id: 3 },
38+
{ id: 4 },
39+
{ id: 5 },
40+
{ id: 6 },
41+
{ id: 7 },
42+
{ id: 8 },
43+
{ id: 9 },
44+
{ id: 10 },
45+
{ id: 11 },
46+
],
47+
links: {
48+
first: 'http://example.com/page/1',
49+
last: 'http://example.com/page/6',
50+
prev: null,
51+
next: 'http://example.com/page/2'
52+
},
53+
meta: {
54+
current_page: 1,
55+
from: 1,
56+
last_page: 6,
57+
path: 'http://example.com/page',
58+
per_page: 2,
59+
to: 2,
60+
total: 11,
61+
}
62+
};
63+
3364
describe('LaravelVuePagination', function() {
3465
it('has correct DOM structure', function() {
3566
const wrapper = getComponent(LaravelVuePagination, {
@@ -112,4 +143,14 @@ describe('LaravelVuePagination', function() {
112143
expect(wrapper.html()).toContain('<span class="custom-prev-nav">Previous</span>');
113144
expect(wrapper.html()).toContain('<span>Next</span>');
114145
});
146+
147+
it('has correct DOM structure for Laravel API Resource responses', function() {
148+
const wrapper = getComponent(LaravelVuePagination, {
149+
data: exampleResourceData
150+
});
151+
152+
expect(wrapper.contains('ul')).toBe(true);
153+
expect(wrapper.findAll('li').length).toBe(7);
154+
expect(wrapper.findAll('li').at(0).element.classList).toContain('active');
155+
});
115156
});

0 commit comments

Comments
 (0)