diff --git a/frontend/src/components/pagination.njk b/frontend/src/components/pagination.njk new file mode 100644 index 0000000..d8d1995 --- /dev/null +++ b/frontend/src/components/pagination.njk @@ -0,0 +1,40 @@ + + + +{% includeOnce 'components/button.njk' %} diff --git a/frontend/src/components/pagination.ts b/frontend/src/components/pagination.ts new file mode 100644 index 0000000..85aa9fa --- /dev/null +++ b/frontend/src/components/pagination.ts @@ -0,0 +1,83 @@ +import {TesoftComponent} from "../scripts/main.ts"; +import {TesoftButton} from "./button.ts"; + +export class TesoftPagination extends TesoftComponent { + static observedAttributes = ["cur-page", "last-page"]; + + private readonly curPageDiv: HTMLDivElement; + private readonly prevButton: TesoftButton; + private readonly nextButton: TesoftButton; + + constructor() { + super(); + + const template = document.getElementById("tesoft-pagination-template") as HTMLTemplateElement; + const templateContent = template.content; + + const shadowRoot = this.attachShadow({mode: "open"}); + shadowRoot.appendChild(templateContent.cloneNode(true)); + + this.curPageDiv = shadowRoot.querySelector(".cur-page")!; + this.prevButton = shadowRoot.querySelector(".prev")!; + this.nextButton = shadowRoot.querySelector(".next")!; + } + + // noinspection JSUnusedGlobalSymbols + attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) { + if (name === "cur-page") { + this.update(this.parsePage(newValue), this.parsePage(this.getAttribute("last-page"))); + } else if (name === "last-page") { + this.update(this.parsePage(this.getAttribute("cur-page")), this.parsePage(newValue)); + } + } + + set curPage(value: number) { + this.setAttribute("cur-page", value.toString()); + } + + set lastPage(value: number) { + this.setAttribute("last-page", value.toString()); + } + + private update(curPage: number, lastPage: number) { + this.curPageDiv.innerText = curPage.toString(); + + if (curPage <= 1) { + this.prevButton.setAttribute("disabled", ""); + } else { + this.prevButton.removeAttribute("disabled"); + } + this.prevButton.onclick = () => { + this.dispatchEvent(new CustomEvent("update-page", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + page: curPage - 1, + }, + })); + }; + + if (curPage >= lastPage) { + this.nextButton.setAttribute("disabled", ""); + } else { + this.nextButton.removeAttribute("disabled"); + } + this.nextButton.onclick = () => { + this.dispatchEvent(new CustomEvent("updatePage", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + page: curPage + 1, + }, + })); + }; + } + + private parsePage(str: string | null): number { + return str ? parseInt(str) : 1; + } +} + +customElements.define("tesoft-pagination", TesoftPagination);