accrete 0.0.142__py3-none-any.whl → 0.0.143__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.
- accrete/contrib/ui/__init__.py +1 -0
- accrete/contrib/ui/templates/ui/form_error.html +1 -1
- accrete/contrib/ui/templates/ui/message.html +1 -1
- accrete/contrib/ui/utils.py +22 -11
- accrete/utils/forms.py +39 -27
- {accrete-0.0.142.dist-info → accrete-0.0.143.dist-info}/METADATA +1 -1
- {accrete-0.0.142.dist-info → accrete-0.0.143.dist-info}/RECORD +9 -9
- {accrete-0.0.142.dist-info → accrete-0.0.143.dist-info}/WHEEL +0 -0
- {accrete-0.0.142.dist-info → accrete-0.0.143.dist-info}/licenses/LICENSE +0 -0
accrete/contrib/ui/__init__.py
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
{{ form.non_field_errors }}
|
6
6
|
{% if form.save_error %}
|
7
7
|
<p>{{ form.save_error }}</p>
|
8
|
-
<span>{% translate 'Error ID' %}: {{ form.save_error_id }}</span>
|
8
|
+
{% if form.save_error_id %}<span>{% translate 'Error ID' %}: {{ form.save_error_id }}</span>{% endif %}
|
9
9
|
{% endif %}
|
10
10
|
</div>
|
11
11
|
{% endif %}
|
@@ -4,7 +4,7 @@
|
|
4
4
|
{% for message in messages %}
|
5
5
|
<div hx-swap-oob="{% if append %}beforeend:#message{% else %}innerHTML:#message{% endif %}">
|
6
6
|
<div class="mb-2" style="min-width: 340px; max-width: 340px" x-data="{ show: false }" x-show="show" x-cloak="" x-init="show = true; {% if not persistent %}setTimeout(() => show = false, 4000){% endif %}" x-transition.duration.200ms>
|
7
|
-
<div class="notification has-text-centered {{ message|message_class }}">
|
7
|
+
<div class="notification has-text-centered {{ message|message_class }}" style="box-shadow: 2px 2px 5px">
|
8
8
|
{% if persistent %}<button class="delete" x-on:click="show = false;"></button>{% endif %}
|
9
9
|
{{ message }}
|
10
10
|
</div>
|
accrete/contrib/ui/utils.py
CHANGED
@@ -3,6 +3,7 @@ import json
|
|
3
3
|
|
4
4
|
from django.http import HttpRequest, HttpResponse
|
5
5
|
from django.shortcuts import render
|
6
|
+
from django.template.loader import render_to_string
|
6
7
|
|
7
8
|
from . import OobContext
|
8
9
|
from .context import BaseContext, ModalContext
|
@@ -30,26 +31,29 @@ def modal_response(
|
|
30
31
|
|
31
32
|
def detail_response(
|
32
33
|
request: HttpRequest,
|
33
|
-
header_template: str,
|
34
|
-
content_template: str,
|
35
|
-
context: BaseContext | dict,
|
34
|
+
header_template: str = None,
|
35
|
+
content_template: str = None,
|
36
|
+
context: BaseContext | dict = None,
|
36
37
|
extra_content: str | None = None
|
37
38
|
) -> HttpResponse:
|
38
39
|
if isinstance(context, BaseContext):
|
39
40
|
context = context.dict()
|
40
|
-
|
41
|
-
('ui/message.html', context)
|
42
|
-
|
41
|
+
templates = [
|
42
|
+
('ui/message.html', context)
|
43
|
+
]
|
44
|
+
if header_template:
|
45
|
+
templates.append(('ui/oob.html', OobContext(
|
43
46
|
template=header_template,
|
44
47
|
swap='innerHTML:#content-right-header',
|
45
48
|
extra=context
|
46
|
-
).dict())
|
47
|
-
|
49
|
+
).dict()))
|
50
|
+
if content_template:
|
51
|
+
templates.append(('ui/oob.html', OobContext(
|
48
52
|
template=content_template,
|
49
53
|
swap='innerHTML:#content-right',
|
50
54
|
extra=context
|
51
|
-
).dict())
|
52
|
-
|
55
|
+
).dict()))
|
56
|
+
content = render_templates(templates, request=request)
|
53
57
|
if extra_content:
|
54
58
|
content += extra_content
|
55
59
|
res = HttpResponse(content=content)
|
@@ -57,8 +61,15 @@ def detail_response(
|
|
57
61
|
return res
|
58
62
|
|
59
63
|
|
64
|
+
def search_select_response(queryset) -> HttpResponse:
|
65
|
+
return HttpResponse(render_to_string(
|
66
|
+
'ui/widgets/model_search_select_options.html',
|
67
|
+
{'options': queryset}
|
68
|
+
))
|
69
|
+
|
70
|
+
|
60
71
|
def add_trigger(
|
61
|
-
response:
|
72
|
+
response: HttpResponse,
|
62
73
|
trigger: dict | str,
|
63
74
|
header: str = 'HX-Trigger'
|
64
75
|
) -> HttpResponse:
|
accrete/utils/forms.py
CHANGED
@@ -1,79 +1,91 @@
|
|
1
1
|
import re
|
2
2
|
import logging
|
3
3
|
from uuid import uuid4
|
4
|
-
from typing import Type
|
4
|
+
from typing import Type, Any
|
5
|
+
from dataclasses import dataclass, field
|
5
6
|
from django.db import transaction
|
6
7
|
from django.forms import BaseFormSet, Form, ModelForm
|
7
8
|
|
8
9
|
_logger = logging.getLogger(__name__)
|
9
10
|
|
10
11
|
|
11
|
-
|
12
|
+
@dataclass
|
13
|
+
class FormResult:
|
14
|
+
|
15
|
+
form: Form | ModelForm
|
16
|
+
is_saved: bool = False
|
17
|
+
save_error: str | None = None
|
18
|
+
save_error_id: str | None = None
|
19
|
+
res: Any = None # return value of form.save()
|
20
|
+
inline_formsets: list = field(default_factory=list)
|
21
|
+
|
22
|
+
def __getattr__(self, item):
|
23
|
+
return getattr(self.form, item)
|
24
|
+
|
25
|
+
def __getitem__(self, item):
|
26
|
+
return self.form.__getitem__(item)
|
27
|
+
|
28
|
+
|
29
|
+
def save_form(form: Form | ModelForm, commit=True, reraise=False) -> FormResult:
|
12
30
|
if not hasattr(form, 'save'):
|
13
31
|
raise AttributeError('Form must have method "save" implemented.')
|
14
|
-
|
15
|
-
form.save_error = None
|
16
|
-
form.save_error_id = None
|
17
|
-
form.res = None
|
32
|
+
result = FormResult(form=form)
|
18
33
|
try:
|
19
34
|
if form.is_valid():
|
20
35
|
with transaction.atomic():
|
21
|
-
|
22
|
-
|
36
|
+
result.res = form.save(commit=commit)
|
37
|
+
result.is_saved = True
|
23
38
|
except Exception as e:
|
24
|
-
|
39
|
+
result.save_error = repr(e)
|
25
40
|
error_id = str(uuid4())[:8]
|
26
41
|
_logger.exception(f'{error_id}: {e}')
|
27
|
-
|
42
|
+
result.save_error_id = error_id
|
28
43
|
if reraise:
|
29
44
|
raise e
|
30
|
-
return
|
45
|
+
return result
|
31
46
|
|
32
47
|
|
33
|
-
def save_forms(form, inline_formsets: list = None, commit=True, reraise: bool = False) ->
|
48
|
+
def save_forms(form, inline_formsets: list = None, commit=True, reraise: bool = False) -> FormResult:
|
34
49
|
|
35
50
|
def handle_error(error):
|
36
|
-
|
51
|
+
result.save_error = repr(error)
|
37
52
|
error_id = str(uuid4())[:8]
|
38
53
|
_logger.exception(f'{error_id}: {error}')
|
39
|
-
|
54
|
+
result.save_error_id = error_id
|
40
55
|
|
41
56
|
if not hasattr(form, 'save'):
|
42
57
|
raise AttributeError('Form must have method "save" implemented.')
|
43
58
|
|
44
|
-
|
45
|
-
|
46
|
-
form.save_error_id = None
|
47
|
-
form.res = None
|
48
|
-
form.inline_forms = inline_formsets
|
59
|
+
result = FormResult(form=form)
|
60
|
+
result.inline_forms = inline_formsets
|
49
61
|
|
50
62
|
try:
|
51
63
|
form.is_valid()
|
52
64
|
inlines_valid = all([
|
53
|
-
inline_formset.is_valid() for inline_formset in inline_formsets
|
65
|
+
inline_formset.is_valid() for inline_formset in result.inline_formsets
|
54
66
|
])
|
55
67
|
except Exception as e:
|
56
68
|
handle_error(e)
|
57
69
|
if reraise:
|
58
70
|
raise e
|
59
|
-
return
|
71
|
+
return result
|
60
72
|
|
61
73
|
if not form.is_valid() or not inlines_valid:
|
62
|
-
return
|
74
|
+
return result
|
63
75
|
|
64
76
|
try:
|
65
77
|
with transaction.atomic():
|
66
|
-
|
67
|
-
for inline_formset in inline_formsets:
|
78
|
+
result.res = form.save(commit=commit)
|
79
|
+
for inline_formset in result.inline_formsets:
|
68
80
|
inline_formset.save(commit=commit)
|
69
81
|
except Exception as e:
|
70
82
|
handle_error(e)
|
71
83
|
if reraise:
|
72
84
|
raise e
|
73
|
-
return
|
85
|
+
return result
|
74
86
|
|
75
|
-
|
76
|
-
return
|
87
|
+
result.is_saved = True
|
88
|
+
return result
|
77
89
|
|
78
90
|
|
79
91
|
def inline_vals_from_post(post: dict, prefix: str) -> list[dict]:
|
@@ -60,7 +60,7 @@ accrete/contrib/system_mail/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2
|
|
60
60
|
accrete/contrib/system_mail/views.py,sha256=xc1IQHrsij7j33TUbo-_oewy3vs03pw_etpBWaMYJl0,63
|
61
61
|
accrete/contrib/system_mail/migrations/0001_initial.py,sha256=6cwkkRXGjXvwXoMjjgmWmcPyXSTlUbhW1vMiHObk9MQ,1074
|
62
62
|
accrete/contrib/system_mail/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
63
|
-
accrete/contrib/ui/__init__.py,sha256=
|
63
|
+
accrete/contrib/ui/__init__.py,sha256=7zRjbKxFZ_ox5XQmHmfxbKKJRcm_wxgmjXS759GdlEo,328
|
64
64
|
accrete/contrib/ui/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
|
65
65
|
accrete/contrib/ui/apps.py,sha256=E0ao2ox6PQ3ldfeR17FXJUUJuGiWjm2DPCxHbPXGzls,152
|
66
66
|
accrete/contrib/ui/context.py,sha256=7FBNcPG77dU7asMomiRACP1bypE3lbsHXdg90MXbjf4,2616
|
@@ -69,7 +69,7 @@ accrete/contrib/ui/middleware.py,sha256=QprWR8FXK9iMPIvLQAeYASaUJSW0uD9BHoYroMKr
|
|
69
69
|
accrete/contrib/ui/models.py,sha256=Vjc0p2XbAPgE6HyTF6vll98A4eDhA5AvaQqsc4kQ9AQ,57
|
70
70
|
accrete/contrib/ui/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
71
71
|
accrete/contrib/ui/urls.py,sha256=5XUfK85HYWYf7oopMoJEEYmQ6pNgHgZBErBEn97pBt4,337
|
72
|
-
accrete/contrib/ui/utils.py,sha256=
|
72
|
+
accrete/contrib/ui/utils.py,sha256=f660YNavcQQkO6TtpnEBsT2O3KoJk-M5wgBnhnWB1EI,2563
|
73
73
|
accrete/contrib/ui/views.py,sha256=5VUbP0jgMcLMv9-3AKxkV315RA0qXuw5PmTRejPc0Yg,1136
|
74
74
|
accrete/contrib/ui/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
75
|
accrete/contrib/ui/static/bulma/LICENSE,sha256=--fY7Bi3Lt7RXXnKc9pe756OJY9fGv-D5OmT5pdSJ5w,1080
|
@@ -199,11 +199,11 @@ accrete/contrib/ui/templates/django/forms/widgets/text.html,sha256=MSmLlQc7PsPoD
|
|
199
199
|
accrete/contrib/ui/templates/django/forms/widgets/textarea.html,sha256=c9BTedqb3IkXLyVYd0p9pR8DFnsXCNGoxVBWZTk_Fic,278
|
200
200
|
accrete/contrib/ui/templates/ui/content_right.html,sha256=3DQqbjAafaLtWUTGcBTCzObQEII35DVLfWQ6i6KDh6Y,379
|
201
201
|
accrete/contrib/ui/templates/ui/favicon.html,sha256=ZSK6qDGV4Cexgt0VA3KOHYN100yZHOFjfOiFZVudWg0,90
|
202
|
-
accrete/contrib/ui/templates/ui/form_error.html,sha256=
|
202
|
+
accrete/contrib/ui/templates/ui/form_error.html,sha256=WWqfFWyJ_LCzm5IkxXztn23GFak5wyM2HZcmiZ3Eq9s,417
|
203
203
|
accrete/contrib/ui/templates/ui/layout.html,sha256=yDcZYMUdT3ZaqXPC1qg2Lme_dBnBUG2ZzGyrG0V6ces,13174
|
204
204
|
accrete/contrib/ui/templates/ui/list.html,sha256=o0YGM2O4SUlFcP5jMwdEOXVTCuEfanvd77yH7OBRRws,2208
|
205
205
|
accrete/contrib/ui/templates/ui/list_update.html,sha256=mLQTCgkKfVI5jrgei-Upc1u87iXL0Q63uLzXHPwMyeo,110
|
206
|
-
accrete/contrib/ui/templates/ui/message.html,sha256=
|
206
|
+
accrete/contrib/ui/templates/ui/message.html,sha256=jhqkPlWtOaPDoclTm4yKwowA7vR-bWbwfjo2b48uJt0,764
|
207
207
|
accrete/contrib/ui/templates/ui/modal.html,sha256=2HwmqcUvGqWfKpuKO1EOfr5F1Lcwn7eChbu3XbrxvYg,2233
|
208
208
|
accrete/contrib/ui/templates/ui/oob.html,sha256=lZHIBBYclefbGkKguS1A7vrtOhODJizbSRaGAAHDvG8,267
|
209
209
|
accrete/contrib/ui/templates/ui/table.html,sha256=u6JJz1FykuljZiiC2hL83hy8RbMeXcSH8xuU1ji2SHc,3939
|
@@ -270,11 +270,11 @@ accrete/migrations/0007_accessgroup_description.py,sha256=T8BX0gSckC_fM_uD6a5-fd
|
|
270
270
|
accrete/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
271
271
|
accrete/utils/__init__.py,sha256=saw9zi2XItJOPbv4fjTXOpl7StNtC803jHhapFcGx08,312
|
272
272
|
accrete/utils/dates.py,sha256=apM6kt6JhGrKgoT0jfav1W-8AUVTxNc9xt3fJQ2n0JI,1492
|
273
|
-
accrete/utils/forms.py,sha256=
|
273
|
+
accrete/utils/forms.py,sha256=H8ojiMRrafdj6Jd-86w2SxkaqshKepNHP2_XOXsMmKQ,3758
|
274
274
|
accrete/utils/log.py,sha256=BH0MBDweAjx30wGBO4F3sFhbgkSoEs7T1lLLjlYZNnA,407
|
275
275
|
accrete/utils/models.py,sha256=2xTacvcpmDK_Bp4rAK7JdVLf8HU009LYNJ6eSpMgYZI,1014
|
276
276
|
accrete/utils/views.py,sha256=PsKpUFjxCm6_l_nfVs-cNIY0lNTdkocm2uohR3o9eEo,5025
|
277
|
-
accrete-0.0.
|
278
|
-
accrete-0.0.
|
279
|
-
accrete-0.0.
|
280
|
-
accrete-0.0.
|
277
|
+
accrete-0.0.143.dist-info/METADATA,sha256=JfyR1afDladHASbgL-b4Kg1nA6ijfDlOmqEv2qV0qyc,4953
|
278
|
+
accrete-0.0.143.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
279
|
+
accrete-0.0.143.dist-info/licenses/LICENSE,sha256=vHwb4Qnv8UfYKFiCWyTuRGsi49x19UQwHRCky3b2_NE,1057
|
280
|
+
accrete-0.0.143.dist-info/RECORD,,
|
File without changes
|
File without changes
|