186 lines
5.3 KiB
JavaScript
186 lines
5.3 KiB
JavaScript
"use strict";
|
|
|
|
const router = require("../router.js");
|
|
const keyboard = require("../util/keyboard.js");
|
|
const views = require("../util/views.js");
|
|
|
|
const holderTemplate = views.getTemplate("manual-pager");
|
|
const navTemplate = views.getTemplate("manual-pager-nav");
|
|
|
|
function _removeConsecutiveDuplicates(a) {
|
|
return a.filter((item, pos, ary) => {
|
|
return !pos || item !== ary[pos - 1];
|
|
});
|
|
}
|
|
|
|
function _getVisiblePageNumbers(currentPage, totalPages) {
|
|
const threshold = 2;
|
|
let pagesVisible = [];
|
|
for (let i = 1; i <= threshold; i++) {
|
|
pagesVisible.push(i);
|
|
}
|
|
for (let i = totalPages - threshold; i <= totalPages; i++) {
|
|
pagesVisible.push(i);
|
|
}
|
|
for (let i = currentPage - threshold; i <= currentPage + threshold; i++) {
|
|
pagesVisible.push(i);
|
|
}
|
|
pagesVisible = pagesVisible.filter((item, pos, ary) => {
|
|
return item >= 1 && item <= totalPages;
|
|
});
|
|
pagesVisible = pagesVisible.sort((a, b) => {
|
|
return a - b;
|
|
});
|
|
pagesVisible = _removeConsecutiveDuplicates(pagesVisible);
|
|
return pagesVisible;
|
|
}
|
|
|
|
function _getPages(
|
|
currentPage,
|
|
pageNumbers,
|
|
limit,
|
|
defaultLimit,
|
|
removedItems
|
|
) {
|
|
const pages = new Map();
|
|
let prevPage = 0;
|
|
for (let page of pageNumbers) {
|
|
if (page !== prevPage + 1) {
|
|
pages.set(page - 1, { ellipsis: true });
|
|
}
|
|
pages.set(page, {
|
|
number: page,
|
|
offset:
|
|
(page - 1) * limit - (page > currentPage ? removedItems : 0),
|
|
limit: limit === defaultLimit ? null : limit,
|
|
active: currentPage === page,
|
|
});
|
|
prevPage = page;
|
|
}
|
|
return pages;
|
|
}
|
|
|
|
class ManualPageView {
|
|
constructor(ctx) {
|
|
this._hostNode = document.getElementById("content-holder");
|
|
views.replaceContent(this._hostNode, holderTemplate());
|
|
}
|
|
|
|
run(ctx) {
|
|
const offset = parseInt(ctx.parameters.offset || 0);
|
|
const limit = parseInt(ctx.parameters.limit || ctx.defaultLimit);
|
|
this.clearMessages();
|
|
views.emptyContent(this._pageNavNode);
|
|
|
|
ctx.requestPage(offset, limit).then(
|
|
(response) => {
|
|
ctx.pageRenderer({
|
|
parameters: ctx.parameters,
|
|
response: response,
|
|
hostNode: this._pageContentHolderNode,
|
|
});
|
|
|
|
keyboard.bind(["a", "left"], () => {
|
|
this._navigateToPrevNextPage("prev");
|
|
});
|
|
keyboard.bind(["d", "right"], () => {
|
|
this._navigateToPrevNextPage("next");
|
|
});
|
|
|
|
let removedItems = 0;
|
|
if (response.total) {
|
|
this._refreshNav(
|
|
offset,
|
|
limit,
|
|
response.total,
|
|
removedItems,
|
|
ctx
|
|
);
|
|
}
|
|
|
|
if (!response.results.length) {
|
|
this.showInfo("No data to show");
|
|
}
|
|
|
|
response.results.addEventListener("remove", (e) => {
|
|
removedItems++;
|
|
this._refreshNav(
|
|
offset,
|
|
limit,
|
|
response.total,
|
|
removedItems,
|
|
ctx
|
|
);
|
|
});
|
|
|
|
views.syncScrollPosition();
|
|
},
|
|
(response) => {
|
|
this.showError(response.message);
|
|
}
|
|
);
|
|
}
|
|
|
|
get pageHeaderHolderNode() {
|
|
return this._hostNode.querySelector(".page-header-holder");
|
|
}
|
|
|
|
get _pageContentHolderNode() {
|
|
return this._hostNode.querySelector(".page-content-holder");
|
|
}
|
|
|
|
get _pageNavNode() {
|
|
return this._hostNode.querySelector(".page-nav");
|
|
}
|
|
|
|
clearMessages() {
|
|
views.clearMessages(this._hostNode);
|
|
}
|
|
|
|
showSuccess(message) {
|
|
views.showSuccess(this._hostNode, message);
|
|
}
|
|
|
|
showError(message) {
|
|
views.showError(this._hostNode, message);
|
|
}
|
|
|
|
showInfo(message) {
|
|
views.showInfo(this._hostNode, message);
|
|
}
|
|
|
|
_navigateToPrevNextPage(className) {
|
|
const linkNode = this._hostNode.querySelector("a." + className);
|
|
if (linkNode.classList.contains("disabled")) {
|
|
return;
|
|
}
|
|
router.show(linkNode.getAttribute("href"));
|
|
}
|
|
|
|
_refreshNav(offset, limit, total, removedItems, ctx) {
|
|
const currentPage = Math.floor((offset + limit - 1) / limit) + 1;
|
|
const totalPages = Math.ceil((total - removedItems) / limit);
|
|
const pageNumbers = _getVisiblePageNumbers(currentPage, totalPages);
|
|
const pages = _getPages(
|
|
currentPage,
|
|
pageNumbers,
|
|
limit,
|
|
ctx.defaultLimit,
|
|
removedItems
|
|
);
|
|
|
|
views.replaceContent(
|
|
this._pageNavNode,
|
|
navTemplate({
|
|
getClientUrlForPage: ctx.getClientUrlForPage,
|
|
prevPage: Math.min(totalPages, Math.max(1, currentPage - 1)),
|
|
nextPage: Math.min(totalPages, Math.max(1, currentPage + 1)),
|
|
currentPage: currentPage,
|
|
totalPages: totalPages,
|
|
pages: pages,
|
|
})
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = ManualPageView;
|