|
| 1 | +from typing import Literal, Optional |
| 2 | + |
| 3 | +from django_components import Component, register |
| 4 | +from pydantic import BaseModel |
| 5 | + |
| 6 | +from base.pagination import PAGE_VAR, Pagination |
| 7 | +from base.templatetags.base_templatetags import querystring |
| 8 | + |
| 9 | + |
| 10 | +class PaginationItem(BaseModel): |
| 11 | + kind: Literal["current", "ellipsis", "number"] |
| 12 | + text: Optional[str | int] = None |
| 13 | + attrs: Optional[dict] = None |
| 14 | + |
| 15 | + |
| 16 | +@register("pagination") |
| 17 | +class PaginationComponent(Component): |
| 18 | + template_file = "pagination.html" |
| 19 | + |
| 20 | + class Kwargs(BaseModel): |
| 21 | + pagination_obj: Pagination |
| 22 | + model_config = {"arbitrary_types_allowed": True} |
| 23 | + |
| 24 | + def pagination_number(self, pagination: Pagination, num: int) -> PaginationItem: |
| 25 | + """ |
| 26 | + Generates a list of `PaginatedItem`, each representing an individual page with |
| 27 | + its associated properties in a pagination navigation list. |
| 28 | + """ |
| 29 | + if num == pagination.paginator.ELLIPSIS: |
| 30 | + return PaginationItem(kind="ellipsis", text=pagination.paginator.ELLIPSIS) |
| 31 | + elif num == pagination.page_num: |
| 32 | + return PaginationItem(kind="current", text=num) |
| 33 | + else: |
| 34 | + link = querystring(None, {**pagination.params, PAGE_VAR: num}) |
| 35 | + return PaginationItem( |
| 36 | + kind="number", |
| 37 | + text=num, |
| 38 | + attrs={"href": link}, |
| 39 | + ) |
| 40 | + |
| 41 | + def get_template_data(self, args, kwargs, slots, context): |
| 42 | + pagination = kwargs.pagination_obj |
| 43 | + page_elements = [self.pagination_number(pagination, page_num) for page_num in pagination.page_range] |
| 44 | + previous_page_link = f"?{PAGE_VAR}={pagination.page_num - 1}" if pagination.page.has_previous() else "" |
| 45 | + next_page_link = f"?{PAGE_VAR}={pagination.page_num + 1}" if pagination.page.has_next() else "" |
| 46 | + return { |
| 47 | + "pagination": pagination, |
| 48 | + "previous_page_link": previous_page_link, |
| 49 | + "next_page_link": next_page_link, |
| 50 | + "page_elements": page_elements, |
| 51 | + } |
0 commit comments