accrete 0.0.9__tar.gz → 0.0.11__tar.gz

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 (115) hide show
  1. {accrete-0.0.9 → accrete-0.0.11}/PKG-INFO +1 -1
  2. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/__init__.py +1 -2
  3. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/helper.py +31 -29
  4. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/css/accrete.css +31 -99
  5. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/detail.html +0 -1
  6. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/form.html +0 -1
  7. accrete-0.0.11/accrete/contrib/ui/templates/ui/layout.html +162 -0
  8. accrete-0.0.11/accrete/contrib/ui/templates/ui/list.html +22 -0
  9. accrete-0.0.11/accrete/contrib/ui/templates/ui/partials/header.html +53 -0
  10. accrete-0.0.11/accrete/contrib/ui/templates/ui/partials/pagination_detail.html +23 -0
  11. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/pagination_list.html +7 -9
  12. accrete-0.0.11/accrete/contrib/ui/templates/ui/table.html +40 -0
  13. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templatetags/accrete_ui.py +15 -0
  14. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/views.py +1 -1
  15. {accrete-0.0.9 → accrete-0.0.11}/pyproject.toml +1 -1
  16. accrete-0.0.9/accrete/contrib/ui/config.py +0 -10
  17. accrete-0.0.9/accrete/contrib/ui/templates/ui/layout.html +0 -147
  18. accrete-0.0.9/accrete/contrib/ui/templates/ui/list.html +0 -34
  19. accrete-0.0.9/accrete/contrib/ui/templates/ui/partials/actions.html +0 -30
  20. accrete-0.0.9/accrete/contrib/ui/templates/ui/partials/header.html +0 -65
  21. accrete-0.0.9/accrete/contrib/ui/templates/ui/partials/pagination_detail.html +0 -27
  22. accrete-0.0.9/accrete/contrib/ui/templates/ui/table.html +0 -41
  23. {accrete-0.0.9 → accrete-0.0.11}/.gitignore +0 -0
  24. {accrete-0.0.9 → accrete-0.0.11}/LICENSE +0 -0
  25. {accrete-0.0.9 → accrete-0.0.11}/README.md +0 -0
  26. {accrete-0.0.9 → accrete-0.0.11}/accrete/__init__.py +0 -0
  27. {accrete-0.0.9 → accrete-0.0.11}/accrete/admin.py +0 -0
  28. {accrete-0.0.9 → accrete-0.0.11}/accrete/apps.py +0 -0
  29. {accrete-0.0.9 → accrete-0.0.11}/accrete/config.py +0 -0
  30. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/__init__.py +0 -0
  31. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/__init__.py +0 -0
  32. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/admin.py +0 -0
  33. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/apps.py +0 -0
  34. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/forms.py +0 -0
  35. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/migrations/0001_initial.py +0 -0
  36. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/migrations/__init__.py +0 -0
  37. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/models.py +0 -0
  38. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/queries.py +0 -0
  39. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/tests.py +0 -0
  40. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/views.py +0 -0
  41. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/__init__.py +0 -0
  42. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/admin.py +0 -0
  43. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/apps.py +0 -0
  44. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/forms.py +0 -0
  45. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/migrations/0001_initial.py +0 -0
  46. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/migrations/__init__.py +0 -0
  47. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/models.py +0 -0
  48. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/tasks.py +0 -0
  49. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/tests.py +0 -0
  50. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/views.py +0 -0
  51. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/admin.py +0 -0
  52. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/apps.py +0 -0
  53. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/filter.py +0 -0
  54. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/migrations/__init__.py +0 -0
  55. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/css/icons.css +0 -0
  56. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/icons/Logo.svg +0 -0
  57. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/icons/accrete.svg +0 -0
  58. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/filter.js +0 -0
  59. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/list.js +0 -0
  60. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/navbar.js +0 -0
  61. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/utils.js +0 -0
  62. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/attrs.html +0 -0
  63. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/email.html +0 -0
  64. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/file.html +0 -0
  65. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/input.html +0 -0
  66. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/select.html +0 -0
  67. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/text.html +0 -0
  68. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/textarea.html +0 -0
  69. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/filter.html +0 -0
  70. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/form_errors.html +0 -0
  71. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/form_modal.html +0 -0
  72. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/onchange_form.html +0 -0
  73. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templatetags/__init__.py +0 -0
  74. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/tests.py +0 -0
  75. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/urls.py +0 -0
  76. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/__init__.py +0 -0
  77. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/admin.py +0 -0
  78. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/apps.py +0 -0
  79. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/locale/de/LC_MESSAGES/django.mo +0 -0
  80. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/locale/de/LC_MESSAGES/django.po +0 -0
  81. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/middleware.py +0 -0
  82. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/migrations/0001_initial.py +0 -0
  83. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/migrations/__init__.py +0 -0
  84. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/models.py +0 -0
  85. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/templates/user/login.html +0 -0
  86. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/tests.py +0 -0
  87. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/urls.py +0 -0
  88. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/views.py +0 -0
  89. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/__init__.py +0 -0
  90. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/admin.py +0 -0
  91. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/apps.py +0 -0
  92. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/config.py +0 -0
  93. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/forms.py +0 -0
  94. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/migrations/0001_initial.py +0 -0
  95. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/migrations/__init__.py +0 -0
  96. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/models.py +0 -0
  97. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/templates/user_registration/mail_templates/confirmation_mail.html +0 -0
  98. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/templates/user_registration/registration.html +0 -0
  99. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/tests.py +0 -0
  100. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/urls.py +0 -0
  101. {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/views.py +0 -0
  102. {accrete-0.0.9 → accrete-0.0.11}/accrete/decorators.py +0 -0
  103. {accrete-0.0.9 → accrete-0.0.11}/accrete/forms.py +0 -0
  104. {accrete-0.0.9 → accrete-0.0.11}/accrete/middleware.py +0 -0
  105. {accrete-0.0.9 → accrete-0.0.11}/accrete/migrations/0001_initial.py +0 -0
  106. {accrete-0.0.9 → accrete-0.0.11}/accrete/migrations/0002_initial.py +0 -0
  107. {accrete-0.0.9 → accrete-0.0.11}/accrete/migrations/__init__.py +0 -0
  108. {accrete-0.0.9 → accrete-0.0.11}/accrete/models.py +0 -0
  109. {accrete-0.0.9 → accrete-0.0.11}/accrete/queries.py +0 -0
  110. {accrete-0.0.9 → accrete-0.0.11}/accrete/shortcuts.py +0 -0
  111. {accrete-0.0.9 → accrete-0.0.11}/accrete/tenant.py +0 -0
  112. {accrete-0.0.9 → accrete-0.0.11}/accrete/tests.py +0 -0
  113. {accrete-0.0.9 → accrete-0.0.11}/accrete/utils/__init__.py +0 -0
  114. {accrete-0.0.9 → accrete-0.0.11}/accrete/utils/dates.py +0 -0
  115. {accrete-0.0.9 → accrete-0.0.11}/accrete/views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: accrete
3
- Version: 0.0.9
3
+ Version: 0.0.11
4
4
  Summary: Django Shared Schema Multi Tenant
5
5
  Author-email: Benedikt Jilek <benedikt.jilek@pm.me>
6
6
  License: Copyright (c) 2023 Benedikt Jilek
@@ -1,4 +1,3 @@
1
- from . import config
2
1
  from .filter import Filter
3
2
  from .helper import (
4
3
  ClientAction,
@@ -6,7 +5,7 @@ from .helper import (
6
5
  FormContext,
7
6
  ListContext,
8
7
  BreadCrumb,
8
+ TableField,
9
9
  build_querystring,
10
- parse_client_actions,
11
10
  queryset_from_querystring
12
11
  )
@@ -8,11 +8,10 @@ from django.utils.translation import gettext_lazy as _
8
8
  from django.core.exceptions import FieldDoesNotExist
9
9
  from django.core.paginator import Paginator
10
10
  from accrete.contrib.ui.filter import Filter
11
- from . import config
12
11
 
13
12
  _logger = logging.getLogger(__name__)
14
13
 
15
- ACTIONS_TEMPLATE = config.ACCRETE_UI_ACTIONS_TEMPLATE
14
+ DEFAULT_PAGINATE_BY = 40
16
15
 
17
16
 
18
17
  @dataclass
@@ -25,18 +24,6 @@ class ClientAction:
25
24
  submit: bool = False
26
25
  form_id: str = 'form'
27
26
  class_list: list = field(default_factory=list)
28
- mobile: bool = True
29
- tablet: bool = True
30
-
31
-
32
- def parse_client_actions(actions: list[ClientAction], actions_template: str = None):
33
- tablet = (not all(action.tablet for action in actions))
34
- mobile = (not all(action.mobile for action in actions))
35
- return {
36
- 'actions_template': actions_template or ACTIONS_TEMPLATE,
37
- 'actions': actions,
38
- 'action_button': {'mobile': mobile, 'tablet': tablet}
39
- }
40
27
 
41
28
 
42
29
  @dataclass
@@ -46,6 +33,13 @@ class BreadCrumb:
46
33
  url: str
47
34
 
48
35
 
36
+ @dataclass
37
+ class TableField:
38
+
39
+ label: str
40
+ name: str
41
+
42
+
49
43
  @dataclass
50
44
  class ListContext:
51
45
 
@@ -57,12 +51,14 @@ class ListContext:
57
51
  extra_query: Q = None
58
52
  related_fields: list[str] = field(default_factory=list)
59
53
  prefetch_fields: list[str] = field(default_factory=list)
60
- paginate_by: int = 20
54
+ paginate_by: int = DEFAULT_PAGINATE_BY
61
55
  order_by: list[str] = None
62
56
  column_width: int = 12
63
57
  filter_relation_depth: int = 4
64
58
  actions: list[ClientAction] = field(default_factory=list)
65
59
  breadcrumbs: list[BreadCrumb] = field(default_factory=list)
60
+ obj_label: str = None
61
+ fields: list[TableField] = field(default_factory=list)
66
62
 
67
63
  def get_queryset(self):
68
64
  order = self.get_order()
@@ -116,10 +112,11 @@ class ListContext:
116
112
  'filter_terms': Filter(self.model, self.filter_relation_depth).get_query_terms(),
117
113
  'view_type': 'list',
118
114
  'breadcrumbs': self.breadcrumbs,
119
- 'querystring': build_querystring(self.get_params)
115
+ 'querystring': build_querystring(self.get_params),
116
+ 'actions': self.actions,
117
+ 'obj_label': self.obj_label or _('Name'),
118
+ 'fields': self.fields
120
119
  }
121
- if self.actions:
122
- context.update(parse_client_actions(self.actions))
123
120
  context.update(self.context)
124
121
  return context
125
122
 
@@ -130,14 +127,15 @@ class DetailContext:
130
127
  obj: Model
131
128
  get_params: dict
132
129
  order_by: str = None
133
- paginate_by: int = 20
130
+ paginate_by: int = DEFAULT_PAGINATE_BY
134
131
  title: str = None
135
132
  queryset: type[QuerySet] = None
136
133
  extra_query: Q = None
137
134
  related_fields: list[str] = field(default_factory=list)
138
135
  prefetch_fields: list[str] = field(default_factory=list)
139
136
  actions: list[ClientAction] = field(default_factory=list)
140
- breadcrumbs: list[BreadCrumb] = field(default_factory=list)
137
+ breadcrumbs: list[BreadCrumb] = field(default_factory=list),
138
+ context: dict = field(default_factory=dict)
141
139
 
142
140
  def get_queryset(self):
143
141
  order = self.get_order()
@@ -197,25 +195,26 @@ class DetailContext:
197
195
  'detail_pagination': False,
198
196
  'view_type': 'detail',
199
197
  'breadcrumbs': self.breadcrumbs,
200
- 'querystring': build_querystring(self.get_params, ['page'])
198
+ 'querystring': build_querystring(self.get_params, ['page']),
199
+ 'actions': self.actions
201
200
  }
