debian-mirror-gitlab/app/assets/javascripts/vue_shared/components/table_pagination.vue

160 lines
4.1 KiB
Vue
Raw Normal View History

2017-09-10 17:25:29 +05:30
<script>
2018-12-13 13:39:08 +05:30
import { s__ } from '../../locale';
const PAGINATION_UI_BUTTON_LIMIT = 4;
const UI_LIMIT = 6;
const SPREAD = '...';
const PREV = s__('Pagination|Prev');
const NEXT = s__('Pagination|Next');
const FIRST = s__('Pagination|« First');
const LAST = s__('Pagination|Last »');
export default {
props: {
/**
2018-03-17 18:26:18 +05:30
This function will take the information given by the pagination component
2018-03-27 19:54:05 +05:30
Here is an example `change` method:
change(pagenum) {
gl.utils.visitUrl(`?page=${pagenum}`);
},
2018-03-17 18:26:18 +05:30
*/
2018-12-13 13:39:08 +05:30
change: {
type: Function,
required: true,
},
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
/**
2018-03-17 18:26:18 +05:30
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'],
});
*/
2018-12-13 13:39:08 +05:30
pageInfo: {
type: Object,
required: true,
},
},
computed: {
prev() {
return this.pageInfo.previousPage;
},
next() {
return this.pageInfo.nextPage;
},
getItems() {
2019-05-18 00:54:41 +05:30
const { totalPages, nextPage, previousPage, page } = this.pageInfo;
2018-12-13 13:39:08 +05:30
const items = [];
if (page > 1) {
items.push({ title: FIRST, first: true });
}
2019-05-18 00:54:41 +05:30
if (previousPage) {
2018-12-13 13:39:08 +05:30
items.push({ title: PREV, prev: true });
} else {
items.push({ title: PREV, disabled: true, prev: true });
}
if (page > UI_LIMIT) items.push({ title: SPREAD, separator: true });
2019-05-18 00:54:41 +05:30
if (totalPages) {
const start = Math.max(page - PAGINATION_UI_BUTTON_LIMIT, 1);
const end = Math.min(page + PAGINATION_UI_BUTTON_LIMIT, totalPages);
2018-12-13 13:39:08 +05:30
2019-05-18 00:54:41 +05:30
for (let i = start; i <= end; i += 1) {
const isActive = i === page;
items.push({ title: i, active: isActive, page: true });
}
2018-12-13 13:39:08 +05:30
2019-05-18 00:54:41 +05:30
if (totalPages - page > PAGINATION_UI_BUTTON_LIMIT) {
items.push({ title: SPREAD, separator: true, page: true });
}
2018-12-13 13:39:08 +05:30
}
2019-05-18 00:54:41 +05:30
if (nextPage) {
2018-12-13 13:39:08 +05:30
items.push({ title: NEXT, next: true });
2019-05-18 00:54:41 +05:30
} else {
items.push({ title: NEXT, disabled: true, next: true });
2018-12-13 13:39:08 +05:30
}
2019-05-18 00:54:41 +05:30
if (totalPages && totalPages - page >= 1) {
2018-12-13 13:39:08 +05:30
items.push({ title: LAST, last: true });
}
return items;
},
showPagination() {
2019-05-18 00:54:41 +05:30
return this.pageInfo.nextPage || this.pageInfo.previousPage;
2017-08-17 22:00:37 +05:30
},
2018-12-13 13:39:08 +05:30
},
methods: {
changePage(text, isDisabled) {
if (isDisabled) return;
const { totalPages, nextPage, previousPage } = this.pageInfo;
switch (text) {
case SPREAD:
break;
case LAST:
this.change(totalPages);
break;
case NEXT:
this.change(nextPage);
break;
case PREV:
this.change(previousPage);
break;
case FIRST:
this.change(1);
break;
default:
this.change(+text);
break;
}
2017-08-17 22:00:37 +05:30
},
2018-12-13 13:39:08 +05:30
hideOnSmallScreen(item) {
return !item.first && !item.last && !item.next && !item.prev && !item.active;
2017-08-17 22:00:37 +05:30
},
2018-12-13 13:39:08 +05:30
},
};
2017-09-10 17:25:29 +05:30
</script>
<template>
2019-02-15 15:39:39 +05:30
<div v-if="showPagination" class="gl-pagination prepend-top-default">
2018-11-08 19:23:39 +05:30
<ul class="pagination justify-content-center">
2017-09-10 17:25:29 +05:30
<li
2018-03-17 18:26:18 +05:30
v-for="(item, index) in getItems"
:key="index"
2017-09-10 17:25:29 +05:30
:class="{
page: item.page,
'js-previous-button': item.prev,
'js-next-button': item.next,
'js-last-button': item.last,
'js-first-button': item.first,
2018-11-08 19:23:39 +05:30
'd-none d-md-block': hideOnSmallScreen(item),
2017-09-10 17:25:29 +05:30
separator: item.separator,
active: item.active,
2019-02-15 15:39:39 +05:30
disabled: item.disabled || item.separator,
2018-03-17 18:26:18 +05:30
}"
2018-11-08 19:23:39 +05:30
class="page-item"
2018-03-17 18:26:18 +05:30
>
2019-05-18 00:54:41 +05:30
<button type="button" class="page-link" @click="changePage(item.title, item.disabled)">
2018-03-17 18:26:18 +05:30
{{ item.title }}
2019-05-18 00:54:41 +05:30
</button>
2017-09-10 17:25:29 +05:30
</li>
</ul>
</div>
</template>