gitlab-org--gitlab-foss/app/assets/javascripts/vue_shared/components/table_pagination.js

148 lines
3.8 KiB
JavaScript
Raw Normal View History

/* global Vue, gl */
2016-11-08 21:57:16 +00:00
/* eslint-disable no-param-reassign, no-plusplus */
window.Vue = require('vue');
((gl) => {
2016-11-18 22:26:49 +00:00
const PAGINATION_UI_BUTTON_LIMIT = 4;
const UI_LIMIT = 6;
2016-11-18 22:26:49 +00:00
const SPREAD = '...';
const PREV = 'Prev';
const NEXT = 'Next';
const FIRST = '<< First';
const LAST = 'Last >>';
gl.VueGlPagination = Vue.extend({
2016-12-15 17:28:17 +00:00
props: {
2017-01-13 21:54:16 +00:00
// TODO: Consider refactoring in light of turbolinks removal.
/**
This function will take the information given by the pagination component
Here is an example `change` method:
change(pagenum) {
gl.utils.visitUrl(`?page=${pagenum}`);
},
*/
2016-12-15 17:28:17 +00:00
change: {
type: Function,
required: true,
},
/**
pageInfo will come from the headers of the API call
in the `.then` clause of the VueResource API call
there should be a function that contructs the pageInfo for this component
This is an example:
const pageInfo = headers => ({
perPage: +headers['X-Per-Page'],
page: +headers['X-Page'],
total: +headers['X-Total'],
totalPages: +headers['X-Total-Pages'],
nextPage: +headers['X-Next-Page'],
previousPage: +headers['X-Prev-Page'],
});
*/
2016-12-15 17:28:17 +00:00
pageInfo: {
type: Object,
required: true,
},
},
methods: {
changePage(e) {
const text = e.target.innerText;
const { totalPages, nextPage, previousPage } = this.pageInfo;
2017-01-06 21:11:42 +00:00
switch (text) {
case SPREAD:
break;
case LAST:
this.change(totalPages);
2017-01-06 21:11:42 +00:00
break;
case NEXT:
this.change(nextPage);
2017-01-06 21:11:42 +00:00
break;
case PREV:
this.change(previousPage);
2017-01-06 21:11:42 +00:00
break;
case FIRST:
this.change(1);
2017-01-06 21:11:42 +00:00
break;
default:
this.change(+text);
2017-01-06 21:11:42 +00:00
break;
}
},
},
computed: {
2016-12-07 20:35:26 +00:00
prev() {
return this.pageInfo.previousPage;
},
next() {
return this.pageInfo.nextPage;
2016-11-08 22:03:25 +00:00
},
2016-11-08 19:23:29 +00:00
getItems() {
2016-12-07 20:35:26 +00:00
const total = this.pageInfo.totalPages;
const page = this.pageInfo.page;
2016-11-08 19:23:29 +00:00
const items = [];
2016-12-07 20:35:26 +00:00
if (page > 1) items.push({ title: FIRST });
2016-11-08 21:57:16 +00:00
if (page > 1) {
2017-01-04 20:41:18 +00:00
items.push({ title: PREV, prev: true });
2016-11-08 21:57:16 +00:00
} else {
2017-01-04 20:41:18 +00:00
items.push({ title: PREV, disabled: true, prev: true });
2016-11-08 21:57:16 +00:00
}
2016-11-08 19:23:29 +00:00
if (page > UI_LIMIT) items.push({ title: SPREAD, separator: true });
2016-11-08 19:23:29 +00:00
2016-11-18 22:26:49 +00:00
const start = Math.max(page - PAGINATION_UI_BUTTON_LIMIT, 1);
const end = Math.min(page + PAGINATION_UI_BUTTON_LIMIT, total);
2016-11-08 21:23:16 +00:00
2016-11-08 21:57:16 +00:00
for (let i = start; i <= end; i++) {
const isActive = i === page;
2017-01-04 20:41:18 +00:00
items.push({ title: i, active: isActive, page: true });
2016-11-08 21:57:16 +00:00
}
2016-11-08 21:23:16 +00:00
2016-11-18 22:26:49 +00:00
if (total - page > PAGINATION_UI_BUTTON_LIMIT) {
2017-01-04 20:41:18 +00:00
items.push({ title: SPREAD, separator: true, page: true });
2016-11-18 22:26:49 +00:00
}
2016-11-08 21:57:16 +00:00
if (page === total) {
2017-01-04 20:41:18 +00:00
items.push({ title: NEXT, disabled: true, next: true });
2016-11-08 21:57:16 +00:00
} else if (total - page >= 1) {
2017-01-04 20:41:18 +00:00
items.push({ title: NEXT, next: true });
2016-11-08 21:57:16 +00:00
}
2017-01-04 20:41:18 +00:00
if (total - page >= 1) items.push({ title: LAST, last: true });
2016-11-08 19:23:29 +00:00
return items;
},
},
template: `
<div class="gl-pagination">
2017-01-04 20:41:18 +00:00
<ul class="pagination clearfix">
<li v-for='item in getItems'
2016-11-08 21:57:16 +00:00
:class='{
2017-01-04 20:41:18 +00:00
page: item.page,
prev: item.prev,
next: item.next,
2016-11-08 21:57:16 +00:00
separator: item.separator,
active: item.active,
disabled: item.disabled
}'
2016-11-08 21:23:16 +00:00
>
<a @click="changePage($event)">{{item.title}}</a>
2016-11-08 21:23:16 +00:00
</li>
</ul>
</div>
`,
});
})(window.gl || (window.gl = {}));