import classNames from "classnames"; import { LightningElement, api } from "lwc"; import { track } from "dxUtils/analytics"; enum PaginationClickType { Number, Next, Previous } export default class Pagination extends LightningElement { @api currentPage: string = "1"; @api totalPages: string = "1"; @api pagesToShow: string = "5"; private get _currentPage() { return parseInt(this.currentPage, 10); } private get _totalPages() { return parseInt(this.totalPages, 10); } private get _pagesToShow() { return parseInt(this.pagesToShow, 10); } private get hasPrev(): boolean { return this._currentPage > 1; } private get hasNext(): boolean { return this._currentPage < this._totalPages; } private get previousIsDisabled(): boolean { return !this.hasPrev; } private get nextIsDisabled(): boolean { return !this.hasNext; } private get rootClass(): string { return classNames( "dx-pagination", this.hasNext && "has-next", this.hasPrev && "has-prev" ); } private get pages(): { label: string; index: number; isCurrentPage: boolean; }[] { const offset = this._pagesToShow === 2 ? 2 : Math.ceil(this._pagesToShow / 2); let start = this._currentPage - offset + 1; let end = this._currentPage + offset - 1; if (this._totalPages < this._pagesToShow) { start = 1; end = this._totalPages; } else if (this._currentPage < offset) { start = 1; end = this._pagesToShow; } else if (this._currentPage + offset > this._totalPages) { start = this._totalPages - this._pagesToShow + 1; end = this._totalPages; } return [ ...Array.from(Array(end - start + 1).keys()).map((index) => { const page = index + start; return { label: `${page}`, index: page, isCurrentPage: page === this._currentPage }; }) ]; } private onPageChange(e: Event) { const page = this.calculatePage(e); const clickType = this.getPaginationClickType(e); const clickText = clickType === PaginationClickType.Number ? page : (e.target as HTMLElement).dataset.partId; track(e.currentTarget!, "custEv_pagination", { click_text: clickText, click_url: window.location.href, element_type: "button", nav_type: "pagination", nav_item: clickText }); this.dispatchEvent(new CustomEvent("pagechange", { detail: page })); } private getPaginationClickType(e: Event): PaginationClickType { const button = (e.target as HTMLElement).dataset.partId; if (button === "previous") { return PaginationClickType.Previous; } else if (button === "next") { return PaginationClickType.Next; } return PaginationClickType.Number; } private calculatePage(e: Event) { const clickType = this.getPaginationClickType(e); let page = 0; if (clickType === PaginationClickType.Previous) { page = this._currentPage - 1; } else if (clickType === PaginationClickType.Next) { page = this._currentPage + 1; } else { page = +(e.target as HTMLElement).dataset.pageId!; } return page; } }