swaf/src/Pagination.ts

89 lines
2.0 KiB
TypeScript
Raw Normal View History

2021-03-30 10:20:38 +02:00
import {WrappingError} from "./Utils";
2020-04-22 15:52:17 +02:00
2021-03-30 10:20:38 +02:00
export default class Pagination {
2020-04-22 15:52:17 +02:00
public readonly page: number;
public readonly perPage: number;
public readonly totalCount: number;
2021-03-30 10:20:38 +02:00
public constructor(page: number, perPage: number, totalCount: number) {
2020-04-22 15:52:17 +02:00
this.page = page;
this.perPage = perPage;
this.totalCount = totalCount;
2021-03-30 10:20:38 +02:00
if (this.page < 1 || this.page > this.lastPage) {
throw new PageNotFoundError(this.page);
}
2020-04-22 15:52:17 +02:00
}
public hasPrevious(): boolean {
return this.page > 1;
}
public hasNext(): boolean {
2021-03-30 10:20:38 +02:00
return this.page < this.lastPage;
}
public get lastPage(): number {
return Math.ceil(this.totalCount / this.perPage);
}
public previousPages(contextSize: number): number[] {
const pages = [];
let i = 1;
// Leftmost context
while (i < this.page && i <= contextSize) {
pages.push(i);
i++;
}
// Ellipsis
if (i < this.page - contextSize) {
pages.push(-1);
}
// Middle left context
i = Math.max(i, this.page - contextSize);
while (i < this.page) {
pages.push(i);
i++;
}
return pages;
2020-04-22 15:52:17 +02:00
}
2021-03-30 10:20:38 +02:00
public nextPages(contextSize: number): number[] {
const pages = [];
let i = this.page + 1;
// Middle right context
while (i <= this.lastPage && i <= this.page + contextSize) {
pages.push(i);
i++;
}
// Ellipsis
if (this.page + contextSize + 1 < this.lastPage - contextSize + 1) {
pages.push(-1);
}
// Rightmost context
i = Math.max(i, this.lastPage - contextSize + 1);
while (i <= this.lastPage) {
pages.push(i);
i++;
}
return pages;
}
}
export class PageNotFoundError extends WrappingError {
public constructor(
public readonly page: number,
) {
super(`Page ${page} not found.`);
}
}