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.
- {accrete-0.0.9 → accrete-0.0.11}/PKG-INFO +1 -1
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/__init__.py +1 -2
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/helper.py +31 -29
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/css/accrete.css +31 -99
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/detail.html +0 -1
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/form.html +0 -1
- accrete-0.0.11/accrete/contrib/ui/templates/ui/layout.html +162 -0
- accrete-0.0.11/accrete/contrib/ui/templates/ui/list.html +22 -0
- accrete-0.0.11/accrete/contrib/ui/templates/ui/partials/header.html +53 -0
- accrete-0.0.11/accrete/contrib/ui/templates/ui/partials/pagination_detail.html +23 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/pagination_list.html +7 -9
- accrete-0.0.11/accrete/contrib/ui/templates/ui/table.html +40 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templatetags/accrete_ui.py +15 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/views.py +1 -1
- {accrete-0.0.9 → accrete-0.0.11}/pyproject.toml +1 -1
- accrete-0.0.9/accrete/contrib/ui/config.py +0 -10
- accrete-0.0.9/accrete/contrib/ui/templates/ui/layout.html +0 -147
- accrete-0.0.9/accrete/contrib/ui/templates/ui/list.html +0 -34
- accrete-0.0.9/accrete/contrib/ui/templates/ui/partials/actions.html +0 -30
- accrete-0.0.9/accrete/contrib/ui/templates/ui/partials/header.html +0 -65
- accrete-0.0.9/accrete/contrib/ui/templates/ui/partials/pagination_detail.html +0 -27
- accrete-0.0.9/accrete/contrib/ui/templates/ui/table.html +0 -41
- {accrete-0.0.9 → accrete-0.0.11}/.gitignore +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/LICENSE +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/README.md +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/admin.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/apps.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/config.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/admin.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/apps.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/forms.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/migrations/0001_initial.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/migrations/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/models.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/queries.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/tests.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/sequence/views.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/admin.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/apps.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/forms.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/migrations/0001_initial.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/migrations/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/models.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/tasks.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/tests.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/system_mail/views.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/admin.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/apps.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/filter.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/migrations/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/css/icons.css +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/icons/Logo.svg +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/icons/accrete.svg +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/filter.js +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/list.js +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/navbar.js +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/static/js/utils.js +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/attrs.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/email.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/file.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/input.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/select.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/text.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/django/forms/widgets/textarea.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/filter.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/form_errors.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/form_modal.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/onchange_form.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templatetags/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/tests.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/urls.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/admin.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/apps.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/locale/de/LC_MESSAGES/django.mo +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/locale/de/LC_MESSAGES/django.po +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/middleware.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/migrations/0001_initial.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/migrations/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/models.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/templates/user/login.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/tests.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/urls.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user/views.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/admin.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/apps.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/config.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/forms.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/migrations/0001_initial.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/migrations/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/models.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/templates/user_registration/mail_templates/confirmation_mail.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/templates/user_registration/registration.html +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/tests.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/urls.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/user_registration/views.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/decorators.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/forms.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/middleware.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/migrations/0001_initial.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/migrations/0002_initial.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/migrations/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/models.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/queries.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/shortcuts.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/tenant.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/tests.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/utils/__init__.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/utils/dates.py +0 -0
- {accrete-0.0.9 → accrete-0.0.11}/accrete/views.py +0 -0
@@ -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
|
-
|
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 =
|
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 =
|
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
|
-
|
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
|
232
|
-
|
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(
|
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
|
-
.
|
2
|
-
|
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
|
-
.
|
29
|
-
|
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
|
-
.
|
38
|
-
|
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
|
-
.
|
59
|
-
|
60
|
-
box-shadow: 0 0 0 0
|
18
|
+
.breadcrumb * a {
|
19
|
+
color: #0a0a0a;
|
61
20
|
}
|
62
21
|
|
63
|
-
.
|
64
|
-
|
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
|
-
|
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
|
-
.
|
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
|
-
.
|
222
|
-
|
223
|
-
|
224
|
-
|
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
|
+
}
|
@@ -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>
|
{accrete-0.0.9 → accrete-0.0.11}/accrete/contrib/ui/templates/ui/partials/pagination_list.html
RENAMED
@@ -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
|
-
|
14
|
-
<
|
15
|
-
|
16
|
-
</
|
17
|
-
|
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>
|