accrete 0.0.103__py3-none-any.whl → 0.0.105__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. accrete/contrib/ui/__init__.py +6 -29
  2. accrete/contrib/ui/context.py +26 -294
  3. accrete/contrib/ui/filter.py +316 -324
  4. accrete/contrib/ui/middleware.py +44 -0
  5. accrete/contrib/ui/models.py +3 -0
  6. accrete/contrib/ui/static/bulma/README.md +4 -2
  7. accrete/contrib/ui/static/bulma/bulma.css +21551 -0
  8. accrete/contrib/ui/static/bulma/bulma.css.map +1 -0
  9. accrete/contrib/ui/static/bulma/bulma.scss +1 -1
  10. accrete/contrib/ui/static/bulma/css/bulma.css +1988 -2874
  11. accrete/contrib/ui/static/bulma/css/bulma.css.map +1 -1
  12. accrete/contrib/ui/static/bulma/css/bulma.min.css +2 -2
  13. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css +19648 -0
  14. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css.map +1 -0
  15. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css +2 -2
  16. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css +11136 -0
  17. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css.map +1 -0
  18. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css +2 -2
  19. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css +11136 -0
  20. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css.map +1 -0
  21. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css +2 -2
  22. accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css +21550 -2
  23. accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css.map +1 -1
  24. accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.min.css +3 -0
  25. accrete/contrib/ui/static/bulma/package.json +12 -11
  26. accrete/contrib/ui/static/bulma/sass/base/animations.css +15 -0
  27. accrete/contrib/ui/static/bulma/sass/base/animations.css.map +1 -0
  28. accrete/contrib/ui/static/bulma/sass/base/generic.css +196 -0
  29. accrete/contrib/ui/static/bulma/sass/base/generic.css.map +1 -0
  30. accrete/contrib/ui/static/bulma/sass/base/minireset.css +82 -0
  31. accrete/contrib/ui/static/bulma/sass/base/minireset.css.map +1 -0
  32. accrete/contrib/ui/static/bulma/sass/base/skeleton.css +113 -0
  33. accrete/contrib/ui/static/bulma/sass/base/skeleton.css.map +1 -0
  34. accrete/contrib/ui/static/bulma/sass/base/skeleton.scss +0 -12
  35. accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css +108 -0
  36. accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css.map +1 -0
  37. accrete/contrib/ui/static/bulma/sass/components/card.css +130 -0
  38. accrete/contrib/ui/static/bulma/sass/components/card.css.map +1 -0
  39. accrete/contrib/ui/static/bulma/sass/components/dropdown.css +119 -0
  40. accrete/contrib/ui/static/bulma/sass/components/dropdown.css.map +1 -0
  41. accrete/contrib/ui/static/bulma/sass/components/menu.css +119 -0
  42. accrete/contrib/ui/static/bulma/sass/components/menu.css.map +1 -0
  43. accrete/contrib/ui/static/bulma/sass/components/message.css +191 -0
  44. accrete/contrib/ui/static/bulma/sass/components/message.css.map +1 -0
  45. accrete/contrib/ui/static/bulma/sass/components/modal.css +194 -0
  46. accrete/contrib/ui/static/bulma/sass/components/modal.css.map +1 -0
  47. accrete/contrib/ui/static/bulma/sass/components/navbar.css +768 -0
  48. accrete/contrib/ui/static/bulma/sass/components/navbar.css.map +1 -0
  49. accrete/contrib/ui/static/bulma/sass/components/navbar.scss +41 -30
  50. accrete/contrib/ui/static/bulma/sass/components/pagination.css +302 -0
  51. accrete/contrib/ui/static/bulma/sass/components/pagination.css.map +1 -0
  52. accrete/contrib/ui/static/bulma/sass/components/panel.css +224 -0
  53. accrete/contrib/ui/static/bulma/sass/components/panel.css.map +1 -0
  54. accrete/contrib/ui/static/bulma/sass/components/panel.scss +2 -2
  55. accrete/contrib/ui/static/bulma/sass/components/tabs.css +192 -0
  56. accrete/contrib/ui/static/bulma/sass/components/tabs.css.map +1 -0
  57. accrete/contrib/ui/static/bulma/sass/elements/block.css +17 -0
  58. accrete/contrib/ui/static/bulma/sass/elements/block.css.map +1 -0
  59. accrete/contrib/ui/static/bulma/sass/elements/box.css +43 -0
  60. accrete/contrib/ui/static/bulma/sass/elements/box.css.map +1 -0
  61. accrete/contrib/ui/static/bulma/sass/elements/button.css +685 -0
  62. accrete/contrib/ui/static/bulma/sass/elements/button.css.map +1 -0
  63. accrete/contrib/ui/static/bulma/sass/elements/button.scss +9 -2
  64. accrete/contrib/ui/static/bulma/sass/elements/content.css +208 -0
  65. accrete/contrib/ui/static/bulma/sass/elements/content.css.map +1 -0
  66. accrete/contrib/ui/static/bulma/sass/elements/content.scss +8 -2
  67. accrete/contrib/ui/static/bulma/sass/elements/delete.css +60 -0
  68. accrete/contrib/ui/static/bulma/sass/elements/delete.css.map +1 -0
  69. accrete/contrib/ui/static/bulma/sass/elements/icon.css +51 -0
  70. accrete/contrib/ui/static/bulma/sass/elements/icon.css.map +1 -0
  71. accrete/contrib/ui/static/bulma/sass/elements/image.css +253 -0
  72. accrete/contrib/ui/static/bulma/sass/elements/image.css.map +1 -0
  73. accrete/contrib/ui/static/bulma/sass/elements/loader.css +14 -0
  74. accrete/contrib/ui/static/bulma/sass/elements/loader.css.map +1 -0
  75. accrete/contrib/ui/static/bulma/sass/elements/notification.css +213 -0
  76. accrete/contrib/ui/static/bulma/sass/elements/notification.css.map +1 -0
  77. accrete/contrib/ui/static/bulma/sass/elements/progress.css +119 -0
  78. accrete/contrib/ui/static/bulma/sass/elements/progress.css.map +1 -0
  79. accrete/contrib/ui/static/bulma/sass/elements/table.css +294 -0
  80. accrete/contrib/ui/static/bulma/sass/elements/table.css.map +1 -0
  81. accrete/contrib/ui/static/bulma/sass/elements/tag.css +252 -0
  82. accrete/contrib/ui/static/bulma/sass/elements/tag.css.map +1 -0
  83. accrete/contrib/ui/static/bulma/sass/elements/title.css +131 -0
  84. accrete/contrib/ui/static/bulma/sass/elements/title.css.map +1 -0
  85. accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css +72 -0
  86. accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css.map +1 -0
  87. accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.scss +7 -3
  88. accrete/contrib/ui/static/bulma/sass/form/file.css +374 -0
  89. accrete/contrib/ui/static/bulma/sass/form/file.css.map +1 -0
  90. accrete/contrib/ui/static/bulma/sass/form/input-textarea.css +284 -0
  91. accrete/contrib/ui/static/bulma/sass/form/input-textarea.css.map +1 -0
  92. accrete/contrib/ui/static/bulma/sass/form/input-textarea.scss +0 -10
  93. accrete/contrib/ui/static/bulma/sass/form/select.css +347 -0
  94. accrete/contrib/ui/static/bulma/sass/form/select.css.map +1 -0
  95. accrete/contrib/ui/static/bulma/sass/form/select.scss +1 -0
  96. accrete/contrib/ui/static/bulma/sass/form/shared.css +48 -0
  97. accrete/contrib/ui/static/bulma/sass/form/shared.css.map +1 -0
  98. accrete/contrib/ui/static/bulma/sass/form/shared.scss +5 -1
  99. accrete/contrib/ui/static/bulma/sass/form/tools.css +356 -0
  100. accrete/contrib/ui/static/bulma/sass/form/tools.css.map +1 -0
  101. accrete/contrib/ui/static/bulma/sass/form/tools.scss +23 -12
  102. accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css +1635 -0
  103. accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css.map +1 -0
  104. accrete/contrib/ui/static/bulma/sass/grid/columns.css +1652 -0
  105. accrete/contrib/ui/static/bulma/sass/grid/columns.css.map +1 -0
  106. accrete/contrib/ui/static/bulma/sass/grid/columns.scss +109 -25
  107. accrete/contrib/ui/static/bulma/sass/grid/grid.css +3011 -0
  108. accrete/contrib/ui/static/bulma/sass/grid/grid.css.map +1 -0
  109. accrete/contrib/ui/static/bulma/sass/grid/grid.scss +3 -3
  110. accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css +61 -0
  111. accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css.map +1 -0
  112. accrete/contrib/ui/static/bulma/sass/helpers/border.css +17 -0
  113. accrete/contrib/ui/static/bulma/sass/helpers/border.css.map +1 -0
  114. accrete/contrib/ui/static/bulma/sass/helpers/color.css +5582 -0
  115. accrete/contrib/ui/static/bulma/sass/helpers/color.css.map +1 -0
  116. accrete/contrib/ui/static/bulma/sass/helpers/color.scss +166 -186
  117. accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css +217 -0
  118. accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css.map +1 -0
  119. accrete/contrib/ui/static/bulma/sass/helpers/float.css +37 -0
  120. accrete/contrib/ui/static/bulma/sass/helpers/float.css.map +1 -0
  121. accrete/contrib/ui/static/bulma/sass/helpers/gap.css +209 -0
  122. accrete/contrib/ui/static/bulma/sass/helpers/gap.css.map +1 -0
  123. accrete/contrib/ui/static/bulma/sass/helpers/other.css +34 -0
  124. accrete/contrib/ui/static/bulma/sass/helpers/other.css.map +1 -0
  125. accrete/contrib/ui/static/bulma/sass/helpers/overflow.css +65 -0
  126. accrete/contrib/ui/static/bulma/sass/helpers/overflow.css.map +1 -0
  127. accrete/contrib/ui/static/bulma/sass/helpers/position.css +45 -0
  128. accrete/contrib/ui/static/bulma/sass/helpers/position.css.map +1 -0
  129. accrete/contrib/ui/static/bulma/sass/helpers/spacing.css +489 -0
  130. accrete/contrib/ui/static/bulma/sass/helpers/spacing.css.map +1 -0
  131. accrete/contrib/ui/static/bulma/sass/helpers/typography.css +423 -0
  132. accrete/contrib/ui/static/bulma/sass/helpers/typography.css.map +1 -0
  133. accrete/contrib/ui/static/bulma/sass/helpers/visibility.css +485 -0
  134. accrete/contrib/ui/static/bulma/sass/helpers/visibility.css.map +1 -0
  135. accrete/contrib/ui/static/bulma/sass/layout/container.scss +16 -8
  136. accrete/contrib/ui/static/bulma/sass/layout/footer.css +9 -0
  137. accrete/contrib/ui/static/bulma/sass/layout/footer.css.map +1 -0
  138. accrete/contrib/ui/static/bulma/sass/layout/hero.css +534 -0
  139. accrete/contrib/ui/static/bulma/sass/layout/hero.css.map +1 -0
  140. accrete/contrib/ui/static/bulma/sass/layout/level.css +102 -0
  141. accrete/contrib/ui/static/bulma/sass/layout/level.css.map +1 -0
  142. accrete/contrib/ui/static/bulma/sass/layout/media.css +90 -0
  143. accrete/contrib/ui/static/bulma/sass/layout/media.css.map +1 -0
  144. accrete/contrib/ui/static/bulma/sass/layout/section.css +23 -0
  145. accrete/contrib/ui/static/bulma/sass/layout/section.css.map +1 -0
  146. accrete/contrib/ui/static/bulma/sass/layout/section.scss +4 -0
  147. accrete/contrib/ui/static/bulma/sass/themes/dark.css +3 -0
  148. accrete/contrib/ui/static/bulma/sass/themes/dark.css.map +1 -0
  149. accrete/contrib/ui/static/bulma/sass/themes/light.css +3 -0
  150. accrete/contrib/ui/static/bulma/sass/themes/light.css.map +1 -0
  151. accrete/contrib/ui/static/bulma/sass/themes/light.scss +1 -0
  152. accrete/contrib/ui/static/bulma/sass/themes/setup.css +3 -0
  153. accrete/contrib/ui/static/bulma/sass/themes/setup.css.map +1 -0
  154. accrete/contrib/ui/static/bulma/sass/utilities/controls.css +13 -0
  155. accrete/contrib/ui/static/bulma/sass/utilities/controls.css.map +1 -0
  156. accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css +3 -0
  157. accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css.map +1 -0
  158. accrete/contrib/ui/static/bulma/sass/utilities/css-variables.scss +3 -2
  159. accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css +3 -0
  160. accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css.map +1 -0
  161. accrete/contrib/ui/static/bulma/sass/utilities/extends.css +13 -0
  162. accrete/contrib/ui/static/bulma/sass/utilities/extends.css.map +1 -0
  163. accrete/contrib/ui/static/bulma/sass/utilities/functions.scss +2 -2
  164. accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css +3 -0
  165. accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css.map +1 -0
  166. accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.scss +4 -4
  167. accrete/contrib/ui/static/bulma/sass/utilities/mixins.css +3 -0
  168. accrete/contrib/ui/static/bulma/sass/utilities/mixins.css.map +1 -0
  169. accrete/contrib/ui/static/bulma/sass/utilities/mixins.scss +1 -1
  170. accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css +19648 -0
  171. accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css.map +1 -0
  172. accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.scss +2 -1
  173. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css +11136 -0
  174. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css.map +1 -0
  175. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.scss +1 -1
  176. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css +11136 -0
  177. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css.map +1 -0
  178. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.scss +1 -1
  179. accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css +21551 -0
  180. accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css.map +1 -0
  181. accrete/contrib/ui/static/bulma/versions/bulma-prefixed.scss +1 -1
  182. accrete/contrib/ui/static/css/accrete.css +20757 -19997
  183. accrete/contrib/ui/static/css/accrete.css.map +1 -1
  184. accrete/contrib/ui/static/css/accrete.scss +185 -462
  185. accrete/contrib/ui/static/js/filter.js +97 -679
  186. accrete/contrib/ui/static/js/htmx.min.js +1 -1
  187. accrete/contrib/ui/templates/django/forms/widgets/date.html +5 -9
  188. accrete/contrib/ui/templates/django/forms/widgets/select.html +7 -5
  189. accrete/contrib/ui/templates/ui/content_right.html +7 -0
  190. accrete/contrib/ui/templates/ui/filter/filter.html +27 -0
  191. accrete/contrib/ui/templates/ui/filter/query_input.html +31 -0
  192. accrete/contrib/ui/templates/ui/filter/query_operator.html +11 -0
  193. accrete/contrib/ui/templates/ui/filter/query_params.html +106 -0
  194. accrete/contrib/ui/templates/ui/filter/query_tags.html +26 -0
  195. accrete/contrib/ui/templates/ui/layout.html +162 -233
  196. accrete/contrib/ui/templates/ui/list.html +39 -28
  197. accrete/contrib/ui/templates/ui/list_update.html +3 -0
  198. accrete/contrib/ui/templates/ui/message.html +13 -0
  199. accrete/contrib/ui/templates/ui/{partials/modal.html → modal.html} +9 -5
  200. accrete/contrib/ui/templates/ui/oob.html +3 -0
  201. accrete/contrib/ui/templates/ui/table.html +67 -71
  202. accrete/contrib/ui/templates/ui/table_row_update.html +14 -0
  203. accrete/contrib/ui/templates/ui/widgets/model_search_select.html +2 -2
  204. accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html +25 -14
  205. accrete/contrib/ui/templates/ui/widgets/model_search_select_options.html +1 -1
  206. accrete/contrib/ui/templatetags/{accrete_ui.py → ui.py} +68 -56
  207. accrete/contrib/ui/urls.py +3 -1
  208. accrete/contrib/ui/views.py +33 -3
  209. accrete/contrib/ui/widgets/__init__.py +1 -0
  210. accrete/contrib/ui/{forms/widgets.py → widgets/search_select.py} +7 -2
  211. accrete/contrib/user/templates/user/login.html +71 -23
  212. accrete/forms.py +0 -2
  213. accrete/managers.py +4 -4
  214. accrete/middleware.py +43 -66
  215. accrete/models.py +7 -1
  216. accrete/storage.py +4 -1
  217. accrete/tenant.py +9 -4
  218. accrete/utils/__init__.py +2 -0
  219. accrete/utils/models.py +9 -1
  220. accrete/utils/views.py +36 -20
  221. accrete/views.py +9 -5
  222. {accrete-0.0.103.dist-info → accrete-0.0.105.dist-info}/METADATA +2 -2
  223. accrete-0.0.105.dist-info/RECORD +370 -0
  224. {accrete-0.0.103.dist-info → accrete-0.0.105.dist-info}/WHEEL +1 -1
  225. accrete/contrib/ui/components/__init__.py +0 -1
  226. accrete/contrib/ui/components/search_select.py +0 -18
  227. accrete/contrib/ui/elements.py +0 -95
  228. accrete/contrib/ui/forms/__init__.py +0 -0
  229. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css.map +0 -1
  230. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css.map +0 -1
  231. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css.map +0 -1
  232. accrete/contrib/ui/static/bulma/sass/grid/columns-v2.scss +0 -957
  233. accrete/contrib/ui/static/js/ui.js +0 -30
  234. accrete/contrib/ui/templates/ui/dashboard.html +0 -7
  235. accrete/contrib/ui/templates/ui/detail.html +0 -19
  236. accrete/contrib/ui/templates/ui/form.html +0 -21
  237. accrete/contrib/ui/templates/ui/partials/filter.html +0 -146
  238. accrete/contrib/ui/templates/ui/partials/form_errors.html +0 -34
  239. accrete/contrib/ui/templates/ui/partials/header.html +0 -123
  240. accrete/contrib/ui/templates/ui/partials/modal_form.html +0 -46
  241. accrete/contrib/ui/templates/ui/partials/onchange_form.html +0 -1
  242. accrete/contrib/ui/templates/ui/partials/pagination_detail.html +0 -23
  243. accrete/contrib/ui/templates/ui/partials/pagination_list.html +0 -28
  244. accrete/contrib/ui/templates/ui/partials/table_field.html +0 -16
  245. accrete/contrib/ui/templates/ui/partials/table_field_float.html +0 -1
  246. accrete/contrib/ui/templates/ui/partials/table_field_monetary.html +0 -4
  247. accrete/contrib/ui/templates/ui/partials/table_field_string.html +0 -1
  248. accrete/contrib/ui/templates/ui/widgets/model_search_select_multi_selected_options.html +0 -3
  249. accrete/contrib/ui/templates/ui/widgets/model_search_select_multi_tags.html +0 -6
  250. accrete-0.0.103.dist-info/RECORD +0 -241
  251. {accrete-0.0.103.dist-info → accrete-0.0.105.dist-info}/licenses/LICENSE +0 -0
