diff --git a/CHANGELOG.md b/CHANGELOG.md index 894a1390..837d0154 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,9 @@ Using the following categories, list your changes in this order: ## [Unreleased] -- Nothing (Yet) +### Added + +- `django_table` component to generate HTML tables. ## [1.2.0] - 2022-09-19 diff --git a/noxfile.py b/noxfile.py index c0c63855..9af1b2a1 100644 --- a/noxfile.py +++ b/noxfile.py @@ -56,7 +56,7 @@ def test_suite(session: Session) -> None: posargs.append("--debug-mode") session.run("playwright", "install", "chromium") - session.run("python", "manage.py", "test", *posargs) + session.run("python", "manage.py", "test", "--keepdb", *posargs) @nox.session diff --git a/requirements/test-env.txt b/requirements/test-env.txt index 32187f96..49e44476 100644 --- a/requirements/test-env.txt +++ b/requirements/test-env.txt @@ -1,3 +1,4 @@ django playwright twisted +django_filter diff --git a/src/django_idom/components.py b/src/django_idom/components.py index 34ce359c..619370ca 100644 --- a/src/django_idom/components.py +++ b/src/django_idom/components.py @@ -14,6 +14,7 @@ from idom.types import VdomDict from django_idom.config import IDOM_CACHE, IDOM_VIEW_COMPONENT_IFRAMES +from django_idom.tables import TableConfig from django_idom.types import ViewComponentIframe @@ -119,6 +120,12 @@ async def async_renderer(): return rendered_view +@component +def django_table(table_config: TableConfig): + print(table_config) + return None + + @component def django_css(static_path: str): """Fetches a CSS static file for use within IDOM. This allows for deferred CSS loading. diff --git a/src/django_idom/tables.py b/src/django_idom/tables.py new file mode 100644 index 00000000..93734fa7 --- /dev/null +++ b/src/django_idom/tables.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Callable, Iterable, Mapping, TypeVar + +from django.db.models.base import Model +from django.db.models.query import QuerySet + + +try: + from django_filters import FilterSet +except ImportError: + FilterSet = TypeVar("FilterSet") # type: ignore + + +__all__ = ["FilterSet", "TableConfig", "bs_table_column_attrs", "bs_table_row_attrs"] + + +@dataclass +class TableConfig: + # Typically fields are contained within `data`, but they also can be defined as properties within a TableConfig subclass + # Automatically tries to get all model and TableConfig fields if `None` + fields: Iterable[str] | None = None + + # Data can be a model, QuerySet, or list of dictionaries + # If no data is provided, only fields declared within the user's TableConfig will be used + data: Model | QuerySet | Iterable[dict[str, Any]] | None = None + + # Allows for renaming columns in the form {old_name: new_name} + column_names: Mapping[str, str] | None = None + + # By default, all fields are sortable + sortable_fields: Iterable[str] | None = None + + # https://django-tables2.readthedocs.io/en/latest/pages/column-attributes.html#id1 + # Probably want a callable API similar to this `func(value:Any, node_type:str)`` + column_attrs: dict[str, Callable | str] | None = None + + # https://django-tables2.readthedocs.io/en/latest/pages/column-attributes.html#row-attributes + # Probably want a callable API similar to this `func(record:Model, node_type:str)`` + row_attrs: dict[str, Callable | str] | None = None + + # https://sparkbyexamples.com/pandas/pandas-sort-dataframe-by-multiple-columns/ + order_by: Iterable[str] | None = None + + # https://django-tables2.readthedocs.io/en/latest/pages/filtering.html + filterset: FilterSet | None = None + + # Zero means no pagination. + # https://docs.djangoproject.com/en/4.1/ref/paginator/#django.core.paginator.Paginator + pagination: int = 0 + + # Allows for a custom render function to change render layout + renderer: Callable | None = None + + +bs_table_column_attrs: dict[str, Callable | str] = {} +bs_table_row_attrs: dict[str, Callable | str] = {} diff --git a/tests/test_app/components.py b/tests/test_app/components.py index c103e01c..2be07114 100644 --- a/tests/test_app/components.py +++ b/tests/test_app/components.py @@ -85,6 +85,13 @@ def use_location(): ) +@component +def django_table(): + return django_idom.components.django_table( + table_config=django_idom.types.TableConfig(fields=["id", "text"]) + ) + + @component def django_css(): return html.div( diff --git a/tests/test_app/templates/base.html b/tests/test_app/templates/base.html index bea9893a..34b09eae 100644 --- a/tests/test_app/templates/base.html +++ b/tests/test_app/templates/base.html @@ -27,6 +27,7 @@