202
201
  if self.paginate_by > 0:
203
202
  ctx.update(self.get_pagination_context())
204
- if self.actions:
205
- ctx.update(parse_client_actions(self.actions))
203
+ ctx.update(self.context)
206
204
  return ctx
207
205
 
208
206
 
209
207
  @dataclass
210
208
  class FormContext:
211
209
 
212
- model: Model|type[Model]
210
+ model: Model | type[Model]
213
211
  get_params: dict
214
212
  title: str = None
215
213
  context: dict = field(default_factory=dict)
216
214
  form_id: str = 'form'
217
215
  add_default_actions: bool = True
218
216
  discard_url: str = None
217
+ actions: list[ClientAction] = field(default_factory=list)
219
218
 
220
219
  def get_default_form_actions(self):
221
220
  actions = [
@@ -228,12 +227,11 @@ class FormContext:
228
227
  ]
229
228
  try:
230
229
  url = self.discard_url or self.model.get_absolute_url()
231
- except TypeError as e:
232
- _logger.exception(
230
+ except TypeError:
231
+ raise TypeError(
233
232
  'Supply the discard_url parameter if FormContext is called '
234
233
  'with a model class instead of an instance.'
235
234
  )
236
- raise e
237
235
  except AttributeError as e:
238
236
  _logger.error(
239
237
  'Supply the discard_url parameter if FormContext is '
@@ -264,10 +262,12 @@ class FormContext:
264
262
  'title': self.get_title(),
265
263
  'view_type': 'form',
266
264
  'form_id': self.form_id,
267
- 'querystring': build_querystring(self.get_params, ['page'])
265
+ 'querystring': build_querystring(self.get_params, ['page']),
266
+ 'actions': []
268
267
  }
269
268
  if self.add_default_actions:
270
- ctx.update(parse_client_actions(self.get_default_form_actions()))
269
+ ctx.update({'actions': self.get_default_form_actions()})
270
+ ctx['actions'].extend(self.actions)
271
271
  ctx.update(self.context)
272
272
  return ctx
273
273
 
@@ -276,6 +276,8 @@ def build_querystring(get_params: dict, extra_params: list[str] = None) -> str:
276
276
  querystring = f'?q={get_params.get("q", "[]")}'
277
277
  if paginate_by := get_params.get('paginate_by', False):
278
278
  querystring += f'&paginate_by={paginate_by}'
279
+ # if page := get_params.get('page', False):
280
+ # querystring += f'&page={page}'
279
281
  if order_by := get_params.get('order_by', False):
280
282
  querystring += f'&order_by={order_by}'
281
283
  for param in extra_params or []:
@@ -1,32 +1,9 @@
1
- .header-sticky {
2
- position: sticky;
3
- top: 0;
4
- background: white;
5
- }
6
-
7
- table {
8
- margin-bottom: 12px !important;
9
- }
10
-
11
- th {
12
- background-color: white;
13
- }
14
-
15
- /*tbody > tr:hover {*/
16
- /* background-color: #f5f5f5;*/
17
- /*}*/
18
-
19
- label {
20
- word-break: break-word;
21
- }
22
-
23
- .dropdown-link:hover {
24
- cursor: pointer;
25
- background-color: #f5f5f5;
1
+ .columns {
2
+ margin: 0;
26
3
  }
27
4
 
28
- .link-row:hover {
29
- cursor: pointer;
5
+ .columns:last-child {
6
+ margin-bottom: 0;
30
7
  }
31
8
 
32
9
  .main-columns {
@@ -34,34 +11,16 @@ label {
34
11
  height: 100vh;
35
12
  }
36
13
 
37
- .side-panel {
38
- height: 100%;
39
- padding: 0 4px 0 0;
40
- border-radius: 0;
41
- position: sticky;
42
- top: 0;
43
- }
44
-
45
- .side-panel > .panel {
46
- border-radius: 0;
47
- height: 100%;
48
- overflow-y: auto;
49
- position: sticky;
50
- top: 0;
51
- }
52
-
53
- .info-panel {
54
- padding: 4px;
55
- border-radius: 0;
14
+ .column {
15
+ padding: 0;
56
16
  }
57
17
 
58
- .info-panel > .panel {
59
- border-radius: 0;
60
- box-shadow: 0 0 0 0
18
+ .breadcrumb * a {
19
+ color: #0a0a0a;
61
20
  }
62
21
 
63
- .title {
64
- word-break: break-all;
22
+ .table td, .table th {
23
+ padding: .2rem .75rem .2rem 0;
65
24
  }
66
25
 
67
26
  td > a {
@@ -69,15 +28,7 @@ td > a {
69
28
  width:100%;
70
29
  }
71
30
 
72
- .notification {
73
- word-wrap: break-word
74
- }
75
-
76
- .list-link {
77
- color: #48c78e;
78
- }
79
-
80
- a:link:not(.list-link) {
31
+ a {
81
32
  color: #0a0a0a;
82
33
  }
83
34
 
@@ -85,39 +36,10 @@ a:visited {
85
36
  color: #0a0a0a;
86
37
  }
87
38
 
88
- .content-column {
89
- height: 100%;
90
- overflow-y: auto;
91
- }
92
-
93
- .content-column > table > thead th {
94
- position: sticky;
95
- top: 0;
96
- }
97
-
98
- .buttons > .panel-block {
99
- padding: .5rem 0 .5rem .5rem;
100
- }
101
-
102
- .level-item > .panel-block {
103
- padding-left: 2px;
104
- padding-right: 2px;
105
- }
106
-
107
- .level-item > .panel-block:first-child {
108
- padding-left: 0;
109
- }
110
-
111
- .panel-block:not(:last-child) {
39
+ .side-panel * .panel-block:not(:last-child) {
112
40
  border-bottom: none !important;
113
41
  }
114
42
 
115
- .container > .level {
116
- margin: 0;
117
- max-width: 100%;
118
- overflow-x: hidden;
119
- }
120
-
121
43
  .level * {
122
44
  max-width: 100%;
123
45
  }
@@ -126,10 +48,6 @@ a:visited {
126
48
  word-break: break-all;
127
49
  }
128
50
 
129
- .columns {
130
- margin: 0;
131
- }
132
-
133
51
  input:focus {
134
52
  outline: 1px solid #48c78e !important;
135
53
  border: 1px solid #48c78e !important;
@@ -218,8 +136,22 @@ select:focus {
218
136
  margin-bottom: 0;
219
137
  }
220
138
 
221
- .level-is-shrinkable .level-left,
222
- .level-is-shrinkable .level-item,
223
- .level-is-shrinkable .level-right {
224
- flex-shrink: 1;
225
- }
139
+ .label.has-field {
140
+ height: 100%;
141
+ display: flex;
142
+ flex-direction: column;
143
+ justify-content: end;
144
+ font-weight: 300;
145
+ word-break: break-all;
146
+ padding: 12px 12px 12px 0;
147
+ }
148
+
149
+ .label.is-required {
150
+ font-weight: 700;
151
+ }
152
+
153
+ @media screen and (max-width: 768px) {
154
+ .label.has-field {
155
+ padding: 12px 0 12px 0;
156
+ }
157
+ }
@@ -5,7 +5,6 @@
5
5
  <div class="columns is-desktop">
6
6
  {% block messages %}{% endblock %}
7
7
  <div class="column p-0 is-8-desktop">
8
- {% include 'ui/partials/header.html' %}
9
8
  <div>
10
9
  {% block detail_content %}{% endblock %}
11
10
  </div>
@@ -4,7 +4,6 @@
4
4
  {% block content %}
5
5
  <div class="columns is-desktop">
6
6
  <div class="column p-0 is-8-desktop">
7
- {% include 'ui/partials/header.html' %}
8
7
  <div>
9
8
  {% include 'ui/partials/form_errors.html' with show_field_errors=True %}
10
9
  {% block form %}{% endblock %}
@@ -0,0 +1,162 @@
1
+ <!doctype html>
2
+ {% load static %}
3
+ {% load i18n %}
4
+ {% load accrete_ui %}
5
+
6
+ <html lang="en" style="overflow: hidden">
7
+
8
+ <head>
9
+ {% block head %}
10
+ <meta charset="utf-8">
11
+ <meta name="viewport" content="width=device-width, initial-scale=1">
12
+ {% block favicon %}<link rel="icon" type="image/svg" href="{% static 'icons/accrete.svg' %}"/>{% endblock %}
13
+ {% block bulma %}<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">{% endblock %}
14
+ {% block style %}
15
+ <link rel="stylesheet" type="text/css" href="{% static "css/accrete.css" %}">
16
+ <link rel="stylesheet" type="text/css" href="{% static "css/icons.css" %}">
17
+ {% endblock %}
18
+ {% block htmx %}
19
+ <script src="https://unpkg.com/htmx.org@1.9.6"></script>
20
+ <script src="https://unpkg.com/hyperscript.org@0.9.11"></script>
21
+ {% endblock %}
22
+ {% block script %}
23
+ <script src="{% static "js/navbar.js" %}" defer type="text/javascript"></script>
24
+ <script src="{% static "js/utils.js" %}" defer type="text/javascript"></script>
25
+ {% endblock %}
26
+ <title>{% block title %}{{ title }}{% endblock %}</title>
27
+ {% endblock %}
28
+ </head>
29
+
30
+
31
+ <body {% block body_attrs %}hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'{% endblock %}>
32
+ {% block navbar %}
33
+ <nav id="navbar" class="navbar is-success is-fixed-top" role="navigation" aria-label="main navigation">
34
+ <div class="navbar-brand">
35
+ {% block navbar_brand %}
36
+ <div class="navbar-item is-unselectable">{{ request.tenant.name }}</div>
37
+ {% endblock %}
38
+ <a id="navbar-burger" role="button" class="navbar-burger"
39
+ aria-label="menu" aria-expanded="false"
40
+ _="on click toggle .is-active on me then toggle .is-active on .navbar-menu"
41
+ >
42
+ {# Display hamburger menu on mobile #}
43
+ <span aria-hidden="true"></span>
44
+ <span aria-hidden="true"></span>
45
+ <span aria-hidden="true"></span>
46
+ </a>
47
+ </div>
48
+
49
+ <div class="navbar-menu is-fixed-top">
50
+ <div class="navbar-start">
51
+ {% block navbar_start %}
52
+ {% combine_templates 'accrete_menu.html' %}
53
+ {% endblock %}
54
+ </div>
55
+
56
+ <div class="navbar-end">
57
+ {% block navbar_end %}
58
+ {% endblock %}
59
+ </div>
60
+ </div>
61
+ </nav>
62
+ {% endblock %}
63
+
64
+ <div class="main-columns columns m-0 is-mobile">
65
+ <div class="side-panel column is-3-widescreen is-2-fullhd is-hidden-touch is-hidden-desktop-only is-hidden-widescreen-only p-0" style="height: 100%; position: sticky; top: 0">
66
+ <nav class="panel is-shadowless pb-5" style="height: 100%; overflow-y: auto; position: sticky; top: 0">
67
+ {% if list_pagination %}
68
+ <div class="panel-block pb-0">
69
+ {% include 'ui/partials/pagination_list.html' %}
70
+ </div>
71
+ {% endif %}
72
+ {% if detail_pagination %}
73
+ <div class="panel-block pb-0">
74
+ {% include 'ui/partials/pagination_detail.html' %}
75
+ </div>
76
+ {% endif %}
77
+ <div id="panel-actions">
78
+ {% for action in actions %}
79
+ <div class="panel-block pb-0">
80
+ {% if action.submit %}
81
+ <input class="button is-fullwidth {{ action.class_list|join:' ' }}"
82
+ type="submit" form={{ action.form_id }} value="{{ action.name }}"
83
+ {% for attr in action.attrs %}{{ attr }}{% endfor %}
84
+ >
85
+ {% else %}
86
+ <a class="button is-fullwidth {{ action.class_list|join:' ' }}"
87
+ href="{{ action.url }}{{ querystring|default_if_none:'?' }}{% if page %}&page={{ page.number }}{% endif %}{{ action.query_params }}"
88
+ {% for attr in action.attrs %}{{ attr }}{% endfor %}
89
+ >{{ action.name }}
90
+ </a>
91
+ {% endif %}
92
+ </div>
93
+ {% endfor %}
94
+ </div>
95
+ {% if filter_terms %}
96
+ <div id="filter-panel" class="mt-2">
97
+ <div class="panel-list px-3 has-text-centered">
98
+ <span>{% translate 'Filter' %}</span>
99
+ </div>
100
+ <div class="panel-block" style="position: sticky">
101
+ <button id="reset-filter-button"
102
+ class="button is-fullwidth mr-1">{% translate 'Reset' %}
103
+ </button>
104
+ <button id="apply-filter-button"
105
+ class="button is-fullwidth ml-1">{% translate 'Filter' %}
106
+ </button>
107
+ </div>
108
+ {% include 'ui/partials/filter.html' %}
109
+ </div>
110
+ {% endif %}
111
+ </nav>
112
+ </div>
113
+
114
+ <div class="column" style="overflow-x: auto">
115
+ <div class="is-flex is-flex-direction-column" style="height: 100%; overflow: hidden">
116
+ <div>
117
+ {% include 'ui/partials/header.html' %}
118
+ </div>
119
+ <div id="content" class="px-3 pb-4" style="overflow: auto; flex-grow: 1">
120
+ {% block messages %}{% endblock %}
121
+ {% block content %}{% endblock %}
122
+ </div>
123
+ <div>
124
+ {% if list_pagination or detail_pagination %}
125
+ <div class="level is-hidden-tablet is-align-self-flex-start m-3">
126
+ <div class="level-item is-align-content-flex-start">
127
+ {% if list_pagination %}
128
+ {% include 'ui/partials/pagination_list.html' %}
129
+ {% elif detail_pagination %}
130
+ {% include 'ui/partials/pagination_detail.html' %}
131
+ {% endif %}
132
+ </div>
133
+ </div>
134
+ {% endif %}
135
+ </div>
136
+ </div>
137
+ </div>
138
+ </div>
139
+
140
+ {% if filter_terms %}
141
+ <div id="filter-modal" class="modal">
142
+ <div class="modal-background filter-modal-close"></div>
143
+ <div class="modal-card" style="height: 100%">
144
+ <header class="modal-card-head">
145
+ <p class="modal-card-title">
146
+ {% block search_modal_title %}{% translate 'Filter' %}{% endblock %}</p>
147
+ <button class="delete filter-modal-close" aria-label="close"></button>
148
+ </header>
149
+ <section id="modal-content" class="modal-card-body">
150
+ </section>
151
+ <footer class="modal-card-foot">
152
+ <button class="button is-fullwidth mr-1"
153
+ onclick="resetFilter()">{% translate 'Reset' %}</button>
154
+ <button id="applyFilterFromModalButton"
155
+ class="button is-fullwidth is-success ml-1">{% translate 'Filter' %}</button>
156
+ </footer>
157
+ </div>
158
+ </div>
159
+ {% endif %}
160
+
161
+ <div id="form-modal" class="modal"></div>
162
+ </body>
@@ -0,0 +1,22 @@
1
+ {% extends 'ui/layout.html' %}
2
+ {% load static %}
3
+ {% load i18n %}
4
+
5
+ {% block script %}
6
+ {{ block.super }}
7
+ <script src="{% static "js/filter.js" %}" defer type="text/javascript"></script>
8
+ {% endblock %}
9
+
10
+ {% block content %}
11
+ <div class="columns is-multiline">
12
+ {% for obj in page %}
13
+ <div class="column is-{{ column_width }}">
14
+ <div class="box p-2 pb-4 mb-1" style="word-break: break-word; height: 100%; border: solid #ccc 1px">
15
+ {% block object_data %}
16
+ {{ obj }}
17
+ {% endblock %}
18
+ </div>
19
+ </div>
20
+ {% endfor %}
21
+ </div>
22
+ {% endblock %}
@@ -0,0 +1,53 @@
1
+ {% load i18n %}
2
+
3
+ <div class="pt-3">
4
+ <div class="level level-is-shrinkable is-flex mb-2 pl-3 {% if detail_pagination %}is-mobile {% endif %}">
5
+ <div class="level-left">
6
+ <div class="level-item has-text-weight-bold">
7
+ <nav class="breadcrumb" aria-label="breadcrumbs" style="white-space: unset; word-break: break-word">
8
+ <ul>
9
+ {% for crumb in breadcrumbs %}
10
+ <li><a class="is-underlined" href="{{ crumb.url|default_if_none:'#' }}{{ querystring }}" aria-current="page">{{ crumb.name }}</a></li>
11
+ {% endfor %}
12
+ <li class="is-active"><a aria-current="page">{{ title }}</a></li>
13
+ </ul>
14
+ </nav>
15
+ </div>
16
+ </div>
17
+ {% if list_pagination or detail_pagination %}
18
+ <div class="level-right is-mobile is-hidden-mobile is-hidden-fullhd is-align-self-flex-start px-3">
19
+ <div class="level-item">
20
+ {% if list_pagination %}
21
+ {% include 'ui/partials/pagination_list.html' %}
22
+ {% elif detail_pagination %}
23
+ {% include 'ui/partials/pagination_detail.html' %}
24
+ {% endif %}
25
+ </div>
26
+ </div>
27
+ {% endif %}
28
+ </div>
29
+
30
+ <div class="is-flex is-hidden-fullhd is-justify-content-space-between mb-2">
31
+ <div class="is-flex py-1 px-1 ml-2" style="overflow-x: auto">
32
+ {% for action in actions %}
33
+ {% if action.submit %}
34
+ <input class="button mr-2 {{ action.class_list|join:' ' }}"
35
+ type="submit" form={{ action.form_id }} value="{{ action.name }}"
36
+ {% for attr in action.attrs %}{{ attr }}{% endfor %}
37
+ >
38
+ {% else %}
39
+ <a class="button mr-2 {{ action.class_list|join:' ' }}"
40
+ href="{{ action.url }}{{ querystring|default_if_none:'?' }}{% if page %}&page={{ page.number }}{% endif %}{{ action.query_params }}"
41
+ {% for attr in action.attrs %}{{ attr }}{% endfor %}
42
+ >{{ action.name }}
43
+ </a>
44
+ {% endif %}
45
+ {% endfor %}
46
+ </div>
47
+ {% if filter_terms %}
48
+ <div class="is-flex ml-2 py-1 pr-3">
49
+ <button id="modal-filter-button" class="button">Filter</button>
50
+ </div>
51
+ {% endif %}
52
+ </div>
53
+ </div>
@@ -0,0 +1,23 @@
1
+ <div id="detail-pagination" class="field has-addons" style="width: 100%">
2
+ <p class="control">
3
+ <button class="button"
4
+ hx-get="{{ previous_object_url }}{{ querystring }}"
5
+ hx-replace-url="true"
6
+ hx-select-oob="#content,#detail-pagination,#panel-actions"
7
+ ><
8
+ </button>
9
+
10
+ </p>
11
+ <p class="control is-expanded">
12
+ <button class="button is-fullwidth px-1" style="white-space: normal">
13
+ <span class="{% if total_objects > 99999 %}is-size-7{% endif %}">{{ current_object_idx }} / {{ total_objects }}</span>
14
+ </button>
15
+ </p>
16
+ <p class="control">
17
+ <button class="button" hx-get="{{ next_object_url }}{{ querystring }}"
18
+ hx-replace-url="true"
19
+ hx-select-oob="#content,#detail-pagination,#panel-actions"
20
+ >>
21
+ </button>
22
+ </p>
23
+ </div>
@@ -4,25 +4,23 @@
4
4
  <button class="button"
5
5
  hx-get="{{ querystring }}&page={% if page.has_previous %}{{ page.previous_page_number }}{% else %}{{ paginator.num_pages }}{% endif %}"
6
6
  hx-replace-url="true"
7
- hx-select-oob="#content,#list-pagination"
7
+ hx-select-oob="#content,#list-pagination,#panel-actions"
8
8
  >
9
9
  <
10
10
  </button>
11
11
  </p>
12
12
  <p class="control is-expanded">
13
- {% if paginator.count > 9999 %}
14
- <button class="button is-fullwidth px-0">
15
- <span class="is-size-7">{{ page.start_index }}-{{ page.end_index }}<br>/{{ paginator.count }}</span>
16
- </button>
17
- {% else %}
18
- <button class="button is-fullwidth">{{ page.start_index }}-{{ page.end_index }}/{{ paginator.count }}</button>
19
- {% endif %}
13
+ <button class="button is-fullwidth px-1" style="white-space: normal">
14
+ <span class="{% if paginator.count > 9999 %}is-size-7{% endif %}">
15
+ {{ page.start_index }}-{{ page.end_index }} / {{ paginator.count }}
16
+ </span>
17
+ </button>
20
18
  </p>
21
19
  <p class="control">
22
20
  <button class="button"
23
21
  hx-get="{{ querystring }}&page={% if page.has_next %}{{ page.next_page_number }}{% else %}1{% endif %}"
24
22
  hx-replace-url="true"
25
- hx-select-oob="#content,#list-pagination"
23
+ hx-select-oob="#content,#list-pagination,#panel-actions"
26
24
  >
27
25
  >
28
26
  </button>