@@ -1,33 +1,10 @@
1
+ from . import widgets
1
2
  from .filter import Filter
2
- from .context import (
3
+ from . context import (
3
4
  Context,
4
- DetailContext,
5
- TableContext,
6
5
  ListContext,
7
- FormContext,
8
- ModalFormContext,
9
- ModalContext,
10
- form_actions,
11
- list_page,
12
- detail_page,
13
- cast_param,
14
- url_param_dict,
15
- extract_url_params,
16
- exclude_params,
17
- url_param_str,
18
- get_table_fields,
19
- table_context_factory,
20
- list_context_factory
21
- )
22
- from .elements import (
23
- ClientActionGroup,
24
- ClientAction,
25
- ActionMethod,
26
- BreadCrumb,
27
- TableField,
28
- TableFieldAlignment,
29
- TableFieldType,
30
- Icon
6
+ ListUpdateContext,
7
+ TableContext,
8
+ TableRowContext,
9
+ ModalContext
31
10
  )
32
-
33
- from . import components
@@ -1,36 +1,11 @@
1
1
  import logging
2
- import json
3
- from urllib.parse import quote_plus
4
- from uuid import uuid4
5
2
  from dataclasses import dataclass, field
6
- from functools import partial
7
- from typing import Type, TypedDict
8
- from django.utils.translation import gettext_lazy as _t
9
- from django.db import models
10
- from django.db.models import Model, QuerySet
11
- from django.core.paginator import Paginator
12
- from django.core import paginator, exceptions
13
- from django.forms import Form, ModelForm
14
- from accrete.annotation import Annotation
15
- from accrete.utils.views import cast_param
16
- from .elements import (
17
- ClientAction, BreadCrumb, TableField, TableFieldType, TableFieldAlignment,
18
- ClientActionGroup
19
- )
3
+ from django.core import paginator
4
+ from django.db.models import QuerySet, Model
20
5
  from .filter import Filter
21
- from accrete.utils import filter_from_querystring
22
6
 
23
7
  _logger = logging.getLogger(__name__)
24
8
 
25
- DEFAULT_PAGINATE_BY = 40
26
-
27
-
28
- class DetailPagination(TypedDict):
29
- previous_object_url: str
30
- next_object_url: str
31
- current_object_idx: int
32
- total_objects: int
33
-
34
9
 
35
10
  @dataclass(kw_only=True)
36
11
  class BaseContext:
@@ -52,303 +27,60 @@ class BaseContext:
52
27
  class Context(BaseContext):
53
28
 
54
29
  title: str = ''
55
- breadcrumbs: list[BreadCrumb] = field(default_factory=list)
56
- actions: list[ClientAction | ClientActionGroup] = field(default_factory=list)
57
-
58
-
59
- @dataclass
60
- class TableContext(Context):
61
-
62
- object_label: str
63
- fields: list[TableField]
64
- list_page: paginator.Page
65
- pagination_param_str: str
66
- endless_scroll: bool
67
- filter: Filter
68
- object_param_str: str = field(default='', kw_only=True)
69
- field_selection: bool = True
70
-
71
-
72
- def table_context_factory(model: Type[Model], params: dict, queryset=None, **kwargs) -> TableContext:
73
- if queryset is None:
74
- queryset = filter_from_querystring(model, params)
75
- page = list_page(
76
- queryset,
77
- cast_param(params, 'paginate_by', int, 40),
78
- cast_param(params, 'page', int, 1)
79
- )
80
- try:
81
- has_name_field = (
82
- model._meta.get_field('name').get_internal_type() == 'CharField'
83
- )
84
- except exceptions.FieldDoesNotExist:
85
- has_name_field = False
86
-
87
- ctx = partial(TableContext, **dict(
88
- title=str(model._meta.verbose_name_plural),
89
- object_label=str(model._meta.verbose_name),
90
- object_param_str=url_param_str(
91
- params,
92
- ['q', 'paginate_by', 'page', 'fields']
93
- ),
94
- fields=get_table_fields(
95
- cast_param(params, 'fields', json.loads, []), model
96
- ),
97
- list_page=page,
98
- pagination_param_str=url_param_str(
99
- params, ['q', 'paginate_by', 'fields']
100
- ),
101
- endless_scroll=True,
102
- filter=Filter(
103
- model,
104
- default_filter_term='name__icontains' if has_name_field else ''
105
- )
106
- ))
107
- return ctx(**kwargs)
108
30
 
109
31
 
110
32
  @dataclass
111
33
  class ListContext(Context):
112
34
 
113
- object_label: str
114
- object_param_str: str
115
- list_page: paginator.Page
116
- pagination_param_str: str
117
- filter: Filter = None
35
+ page: paginator.Page
36
+ queryset: QuerySet
118
37
  endless_scroll: bool = True
119
- column_width: int = 12
120
- column_width_widescreen: int = None
121
- column_width_desktop: int = None
38
+ detail_enabled: bool = True
39
+ filter: Filter = None
40
+ column_count: int = 1
122
41
  column_height: int = 150
123
42
  column_height_unit: str = 'px'
124
- field_selection: bool = False
125
43
 
126
44
  def __post_init__(self):
127
45
  super().__post_init__()
128
- if self.column_width not in range(1, 13):
46
+ if self.column_count not in range(1, 13):
129
47
  _logger.warning(
130
- 'ListContext parameter column_width should be in range 1 - 12'
48
+ 'ListContext parameter column_count should be in range 1 - 12'
131
49
  )
132
- if self.column_width_widescreen is None:
133
- self.column_width_widescreen = self.column_width
134
- if self.column_width_desktop is None:
135
- self.column_width_desktop = self.column_width
136
-
137
-
138
- def list_context_factory(model: Type[Model], params: dict, queryset=None, paginate_by=None, **kwargs) -> ListContext:
139
- if queryset is None:
140
- queryset = filter_from_querystring(model, params)
141
- page = list_page(
142
- queryset,
143
- cast_param(params, 'paginate_by', int, paginate_by or 20),
144
- cast_param(params, 'page', int, 1)
145
- )
146
- try:
147
- has_name_field = (
148
- model._meta.get_field('name').get_internal_type() == 'CharField'
149
- )
150
- except exceptions.FieldDoesNotExist:
151
- has_name_field = False
152
-
153
- ctx = partial(ListContext, **dict(
154
- title=str(model._meta.verbose_name_plural),
155
- object_label=str(model._meta.verbose_name),
156
- object_param_str=url_param_str(
157
- params,
158
- ['q', 'paginate_by', 'page']
159
- ),
160
- list_page=page,
161
- pagination_param_str=url_param_str(
162
- params, ['q', 'paginate_by']
163
- ),
164
- endless_scroll=True,
165
- filter=Filter(
166
- model,
167
- default_filter_term='name__icontains' if has_name_field else ''
168
- ),
169
- column_width=4,
170
- column_height=150
171
- ))
172
- return ctx(**kwargs)
173
50
 
174
51
 
175
52
  @dataclass
176
- class DetailContext(Context):
53
+ class ListUpdateContext(BaseContext):
177
54
 
178
55
  object: Model
179
- detail_page: DetailPagination = None
180
- pagination_param_str: str = ''
56
+ template: str
181
57
 
182
58
 
183
59
  @dataclass
184
- class FormContext(Context):
60
+ class TableContext(Context):
185
61
 
186
- form: Form | ModelForm
187
- form_id: str = 'form'
188
- form_method: str = 'post'
189
- form_action: str = ''
62
+ object_label: str
63
+ fields: list[str]
64
+ page: paginator.Page
65
+ queryset: QuerySet
66
+ footer: dict = field(default_factory=dict)
67
+ endless_scroll: bool = True
68
+ detail_enabled: bool = True
69
+ filter: Filter = None
190
70
 
191
71
 
192
72
  @dataclass
193
- class ModalFormContext(BaseContext):
73
+ class TableRowContext(BaseContext):
194
74
 
195
- title: str
196
- form: Form | ModelForm
197
- form_id: str = 'form'
198
- blocking: bool = True
75
+ object: Model
76
+ fields: list[str]
77
+ queryset: QuerySet
78
+ footer: dict = field(default_factory=dict)
199
79
 
200
80
 
201
81
  @dataclass
202
82
  class ModalContext(BaseContext):
203
83
 
204
84
  title: str
85
+ modal_id: str
205
86
  blocking: bool = False
206
- modal_id: str = None
207
-
208
- def __post_init__(self):
209
- super().__post_init__()
210
- if not self.modal_id:
211
- self.modal_id = f'modal{str(uuid4())[:8]}'
212
-
213
-
214
- def url_param_dict(get_params: dict) -> dict:
215
- return {
216
- key: f'&{key}={quote_plus(value)}'
217
- for key, value in get_params.items()
218
- }
219
-
220
-
221
- def url_param_str(params: dict, extract: list[str] = None) -> str:
222
- """
223
- Return a URL Querystring from the given params dict.
224
- If extract is supplied, only specified keys will be used.
225
- """
226
- if extract:
227
- params = extract_url_params(params, extract)
228
- param_str = (
229
- "".join(str(value) for value in url_param_dict(params).values())
230
- .replace('&&', '&')
231
- .replace('?&', '?')
232
- .strip('?&')
233
- )
234
- return f'?{param_str}'
235
-
236
-
237
- def extract_url_params(params: dict, keys: list[str]) -> dict:
238
- return {key: params[key] for key in keys if key in params}
239
-
240
-
241
- def exclude_params(params: dict, keys: list[str]) -> dict:
242
- return {key: val for key, val in params.items() if key not in keys}
243
-
244
-
245
- def list_page(
246
- queryset: QuerySet, paginate_by: int, page_number: int
247
- ) -> paginator.Page:
248
- pages = Paginator(queryset, per_page=paginate_by)
249
- return pages.page(
250
- page_number <= pages.num_pages and page_number or pages.num_pages
251
- )
252
-
253
-
254
- def detail_page(queryset: QuerySet, obj: Model) -> dict:
255
- if not hasattr(obj, 'get_absolute_url'):
256
- _logger.warning(
257
- 'Detail pagination disabled for models without the '
258
- 'get_absolute_url attribute. Set paginate_by to 0 to '
259
- 'deactivate pagination.'
260
- )
261
- return {}
262
- if obj not in queryset:
263
- url = obj.get_absolute_url()
264
- return {
265
- 'previous_object_url': url,
266
- 'next_object_url': url,
267
- 'current_object_idx': 1,
268
- 'total_objects': 1
269
- }
270
-
271
- idx = (*queryset,).index(obj)
272
- previous_object_url = (
273
- queryset[idx - 1] if idx - 1 >= 0 else queryset.last()
274
- ).get_absolute_url()
275
- next_object_url = (
276
- queryset[idx + 1] if idx + 1 <= queryset.count() - 1 else queryset.first()
277
- ).get_absolute_url()
278
- return {
279
- 'previous_object_url': previous_object_url,
280
- 'next_object_url': next_object_url,
281
- 'current_object_idx': idx + 1,
282
- 'total_objects': queryset.count()
283
- }
284
-
285
-
286
- def form_actions(discard_url: str, form_id: str = 'form') -> list[ClientAction]:
287
- return [
288
- ClientAction(
289
- name=_t('Save'),
290
- submit=True,
291
- class_list=['is-success'],
292
- form_id=form_id,
293
- ),
294
- ClientAction(
295
- name=_t('Discard'),
296
- url=discard_url
297
- )
298
- ]
299
-
300
-
301
- def get_table_fields(
302
- fields: list[str],
303
- model: type[Model],
304
- field_definition: dict[str | TableField] = None
305
- ) -> list[TableField]:
306
-
307
- def get_alignment(field_attr) -> TableFieldAlignment:
308
- number_field_types = (
309
- models.DecimalField, models.IntegerField, models.FloatField
310
- )
311
- if (
312
- isinstance(field_attr, number_field_types)
313
- or (
314
- isinstance(field_attr, Annotation)
315
- and field_attr.field in number_field_types
316
- )
317
- ):
318
- return TableFieldAlignment.RIGHT
319
- return TableFieldAlignment.LEFT
320
-
321
- def get_field_definition(f_name: str) -> TableField:
322
- if definition := field_definition.get(f_name):
323
- return definition
324
- try:
325
- return model.table_field_definition[f_name]
326
- except (AttributeError, KeyError):
327
- attr = getattr(model, f_name)
328
- if not isinstance(attr, Annotation) and hasattr(attr, 'field'):
329
- attr = attr.field
330
- is_relation = (
331
- hasattr(attr, 'related_model')
332
- and hasattr(attr.related_model, 'get_absolute_url')
333
- )
334
- field_type = TableFieldType.NONE
335
- if getattr(attr, 'choices', False):
336
- field_type = TableFieldType.CHOICE_DISPLAY
337
- return TableField(
338
- label=attr.verbose_name,
339
- name=f_name,
340
- field_type=field_type,
341
- alignment=get_alignment(attr),
342
- is_relation=is_relation
343
- )
344
-
345
- if field_definition is None:
346
- field_definition = {}
347
- table_fields = []
348
- for field_name in fields:
349
- try:
350
- table_fields.append(get_field_definition(field_name))
351
- except AttributeError as e:
352
- _logger.error(e)
353
- pass
354
- return table_fields